/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Enemy class (moves left/right) var Enemy = Container.expand(function () { var self = Container.call(this); var en = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 3 + Math.random() * 2; self.direction = Math.random() < 0.5 ? 1 : -1; self.range = 300 + Math.random() * 200; self.originX = 0; self.update = function () { self.x += self.speed * self.direction; if (Math.abs(self.x - self.originX) > self.range) { self.direction *= -1; } }; return self; }); // Football class (follows player or can be dropped) var Football = Container.expand(function () { var self = Container.call(this); var fb = self.attachAsset('football', { anchorX: 0.5, anchorY: 0.5 }); self.carried = true; self.vx = 0; self.vy = 0; self.update = function () { if (!self.carried) { // Gravity self.vy += 2.5; self.x += self.vx; self.y += self.vy; // Collide with platforms for (var i = 0; i < platforms.length; ++i) { var p = platforms[i]; if (self.intersects(p) && self.vy > 0) { self.y = p.y - p.height / 2 - self.height / 2; self.vy = 0; } } // Clamp to ground if (self.y > 2732 - 40) { self.y = 2732 - 40; self.vy = 0; } } }; return self; }); // Goal class var Goal = Container.expand(function () { var self = Container.call(this); var g = self.attachAsset('goal', { anchorX: 0.5, anchorY: 1 }); return self; }); // Hazard class var Hazard = Container.expand(function () { var self = Container.call(this); var hz = self.attachAsset('hazard', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Platform class var Platform = Container.expand(function () { var self = Container.call(this); var plat = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var pl = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.onGround = false; self.carrying = true; self.update = function () { // Apply gravity self.vy += 3.5; // Move self.x += self.vx; self.y += self.vy; // Clamp to world bounds if (self.x < self.width / 2) self.x = self.width / 2; if (self.x > 2048 - self.width / 2) self.x = 2048 - self.width / 2; if (self.y > 2732 - 40) { self.y = 2732 - 40; self.vy = 0; self.onGround = true; } // Collide with platforms self.onGround = false; for (var i = 0; i < platforms.length; ++i) { var p = platforms[i]; if (self.intersects(p) && self.vy > 0) { self.y = p.y - p.height / 2 - self.height / 2; self.vy = 0; self.onGround = true; } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222244 }); /**** * Game Code ****/ // Football (ellipse), Player (box), Enemy (box), Platform (box), Goal (box), Hazard (box) // Level data (platforms, hazards, enemies) var level = 1; if (storage.level) level = storage.level; var platforms = []; var hazards = []; var enemies = []; var player = null; var football = null; var goal = null; var dragging = false; var dragStartX = 0; var dragStartY = 0; var moveDir = 0; // -1 left, 1 right, 0 none var jumpQueued = false; var infoText = null; var levelText = null; var carryingBall = true; var canPickupBall = false; var lastGoalIntersect = false; var lastEnemyIntersect = false; var lastHazardIntersect = false; var lastFootballIntersect = false; var lastFootballGoalIntersect = false; var lastFootballHazardIntersect = false; var lastFootballEnemyIntersect = false; // GUI: Level display levelText = new Text2('Level ' + level, { size: 90, fill: '#fff' }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); // GUI: Info text infoText = new Text2('', { size: 70, fill: '#fff' }); infoText.anchor.set(0.5, 0); LK.gui.bottom.addChild(infoText); // Helper: Reset level function setupLevel() { // Clear old for (var i = 0; i < platforms.length; ++i) platforms[i].destroy(); for (var i = 0; i < hazards.length; ++i) hazards[i].destroy(); for (var i = 0; i < enemies.length; ++i) enemies[i].destroy(); if (player) player.destroy(); if (football) football.destroy(); if (goal) goal.destroy(); platforms = []; hazards = []; enemies = []; player = null; football = null; goal = null; carryingBall = true; canPickupBall = false; lastGoalIntersect = false; lastEnemyIntersect = false; lastHazardIntersect = false; lastFootballIntersect = false; lastFootballGoalIntersect = false; lastFootballHazardIntersect = false; lastFootballEnemyIntersect = false; // Level layout // Start platform var plat = new Platform(); plat.x = 200; plat.y = 2500; game.addChild(plat); platforms.push(plat); // Middle platforms var platCount = 4 + level; for (var i = 0; i < platCount; ++i) { var p = new Platform(); p.x = 400 + i * 350 + Math.random() * 80; p.y = 2500 - i * 350 + Math.random() * 60; game.addChild(p); platforms.push(p); // Hazards if (level > 1 && Math.random() < 0.4) { var hz = new Hazard(); hz.x = p.x + (Math.random() < 0.5 ? -1 : 1) * 100; hz.y = p.y - 40; game.addChild(hz); hazards.push(hz); } // Enemies if (level > 1 && Math.random() < 0.5) { var en = new Enemy(); en.x = p.x; en.y = p.y - 100; en.originX = en.x; game.addChild(en); enemies.push(en); } } // Goal goal = new Goal(); goal.x = platforms[platforms.length - 1].x + 300; goal.y = platforms[platforms.length - 1].y - 60; game.addChild(goal); // Player player = new Player(); player.x = plat.x; player.y = plat.y - 120; game.addChild(player); // Football football = new Football(); football.x = player.x; football.y = player.y - 100; football.carried = true; game.addChild(football); // GUI levelText.setText('Level ' + level); infoText.setText('Drag to move, tap to jump'); } // Touch controls game.down = function (x, y, obj) { // If tap below half screen, jump if (y > 2732 / 2) { jumpQueued = true; return; } // Else, drag to move dragging = true; dragStartX = x; dragStartY = y; moveDir = 0; }; game.move = function (x, y, obj) { if (dragging) { var dx = x - dragStartX; if (Math.abs(dx) > 30) { moveDir = dx > 0 ? 1 : -1; } else { moveDir = 0; } } }; game.up = function (x, y, obj) { dragging = false; moveDir = 0; }; // Main update loop game.update = function () { // Player movement if (moveDir !== 0) { player.vx = 14 * moveDir; } else { player.vx *= 0.7; if (Math.abs(player.vx) < 1) player.vx = 0; } // Jump if (jumpQueued && player.onGround) { player.vy = -55 - 4 * level; jumpQueued = false; } jumpQueued = false; // Update player, football, enemies player.update(); football.update(); for (var i = 0; i < enemies.length; ++i) enemies[i].update(); // Carry football if (football.carried) { football.x = player.x; football.y = player.y - player.height / 2 - football.height / 2 + 20; football.vx = 0; football.vy = 0; } // Football pickup var footballNear = player.intersects(football); if (!football.carried && footballNear && !carryingBall) { carryingBall = true; football.carried = true; infoText.setText('Ball picked up!'); tween(infoText, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { infoText.setText(''); infoText.alpha = 1; } }); } // Football drop on enemy/hazard var hitEnemy = false; for (var i = 0; i < enemies.length; ++i) { if (player.intersects(enemies[i]) && football.carried) hitEnemy = true; } var hitHazard = false; for (var i = 0; i < hazards.length; ++i) { if (player.intersects(hazards[i]) && football.carried) hitHazard = true; } if ((hitEnemy || hitHazard) && football.carried) { football.carried = false; carryingBall = false; football.vx = player.vx * 0.7; football.vy = -20; infoText.setText('You dropped the ball!'); tween(infoText, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { infoText.setText(''); infoText.alpha = 1; } }); LK.effects.flashObject(player, 0xff0000, 600); } // Football collides with hazard/enemy: reset to start var fbHitHazard = false; for (var i = 0; i < hazards.length; ++i) { if (football.intersects(hazards[i]) && !football.carried) fbHitHazard = true; } var fbHitEnemy = false; for (var i = 0; i < enemies.length; ++i) { if (football.intersects(enemies[i]) && !football.carried) fbHitEnemy = true; } if ((fbHitHazard || fbHitEnemy) && !football.carried) { // Reset football to start football.x = platforms[0].x; football.y = platforms[0].y - 100; football.vx = 0; football.vy = 0; infoText.setText('Ball reset!'); tween(infoText, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { infoText.setText(''); infoText.alpha = 1; } }); } // Win condition: player+football at goal var atGoal = player.intersects(goal); var fbAtGoal = football.intersects(goal); if (atGoal && football.carried && fbAtGoal) { // Next level infoText.setText('Touchdown! Next level...'); tween(infoText, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { infoText.setText(''); infoText.alpha = 1; } }); level += 1; storage.level = level; LK.setTimeout(setupLevel, 1200); return; } // Lose condition: player falls off if (player.y > 2732 - 10) { LK.effects.flashScreen(0xff0000, 1000); infoText.setText('You fell! Try again.'); tween(infoText, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { infoText.setText(''); infoText.alpha = 1; } }); LK.setTimeout(setupLevel, 1200); return; } // Lose condition: football lost off screen if (football.y > 2732 - 10) { infoText.setText('Ball lost! Try again.'); tween(infoText, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { infoText.setText(''); infoText.alpha = 1; } }); LK.setTimeout(setupLevel, 1200); return; } }; // Start first level setupLevel();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,429 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+// Enemy class (moves left/right)
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var en = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 3 + Math.random() * 2;
+ self.direction = Math.random() < 0.5 ? 1 : -1;
+ self.range = 300 + Math.random() * 200;
+ self.originX = 0;
+ self.update = function () {
+ self.x += self.speed * self.direction;
+ if (Math.abs(self.x - self.originX) > self.range) {
+ self.direction *= -1;
+ }
+ };
+ return self;
+});
+// Football class (follows player or can be dropped)
+var Football = Container.expand(function () {
+ var self = Container.call(this);
+ var fb = self.attachAsset('football', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.carried = true;
+ self.vx = 0;
+ self.vy = 0;
+ self.update = function () {
+ if (!self.carried) {
+ // Gravity
+ self.vy += 2.5;
+ self.x += self.vx;
+ self.y += self.vy;
+ // Collide with platforms
+ for (var i = 0; i < platforms.length; ++i) {
+ var p = platforms[i];
+ if (self.intersects(p) && self.vy > 0) {
+ self.y = p.y - p.height / 2 - self.height / 2;
+ self.vy = 0;
+ }
+ }
+ // Clamp to ground
+ if (self.y > 2732 - 40) {
+ self.y = 2732 - 40;
+ self.vy = 0;
+ }
+ }
+ };
+ return self;
+});
+// Goal class
+var Goal = Container.expand(function () {
+ var self = Container.call(this);
+ var g = self.attachAsset('goal', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ return self;
+});
+// Hazard class
+var Hazard = Container.expand(function () {
+ var self = Container.call(this);
+ var hz = self.attachAsset('hazard', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ return self;
+});
+// Platform class
+var Platform = Container.expand(function () {
+ var self = Container.call(this);
+ var plat = self.attachAsset('platform', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ return self;
+});
+// Player class
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var pl = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.vx = 0;
+ self.vy = 0;
+ self.onGround = false;
+ self.carrying = true;
+ self.update = function () {
+ // Apply gravity
+ self.vy += 3.5;
+ // Move
+ self.x += self.vx;
+ self.y += self.vy;
+ // Clamp to world bounds
+ if (self.x < self.width / 2) self.x = self.width / 2;
+ if (self.x > 2048 - self.width / 2) self.x = 2048 - self.width / 2;
+ if (self.y > 2732 - 40) {
+ self.y = 2732 - 40;
+ self.vy = 0;
+ self.onGround = true;
+ }
+ // Collide with platforms
+ self.onGround = false;
+ for (var i = 0; i < platforms.length; ++i) {
+ var p = platforms[i];
+ if (self.intersects(p) && self.vy > 0) {
+ self.y = p.y - p.height / 2 - self.height / 2;
+ self.vy = 0;
+ self.onGround = true;
+ }
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222244
+});
+
+/****
+* Game Code
+****/
+// Football (ellipse), Player (box), Enemy (box), Platform (box), Goal (box), Hazard (box)
+// Level data (platforms, hazards, enemies)
+var level = 1;
+if (storage.level) level = storage.level;
+var platforms = [];
+var hazards = [];
+var enemies = [];
+var player = null;
+var football = null;
+var goal = null;
+var dragging = false;
+var dragStartX = 0;
+var dragStartY = 0;
+var moveDir = 0; // -1 left, 1 right, 0 none
+var jumpQueued = false;
+var infoText = null;
+var levelText = null;
+var carryingBall = true;
+var canPickupBall = false;
+var lastGoalIntersect = false;
+var lastEnemyIntersect = false;
+var lastHazardIntersect = false;
+var lastFootballIntersect = false;
+var lastFootballGoalIntersect = false;
+var lastFootballHazardIntersect = false;
+var lastFootballEnemyIntersect = false;
+// GUI: Level display
+levelText = new Text2('Level ' + level, {
+ size: 90,
+ fill: '#fff'
+});
+levelText.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelText);
+// GUI: Info text
+infoText = new Text2('', {
+ size: 70,
+ fill: '#fff'
+});
+infoText.anchor.set(0.5, 0);
+LK.gui.bottom.addChild(infoText);
+// Helper: Reset level
+function setupLevel() {
+ // Clear old
+ for (var i = 0; i < platforms.length; ++i) platforms[i].destroy();
+ for (var i = 0; i < hazards.length; ++i) hazards[i].destroy();
+ for (var i = 0; i < enemies.length; ++i) enemies[i].destroy();
+ if (player) player.destroy();
+ if (football) football.destroy();
+ if (goal) goal.destroy();
+ platforms = [];
+ hazards = [];
+ enemies = [];
+ player = null;
+ football = null;
+ goal = null;
+ carryingBall = true;
+ canPickupBall = false;
+ lastGoalIntersect = false;
+ lastEnemyIntersect = false;
+ lastHazardIntersect = false;
+ lastFootballIntersect = false;
+ lastFootballGoalIntersect = false;
+ lastFootballHazardIntersect = false;
+ lastFootballEnemyIntersect = false;
+ // Level layout
+ // Start platform
+ var plat = new Platform();
+ plat.x = 200;
+ plat.y = 2500;
+ game.addChild(plat);
+ platforms.push(plat);
+ // Middle platforms
+ var platCount = 4 + level;
+ for (var i = 0; i < platCount; ++i) {
+ var p = new Platform();
+ p.x = 400 + i * 350 + Math.random() * 80;
+ p.y = 2500 - i * 350 + Math.random() * 60;
+ game.addChild(p);
+ platforms.push(p);
+ // Hazards
+ if (level > 1 && Math.random() < 0.4) {
+ var hz = new Hazard();
+ hz.x = p.x + (Math.random() < 0.5 ? -1 : 1) * 100;
+ hz.y = p.y - 40;
+ game.addChild(hz);
+ hazards.push(hz);
+ }
+ // Enemies
+ if (level > 1 && Math.random() < 0.5) {
+ var en = new Enemy();
+ en.x = p.x;
+ en.y = p.y - 100;
+ en.originX = en.x;
+ game.addChild(en);
+ enemies.push(en);
+ }
+ }
+ // Goal
+ goal = new Goal();
+ goal.x = platforms[platforms.length - 1].x + 300;
+ goal.y = platforms[platforms.length - 1].y - 60;
+ game.addChild(goal);
+ // Player
+ player = new Player();
+ player.x = plat.x;
+ player.y = plat.y - 120;
+ game.addChild(player);
+ // Football
+ football = new Football();
+ football.x = player.x;
+ football.y = player.y - 100;
+ football.carried = true;
+ game.addChild(football);
+ // GUI
+ levelText.setText('Level ' + level);
+ infoText.setText('Drag to move, tap to jump');
+}
+// Touch controls
+game.down = function (x, y, obj) {
+ // If tap below half screen, jump
+ if (y > 2732 / 2) {
+ jumpQueued = true;
+ return;
+ }
+ // Else, drag to move
+ dragging = true;
+ dragStartX = x;
+ dragStartY = y;
+ moveDir = 0;
+};
+game.move = function (x, y, obj) {
+ if (dragging) {
+ var dx = x - dragStartX;
+ if (Math.abs(dx) > 30) {
+ moveDir = dx > 0 ? 1 : -1;
+ } else {
+ moveDir = 0;
+ }
+ }
+};
+game.up = function (x, y, obj) {
+ dragging = false;
+ moveDir = 0;
+};
+// Main update loop
+game.update = function () {
+ // Player movement
+ if (moveDir !== 0) {
+ player.vx = 14 * moveDir;
+ } else {
+ player.vx *= 0.7;
+ if (Math.abs(player.vx) < 1) player.vx = 0;
+ }
+ // Jump
+ if (jumpQueued && player.onGround) {
+ player.vy = -55 - 4 * level;
+ jumpQueued = false;
+ }
+ jumpQueued = false;
+ // Update player, football, enemies
+ player.update();
+ football.update();
+ for (var i = 0; i < enemies.length; ++i) enemies[i].update();
+ // Carry football
+ if (football.carried) {
+ football.x = player.x;
+ football.y = player.y - player.height / 2 - football.height / 2 + 20;
+ football.vx = 0;
+ football.vy = 0;
+ }
+ // Football pickup
+ var footballNear = player.intersects(football);
+ if (!football.carried && footballNear && !carryingBall) {
+ carryingBall = true;
+ football.carried = true;
+ infoText.setText('Ball picked up!');
+ tween(infoText, {
+ alpha: 0
+ }, {
+ duration: 1200,
+ onFinish: function onFinish() {
+ infoText.setText('');
+ infoText.alpha = 1;
+ }
+ });
+ }
+ // Football drop on enemy/hazard
+ var hitEnemy = false;
+ for (var i = 0; i < enemies.length; ++i) {
+ if (player.intersects(enemies[i]) && football.carried) hitEnemy = true;
+ }
+ var hitHazard = false;
+ for (var i = 0; i < hazards.length; ++i) {
+ if (player.intersects(hazards[i]) && football.carried) hitHazard = true;
+ }
+ if ((hitEnemy || hitHazard) && football.carried) {
+ football.carried = false;
+ carryingBall = false;
+ football.vx = player.vx * 0.7;
+ football.vy = -20;
+ infoText.setText('You dropped the ball!');
+ tween(infoText, {
+ alpha: 0
+ }, {
+ duration: 1200,
+ onFinish: function onFinish() {
+ infoText.setText('');
+ infoText.alpha = 1;
+ }
+ });
+ LK.effects.flashObject(player, 0xff0000, 600);
+ }
+ // Football collides with hazard/enemy: reset to start
+ var fbHitHazard = false;
+ for (var i = 0; i < hazards.length; ++i) {
+ if (football.intersects(hazards[i]) && !football.carried) fbHitHazard = true;
+ }
+ var fbHitEnemy = false;
+ for (var i = 0; i < enemies.length; ++i) {
+ if (football.intersects(enemies[i]) && !football.carried) fbHitEnemy = true;
+ }
+ if ((fbHitHazard || fbHitEnemy) && !football.carried) {
+ // Reset football to start
+ football.x = platforms[0].x;
+ football.y = platforms[0].y - 100;
+ football.vx = 0;
+ football.vy = 0;
+ infoText.setText('Ball reset!');
+ tween(infoText, {
+ alpha: 0
+ }, {
+ duration: 1200,
+ onFinish: function onFinish() {
+ infoText.setText('');
+ infoText.alpha = 1;
+ }
+ });
+ }
+ // Win condition: player+football at goal
+ var atGoal = player.intersects(goal);
+ var fbAtGoal = football.intersects(goal);
+ if (atGoal && football.carried && fbAtGoal) {
+ // Next level
+ infoText.setText('Touchdown! Next level...');
+ tween(infoText, {
+ alpha: 0
+ }, {
+ duration: 1200,
+ onFinish: function onFinish() {
+ infoText.setText('');
+ infoText.alpha = 1;
+ }
+ });
+ level += 1;
+ storage.level = level;
+ LK.setTimeout(setupLevel, 1200);
+ return;
+ }
+ // Lose condition: player falls off
+ if (player.y > 2732 - 10) {
+ LK.effects.flashScreen(0xff0000, 1000);
+ infoText.setText('You fell! Try again.');
+ tween(infoText, {
+ alpha: 0
+ }, {
+ duration: 1200,
+ onFinish: function onFinish() {
+ infoText.setText('');
+ infoText.alpha = 1;
+ }
+ });
+ LK.setTimeout(setupLevel, 1200);
+ return;
+ }
+ // Lose condition: football lost off screen
+ if (football.y > 2732 - 10) {
+ infoText.setText('Ball lost! Try again.');
+ tween(infoText, {
+ alpha: 0
+ }, {
+ duration: 1200,
+ onFinish: function onFinish() {
+ infoText.setText('');
+ infoText.alpha = 1;
+ }
+ });
+ LK.setTimeout(setupLevel, 1200);
+ return;
+ }
+};
+// Start first level
+setupLevel();
\ No newline at end of file