/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = gameSpeed;
self.collected = false;
self.update = function () {
self.y += self.speed;
// Spinning animation
graphics.rotation += 0.1;
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
self.obstacleType = type || 'train';
var graphics = self.attachAsset(self.obstacleType, {
anchorX: 0.5,
anchorY: 1.0
});
self.speed = gameSpeed;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.currentLane = 1; // 0=left, 1=center, 2=right
self.targetX = 0;
self.isJumping = false;
self.isSliding = false;
self.invincible = false;
self.getLaneX = function (lane) {
var laneWidth = 2048 / 3;
return laneWidth * lane + laneWidth / 2;
};
self.switchLane = function (newLane) {
if (newLane >= 0 && newLane <= 2) {
self.currentLane = newLane;
self.targetX = self.getLaneX(newLane);
}
};
self.jump = function () {
if (!self.isJumping && !self.isSliding) {
self.isJumping = true;
var originalY = self.y;
tween(self, {
y: originalY - 150
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: originalY
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
self.isJumping = false;
}
});
}
});
}
};
self.slide = function () {
if (!self.isJumping && !self.isSliding) {
self.isSliding = true;
graphics.height = 60;
LK.setTimeout(function () {
graphics.height = 120;
self.isSliding = false;
}, 800);
}
};
self.update = function () {
// Smooth lane switching
var diff = self.targetX - self.x;
if (Math.abs(diff) > 5) {
self.x += diff * 0.15;
}
// Flash effect when invincible
if (self.invincible) {
graphics.alpha = LK.ticks % 10 < 5 ? 0.5 : 1.0;
} else {
graphics.alpha = 1.0;
}
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.powerType = type || 'invincible';
var graphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
// Color code power-ups
if (self.powerType === 'invincible') {
graphics.tint = 0x00FF00;
} else if (self.powerType === 'magnet') {
graphics.tint = 0x0000FF;
}
self.speed = gameSpeed;
self.collected = false;
self.update = function () {
self.y += self.speed;
graphics.rotation += 0.05;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x212121
});
/****
* Game Code
****/
// Game variables
var gameSpeed = 8;
var baseSpeed = 8;
var player;
var obstacles = [];
var coins = [];
var powerups = [];
var distance = 0;
var coinCount = 0;
var lastObstacleY = -500;
var lastCoinY = -300;
var swipeStartX = 0;
var swipeStartY = 0;
var isSwipeStarted = false;
// Power-up states
var invincibleTimer = 0;
var magnetTimer = 0;
// Create background tracks
for (var i = 0; i < 4; i++) {
var track = game.addChild(LK.getAsset('track', {
anchorX: 0,
anchorY: 0,
x: 0,
y: i * 100 - 200
}));
}
// Create player
player = game.addChild(new Player());
player.x = player.getLaneX(1);
player.y = 2500;
player.targetX = player.x;
// UI Elements
var distanceText = new Text2('Distance: 0m', {
size: 60,
fill: 0xFFFFFF
});
distanceText.anchor.set(0, 0);
LK.gui.topRight.addChild(distanceText);
var coinText = new Text2('Coins: 0', {
size: 60,
fill: 0xFFD700
});
coinText.anchor.set(1, 0);
coinText.x = -20;
coinText.y = 80;
LK.gui.topRight.addChild(coinText);
// Touch controls
game.down = function (x, y, obj) {
swipeStartX = x;
swipeStartY = y;
isSwipeStarted = true;
};
game.up = function (x, y, obj) {
if (!isSwipeStarted) return;
var deltaX = x - swipeStartX;
var deltaY = y - swipeStartY;
var swipeThreshold = 100;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
// Horizontal swipe
if (Math.abs(deltaX) > swipeThreshold) {
if (deltaX > 0) {
// Swipe right
player.switchLane(player.currentLane + 1);
} else {
// Swipe left
player.switchLane(player.currentLane - 1);
}
}
} else {
// Vertical swipe
if (Math.abs(deltaY) > swipeThreshold) {
if (deltaY < 0) {
// Swipe up - jump
player.jump();
} else {
// Swipe down - slide
player.slide();
}
}
}
// Tap to jump if no swipe detected
if (Math.abs(deltaX) < 50 && Math.abs(deltaY) < 50) {
player.jump();
}
isSwipeStarted = false;
};
function spawnObstacle() {
if (lastObstacleY > -800) return;
var lane = Math.floor(Math.random() * 3);
var type = Math.random() < 0.7 ? 'train' : 'barrier';
var obstacle = new Obstacle(type);
obstacle.x = player.getLaneX(lane);
obstacle.y = -200;
obstacles.push(obstacle);
game.addChild(obstacle);
lastObstacleY = obstacle.y;
}
function spawnCoin() {
if (lastCoinY > -400) return;
var lane = Math.floor(Math.random() * 3);
var coin = new Coin();
coin.x = player.getLaneX(lane);
coin.y = -150;
coins.push(coin);
game.addChild(coin);
lastCoinY = coin.y;
}
function spawnPowerUp() {
if (Math.random() < 0.02) {
// 2% chance per frame
var lane = Math.floor(Math.random() * 3);
var types = ['invincible', 'magnet'];
var type = types[Math.floor(Math.random() * types.length)];
var powerup = new PowerUp(type);
powerup.x = player.getLaneX(lane);
powerup.y = -100;
powerups.push(powerup);
game.addChild(powerup);
}
}
function checkCollisions() {
// Check obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.y > 2800) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with player
if (Math.abs(obstacle.x - player.x) < 100 && Math.abs(obstacle.y - player.y) < 100) {
// Check if player can avoid collision
var canAvoid = false;
if (obstacle.obstacleType === 'barrier' && player.isJumping) {
canAvoid = true;
} else if (obstacle.obstacleType === 'train' && player.isSliding) {
canAvoid = true;
}
if (!canAvoid && !player.invincible) {
LK.getSound('crash').play();
LK.showGameOver();
return;
}
}
}
// Check coin collection
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (coin.y > 2800) {
coin.destroy();
coins.splice(i, 1);
continue;
}
var collectRadius = magnetTimer > 0 ? 200 : 60;
if (Math.abs(coin.x - player.x) < collectRadius && Math.abs(coin.y - player.y) < collectRadius && !coin.collected) {
coin.collected = true;
coinCount++;
LK.setScore(LK.getScore() + 10);
LK.getSound('collect').play();
coin.destroy();
coins.splice(i, 1);
}
}
// Check power-up collection
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
if (powerup.y > 2800) {
powerup.destroy();
powerups.splice(i, 1);
continue;
}
if (Math.abs(powerup.x - player.x) < 80 && Math.abs(powerup.y - player.y) < 80 && !powerup.collected) {
powerup.collected = true;
if (powerup.powerType === 'invincible') {
invincibleTimer = 300; // 5 seconds at 60fps
player.invincible = true;
} else if (powerup.powerType === 'magnet') {
magnetTimer = 600; // 10 seconds at 60fps
}
powerup.destroy();
powerups.splice(i, 1);
}
}
}
game.update = function () {
// Update distance and speed
distance += gameSpeed;
gameSpeed = baseSpeed + Math.floor(distance / 1000) * 0.5;
// Update power-up timers
if (invincibleTimer > 0) {
invincibleTimer--;
if (invincibleTimer <= 0) {
player.invincible = false;
}
}
if (magnetTimer > 0) {
magnetTimer--;
}
// Update obstacle spawn positions
lastObstacleY += gameSpeed;
lastCoinY += gameSpeed;
// Spawn new objects
spawnObstacle();
spawnCoin();
spawnPowerUp();
// Update all objects
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].speed = gameSpeed;
}
for (var i = 0; i < coins.length; i++) {
coins[i].speed = gameSpeed;
}
for (var i = 0; i < powerups.length; i++) {
powerups[i].speed = gameSpeed;
}
// Move background tracks
var tracks = game.children.slice(0, 4);
for (var i = 0; i < tracks.length; i++) {
tracks[i].y += gameSpeed;
if (tracks[i].y > 2732) {
tracks[i].y -= 400;
}
}
// Check collisions
checkCollisions();
// Update UI
distanceText.setText('Distance: ' + Math.floor(distance / 10) + 'm');
coinText.setText('Coins: ' + coinCount);
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,366 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Coin = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('coin', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = gameSpeed;
+ self.collected = false;
+ self.update = function () {
+ self.y += self.speed;
+ // Spinning animation
+ graphics.rotation += 0.1;
+ };
+ return self;
+});
+var Obstacle = Container.expand(function (type) {
+ var self = Container.call(this);
+ self.obstacleType = type || 'train';
+ var graphics = self.attachAsset(self.obstacleType, {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ self.speed = gameSpeed;
+ self.update = function () {
+ self.y += self.speed;
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 1.0
+ });
+ self.currentLane = 1; // 0=left, 1=center, 2=right
+ self.targetX = 0;
+ self.isJumping = false;
+ self.isSliding = false;
+ self.invincible = false;
+ self.getLaneX = function (lane) {
+ var laneWidth = 2048 / 3;
+ return laneWidth * lane + laneWidth / 2;
+ };
+ self.switchLane = function (newLane) {
+ if (newLane >= 0 && newLane <= 2) {
+ self.currentLane = newLane;
+ self.targetX = self.getLaneX(newLane);
+ }
+ };
+ self.jump = function () {
+ if (!self.isJumping && !self.isSliding) {
+ self.isJumping = true;
+ var originalY = self.y;
+ tween(self, {
+ y: originalY - 150
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(self, {
+ y: originalY
+ }, {
+ duration: 300,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ self.isJumping = false;
+ }
+ });
+ }
+ });
+ }
+ };
+ self.slide = function () {
+ if (!self.isJumping && !self.isSliding) {
+ self.isSliding = true;
+ graphics.height = 60;
+ LK.setTimeout(function () {
+ graphics.height = 120;
+ self.isSliding = false;
+ }, 800);
+ }
+ };
+ self.update = function () {
+ // Smooth lane switching
+ var diff = self.targetX - self.x;
+ if (Math.abs(diff) > 5) {
+ self.x += diff * 0.15;
+ }
+ // Flash effect when invincible
+ if (self.invincible) {
+ graphics.alpha = LK.ticks % 10 < 5 ? 0.5 : 1.0;
+ } else {
+ graphics.alpha = 1.0;
+ }
+ };
+ return self;
+});
+var PowerUp = Container.expand(function (type) {
+ var self = Container.call(this);
+ self.powerType = type || 'invincible';
+ var graphics = self.attachAsset('powerup', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Color code power-ups
+ if (self.powerType === 'invincible') {
+ graphics.tint = 0x00FF00;
+ } else if (self.powerType === 'magnet') {
+ graphics.tint = 0x0000FF;
+ }
+ self.speed = gameSpeed;
+ self.collected = false;
+ self.update = function () {
+ self.y += self.speed;
+ graphics.rotation += 0.05;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x212121
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var gameSpeed = 8;
+var baseSpeed = 8;
+var player;
+var obstacles = [];
+var coins = [];
+var powerups = [];
+var distance = 0;
+var coinCount = 0;
+var lastObstacleY = -500;
+var lastCoinY = -300;
+var swipeStartX = 0;
+var swipeStartY = 0;
+var isSwipeStarted = false;
+// Power-up states
+var invincibleTimer = 0;
+var magnetTimer = 0;
+// Create background tracks
+for (var i = 0; i < 4; i++) {
+ var track = game.addChild(LK.getAsset('track', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: i * 100 - 200
+ }));
+}
+// Create player
+player = game.addChild(new Player());
+player.x = player.getLaneX(1);
+player.y = 2500;
+player.targetX = player.x;
+// UI Elements
+var distanceText = new Text2('Distance: 0m', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+distanceText.anchor.set(0, 0);
+LK.gui.topRight.addChild(distanceText);
+var coinText = new Text2('Coins: 0', {
+ size: 60,
+ fill: 0xFFD700
+});
+coinText.anchor.set(1, 0);
+coinText.x = -20;
+coinText.y = 80;
+LK.gui.topRight.addChild(coinText);
+// Touch controls
+game.down = function (x, y, obj) {
+ swipeStartX = x;
+ swipeStartY = y;
+ isSwipeStarted = true;
+};
+game.up = function (x, y, obj) {
+ if (!isSwipeStarted) return;
+ var deltaX = x - swipeStartX;
+ var deltaY = y - swipeStartY;
+ var swipeThreshold = 100;
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
+ // Horizontal swipe
+ if (Math.abs(deltaX) > swipeThreshold) {
+ if (deltaX > 0) {
+ // Swipe right
+ player.switchLane(player.currentLane + 1);
+ } else {
+ // Swipe left
+ player.switchLane(player.currentLane - 1);
+ }
+ }
+ } else {
+ // Vertical swipe
+ if (Math.abs(deltaY) > swipeThreshold) {
+ if (deltaY < 0) {
+ // Swipe up - jump
+ player.jump();
+ } else {
+ // Swipe down - slide
+ player.slide();
+ }
+ }
+ }
+ // Tap to jump if no swipe detected
+ if (Math.abs(deltaX) < 50 && Math.abs(deltaY) < 50) {
+ player.jump();
+ }
+ isSwipeStarted = false;
+};
+function spawnObstacle() {
+ if (lastObstacleY > -800) return;
+ var lane = Math.floor(Math.random() * 3);
+ var type = Math.random() < 0.7 ? 'train' : 'barrier';
+ var obstacle = new Obstacle(type);
+ obstacle.x = player.getLaneX(lane);
+ obstacle.y = -200;
+ obstacles.push(obstacle);
+ game.addChild(obstacle);
+ lastObstacleY = obstacle.y;
+}
+function spawnCoin() {
+ if (lastCoinY > -400) return;
+ var lane = Math.floor(Math.random() * 3);
+ var coin = new Coin();
+ coin.x = player.getLaneX(lane);
+ coin.y = -150;
+ coins.push(coin);
+ game.addChild(coin);
+ lastCoinY = coin.y;
+}
+function spawnPowerUp() {
+ if (Math.random() < 0.02) {
+ // 2% chance per frame
+ var lane = Math.floor(Math.random() * 3);
+ var types = ['invincible', 'magnet'];
+ var type = types[Math.floor(Math.random() * types.length)];
+ var powerup = new PowerUp(type);
+ powerup.x = player.getLaneX(lane);
+ powerup.y = -100;
+ powerups.push(powerup);
+ game.addChild(powerup);
+ }
+}
+function checkCollisions() {
+ // Check obstacle collisions
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ var obstacle = obstacles[i];
+ if (obstacle.y > 2800) {
+ obstacle.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ // Check collision with player
+ if (Math.abs(obstacle.x - player.x) < 100 && Math.abs(obstacle.y - player.y) < 100) {
+ // Check if player can avoid collision
+ var canAvoid = false;
+ if (obstacle.obstacleType === 'barrier' && player.isJumping) {
+ canAvoid = true;
+ } else if (obstacle.obstacleType === 'train' && player.isSliding) {
+ canAvoid = true;
+ }
+ if (!canAvoid && !player.invincible) {
+ LK.getSound('crash').play();
+ LK.showGameOver();
+ return;
+ }
+ }
+ }
+ // Check coin collection
+ for (var i = coins.length - 1; i >= 0; i--) {
+ var coin = coins[i];
+ if (coin.y > 2800) {
+ coin.destroy();
+ coins.splice(i, 1);
+ continue;
+ }
+ var collectRadius = magnetTimer > 0 ? 200 : 60;
+ if (Math.abs(coin.x - player.x) < collectRadius && Math.abs(coin.y - player.y) < collectRadius && !coin.collected) {
+ coin.collected = true;
+ coinCount++;
+ LK.setScore(LK.getScore() + 10);
+ LK.getSound('collect').play();
+ coin.destroy();
+ coins.splice(i, 1);
+ }
+ }
+ // Check power-up collection
+ for (var i = powerups.length - 1; i >= 0; i--) {
+ var powerup = powerups[i];
+ if (powerup.y > 2800) {
+ powerup.destroy();
+ powerups.splice(i, 1);
+ continue;
+ }
+ if (Math.abs(powerup.x - player.x) < 80 && Math.abs(powerup.y - player.y) < 80 && !powerup.collected) {
+ powerup.collected = true;
+ if (powerup.powerType === 'invincible') {
+ invincibleTimer = 300; // 5 seconds at 60fps
+ player.invincible = true;
+ } else if (powerup.powerType === 'magnet') {
+ magnetTimer = 600; // 10 seconds at 60fps
+ }
+ powerup.destroy();
+ powerups.splice(i, 1);
+ }
+ }
+}
+game.update = function () {
+ // Update distance and speed
+ distance += gameSpeed;
+ gameSpeed = baseSpeed + Math.floor(distance / 1000) * 0.5;
+ // Update power-up timers
+ if (invincibleTimer > 0) {
+ invincibleTimer--;
+ if (invincibleTimer <= 0) {
+ player.invincible = false;
+ }
+ }
+ if (magnetTimer > 0) {
+ magnetTimer--;
+ }
+ // Update obstacle spawn positions
+ lastObstacleY += gameSpeed;
+ lastCoinY += gameSpeed;
+ // Spawn new objects
+ spawnObstacle();
+ spawnCoin();
+ spawnPowerUp();
+ // Update all objects
+ for (var i = 0; i < obstacles.length; i++) {
+ obstacles[i].speed = gameSpeed;
+ }
+ for (var i = 0; i < coins.length; i++) {
+ coins[i].speed = gameSpeed;
+ }
+ for (var i = 0; i < powerups.length; i++) {
+ powerups[i].speed = gameSpeed;
+ }
+ // Move background tracks
+ var tracks = game.children.slice(0, 4);
+ for (var i = 0; i < tracks.length; i++) {
+ tracks[i].y += gameSpeed;
+ if (tracks[i].y > 2732) {
+ tracks[i].y -= 400;
+ }
+ }
+ // Check collisions
+ checkCollisions();
+ // Update UI
+ distanceText.setText('Distance: ' + Math.floor(distance / 10) + 'm');
+ coinText.setText('Coins: ' + coinCount);
+};
\ No newline at end of file