User prompt
i'm not sure what feather effect is but ideally its a powerful attack where feathers are spawn on either side of the character and fly towards the exteriors of the playspace
User prompt
move it higher again
User prompt
move special_idle higher
User prompt
if i mouse over helmet to collect it nothing happens, it doesn't seem to work, can you fix it
User prompt
make sure only one helmet can be active on screen
User prompt
loop the helmet's floating animation
User prompt
make sure helmet spawns from on top of the playspace and slowly descends at the same y coordinates as the player
User prompt
give helmet the same collection as coin
Code edit (2 edits merged)
Please save this source code
User prompt
Pause or cancel idle/breathing tweens when you attack. Use consistent anchors for every sprite frame (idle, attack, jump, special, etc.). Keep your flip/scale logic centralized so you donβt apply multiple contradictory transformations at once. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
And when the player lands, why is it always the same side? Fix it
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
/**** * 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 ****/ /**** * Utility: findChildByName ****/ 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; var pressDownY = 0; // Global mouse coordinates var mouseX = 0; var mouseY = 0; game.move = function (x, y) { mouseX = x; mouseY = y; }; // Score setup var score = 0; var scoreTxt; function updateScoreDisplay() { game.removeChild(scoreTxt); scoreTxt = createScoreText(score); scoreTxt.scaleX = 1.0; scoreTxt.scaleY = 1.0; game.addChild(scoreTxt); 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 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; } 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); // High score display var highScore = storage.highScore || 0; var highScoreTxt = new Text2('High Score: ' + highScore, { size: 50, fill: 0xFFFFFF }); highScoreTxt.name = 'highScoreTxt'; highScoreTxt.anchor.set(1, 1); highScoreTxt.x = 1900; highScoreTxt.y = 2720; 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; /**** * Power-Up: Helmet ****/ // Global array for helmet powerups var helmets = []; function spawnHelmet() { var helmet = new Container(); helmet.attachAsset('helmet', { anchorX: 0.5, anchorY: 0.5 }); // Spawn at a random position within visible bounds helmet.x = Math.random() * 2048; helmet.y = Math.random() * (2732 - 200) + 100; game.addChild(helmet); helmets.push(helmet); } LK.setInterval(spawnHelmet, 10000); // spawn a helmet every 10 seconds // Power-up activation flag to prevent re-triggering var helmetActive = false; function activateHelmetPowerUp() { if (helmetActive) { return; } // already active helmetActive = true; // Change player's sprite to special_idle swapPlayerVisual('special_idle', player.x, player.y, visualContainer.scaleX); // Remain in power-up state for 5 seconds, then perform special attack (feather) and revert LK.setTimeout(function () { // Spawn a feather effect at player's position (special attack) var featherEffect = new Container(); featherEffect.attachAsset('feather', { anchorX: 0.5, anchorY: 0.5 }); featherEffect.x = player.x; featherEffect.y = player.y; game.addChild(featherEffect); tween(featherEffect, { alpha: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { featherEffect.destroy(); } }); // Revert player's sprite back to normal idle swapPlayerVisual('player_idle', player.x, player.y, visualContainer.scaleX); helmetActive = false; }, 5000); } /**** * Swap Player Sprite Function ****/ 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; pressDownY = y; // 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; var landingFlip = Math.random() < 0.5 ? -1 : 1; swapPlayerVisual('player_idle', 1024, 2732 - 250, landingFlip, 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); 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(); 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); /**** * 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(); 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); 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; var dx = targetX - player.x, 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; proj.scaleX = targetX < player.x ? -1 : 1; proj.distanceTraveled = 0; proj.maxDistance = 1000; projectiles.push(proj); game.addChild(proj); } /**** * Coins ****/ var coins = []; function dropCoin(x, y) { var rand = Math.random(); if (rand < 0.5) { 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); 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() { tween(coin, { y: coin.y - 20 }, { duration: 1000, easing: tween.easeInOut }); } }); } }); } else if (rand < 0.6) { 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); } } /**** * Enemy Hit Logic ****/ 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; } } }); } }); } }); } 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 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; } for (var ei = enemies.length - 1; ei >= 0; ei--) { var enemy = enemies[ei]; if (proj.intersects(enemy)) { 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; } if (jumpColGlobal && jumpColGlobal.visible && e.intersects(jumpColGlobal)) { handleEnemyJumpHit(e, i); continue; } if (attackCol.visible && e.intersects(attackCol)) { handleEnemyHit(e, i, 'melee'); } if (!isJumping && !attackCol.visible && e.intersects(player)) { storage.lastScore = score; LK.showGameOver(); } } // Update coins (using mouse collision) for (var i = coins.length - 1; i >= 0; i--) { var coin = coins[i]; if (!coin.collecting && Math.abs(coin.x - mouseX) < 32.5 && Math.abs(coin.y - mouseY) < 32.5) { coin.collecting = true; tween(coin, { x: scoreTxt.x, y: scoreTxt.y, alpha: 0 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { 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(); } }); } } // Update helmets (power-up) by checking collision with player for (var i = helmets.length - 1; i >= 0; i--) { var helm = helmets[i]; if (helm.intersects(player)) { activateHelmetPowerUp(); helmets.splice(i, 1); helm.destroy(); } } };
===================================================================
--- original.js
+++ change.js
@@ -30,8 +30,11 @@
/****
* Game Code
****/
+/****
+* Utility: findChildByName
+****/
function findChildByName(container, name) {
for (var i = 0; i < container.children.length; i++) {
if (container.children[i].name === name) {
return container.children[i];
@@ -45,52 +48,26 @@
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)
+var pressDownX = 0;
+var pressDownY = 0;
// 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
-****/
+// Score setup
var score = 0;
-var scoreTxt; // container for the score text
+var scoreTxt;
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
}, {
@@ -106,12 +83,8 @@
});
}
});
}
-function incrementScore() {
- score++;
- updateScoreDisplay();
-}
function createScoreText(value) {
var shadow = new Text2(String(value), {
size: 600,
fill: 0x000000,
@@ -135,9 +108,8 @@
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', {
@@ -150,18 +122,18 @@
y: 1366
});
game.addChild(bg01);
game.addChild(scoreTxt);
-// Display high score at the bottom right at game start
+// High score display
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
+highScoreTxt.anchor.set(1, 1);
+highScoreTxt.x = 1900;
+highScoreTxt.y = 2720;
game.addChild(highScoreTxt);
/****
* Petals
****/
@@ -262,10 +234,62 @@
game.addChild(attackCol);
attackCol.visible = false;
attackCol.alpha = 0;
/****
-* Swap Player Sprite
+* Power-Up: Helmet
****/
+// Global array for helmet powerups
+var helmets = [];
+function spawnHelmet() {
+ var helmet = new Container();
+ helmet.attachAsset('helmet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Spawn at a random position within visible bounds
+ helmet.x = Math.random() * 2048;
+ helmet.y = Math.random() * (2732 - 200) + 100;
+ game.addChild(helmet);
+ helmets.push(helmet);
+}
+LK.setInterval(spawnHelmet, 10000); // spawn a helmet every 10 seconds
+// Power-up activation flag to prevent re-triggering
+var helmetActive = false;
+function activateHelmetPowerUp() {
+ if (helmetActive) {
+ return;
+ } // already active
+ helmetActive = true;
+ // Change player's sprite to special_idle
+ swapPlayerVisual('special_idle', player.x, player.y, visualContainer.scaleX);
+ // Remain in power-up state for 5 seconds, then perform special attack (feather) and revert
+ LK.setTimeout(function () {
+ // Spawn a feather effect at player's position (special attack)
+ var featherEffect = new Container();
+ featherEffect.attachAsset('feather', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ featherEffect.x = player.x;
+ featherEffect.y = player.y;
+ game.addChild(featherEffect);
+ tween(featherEffect, {
+ alpha: 0
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ featherEffect.destroy();
+ }
+ });
+ // Revert player's sprite back to normal idle
+ swapPlayerVisual('player_idle', player.x, player.y, visualContainer.scaleX);
+ helmetActive = false;
+ }, 5000);
+}
+/****
+* Swap Player Sprite Function
+****/
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');
@@ -332,10 +356,10 @@
return;
}
isPressHeld = true;
pressHoldStartTime = Date.now();
- pressDownX = x; // remember where the press happened
- pressDownY = y; // remember where the press happened
+ pressDownX = x;
+ pressDownY = y;
// Jump if tapped in top 2/3
if (y < 2732 * 2 / 3 && !isJumping) {
isJumping = true;
LK.getSound('hup').play();
@@ -445,9 +469,8 @@
});
}
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;
@@ -466,14 +489,13 @@
}, 250);
}, 250);
};
/****
-* Enemies Array + Spawn
+* 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,
@@ -516,9 +538,9 @@
game.addChild(e);
}
LK.setInterval(spawnEnemy, Math.random() * 1500 + 1000);
/****
-* NEW CODE: Projectile Logic
+* Projectile Logic
****/
var projectiles = [];
function spawnProjectile(targetX, targetY) {
var proj = new Container();
@@ -526,9 +548,8 @@
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,
@@ -537,9 +558,8 @@
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
@@ -551,42 +571,31 @@
}
});
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 dx = targetX - player.x,
+ 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
+* 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,
@@ -595,9 +604,8 @@
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,
@@ -608,9 +616,8 @@
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
- // Loop the floating animation
tween(coin, {
y: coin.y - 20
}, {
duration: 1000,
@@ -620,9 +627,8 @@
});
}
});
} else if (rand < 0.6) {
- // 10% chance for gold coin
var coin = new Container();
coin.type = 'gold';
coin.attachAsset('gold_coin', {
anchorX: 0.5,
@@ -632,13 +638,11 @@
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'
+* Enemy Hit Logic
****/
function handleEnemyHit(enemy, index, attackType) {
if (!enemies.includes(enemy)) {
return;
@@ -691,12 +695,8 @@
});
}
});
}
-/****
-* 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;
}
@@ -768,9 +768,9 @@
isPressHeld = false;
spawnProjectile(pressDownX, pressDownY);
}
}
- // Update all projectiles
+ // Update projectiles
for (var p = projectiles.length - 1; p >= 0; p--) {
var proj = projectiles[p];
proj.x += proj.vx;
proj.y += proj.vy;
@@ -785,13 +785,11 @@
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;
@@ -809,40 +807,33 @@
}
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)
+ // Update coins (using mouse collision)
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);
}
@@ -858,5 +849,14 @@
}
});
}
}
+ // Update helmets (power-up) by checking collision with player
+ for (var i = helmets.length - 1; i >= 0; i--) {
+ var helm = helmets[i];
+ if (helm.intersects(player)) {
+ activateHelmetPowerUp();
+ helmets.splice(i, 1);
+ helm.destroy();
+ }
+ }
};
\ No newline at end of file
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
snes white feather. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
add a wooden shield
white 3d questionmark with a shadow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
caligraphy paper front facing flat. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
the letters 'Ready' in 3d with a japanese cartoon cherry blossom flair. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
add eyebrows