User prompt
Add a bit of floating animation to the coins when they are instantiated βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Move the high score vertically a very very small bit
User prompt
Instead of 2.5/3 change it back to 2/3
User prompt
Can you fix that
User prompt
Move it a bit to the right
User prompt
Please fix the bug: 'TypeError: game.findChildByName is not a function' in or related to this line: 'var existingHighScoreTxt = game.findChildByName('highScoreTxt');' Line Number: 116
User prompt
Please fix the bug: 'TypeError: game.findChildByName is not a function' in or related to this line: 'if (!game.findChildByName('highScoreTxt')) {' Line Number: 97
User prompt
If the current high score is higher than the existing one update it do not overlap it
User prompt
Again
User prompt
Move the high score a bit to the left of it's current position
User prompt
Move it to the left
User prompt
Move the high score a bit to the left
User prompt
Show it at game start
User prompt
It's High Score not Last Score
User prompt
Save the score before game over and add it at the bottom right of the play space in white βͺπ‘ Consider importing and using the following plugins: @upit/storage.v1
User prompt
Make sure that killing an enemy only drops coins once
User prompt
before destroying goldcoin play goldsnd
User prompt
before destroying silvercoin play silversnd, before destroying goldcoin play goldsnd
Code edit (1 edits merged)
Please save this source code
User prompt
sometimes when coins overlap, they glitch, can you fix that?
User prompt
the score is given too quickly, wait until the coin is fully faded out first βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the coins fly towards that
User prompt
make them fly towards the player_idle, not the mouse
User prompt
make them fly towards the player who is static, not the mouse
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Basic Shape class (so "Shape" is defined) var Shape = Container.expand(function (options) { var self = Container.call(this); self.attachAsset('shape', { width: options.width, height: options.height, anchorX: options.anchorX || 0, anchorY: options.anchorY || 0, color: options.color || 0x66ff00, alpha: typeof options.alpha === 'number' ? options.alpha : 0 // invisible shape }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ function findChildByName(container, name) { for (var i = 0; i < container.children.length; i++) { if (container.children[i].name === name) { return container.children[i]; } } return null; } /**** * Global Variables ****/ var jumpColGlobal = null; // For projectile input tracking var isPressHeld = false; var pressHoldStartTime = 0; var pressDownX = 0; // track where the press started (X) var pressDownY = 0; // track where the press started (Y) // Global mouse coordinates var mouseX = 0; var mouseY = 0; // Update mouse coordinates as the mouse moves over the game game.move = function (x, y) { mouseX = x; mouseY = y; }; /**** * Score Setup ****/ var score = 0; var scoreTxt; // container for the score text function updateScoreDisplay() { // Remove the old scoreTxt from the game game.removeChild(scoreTxt); // Create a new score container with the updated score scoreTxt = createScoreText(score); scoreTxt.scaleX = 1.0; scoreTxt.scaleY = 1.0; game.addChild(scoreTxt); // Display high score at the bottom right var highScore = storage.highScore || 0; if (score > highScore) { highScore = score; storage.highScore = highScore; } if (!findChildByName(game, 'highScoreTxt')) { var highScoreTxt = new Text2('High Score: ' + highScore, { size: 50, fill: 0xFFFFFF }); highScoreTxt.name = 'highScoreTxt'; highScoreTxt.anchor.set(1, 1); // Anchor to the bottom right highScoreTxt.x = 1900; // Move further right from the previous position highScoreTxt.y = 2732; // Bottom edge game.addChild(highScoreTxt); } else { var existingHighScoreTxt = findChildByName(game, 'highScoreTxt'); existingHighScoreTxt.setText('High Score: ' + highScore); } // Add tween animation to score display tween(scoreTxt, { scaleX: 1.5, scaleY: 1.5 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(scoreTxt, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeIn }); } }); } function incrementScore() { score++; updateScoreDisplay(); } function createScoreText(value) { var shadow = new Text2(String(value), { size: 600, fill: 0x000000, fontFamily: "Arial" }); shadow.name = "shadow"; shadow.anchor.set(0.5, 0); shadow.x = 4; shadow.y = 4; var main = new Text2(String(value), { size: 600, fill: 0xFF69B4, fontFamily: "Arial" }); main.name = "main"; main.anchor.set(0.5, 0); var container = new Container(); container.name = "scoreTxt"; container.x = 1024; container.y = 50; container.addChild(shadow); container.addChild(main); return container; } // build the score text container once scoreTxt = createScoreText(score); scoreTxt.scaleX = 1.0; scoreTxt.scaleY = 1.0; LK.playMusic('bgm', { loop: true }); var bg01 = LK.getAsset('bg01', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); game.addChild(bg01); game.addChild(scoreTxt); // Display high score at the bottom right at game start var highScore = storage.highScore || 0; var highScoreTxt = new Text2('High Score: ' + highScore, { size: 50, fill: 0xFFFFFF }); highScoreTxt.name = 'highScoreTxt'; highScoreTxt.anchor.set(1, 1); // Anchor to the bottom right highScoreTxt.x = 1900; // Move further right from the previous position highScoreTxt.y = 2720; // Slightly above the bottom edge game.addChild(highScoreTxt); /**** * Petals ****/ var petals = []; for (var i = 0; i < 50; i++) { var petal = new Container(); petal.attachAsset('petals', { anchorX: 0.5, anchorY: 0.5, rotation: Math.random() * Math.PI * 2 }); petal.x = Math.random() * 2048; petal.y = Math.random() * 2732; petal.speedY = Math.random() * 2 + 1; petal.speedX = Math.random() * 2 - 1; petal.update = function () { this.y += this.speedY; this.x += this.speedX; if (this.y > 2732) { this.y = -50; this.x = Math.random() * 2048; } }; petals.push(petal); game.addChild(petal); } /**** * Player Setup ****/ var player = new Container(); var visualContainer = new Container(); visualContainer.name = 'visual'; var playerSprite = visualContainer.attachAsset('player_idle', { anchorX: 0.5, anchorY: 0.5 }); player.addChild(visualContainer); player.x = 1024; player.y = 2732 - 250; game.addChild(player); /**** * Idle Animations ****/ function startBreathingAnimation() { tween(player, { scaleX: 1.05, scaleY: 1.05 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(player, { scaleX: 1.0, scaleY: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: startBreathingAnimation }); } }); } function startTiltAnimation() { tween(player, { rotation: Math.PI / 32 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(player, { rotation: -Math.PI / 32 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(player, { rotation: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: startTiltAnimation }); } }); } }); } startBreathingAnimation(); startTiltAnimation(); /**** * Attack Collider ****/ var attackCol = LK.getAsset('attackcol', { anchorX: 0.5, anchorY: 0.5, alpha: 0.75 }); game.addChild(attackCol); attackCol.visible = false; attackCol.alpha = 0; /**** * Swap Player Sprite ****/ function swapPlayerVisual(newVisualId, x, y) { var flip = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; var onDone = arguments.length > 4 ? arguments[4] : undefined; var visualContainer = player.findChildByName('visual'); if (!visualContainer) { visualContainer = new Container(); visualContainer.name = 'visual'; player.addChild(visualContainer); } else { visualContainer.removeChildAt(0); } playerSprite = visualContainer.attachAsset(newVisualId, { anchorX: 0.5, anchorY: 0.5 }); visualContainer.scaleX = flip; player.x = x; player.y = y; if (newVisualId === 'player_jump') { flip = Math.random() < 0.5 ? -1 : 1; visualContainer.scaleX = flip; jumpColGlobal = LK.getAsset('jumpcol', { anchorX: 0.5, anchorY: 0.5, x: x, y: y + player.height / 2, alpha: 0 }); game.addChild(jumpColGlobal); tween(jumpColGlobal, { y: jumpColGlobal.y - 600 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { tween(jumpColGlobal, { y: 2732 - 250 + player.height / 2 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { jumpColGlobal.destroy(); jumpColGlobal = null; } }); } }); } if (typeof onDone === 'function') { if (newVisualId === 'player_idle') { startBreathingAnimation(); startTiltAnimation(); } onDone(); } } /**** * Input Logic ****/ var isSequenceRunning = false; var isJumping = false; var playerState = 'idle'; game.down = function (x, y) { if (isSequenceRunning) { return; } isPressHeld = true; pressHoldStartTime = Date.now(); pressDownX = x; // remember where the press happened pressDownY = y; // remember where the press happened // Jump if tapped in top 2/3 if (y < 2732 * 2 / 3 && !isJumping) { isJumping = true; LK.getSound('hup').play(); swapPlayerVisual('player_jump', player.x, player.y); // Dust effect for (var i = 0; i < 10; i++) { var p = LK.getAsset('dust', { anchorX: 0.5, anchorY: 0.5, x: player.x + (Math.random() * 100 - 50), y: player.y + (Math.random() * 100 - 50) }); game.addChild(p); tween(p, { alpha: 0, x: p.x + (Math.random() * 200 - 100), y: p.y - Math.random() * 200 }, { duration: 500, onFinish: function onFinish() { p.destroy(); } }); } tween(player, { y: player.y - 600 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { tween(player, { y: 2732 - 250 }, { duration: 300, easing: tween.bounceOut, onFinish: function onFinish() { // Landing dust effect for (var j = 0; j < 10; j++) { var pp = LK.getAsset('dust', { anchorX: 0.5, anchorY: 0.5, x: player.x + (Math.random() * 100 - 50), y: player.y + (Math.random() * 100 - 50) }); game.addChild(pp); tween(pp, { alpha: 0, x: pp.x + (Math.random() * 200 - 100), y: pp.y + Math.random() * 200 }, { duration: 500, onFinish: function onFinish() { pp.destroy(); } }); } isJumping = false; swapPlayerVisual('player_idle', 1024, 2732 - 250, 1, function () { startBreathingAnimation(); startTiltAnimation(); }); var v = player.findChildByName('visual'); if (v) { var dir = v.scaleX < 0 ? -1 : 1; tween(v, { scaleX: dir * 1.3, scaleY: 1.3 }, { duration: 50, onFinish: function onFinish() { tween(v, { scaleX: dir * 1.0, scaleY: 1.0 }, { duration: 100 }); } }); } } }); } }); return; } // Attack if tapped in bottom 1/3 isSequenceRunning = true; var flip = x < 1024 ? -1 : 1; swapPlayerVisual('player_attackf01', 1024, 2732 - 250, flip); LK.getSound('retroslash').play(); var vis = player.findChildByName('visual'); if (vis) { tween(vis, { scaleX: flip * 1.3, scaleY: 1.3 }, { duration: 50, onFinish: function onFinish() { tween(vis, { scaleX: flip * 1.0, scaleY: 1.0 }, { duration: 100 }); } }); } LK.setTimeout(function () { swapPlayerVisual('player_attackf02', 1024, 2732 - 250, flip); // Bigger/visible collider, offset so you see it overlapping attackCol.width = 180; attackCol.height = 180; attackCol.x = flip === -1 ? 874 : 1174; attackCol.y = 2732 - 250; attackCol.scaleX = flip; attackCol.visible = true; LK.setTimeout(function () { if (attackCol) { attackCol.visible = false; } swapPlayerVisual('player_idle', 1024, 2732 - 250, 1, function () { startBreathingAnimation(); startTiltAnimation(); }); isSequenceRunning = false; playerState = 'idle'; }, 250); }, 250); }; /**** * Enemies Array + Spawn ****/ var enemies = []; function spawnEnemy() { var e = new Container(); // Shape child as the "hitbox" var hitbox = new Shape({ width: 200, height: 209, anchorX: 0.5, anchorY: 0.5, color: 0x00FF00, alpha: 0 }); hitbox.x = 0; hitbox.y = 0; e.addChild(hitbox); var gfx = e.attachAsset('enemy01', { anchorX: 0.5, anchorY: 0.5 }); var fromLeft = Math.random() < 0.5; e.x = fromLeft ? -gfx.width / 2 : 2048 + gfx.width / 2; e.y = 2732 - 225; e.speedX = fromLeft ? Math.random() * 4 + 2 : -(Math.random() * 4 + 2); gfx.scaleX = fromLeft ? 1 : -1; var baseY = e.y; function bounce() { tween(e, { y: baseY - 50 }, { duration: 500, easing: tween.bounceInOut, onFinish: function onFinish() { tween(e, { y: baseY }, { duration: 500, easing: tween.bounceInOut, onFinish: bounce }); } }); } bounce(); enemies.push(e); game.addChild(e); } LK.setInterval(spawnEnemy, Math.random() * 1500 + 1000); /**** * NEW CODE: Projectile Logic ****/ var projectiles = []; function spawnProjectile(targetX, targetY) { var proj = new Container(); proj.attachAsset('player_throw', { anchorX: 0.5, anchorY: 0.5 }); LK.getSound('throwsnd').play(); // Instantiate cloudsmoke at the same position as the projectile proj.x = player.x; proj.y = player.y; var cloudSmoke = LK.getAsset('cloudsmoke', { anchorX: 0.5, anchorY: 0.5, x: proj.x, y: proj.y, alpha: 0.75 }); game.addChild(cloudSmoke); // Add tween for pop and disappear effect tween(cloudSmoke, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { cloudSmoke.destroy(); } }); proj.x = player.x; proj.y = player.y; // Calculate direction from player to the press location. var dx = targetX - player.x; var dy = targetY - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist !== 0) { dx /= dist; dy /= dist; } var speed = 25; proj.vx = dx * speed; proj.vy = dy * speed; // Adjust scaleX based on target relative to player proj.scaleX = targetX < player.x ? -1 : 1; proj.distanceTraveled = 0; proj.maxDistance = 1000; projectiles.push(proj); game.addChild(proj); } /**** * NEW GLOBAL: Coins ****/ // Array to track coins dropped by enemies var coins = []; /**** * Coin Drop Helper **** * When an enemy is killed, dropCoin is called at its (x, y) location. * It randomly decides whether to drop a silver coin (50% chance), * a gold coin (10% chance), or nothing (40% chance). ****/ function dropCoin(x, y) { var rand = Math.random(); if (rand < 0.5) { // 50% chance for silver coin var coin = new Container(); coin.type = 'silver'; coin.attachAsset('silver_coin', { anchorX: 0.5, anchorY: 0.5 }); coin.x = x; coin.y = y; game.addChild(coin); coins.push(coin); // Add floating animation to the coin tween(coin, { y: coin.y - 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(coin, { y: coin.y + 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Loop the floating animation tween(coin, { y: coin.y - 20 }, { duration: 1000, easing: tween.easeInOut }); } }); } }); } else if (rand < 0.6) { // 10% chance for gold coin var coin = new Container(); coin.type = 'gold'; coin.attachAsset('gold_coin', { anchorX: 0.5, anchorY: 0.5 }); coin.x = x; coin.y = y; game.addChild(coin); coins.push(coin); } // Else 40% chance: no coin drop. } /**** * Enemy Hit Logic for Both Attack and Projectile * attackType should be 'melee' or 'throw' ****/ function handleEnemyHit(enemy, index, attackType) { if (!enemies.includes(enemy)) { return; } LK.getSound('slimedeath').play(); if (enemy.bounceTween && typeof enemy.bounceTween.cancel === 'function') { enemy.bounceTween.cancel(); } tween(enemy, { tint: 0xFF0000 }, { duration: 0, onFinish: function onFinish() { tween(enemy, { scaleX: 1.3, scaleY: 1.3 }, { duration: 50, onFinish: function onFinish() { tween(enemy, { scaleX: 0.5, scaleY: 0.5, alpha: 0 }, { duration: 100, onFinish: function onFinish() { var idx = enemies.indexOf(enemy); if (idx !== -1) { enemies.splice(idx, 1); } enemy.destroy(); if (!enemy.coinsDropped) { dropCoin(enemy.x, enemy.y); enemy.coinsDropped = true; } if (!enemy.scoreCounted) { if (attackType === 'melee') { score += 2; } else if (attackType === 'throw') { score += 1; } else { score++; } updateScoreDisplay(); enemy.scoreCounted = true; } } }); } }); } }); } /**** * Enemy Hit Logic for Jump Collider * When an enemy is hit by jumpCol, it will fly off the screen ****/ function handleEnemyJumpHit(enemy, index) { if (!enemies.includes(enemy)) { return; } LK.getSound('boing').play(); if (enemy.bounceTween && typeof enemy.bounceTween.cancel === 'function') { enemy.bounceTween.cancel(); } tween(enemy, { tint: 0xFF0000 }, { duration: 0, onFinish: function onFinish() { var targetX = enemy.x < 1024 ? -300 : 2048 + 300; var targetY = enemy.y - 600; tween(enemy, { x: targetX, y: targetY, alpha: 0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { var idx = enemies.indexOf(enemy); if (idx !== -1) { enemies.splice(idx, 1); } enemy.destroy(); if (!enemy.coinsDropped) { dropCoin(enemy.x, enemy.y); enemy.coinsDropped = true; } if (!enemy.scoreCounted) { score += 3; updateScoreDisplay(); enemy.scoreCounted = true; } } }); } }); } /**** * findChildByName Helper ****/ Container.prototype.findChildByName = function (name) { for (var i = 0; i < this.children.length; i++) { if (this.children[i].name === name) { return this.children[i]; } } return null; }; /**** * game.up to Reset Press ****/ game.up = function (x, y) { isPressHeld = false; pressHoldStartTime = 0; }; /**** * Main Update ****/ game.update = function () { // Check hold duration for long press projectile if (isPressHeld) { var holdDuration = Date.now() - pressHoldStartTime; if (holdDuration > 500) { console.log("Long press detected, spawn projectile!"); isPressHeld = false; spawnProjectile(pressDownX, pressDownY); } } // Update all projectiles for (var p = projectiles.length - 1; p >= 0; p--) { var proj = projectiles[p]; proj.x += proj.vx; proj.y += proj.vy; var stepDist = Math.sqrt(proj.vx * proj.vx + proj.vy * proj.vy); proj.distanceTraveled += stepDist; if (proj.distanceTraveled > proj.maxDistance) { projectiles.splice(p, 1); proj.destroy(); continue; } if (proj.x < -100 || proj.x > 2148 || proj.y < -100 || proj.y > 2832) { projectiles.splice(p, 1); proj.destroy(); continue; } // Check collision with enemies for (var ei = enemies.length - 1; ei >= 0; ei--) { var enemy = enemies[ei]; if (proj.intersects(enemy)) { // Use the 'throw' attack type for projectiles handleEnemyHit(enemy, ei, 'throw'); projectiles.splice(p, 1); proj.destroy(); break; } } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; e.x += e.speedX; if (e.x < -300 || e.x > 2048 + 300) { var index = enemies.indexOf(e); if (index !== -1) { enemies.splice(index, 1); } e.destroy(); continue; } // Check collision with jump collider first if (jumpColGlobal && jumpColGlobal.visible && e.intersects(jumpColGlobal)) { handleEnemyJumpHit(e, i); continue; } // Check collisions with attack collider (melee) if (attackCol.visible && e.intersects(attackCol)) { handleEnemyHit(e, i, 'melee'); } // Check if enemy intersects with player (game over) if (!isJumping && !attackCol.visible && e.intersects(player)) { storage.lastScore = score; LK.showGameOver(); } } // Update coins for pickup using mouse collision (point test) // We assume coins are 65x65 (half-size: 32.5) for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; // Only trigger collection if the coin is not already being collected if (!coin.collecting && Math.abs(coin.x - mouseX) < 32.5 && Math.abs(coin.y - mouseY) < 32.5) { coin.collecting = true; // Animate coin flying toward the score display tween(coin, { x: scoreTxt.x, y: scoreTxt.y, alpha: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { // Remove coin from the global coins array by checking its own index var index = coins.indexOf(coin); if (index !== -1) { coins.splice(index, 1); } if (coin.type === 'silver') { LK.getSound('silversnd').play(); score += 5; } else if (coin.type === 'gold') { LK.getSound('goldsnd').play(); score += 10; } updateScoreDisplay(); coin.destroy(); } }); } } };
===================================================================
--- original.js
+++ change.js
@@ -594,8 +594,32 @@
coin.x = x;
coin.y = y;
game.addChild(coin);
coins.push(coin);
+ // Add floating animation to the coin
+ tween(coin, {
+ y: coin.y - 20
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(coin, {
+ y: coin.y + 20
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ // Loop the floating animation
+ tween(coin, {
+ y: coin.y - 20
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ }
+ });
} else if (rand < 0.6) {
// 10% chance for gold coin
var coin = new Container();
coin.type = 'gold';
high definition super nintendo background of a japanese sakura tree forest Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
2d snes dust particle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
silver coin, $ sign on it, snes art. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
gold coin, $ sign on it, snes art. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows