/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Boost: Speed boost pad
var Boost = Container.expand(function () {
var self = Container.call(this);
var boost = self.attachAsset('boost', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Coin: Collectible
var Coin = Container.expand(function () {
var self = Container.call(this);
var coin = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// For simple spin animation
self.spinTick = 0;
self.update = function () {
self.spinTick++;
coin.scaleX = 0.7 + 0.3 * Math.abs(Math.sin(self.spinTick * 0.15));
};
return self;
});
// Obstacle: Stationary object on the slide
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obs = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Player: The character controlled by the player
var Player = Container.expand(function () {
var self = Container.call(this);
var player = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// For jump animation
self.isJumping = false;
self.jumpTick = 0;
self.jumpDuration = 0;
self.jumpHeight = 0;
self.update = function () {
if (self.isJumping) {
self.jumpTick++;
// Simple jump arc
var t = self.jumpTick / self.jumpDuration;
if (t > 1) t = 1;
self.y = self.baseY - Math.sin(Math.PI * t) * self.jumpHeight;
if (self.jumpTick >= self.jumpDuration) {
self.isJumping = false;
self.y = self.baseY;
}
}
};
// Start jump
self.startJump = function (duration, height) {
if (!self.isJumping) {
self.isJumping = true;
self.jumpTick = 0;
self.jumpDuration = duration;
self.jumpHeight = height;
self.baseY = self.y;
}
};
return self;
});
// SlideSegment: A piece of the slide, can be straight or curved
var SlideSegment = Container.expand(function () {
var self = Container.call(this);
var segment = self.attachAsset('slideSegment', {
anchorX: 0.5,
anchorY: 0.5
});
// Type: 'straight', 'left', 'right', 'jump', 'boost'
self.type = 'straight';
// For curve: curveAmount in px, positive=right, negative=left
self.curveAmount = 0;
// For jump: isJump
self.isJump = false;
// For boost: isBoost
self.isBoost = false;
// For segment index
self.segmentIndex = 0;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Speed boost
// Player character
// Coin
// Obstacle
// Slide (track) segment
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var SLIDE_WIDTH = 800;
var SLIDE_SEGMENT_HEIGHT = 300;
var PLAYER_START_X = GAME_WIDTH / 2;
var PLAYER_START_Y = GAME_HEIGHT * 0.7;
var PLAYER_MOVE_LIMIT = SLIDE_WIDTH / 2 - 80;
var PLAYER_SPEED = 18; // px per tick (vertical)
var PLAYER_MAX_SPEED = 38;
var PLAYER_MIN_SPEED = 12;
var PLAYER_ACCEL = 0.01;
var PLAYER_DECEL = 0.02;
var BOOST_SPEED = 32;
var BOOST_DURATION = 60; // ticks
var JUMP_DURATION = 50; // ticks
var JUMP_HEIGHT = 220;
var OBSTACLE_RADIUS = 60;
var COIN_RADIUS = 40;
var SLIDE_CURVE_MAX = 220; // px per segment
var SLIDE_CURVE_CHANCE = 0.25;
var OBSTACLE_CHANCE = 0.35;
var COIN_CHANCE = 0.25;
var BOOST_CHANCE = 0.10;
var JUMP_CHANCE = 0.08;
// Game state
var slideSegments = [];
var obstacles = [];
var coins = [];
var boosts = [];
var player = null;
var distance = 0;
var coinCount = 0;
var speed = PLAYER_SPEED;
var boostTicks = 0;
var isGameOver = false;
var dragX = null;
var dragStartX = null;
var dragStartPlayerX = null;
var lastMoveX = null;
var lastMoveY = null;
var lastSegmentIndex = 0;
var jumpQueued = false;
// Score display (English)
var scoreTxt = new Text2('Score: 0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Coin display (English)
var coinTxt = new Text2('Coins: 0', {
size: 70,
fill: 0xFFE066
});
// Anchor to right edge, top (so text grows leftward, not offscreen)
coinTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(coinTxt);
// Helper: Generate a slide segment
function createSlideSegment(type, curveAmount, y) {
var seg = new SlideSegment();
seg.type = type;
seg.curveAmount = curveAmount || 0;
seg.x = GAME_WIDTH / 2;
seg.y = y;
seg.segmentIndex = lastSegmentIndex++;
if (type === 'left' || type === 'right') {
seg.curveAmount = curveAmount;
}
if (type === 'jump') {
seg.isJump = true;
}
if (type === 'boost') {
seg.isBoost = true;
}
slideSegments.push(seg);
game.addChild(seg);
return seg;
}
// Helper: Generate an obstacle
function createObstacle(x, y) {
var obs = new Obstacle();
obs.x = x;
obs.y = y;
obstacles.push(obs);
game.addChild(obs);
return obs;
}
// Helper: Generate a coin
function createCoin(x, y) {
var c = new Coin();
c.x = x;
c.y = y;
coins.push(c);
game.addChild(c);
return c;
}
// Helper: Generate a boost
function createBoost(x, y) {
var b = new Boost();
b.x = x;
b.y = y;
boosts.push(b);
game.addChild(b);
return b;
}
// Helper: Remove offscreen objects
function cleanupObjects() {
// Slide segments
for (var i = slideSegments.length - 1; i >= 0; i--) {
if (slideSegments[i].y > GAME_HEIGHT + SLIDE_SEGMENT_HEIGHT) {
slideSegments[i].destroy();
slideSegments.splice(i, 1);
}
}
// Obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].y > GAME_HEIGHT + 200) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Coins
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i].y > GAME_HEIGHT + 200) {
coins[i].destroy();
coins.splice(i, 1);
}
}
// Boosts
for (var i = boosts.length - 1; i >= 0; i--) {
if (boosts[i].y > GAME_HEIGHT + 200) {
boosts[i].destroy();
boosts.splice(i, 1);
}
}
}
// Helper: Generate next slide segment (randomly)
function generateNextSegment() {
var lastSeg = slideSegments[slideSegments.length - 1];
var y = lastSeg.y - SLIDE_SEGMENT_HEIGHT;
var type = 'straight';
var curveAmount = 0;
var rand = Math.random();
if (rand < SLIDE_CURVE_CHANCE) {
// Curve
if (Math.random() < 0.5) {
type = 'left';
curveAmount = -SLIDE_CURVE_MAX * (0.5 + Math.random() * 0.5);
} else {
type = 'right';
curveAmount = SLIDE_CURVE_MAX * (0.5 + Math.random() * 0.5);
}
} else if (rand < SLIDE_CURVE_CHANCE + JUMP_CHANCE) {
type = 'jump';
} else if (rand < SLIDE_CURVE_CHANCE + JUMP_CHANCE + BOOST_CHANCE) {
type = 'boost';
}
var seg = createSlideSegment(type, curveAmount, y);
// Place obstacles, coins, boosts
// Obstacles: not on jump or boost
if (type !== 'jump' && type !== 'boost' && Math.random() < OBSTACLE_CHANCE) {
var obsX = GAME_WIDTH / 2 + (Math.random() - 0.5) * (SLIDE_WIDTH - 200);
createObstacle(obsX, y);
}
// Coins: not on jump
if (type !== 'jump' && Math.random() < COIN_CHANCE) {
var coinX = GAME_WIDTH / 2 + (Math.random() - 0.5) * (SLIDE_WIDTH - 200);
createCoin(coinX, y - SLIDE_SEGMENT_HEIGHT / 3);
}
// Boost: only on boost segment
if (type === 'boost') {
createBoost(GAME_WIDTH / 2, y);
}
}
// Helper: Check if player is on slide
function isPlayerOnSlide() {
// Find the closest segment under the player
var minDist = 99999;
var seg = null;
for (var i = 0; i < slideSegments.length; i++) {
var s = slideSegments[i];
var dy = Math.abs(player.y - s.y);
if (dy < SLIDE_SEGMENT_HEIGHT / 2 && dy < minDist) {
minDist = dy;
seg = s;
}
}
if (!seg) return false;
// Slide center x
var centerX = seg.x;
// Slide width
var width = SLIDE_WIDTH;
// For curve, offset centerX
if (seg.type === 'left' || seg.type === 'right') {
centerX += seg.curveAmount * ((player.y - seg.y) / SLIDE_SEGMENT_HEIGHT);
}
// For jump, always on slide
if (seg.isJump) return true;
// Check if player.x is within slide bounds
return Math.abs(player.x - centerX) < width / 2 - 60;
}
// Helper: Start jump
function startPlayerJump() {
if (!player.isJumping) {
player.startJump(JUMP_DURATION, JUMP_HEIGHT);
}
}
// Helper: End game
function triggerGameOver() {
if (!isGameOver) {
isGameOver = true;
LK.effects.flashScreen(0xff0000, 1000);
// Calculate and set the final score so it appears in the game over popup
var finalScore = Math.floor(distance / 10) + coinCount * 10;
LK.setScore(finalScore);
LK.showGameOver();
}
}
// Initialize player
player = new Player();
player.x = PLAYER_START_X;
player.y = PLAYER_START_Y;
game.addChild(player);
// Generate initial slide
slideSegments = [];
lastSegmentIndex = 0;
var segY = PLAYER_START_Y + 200;
for (var i = 0; i < 10; i++) {
createSlideSegment('straight', 0, segY);
segY -= SLIDE_SEGMENT_HEIGHT;
}
// Initial objects
obstacles = [];
coins = [];
boosts = [];
distance = 0;
coinCount = 0;
speed = PLAYER_SPEED;
boostTicks = 0;
isGameOver = false;
jumpQueued = false;
// Input: Drag to steer
game.down = function (x, y, obj) {
if (isGameOver) return;
dragX = x;
dragStartX = x;
dragStartPlayerX = player.x;
lastMoveX = x;
lastMoveY = y;
};
game.move = function (x, y, obj) {
if (isGameOver) return;
if (dragX !== null) {
var dx = x - dragStartX;
var newX = dragStartPlayerX + dx;
// Clamp to slide width
var minX = GAME_WIDTH / 2 - PLAYER_MOVE_LIMIT;
var maxX = GAME_WIDTH / 2 + PLAYER_MOVE_LIMIT;
if (newX < minX) newX = minX;
if (newX > maxX) newX = maxX;
player.x = newX;
lastMoveX = x;
lastMoveY = y;
}
};
game.up = function (x, y, obj) {
dragX = null;
dragStartX = null;
dragStartPlayerX = null;
};
// Main game loop
game.update = function () {
if (isGameOver) return;
// Move slide and objects down (simulate player moving down)
for (var i = 0; i < slideSegments.length; i++) {
slideSegments[i].y += speed;
// For curve, move segment center
if (slideSegments[i].type === 'left' || slideSegments[i].type === 'right') {
slideSegments[i].x += slideSegments[i].curveAmount * (speed / SLIDE_SEGMENT_HEIGHT);
}
}
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].y += speed;
}
for (var i = 0; i < coins.length; i++) {
coins[i].y += speed;
if (coins[i].update) coins[i].update();
}
for (var i = 0; i < boosts.length; i++) {
boosts[i].y += speed;
}
// Player jump update
if (player.update) player.update();
// Generate new slide segments if needed
var lastSeg = slideSegments[slideSegments.length - 1];
while (lastSeg.y > -SLIDE_SEGMENT_HEIGHT * 0.5) {
generateNextSegment();
lastSeg = slideSegments[slideSegments.length - 1];
}
// Remove offscreen objects
cleanupObjects();
// Check for jump segment under player
var onJump = false;
for (var i = 0; i < slideSegments.length; i++) {
var seg = slideSegments[i];
if (seg.isJump && Math.abs(player.y - seg.y) < SLIDE_SEGMENT_HEIGHT / 2) {
onJump = true;
break;
}
}
if (onJump && !player.isJumping) {
startPlayerJump();
}
// Check for boost under player
var onBoost = false;
for (var i = 0; i < boosts.length; i++) {
if (Math.abs(player.x - boosts[i].x) < 100 && Math.abs(player.y - boosts[i].y) < 80) {
onBoost = true;
break;
}
}
if (onBoost) {
boostTicks = BOOST_DURATION;
}
// Handle boost
if (boostTicks > 0) {
speed = BOOST_SPEED;
boostTicks--;
} else {
// Gradually return to normal speed
if (speed > PLAYER_SPEED) {
speed -= PLAYER_DECEL;
if (speed < PLAYER_SPEED) speed = PLAYER_SPEED;
} else if (speed < PLAYER_SPEED) {
speed += PLAYER_ACCEL;
if (speed > PLAYER_SPEED) speed = PLAYER_SPEED;
}
}
// Check for coin collection
for (var i = coins.length - 1; i >= 0; i--) {
var c = coins[i];
if (Math.abs(player.x - c.x) < COIN_RADIUS + 40 && Math.abs(player.y - c.y) < COIN_RADIUS + 40) {
coinCount++;
coinTxt.setText('Coins: ' + coinCount);
c.destroy();
coins.splice(i, 1);
}
}
// Check for obstacle collision (ignore if jumping)
if (!player.isJumping) {
for (var i = 0; i < obstacles.length; i++) {
var obs = obstacles[i];
if (Math.abs(player.x - obs.x) < OBSTACLE_RADIUS + 50 && Math.abs(player.y - obs.y) < OBSTACLE_RADIUS + 50) {
triggerGameOver();
return;
}
}
}
// Check if player is on slide (unless jumping)
if (!player.isJumping && !isPlayerOnSlide()) {
// If player is not on slide and not jumping, trigger auto jump instead of game over
startPlayerJump();
// Do not trigger game over, allow jump to save the player
// Optionally, you could add a sound or effect here
}
// Update distance and score
distance += speed;
var score = Math.floor(distance / 10) + coinCount * 10;
scoreTxt.setText('Score: ' + score);
// Win condition: none (endless)
};
/* End of game code */ /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Boost: Speed boost pad
var Boost = Container.expand(function () {
var self = Container.call(this);
var boost = self.attachAsset('boost', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Coin: Collectible
var Coin = Container.expand(function () {
var self = Container.call(this);
var coin = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
// For simple spin animation
self.spinTick = 0;
self.update = function () {
self.spinTick++;
coin.scaleX = 0.7 + 0.3 * Math.abs(Math.sin(self.spinTick * 0.15));
};
return self;
});
// Obstacle: Stationary object on the slide
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obs = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Player: The character controlled by the player
var Player = Container.expand(function () {
var self = Container.call(this);
var player = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// For jump animation
self.isJumping = false;
self.jumpTick = 0;
self.jumpDuration = 0;
self.jumpHeight = 0;
self.update = function () {
if (self.isJumping) {
self.jumpTick++;
// Simple jump arc
var t = self.jumpTick / self.jumpDuration;
if (t > 1) t = 1;
self.y = self.baseY - Math.sin(Math.PI * t) * self.jumpHeight;
if (self.jumpTick >= self.jumpDuration) {
self.isJumping = false;
self.y = self.baseY;
}
}
};
// Start jump
self.startJump = function (duration, height) {
if (!self.isJumping) {
self.isJumping = true;
self.jumpTick = 0;
self.jumpDuration = duration;
self.jumpHeight = height;
self.baseY = self.y;
}
};
return self;
});
// SlideSegment: A piece of the slide, can be straight or curved
var SlideSegment = Container.expand(function () {
var self = Container.call(this);
var segment = self.attachAsset('slideSegment', {
anchorX: 0.5,
anchorY: 0.5
});
// Type: 'straight', 'left', 'right', 'jump', 'boost'
self.type = 'straight';
// For curve: curveAmount in px, positive=right, negative=left
self.curveAmount = 0;
// For jump: isJump
self.isJump = false;
// For boost: isBoost
self.isBoost = false;
// For segment index
self.segmentIndex = 0;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Speed boost
// Player character
// Coin
// Obstacle
// Slide (track) segment
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var SLIDE_WIDTH = 800;
var SLIDE_SEGMENT_HEIGHT = 300;
var PLAYER_START_X = GAME_WIDTH / 2;
var PLAYER_START_Y = GAME_HEIGHT * 0.7;
var PLAYER_MOVE_LIMIT = SLIDE_WIDTH / 2 - 80;
var PLAYER_SPEED = 18; // px per tick (vertical)
var PLAYER_MAX_SPEED = 38;
var PLAYER_MIN_SPEED = 12;
var PLAYER_ACCEL = 0.01;
var PLAYER_DECEL = 0.02;
var BOOST_SPEED = 32;
var BOOST_DURATION = 60; // ticks
var JUMP_DURATION = 50; // ticks
var JUMP_HEIGHT = 220;
var OBSTACLE_RADIUS = 60;
var COIN_RADIUS = 40;
var SLIDE_CURVE_MAX = 220; // px per segment
var SLIDE_CURVE_CHANCE = 0.25;
var OBSTACLE_CHANCE = 0.35;
var COIN_CHANCE = 0.25;
var BOOST_CHANCE = 0.10;
var JUMP_CHANCE = 0.08;
// Game state
var slideSegments = [];
var obstacles = [];
var coins = [];
var boosts = [];
var player = null;
var distance = 0;
var coinCount = 0;
var speed = PLAYER_SPEED;
var boostTicks = 0;
var isGameOver = false;
var dragX = null;
var dragStartX = null;
var dragStartPlayerX = null;
var lastMoveX = null;
var lastMoveY = null;
var lastSegmentIndex = 0;
var jumpQueued = false;
// Score display (English)
var scoreTxt = new Text2('Score: 0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Coin display (English)
var coinTxt = new Text2('Coins: 0', {
size: 70,
fill: 0xFFE066
});
// Anchor to right edge, top (so text grows leftward, not offscreen)
coinTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(coinTxt);
// Helper: Generate a slide segment
function createSlideSegment(type, curveAmount, y) {
var seg = new SlideSegment();
seg.type = type;
seg.curveAmount = curveAmount || 0;
seg.x = GAME_WIDTH / 2;
seg.y = y;
seg.segmentIndex = lastSegmentIndex++;
if (type === 'left' || type === 'right') {
seg.curveAmount = curveAmount;
}
if (type === 'jump') {
seg.isJump = true;
}
if (type === 'boost') {
seg.isBoost = true;
}
slideSegments.push(seg);
game.addChild(seg);
return seg;
}
// Helper: Generate an obstacle
function createObstacle(x, y) {
var obs = new Obstacle();
obs.x = x;
obs.y = y;
obstacles.push(obs);
game.addChild(obs);
return obs;
}
// Helper: Generate a coin
function createCoin(x, y) {
var c = new Coin();
c.x = x;
c.y = y;
coins.push(c);
game.addChild(c);
return c;
}
// Helper: Generate a boost
function createBoost(x, y) {
var b = new Boost();
b.x = x;
b.y = y;
boosts.push(b);
game.addChild(b);
return b;
}
// Helper: Remove offscreen objects
function cleanupObjects() {
// Slide segments
for (var i = slideSegments.length - 1; i >= 0; i--) {
if (slideSegments[i].y > GAME_HEIGHT + SLIDE_SEGMENT_HEIGHT) {
slideSegments[i].destroy();
slideSegments.splice(i, 1);
}
}
// Obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].y > GAME_HEIGHT + 200) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Coins
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i].y > GAME_HEIGHT + 200) {
coins[i].destroy();
coins.splice(i, 1);
}
}
// Boosts
for (var i = boosts.length - 1; i >= 0; i--) {
if (boosts[i].y > GAME_HEIGHT + 200) {
boosts[i].destroy();
boosts.splice(i, 1);
}
}
}
// Helper: Generate next slide segment (randomly)
function generateNextSegment() {
var lastSeg = slideSegments[slideSegments.length - 1];
var y = lastSeg.y - SLIDE_SEGMENT_HEIGHT;
var type = 'straight';
var curveAmount = 0;
var rand = Math.random();
if (rand < SLIDE_CURVE_CHANCE) {
// Curve
if (Math.random() < 0.5) {
type = 'left';
curveAmount = -SLIDE_CURVE_MAX * (0.5 + Math.random() * 0.5);
} else {
type = 'right';
curveAmount = SLIDE_CURVE_MAX * (0.5 + Math.random() * 0.5);
}
} else if (rand < SLIDE_CURVE_CHANCE + JUMP_CHANCE) {
type = 'jump';
} else if (rand < SLIDE_CURVE_CHANCE + JUMP_CHANCE + BOOST_CHANCE) {
type = 'boost';
}
var seg = createSlideSegment(type, curveAmount, y);
// Place obstacles, coins, boosts
// Obstacles: not on jump or boost
if (type !== 'jump' && type !== 'boost' && Math.random() < OBSTACLE_CHANCE) {
var obsX = GAME_WIDTH / 2 + (Math.random() - 0.5) * (SLIDE_WIDTH - 200);
createObstacle(obsX, y);
}
// Coins: not on jump
if (type !== 'jump' && Math.random() < COIN_CHANCE) {
var coinX = GAME_WIDTH / 2 + (Math.random() - 0.5) * (SLIDE_WIDTH - 200);
createCoin(coinX, y - SLIDE_SEGMENT_HEIGHT / 3);
}
// Boost: only on boost segment
if (type === 'boost') {
createBoost(GAME_WIDTH / 2, y);
}
}
// Helper: Check if player is on slide
function isPlayerOnSlide() {
// Find the closest segment under the player
var minDist = 99999;
var seg = null;
for (var i = 0; i < slideSegments.length; i++) {
var s = slideSegments[i];
var dy = Math.abs(player.y - s.y);
if (dy < SLIDE_SEGMENT_HEIGHT / 2 && dy < minDist) {
minDist = dy;
seg = s;
}
}
if (!seg) return false;
// Slide center x
var centerX = seg.x;
// Slide width
var width = SLIDE_WIDTH;
// For curve, offset centerX
if (seg.type === 'left' || seg.type === 'right') {
centerX += seg.curveAmount * ((player.y - seg.y) / SLIDE_SEGMENT_HEIGHT);
}
// For jump, always on slide
if (seg.isJump) return true;
// Check if player.x is within slide bounds
return Math.abs(player.x - centerX) < width / 2 - 60;
}
// Helper: Start jump
function startPlayerJump() {
if (!player.isJumping) {
player.startJump(JUMP_DURATION, JUMP_HEIGHT);
}
}
// Helper: End game
function triggerGameOver() {
if (!isGameOver) {
isGameOver = true;
LK.effects.flashScreen(0xff0000, 1000);
// Calculate and set the final score so it appears in the game over popup
var finalScore = Math.floor(distance / 10) + coinCount * 10;
LK.setScore(finalScore);
LK.showGameOver();
}
}
// Initialize player
player = new Player();
player.x = PLAYER_START_X;
player.y = PLAYER_START_Y;
game.addChild(player);
// Generate initial slide
slideSegments = [];
lastSegmentIndex = 0;
var segY = PLAYER_START_Y + 200;
for (var i = 0; i < 10; i++) {
createSlideSegment('straight', 0, segY);
segY -= SLIDE_SEGMENT_HEIGHT;
}
// Initial objects
obstacles = [];
coins = [];
boosts = [];
distance = 0;
coinCount = 0;
speed = PLAYER_SPEED;
boostTicks = 0;
isGameOver = false;
jumpQueued = false;
// Input: Drag to steer
game.down = function (x, y, obj) {
if (isGameOver) return;
dragX = x;
dragStartX = x;
dragStartPlayerX = player.x;
lastMoveX = x;
lastMoveY = y;
};
game.move = function (x, y, obj) {
if (isGameOver) return;
if (dragX !== null) {
var dx = x - dragStartX;
var newX = dragStartPlayerX + dx;
// Clamp to slide width
var minX = GAME_WIDTH / 2 - PLAYER_MOVE_LIMIT;
var maxX = GAME_WIDTH / 2 + PLAYER_MOVE_LIMIT;
if (newX < minX) newX = minX;
if (newX > maxX) newX = maxX;
player.x = newX;
lastMoveX = x;
lastMoveY = y;
}
};
game.up = function (x, y, obj) {
dragX = null;
dragStartX = null;
dragStartPlayerX = null;
};
// Main game loop
game.update = function () {
if (isGameOver) return;
// Move slide and objects down (simulate player moving down)
for (var i = 0; i < slideSegments.length; i++) {
slideSegments[i].y += speed;
// For curve, move segment center
if (slideSegments[i].type === 'left' || slideSegments[i].type === 'right') {
slideSegments[i].x += slideSegments[i].curveAmount * (speed / SLIDE_SEGMENT_HEIGHT);
}
}
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].y += speed;
}
for (var i = 0; i < coins.length; i++) {
coins[i].y += speed;
if (coins[i].update) coins[i].update();
}
for (var i = 0; i < boosts.length; i++) {
boosts[i].y += speed;
}
// Player jump update
if (player.update) player.update();
// Generate new slide segments if needed
var lastSeg = slideSegments[slideSegments.length - 1];
while (lastSeg.y > -SLIDE_SEGMENT_HEIGHT * 0.5) {
generateNextSegment();
lastSeg = slideSegments[slideSegments.length - 1];
}
// Remove offscreen objects
cleanupObjects();
// Check for jump segment under player
var onJump = false;
for (var i = 0; i < slideSegments.length; i++) {
var seg = slideSegments[i];
if (seg.isJump && Math.abs(player.y - seg.y) < SLIDE_SEGMENT_HEIGHT / 2) {
onJump = true;
break;
}
}
if (onJump && !player.isJumping) {
startPlayerJump();
}
// Check for boost under player
var onBoost = false;
for (var i = 0; i < boosts.length; i++) {
if (Math.abs(player.x - boosts[i].x) < 100 && Math.abs(player.y - boosts[i].y) < 80) {
onBoost = true;
break;
}
}
if (onBoost) {
boostTicks = BOOST_DURATION;
}
// Handle boost
if (boostTicks > 0) {
speed = BOOST_SPEED;
boostTicks--;
} else {
// Gradually return to normal speed
if (speed > PLAYER_SPEED) {
speed -= PLAYER_DECEL;
if (speed < PLAYER_SPEED) speed = PLAYER_SPEED;
} else if (speed < PLAYER_SPEED) {
speed += PLAYER_ACCEL;
if (speed > PLAYER_SPEED) speed = PLAYER_SPEED;
}
}
// Check for coin collection
for (var i = coins.length - 1; i >= 0; i--) {
var c = coins[i];
if (Math.abs(player.x - c.x) < COIN_RADIUS + 40 && Math.abs(player.y - c.y) < COIN_RADIUS + 40) {
coinCount++;
coinTxt.setText('Coins: ' + coinCount);
c.destroy();
coins.splice(i, 1);
}
}
// Check for obstacle collision (ignore if jumping)
if (!player.isJumping) {
for (var i = 0; i < obstacles.length; i++) {
var obs = obstacles[i];
if (Math.abs(player.x - obs.x) < OBSTACLE_RADIUS + 50 && Math.abs(player.y - obs.y) < OBSTACLE_RADIUS + 50) {
triggerGameOver();
return;
}
}
}
// Check if player is on slide (unless jumping)
if (!player.isJumping && !isPlayerOnSlide()) {
// If player is not on slide and not jumping, trigger auto jump instead of game over
startPlayerJump();
// Do not trigger game over, allow jump to save the player
// Optionally, you could add a sound or effect here
}
// Update distance and score
distance += speed;
var score = Math.floor(distance / 10) + coinCount * 10;
scoreTxt.setText('Score: ' + score);
// Win condition: none (endless)
};
/* End of game code */
Arttırmak. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Madeni Para. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Engel. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Çocuk. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Kaydırak. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat