/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Checkpoint class: save progress var Checkpoint = Container.expand(function () { var self = Container.call(this); var cp = self.attachAsset('checkpoint', { anchorX: 0.5, anchorY: 1 }); self.activated = false; self.activate = function () { if (!self.activated) { self.activated = true; tween(cp, { tint: 0x00ff00 }, { duration: 300 }); } }; return self; }); // Platform class: static or moving platform var Platform = Container.expand(function () { var self = Container.call(this); // Attach platform asset (box shape) var plat = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); // Platform movement config self.isMoving = false; self.moveAxis = 'x'; // 'x' or 'y' self.moveFrom = 0; self.moveTo = 0; self.moveDuration = 0; self.moveDir = 1; // For moving platforms, set up tween self.startMove = function () { if (!self.isMoving) return; var prop = {}; prop[self.moveAxis] = self.moveTo; tween(self, prop, { duration: self.moveDuration, easing: tween.linear, onFinish: function onFinish() { // Swap direction var tmp = self.moveFrom; self.moveFrom = self.moveTo; self.moveTo = tmp; self.startMove(); } }); }; return self; }); // Player class: main character var Player = Container.expand(function () { var self = Container.call(this); var _char = self.attachAsset('player', { anchorX: 0.5, anchorY: 1 }); self.width = _char.width; self.height = _char.height; self.vx = 0; self.vy = 0; self.onGround = false; self.dead = false; self.jumpQueued = false; self.respawn = function (x, y) { self.x = x; self.y = y; self.vx = 0; self.vy = 0; self.dead = false; }; return self; }); // Spike class: deadly obstacle var Spike = Container.expand(function () { var self = Container.call(this); // Attach spike asset (triangle shape, but use box for now) var spike = self.attachAsset('spike', { anchorX: 0.5, anchorY: 1 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ /* Level is an array of objects: {type: 'platform'|'spike'|'checkpoint', x, y, [w], [h], [moveAxis], [moveFrom], [moveTo], [moveDuration]} All positions are in game coordinates. */ // --- Level Data (MVP: 1 level, hardcoded) --- // Tween plugin for platform/character movement and effects // --- Asset Initialization --- var levelData = [ // Floor { type: 'platform', x: 1024, y: 2600, w: 1200, h: 60 }, // First jump { type: 'platform', x: 600, y: 2200, w: 400, h: 40 }, { type: 'spike', x: 800, y: 2160 }, // Second jump { type: 'platform', x: 1400, y: 2000, w: 400, h: 40 }, { type: 'spike', x: 1200, y: 1960 }, // Moving platform { type: 'platform', x: 1024, y: 1700, w: 300, h: 40, moveAxis: 'x', moveFrom: 724, moveTo: 1324, moveDuration: 1800 }, { type: 'spike', x: 1024, y: 1660 }, // Checkpoint { type: 'checkpoint', x: 1024, y: 1600 }, // Final platform { type: 'platform', x: 1024, y: 1200, w: 400, h: 40 }, // End spike { type: 'spike', x: 1024, y: 1160 }]; // --- Game State --- var platforms = []; var spikes = []; var checkpoints = []; var player = null; var currentCheckpoint = null; var deaths = 0; var levelEndY = 1100; // Y position to reach to win // --- UI --- var deathsTxt = new Text2('Deaths: 0', { size: 90, fill: "#fff" }); deathsTxt.anchor.set(0.5, 0); LK.gui.top.addChild(deathsTxt); // --- Level Construction --- function buildLevel() { // Clear previous for (var i = 0; i < platforms.length; ++i) platforms[i].destroy(); for (var i = 0; i < spikes.length; ++i) spikes[i].destroy(); for (var i = 0; i < checkpoints.length; ++i) checkpoints[i].destroy(); platforms = []; spikes = []; checkpoints = []; currentCheckpoint = null; // Build for (var i = 0; i < levelData.length; ++i) { var obj = levelData[i]; if (obj.type === 'platform') { var plat = new Platform(); plat.x = obj.x; plat.y = obj.y; plat.width = obj.w || 400; plat.height = obj.h || 40; plat.children[0].width = plat.width; plat.children[0].height = plat.height; if (obj.moveAxis) { plat.isMoving = true; plat.moveAxis = obj.moveAxis; plat.moveFrom = obj.moveFrom; plat.moveTo = obj.moveTo; plat.moveDuration = obj.moveDuration; plat[plat.moveAxis] = plat.moveFrom; plat.startMove(); } game.addChild(plat); platforms.push(plat); } else if (obj.type === 'spike') { var spike = new Spike(); spike.x = obj.x; spike.y = obj.y; game.addChild(spike); spikes.push(spike); } else if (obj.type === 'checkpoint') { var cp = new Checkpoint(); cp.x = obj.x; cp.y = obj.y; game.addChild(cp); checkpoints.push(cp); } } } // --- Player Spawn --- function spawnPlayer() { if (player) player.destroy(); player = new Player(); var spawnX = 1024, spawnY = 2500; if (currentCheckpoint) { spawnX = currentCheckpoint.x; spawnY = currentCheckpoint.y - 10; } player.respawn(spawnX, spawnY); game.addChild(player); } // --- Death/Respawn --- function killPlayer() { if (player.dead) return; player.dead = true; deaths += 1; deathsTxt.setText('Deaths: ' + deaths); LK.effects.flashScreen(0xff2222, 400); LK.setTimeout(function () { spawnPlayer(); }, 400); } // --- Win Condition --- function checkWin() { if (player.y < levelEndY) { LK.showYouWin(); } } // --- Collision Helpers --- function rectsIntersect(a, b) { return a.x - a.width / 2 < b.x + b.width / 2 && a.x + a.width / 2 > b.x - b.width / 2 && a.y - a.height < b.y && a.y > b.y - b.height; } // --- Touch Controls (Mobile) --- var touchLeft = false, touchRight = false, touchJump = false; var dragStartX = null, dragStartY = null; var dragActive = false; // Touch areas: left 1/3 = left, right 1/3 = right, bottom 1/3 = jump game.down = function (x, y, obj) { if (y > 2732 - 400) { touchJump = true; player.jumpQueued = true; } else if (x < 2048 / 3) { touchLeft = true; } else if (x > 2048 * 2 / 3) { touchRight = true; } }; game.up = function (x, y, obj) { touchLeft = false; touchRight = false; touchJump = false; player.jumpQueued = false; }; game.move = function (x, y, obj) { // No drag controls for MVP }; // --- Physics Constants --- var GRAVITY = 2.2; var MOVE_SPEED = 18; var JUMP_VEL = -48; var MAX_FALL = 60; // --- Game Update Loop --- game.update = function () { if (!player || player.dead) return; // Horizontal movement if (touchLeft) { player.vx = -MOVE_SPEED; } else if (touchRight) { player.vx = MOVE_SPEED; } else { player.vx = 0; } // Jump if (player.jumpQueued && player.onGround) { player.vy = JUMP_VEL; player.onGround = false; player.jumpQueued = false; } // Gravity player.vy += GRAVITY; if (player.vy > MAX_FALL) player.vy = MAX_FALL; // Save old position var oldX = player.x, oldY = player.y; // Move X player.x += player.vx; // Collide with platforms (X axis) for (var i = 0; i < platforms.length; ++i) { var plat = platforms[i]; if (rectsIntersect(player, plat)) { if (player.vx > 0) { player.x = plat.x - plat.width / 2 - player.width / 2; } else if (player.vx < 0) { player.x = plat.x + plat.width / 2 + player.width / 2; } player.vx = 0; } } // Move Y player.y += player.vy; player.onGround = false; // Collide with platforms (Y axis) for (var i = 0; i < platforms.length; ++i) { var plat = platforms[i]; if (rectsIntersect(player, plat)) { if (player.vy > 0) { player.y = plat.y - plat.height / 2; player.onGround = true; } else if (player.vy < 0) { player.y = plat.y + plat.height / 2 + player.height; } player.vy = 0; } } // Collide with spikes for (var i = 0; i < spikes.length; ++i) { var spike = spikes[i]; if (rectsIntersect(player, spike)) { killPlayer(); return; } } // Collide with checkpoints for (var i = 0; i < checkpoints.length; ++i) { var cp = checkpoints[i]; if (!cp.activated && rectsIntersect(player, cp)) { cp.activate(); currentCheckpoint = cp; } } // Out of bounds (fall) if (player.y > 2800) { killPlayer(); return; } // Win checkWin(); }; // --- Build Level and Start --- buildLevel(); spawnPlayer(); deaths = 0; deathsTxt.setText('Deaths: 0');
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,393 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Checkpoint class: save progress
+var Checkpoint = Container.expand(function () {
+ var self = Container.call(this);
+ var cp = self.attachAsset('checkpoint', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ self.activated = false;
+ self.activate = function () {
+ if (!self.activated) {
+ self.activated = true;
+ tween(cp, {
+ tint: 0x00ff00
+ }, {
+ duration: 300
+ });
+ }
+ };
+ return self;
+});
+// Platform class: static or moving platform
+var Platform = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach platform asset (box shape)
+ var plat = self.attachAsset('platform', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Platform movement config
+ self.isMoving = false;
+ self.moveAxis = 'x'; // 'x' or 'y'
+ self.moveFrom = 0;
+ self.moveTo = 0;
+ self.moveDuration = 0;
+ self.moveDir = 1;
+ // For moving platforms, set up tween
+ self.startMove = function () {
+ if (!self.isMoving) return;
+ var prop = {};
+ prop[self.moveAxis] = self.moveTo;
+ tween(self, prop, {
+ duration: self.moveDuration,
+ easing: tween.linear,
+ onFinish: function onFinish() {
+ // Swap direction
+ var tmp = self.moveFrom;
+ self.moveFrom = self.moveTo;
+ self.moveTo = tmp;
+ self.startMove();
+ }
+ });
+ };
+ return self;
+});
+// Player class: main character
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var _char = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ self.width = _char.width;
+ self.height = _char.height;
+ self.vx = 0;
+ self.vy = 0;
+ self.onGround = false;
+ self.dead = false;
+ self.jumpQueued = false;
+ self.respawn = function (x, y) {
+ self.x = x;
+ self.y = y;
+ self.vx = 0;
+ self.vy = 0;
+ self.dead = false;
+ };
+ return self;
+});
+// Spike class: deadly obstacle
+var Spike = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach spike asset (triangle shape, but use box for now)
+ var spike = self.attachAsset('spike', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+/*
+ Level is an array of objects:
+ {type: 'platform'|'spike'|'checkpoint', x, y, [w], [h], [moveAxis], [moveFrom], [moveTo], [moveDuration]}
+ All positions are in game coordinates.
+*/
+// --- Level Data (MVP: 1 level, hardcoded) ---
+// Tween plugin for platform/character movement and effects
+// --- Asset Initialization ---
+var levelData = [
+// Floor
+{
+ type: 'platform',
+ x: 1024,
+ y: 2600,
+ w: 1200,
+ h: 60
+},
+// First jump
+{
+ type: 'platform',
+ x: 600,
+ y: 2200,
+ w: 400,
+ h: 40
+}, {
+ type: 'spike',
+ x: 800,
+ y: 2160
+},
+// Second jump
+{
+ type: 'platform',
+ x: 1400,
+ y: 2000,
+ w: 400,
+ h: 40
+}, {
+ type: 'spike',
+ x: 1200,
+ y: 1960
+},
+// Moving platform
+{
+ type: 'platform',
+ x: 1024,
+ y: 1700,
+ w: 300,
+ h: 40,
+ moveAxis: 'x',
+ moveFrom: 724,
+ moveTo: 1324,
+ moveDuration: 1800
+}, {
+ type: 'spike',
+ x: 1024,
+ y: 1660
+},
+// Checkpoint
+{
+ type: 'checkpoint',
+ x: 1024,
+ y: 1600
+},
+// Final platform
+{
+ type: 'platform',
+ x: 1024,
+ y: 1200,
+ w: 400,
+ h: 40
+},
+// End spike
+{
+ type: 'spike',
+ x: 1024,
+ y: 1160
+}];
+// --- Game State ---
+var platforms = [];
+var spikes = [];
+var checkpoints = [];
+var player = null;
+var currentCheckpoint = null;
+var deaths = 0;
+var levelEndY = 1100; // Y position to reach to win
+// --- UI ---
+var deathsTxt = new Text2('Deaths: 0', {
+ size: 90,
+ fill: "#fff"
+});
+deathsTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(deathsTxt);
+// --- Level Construction ---
+function buildLevel() {
+ // Clear previous
+ for (var i = 0; i < platforms.length; ++i) platforms[i].destroy();
+ for (var i = 0; i < spikes.length; ++i) spikes[i].destroy();
+ for (var i = 0; i < checkpoints.length; ++i) checkpoints[i].destroy();
+ platforms = [];
+ spikes = [];
+ checkpoints = [];
+ currentCheckpoint = null;
+ // Build
+ for (var i = 0; i < levelData.length; ++i) {
+ var obj = levelData[i];
+ if (obj.type === 'platform') {
+ var plat = new Platform();
+ plat.x = obj.x;
+ plat.y = obj.y;
+ plat.width = obj.w || 400;
+ plat.height = obj.h || 40;
+ plat.children[0].width = plat.width;
+ plat.children[0].height = plat.height;
+ if (obj.moveAxis) {
+ plat.isMoving = true;
+ plat.moveAxis = obj.moveAxis;
+ plat.moveFrom = obj.moveFrom;
+ plat.moveTo = obj.moveTo;
+ plat.moveDuration = obj.moveDuration;
+ plat[plat.moveAxis] = plat.moveFrom;
+ plat.startMove();
+ }
+ game.addChild(plat);
+ platforms.push(plat);
+ } else if (obj.type === 'spike') {
+ var spike = new Spike();
+ spike.x = obj.x;
+ spike.y = obj.y;
+ game.addChild(spike);
+ spikes.push(spike);
+ } else if (obj.type === 'checkpoint') {
+ var cp = new Checkpoint();
+ cp.x = obj.x;
+ cp.y = obj.y;
+ game.addChild(cp);
+ checkpoints.push(cp);
+ }
+ }
+}
+// --- Player Spawn ---
+function spawnPlayer() {
+ if (player) player.destroy();
+ player = new Player();
+ var spawnX = 1024,
+ spawnY = 2500;
+ if (currentCheckpoint) {
+ spawnX = currentCheckpoint.x;
+ spawnY = currentCheckpoint.y - 10;
+ }
+ player.respawn(spawnX, spawnY);
+ game.addChild(player);
+}
+// --- Death/Respawn ---
+function killPlayer() {
+ if (player.dead) return;
+ player.dead = true;
+ deaths += 1;
+ deathsTxt.setText('Deaths: ' + deaths);
+ LK.effects.flashScreen(0xff2222, 400);
+ LK.setTimeout(function () {
+ spawnPlayer();
+ }, 400);
+}
+// --- Win Condition ---
+function checkWin() {
+ if (player.y < levelEndY) {
+ LK.showYouWin();
+ }
+}
+// --- Collision Helpers ---
+function rectsIntersect(a, b) {
+ return a.x - a.width / 2 < b.x + b.width / 2 && a.x + a.width / 2 > b.x - b.width / 2 && a.y - a.height < b.y && a.y > b.y - b.height;
+}
+// --- Touch Controls (Mobile) ---
+var touchLeft = false,
+ touchRight = false,
+ touchJump = false;
+var dragStartX = null,
+ dragStartY = null;
+var dragActive = false;
+// Touch areas: left 1/3 = left, right 1/3 = right, bottom 1/3 = jump
+game.down = function (x, y, obj) {
+ if (y > 2732 - 400) {
+ touchJump = true;
+ player.jumpQueued = true;
+ } else if (x < 2048 / 3) {
+ touchLeft = true;
+ } else if (x > 2048 * 2 / 3) {
+ touchRight = true;
+ }
+};
+game.up = function (x, y, obj) {
+ touchLeft = false;
+ touchRight = false;
+ touchJump = false;
+ player.jumpQueued = false;
+};
+game.move = function (x, y, obj) {
+ // No drag controls for MVP
+};
+// --- Physics Constants ---
+var GRAVITY = 2.2;
+var MOVE_SPEED = 18;
+var JUMP_VEL = -48;
+var MAX_FALL = 60;
+// --- Game Update Loop ---
+game.update = function () {
+ if (!player || player.dead) return;
+ // Horizontal movement
+ if (touchLeft) {
+ player.vx = -MOVE_SPEED;
+ } else if (touchRight) {
+ player.vx = MOVE_SPEED;
+ } else {
+ player.vx = 0;
+ }
+ // Jump
+ if (player.jumpQueued && player.onGround) {
+ player.vy = JUMP_VEL;
+ player.onGround = false;
+ player.jumpQueued = false;
+ }
+ // Gravity
+ player.vy += GRAVITY;
+ if (player.vy > MAX_FALL) player.vy = MAX_FALL;
+ // Save old position
+ var oldX = player.x,
+ oldY = player.y;
+ // Move X
+ player.x += player.vx;
+ // Collide with platforms (X axis)
+ for (var i = 0; i < platforms.length; ++i) {
+ var plat = platforms[i];
+ if (rectsIntersect(player, plat)) {
+ if (player.vx > 0) {
+ player.x = plat.x - plat.width / 2 - player.width / 2;
+ } else if (player.vx < 0) {
+ player.x = plat.x + plat.width / 2 + player.width / 2;
+ }
+ player.vx = 0;
+ }
+ }
+ // Move Y
+ player.y += player.vy;
+ player.onGround = false;
+ // Collide with platforms (Y axis)
+ for (var i = 0; i < platforms.length; ++i) {
+ var plat = platforms[i];
+ if (rectsIntersect(player, plat)) {
+ if (player.vy > 0) {
+ player.y = plat.y - plat.height / 2;
+ player.onGround = true;
+ } else if (player.vy < 0) {
+ player.y = plat.y + plat.height / 2 + player.height;
+ }
+ player.vy = 0;
+ }
+ }
+ // Collide with spikes
+ for (var i = 0; i < spikes.length; ++i) {
+ var spike = spikes[i];
+ if (rectsIntersect(player, spike)) {
+ killPlayer();
+ return;
+ }
+ }
+ // Collide with checkpoints
+ for (var i = 0; i < checkpoints.length; ++i) {
+ var cp = checkpoints[i];
+ if (!cp.activated && rectsIntersect(player, cp)) {
+ cp.activate();
+ currentCheckpoint = cp;
+ }
+ }
+ // Out of bounds (fall)
+ if (player.y > 2800) {
+ killPlayer();
+ return;
+ }
+ // Win
+ checkWin();
+};
+// --- Build Level and Start ---
+buildLevel();
+spawnPlayer();
+deaths = 0;
+deathsTxt.setText('Deaths: 0');
\ No newline at end of file