User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(bear, {' Line Number: 34 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add walkıng anımatıon to bear
User prompt
bear moves left to rıght
User prompt
spawn bear
User prompt
each hit removes no more than one life
User prompt
each hit costs one life
User prompt
show lives on top right
User prompt
give three lives
User prompt
remove life count
User prompt
gameover after 3 crash
User prompt
game ends after 3 chrashes
User prompt
every obstacle hit deducts 1 life
User prompt
each crash reduces 1 life
User prompt
game ends after 3 lives
User prompt
each crash reduces 1 life
User prompt
protect from collision in first 200 points
User prompt
Please fix the bug: 'GAME_WIDTH is not defined' in or related to this line: 'var OBSTACLE_MAX_X = GAME_WIDTH - PLAY_AREA_MARGIN;' Line Number: 139
User prompt
Please fix the bug: 'GAME_WIDTH is not defined' in or related to this line: 'var OBSTACLE_MAX_X = GAME_WIDTH - PLAY_AREA_MARGIN;' Line Number: 139
User prompt
press mouse to start
User prompt
no obstacles in first 200 points
User prompt
give three lives
User prompt
turn boarder in the movement direction
User prompt
spread obstacles on screen more densely
User prompt
increase tree intensity by 5%
User prompt
spawn rock2 after 500 points
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Obstacle class (tree or rock) var Obstacle = Container.expand(function () { var self = Container.call(this); self.type = Math.random() < 0.6 ? 'tree' : 'rock'; var assetId = self.type === 'tree' ? 'tree' : 'rock'; var obs = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.radius = obs.width * 0.45; self.speed = 0; // Set by game return self; }); // Powerup class (shield or boost) var Powerup = Container.expand(function () { var self = Container.call(this); self.kind = Math.random() < 0.5 ? 'shield' : 'boost'; var assetId = self.kind === 'shield' ? 'shield' : 'boost'; var pu = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.radius = pu.width * 0.45; self.speed = 0; // Set by game return self; }); // Rock2Obstacle class (spawns rock2 image) var Rock2Obstacle = Container.expand(function () { var self = Container.call(this); var obs = self.attachAsset('rock2', { anchorX: 0.5, anchorY: 0.5 }); self.radius = obs.width * 0.45; self.speed = 0; // Set by game return self; }); // Snowboarder (player) class var Snowboarder = Container.expand(function () { var self = Container.call(this); var sb = self.attachAsset('snowboarder', { anchorX: 0.5, anchorY: 0.5 }); self.radius = sb.width * 0.45; // For collision self.hasShield = false; self.shieldNode = null; // Show shield visual if active self.setShield = function (active) { self.hasShield = active; if (active && !self.shieldNode) { self.shieldNode = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 1.3, alpha: 0.5 }); } else if (!active && self.shieldNode) { self.shieldNode.destroy(); self.shieldNode = null; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xffffff // White for snow }); /**** * Game Code ****/ // Speed boost powerup // Shield powerup // Rock obstacle // Tree obstacle // Snowboarder (player) // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var PLAY_AREA_MARGIN = 60; // px, left/right margin for obstacles (reduced for denser spread) var OBSTACLE_MIN_Y_DIST = 320; // Minimum vertical distance between obstacles (denser) var OBSTACLE_MAX_Y_DIST = 540; // Maximum vertical distance between obstacles (denser) var OBSTACLE_MIN_X = PLAY_AREA_MARGIN; var OBSTACLE_MAX_X = GAME_WIDTH - PLAY_AREA_MARGIN; var POWERUP_CHANCE = 0.12; // Chance to spawn a powerup instead of obstacle // Intensity increase after 1000 points var INTENSITY_SCORE_THRESHOLD = 1000; var INTENSE_OBSTACLE_MIN_Y_DIST = 160; // Denser in intense mode var INTENSE_OBSTACLE_MAX_Y_DIST = 320; var INTENSE_POWERUP_CHANCE = 0.16; // Game state var snowboarder; var obstacles = []; var powerups = []; var dragNode = null; var dragOffsetX = 0; var dragStartX = 0; var dragStartSnowboarderX = 0; var lastObstacleY = 0; var speed = 18; // Initial speed (pixels per frame) var maxSpeed = 48; var speedIncreaseEvery = 600; // Increase speed every N ticks var ticksSinceStart = 0; var distance = 0; // Distance traveled (score) var scoreTxt; var shieldTimer = 0; var boostTimer = 0; var isBoosting = false; // Add tree images to both sides of the screen as static background elements var leftTrees = []; var rightTrees = []; var treeSpacingY = 320 * 0.95; // Increase tree intensity by reducing spacing by 5% var treeY = 0; while (treeY < GAME_HEIGHT + 200) { // Left side var leftTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: PLAY_AREA_MARGIN / 2, y: treeY }); game.addChild(leftTree); leftTrees.push(leftTree); // Right side var rightTree = LK.getAsset('tree', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH - PLAY_AREA_MARGIN / 2, y: treeY }); game.addChild(rightTree); rightTrees.push(rightTree); treeY += treeSpacingY; } // GUI: Score scoreTxt = new Text2('0', { size: 120, fill: "#222" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // GUI: Lives var lives = 3; var livesTxt = new Text2('❤❤❤', { size: 100, fill: 0xD83318 }); livesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(livesTxt); livesTxt.x = 300; livesTxt.y = 0; // Initialize player snowboarder = new Snowboarder(); game.addChild(snowboarder); snowboarder.x = GAME_WIDTH / 2; snowboarder.y = GAME_HEIGHT * 0.12; // Helper: Clamp value function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); } // Helper: Distance between two objects function dist(a, b) { var dx = a.x - b.x; var dy = a.y - b.y; return Math.sqrt(dx * dx + dy * dy); } // Spawn an obstacle or powerup function spawnObstacleOrPowerup(y) { // Determine if intensity should be increased var scoreVal = Math.floor(distance / 10); var minYDist = OBSTACLE_MIN_Y_DIST; var maxYDist = OBSTACLE_MAX_Y_DIST; var powerupChance = POWERUP_CHANCE; if (scoreVal >= INTENSITY_SCORE_THRESHOLD) { minYDist = INTENSE_OBSTACLE_MIN_Y_DIST; maxYDist = INTENSE_OBSTACLE_MAX_Y_DIST; powerupChance = INTENSE_POWERUP_CHANCE; } if (Math.random() < powerupChance) { // Powerup var pu = new Powerup(); pu.x = Math.random() * (OBSTACLE_MAX_X - OBSTACLE_MIN_X) + OBSTACLE_MIN_X; pu.y = y; pu.speed = speed; powerups.push(pu); game.addChild(pu); } else { // Obstacle var obs; if (scoreVal >= 500 && Math.random() < 0.33) { // After 500 points, 33% chance to spawn rock2 obs = new Rock2Obstacle(); } else { obs = new Obstacle(); } obs.x = Math.random() * (OBSTACLE_MAX_X - OBSTACLE_MIN_X) + OBSTACLE_MIN_X; obs.y = y; obs.speed = speed; obstacles.push(obs); game.addChild(obs); } } // Initial obstacles lastObstacleY = snowboarder.y - 600; for (var i = 0; i < 6; i++) { lastObstacleY -= Math.random() * (OBSTACLE_MAX_Y_DIST - OBSTACLE_MIN_Y_DIST) + OBSTACLE_MIN_Y_DIST; spawnObstacleOrPowerup(lastObstacleY); } // Touch/drag controls game.down = function (x, y, obj) { // Only allow drag if touch is on lower 2/3 of screen (to avoid top menu) if (y > GAME_HEIGHT * 0.2) { dragNode = snowboarder; dragStartX = x; dragStartSnowboarderX = snowboarder.x; } }; game.move = function (x, y, obj) { if (dragNode === snowboarder) { var dx = x - dragStartX; var newX = clamp(dragStartSnowboarderX + dx, OBSTACLE_MIN_X, OBSTACLE_MAX_X); snowboarder.x = newX; // Rotate snowboarder to face movement direction if (Math.abs(dx) > 8) { // Limit max angle to 30 degrees (PI/6) var maxAngle = Math.PI / 6; var angle = clamp(dx / 400, -1, 1) * maxAngle; snowboarder.rotation = angle; } else { snowboarder.rotation = 0; } } }; game.up = function (x, y, obj) { dragNode = null; if (snowboarder) snowboarder.rotation = 0; }; // Main game loop game.update = function () { ticksSinceStart++; // Increase speed over time if (ticksSinceStart % speedIncreaseEvery === 0 && speed < maxSpeed) { speed += 2; } // Speed scaling: increase by 20% for each 1000 points after the first 1000 points var scoreVal = Math.floor(distance / 10); if (scoreVal >= 1000) { // Number of 1000-point steps after the first 1000 var speedSteps = Math.floor((scoreVal - 1000) / 1000) + 1; var scaledSpeed = speed * Math.pow(1.2, speedSteps); // Clamp to maxSpeed if needed if (scaledSpeed > maxSpeed) { scaledSpeed = maxSpeed; } speed = scaledSpeed; } // If boosting, increase speed temporarily var currentSpeed = isBoosting ? speed * 1.7 : speed; // Move side trees up (reverse flow) for (var i = 0; i < leftTrees.length; i++) { leftTrees[i].y -= currentSpeed; // If tree goes off top, move it to bottom if (leftTrees[i].y < -200) { leftTrees[i].y += treeSpacingY * leftTrees.length; } } for (var i = 0; i < rightTrees.length; i++) { rightTrees[i].y -= currentSpeed; if (rightTrees[i].y < -200) { rightTrees[i].y += treeSpacingY * rightTrees.length; } } // Move obstacles and powerups up (reverse flow) for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.y -= currentSpeed; obs.speed = currentSpeed; // Remove if off screen (now above screen) if (obs.y + obs.height / 2 < -100) { obs.destroy(); obstacles.splice(i, 1); } } for (var i = powerups.length - 1; i >= 0; i--) { var pu = powerups[i]; pu.y -= currentSpeed; pu.speed = currentSpeed; // Remove if off screen (now above screen) if (pu.y + pu.height / 2 < -100) { pu.destroy(); powerups.splice(i, 1); } } // Continuously spawn obstacles and powerups as the player progresses (now below player) while (lastObstacleY < snowboarder.y + 3000) { // Use more intense spawn distances after threshold var scoreVal = Math.floor(distance / 10); var minYDist = OBSTACLE_MIN_Y_DIST; var maxYDist = OBSTACLE_MAX_Y_DIST; if (scoreVal >= INTENSITY_SCORE_THRESHOLD) { minYDist = INTENSE_OBSTACLE_MIN_Y_DIST; maxYDist = INTENSE_OBSTACLE_MAX_Y_DIST; } lastObstacleY += Math.random() * (maxYDist - minYDist) + minYDist; spawnObstacleOrPowerup(lastObstacleY); } // Obstacles and powerups keep coming endlessly as the player progresses // Always ensure obstacles continue to spawn all game, even if the player is not moving if (obstacles.length < 8) { // If for any reason there are too few obstacles, spawn more to keep the game challenging var scoreVal = Math.floor(distance / 10); var minYDist = OBSTACLE_MIN_Y_DIST; var maxYDist = OBSTACLE_MAX_Y_DIST; if (scoreVal >= INTENSITY_SCORE_THRESHOLD) { minYDist = INTENSE_OBSTACLE_MIN_Y_DIST; maxYDist = INTENSE_OBSTACLE_MAX_Y_DIST; } lastObstacleY += Math.random() * (maxYDist - minYDist) + minYDist; spawnObstacleOrPowerup(lastObstacleY); } // Collision: obstacles var crashedThisFrame = false; for (var i = 0; i < obstacles.length; i++) { var obs = obstacles[i]; // Only process the first collision per frame if (!crashedThisFrame && dist(snowboarder, obs) < snowboarder.radius + obs.radius) { crashedThisFrame = true; var scoreVal = Math.floor(distance / 10); if (scoreVal < 200) { // Protect from collision in first 200 points: ignore collision // Optionally, flash snowboarder to indicate invulnerability LK.effects.flashObject(snowboarder, 0x66ffcc, 300); } else { if (snowboarder.hasShield) { snowboarder.setShield(false); // Flash snowboarder LK.effects.flashObject(snowboarder, 0xffe066, 600); } else { // Only reduce lives by 1 per crash, even if multiple obstacles overlap lives = Math.max(0, lives - 1); // Update lives display var heartStr = ''; for (var j = 0; j < lives; j++) heartStr += '❤'; livesTxt.setText(heartStr); LK.effects.flashScreen(0xff0000, 900); // End game immediately after 3 lives are lost if (lives <= 0) { LK.showGameOver(); return; } } } // Only one life lost per frame, even if multiple obstacles overlap } } // Collision: powerups for (var i = powerups.length - 1; i >= 0; i--) { var pu = powerups[i]; if (dist(snowboarder, pu) < snowboarder.radius + pu.radius) { if (pu.kind === 'shield') { snowboarder.setShield(true); shieldTimer = 360; // 6 seconds at 60fps } else if (pu.kind === 'boost') { isBoosting = true; boostTimer = 180; // 3 seconds at 60fps // Flash snowboarder red for boost LK.effects.flashObject(snowboarder, 0xff3b3b, 400); } pu.destroy(); powerups.splice(i, 1); } } // Powerup timers if (snowboarder.hasShield) { shieldTimer--; if (shieldTimer <= 0) { snowboarder.setShield(false); } } if (isBoosting) { boostTimer--; if (boostTimer <= 0) { isBoosting = false; } } // Snowboarder stays at the top; do not move snowboarder down the screen (reverse flow) // snowboarder.y += currentSpeed; // Score: distance traveled distance += currentSpeed; var scoreVal = Math.floor(distance / 10); LK.setScore(scoreVal); scoreTxt.setText(scoreVal); // Endless game: no win condition, continues until hit }; /* End of game code */
===================================================================
--- original.js
+++ change.js
@@ -334,8 +334,9 @@
// Collision: obstacles
var crashedThisFrame = false;
for (var i = 0; i < obstacles.length; i++) {
var obs = obstacles[i];
+ // Only process the first collision per frame
if (!crashedThisFrame && dist(snowboarder, obs) < snowboarder.radius + obs.radius) {
crashedThisFrame = true;
var scoreVal = Math.floor(distance / 10);
if (scoreVal < 200) {
@@ -347,9 +348,10 @@
snowboarder.setShield(false);
// Flash snowboarder
LK.effects.flashObject(snowboarder, 0xffe066, 600);
} else {
- lives--;
+ // Only reduce lives by 1 per crash, even if multiple obstacles overlap
+ lives = Math.max(0, lives - 1);
// Update lives display
var heartStr = '';
for (var j = 0; j < lives; j++) heartStr += '❤';
livesTxt.setText(heartStr);
pine tree seen from above. In-Game asset. 2d. High contrast. No shadows
snowboarder seen from above. In-Game asset. 2d. High contrast. No shadows
rock. In-Game asset. 2d. High contrast. No shadows
grey rock. In-Game asset. 2d. High contrast. No shadows
boost arrow. In-Game asset. 2d. High contrast. No shadows
remove background