User prompt
helmet meter max 100
User prompt
helmet meter max 30
User prompt
make the progress bar color white
User prompt
make the progress bar thicker
User prompt
raise both back just by a tiny bit
User prompt
lower the helmet and the progress bar a little bit
User prompt
when the feathers kill enemys, it should not fill the progress bar
User prompt
make the progress bar thicker
User prompt
lower the helmet and the progress bar i can't see it
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'width')' in or related to this line: 'powerHelmet.x = 2048 - helmetSprite.width / 2 - 20; // Position helmet in the top right' Line Number: 176
User prompt
put the helmet and the progress bar in the top right of the playspace
User prompt
Initial Width of the bar should not be 0, lets try 5%
User prompt
Verify that your fill bar’s container is added after the helmet sprite,
User prompt
i don't see the progress bar
User prompt
helmet meter max 10
User prompt
move the helmet and the bar a bit higher
Code edit (3 edits merged)
Please save this source code
User prompt
helmet meter max = 3
User prompt
raise it again
User prompt
the helmet position is too low, raise it
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: storage.set is not a function' in or related to this line: 'storage.set('highScore', highScore);' Line Number: 98 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var highScore = storage.get('highScore') || 0;' Line Number: 163 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Fiz it
User prompt
Disable the ability to attack and jump when player is special idle
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ 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 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ /* Note: We are now using a “helmet” asset that is permanently displayed. Its dimensions in this example are 100 x 138.65 */ 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; var isPressHeld = false; var pressHoldStartTime = 0; var pressDownX = 0; var pressDownY = 0; var mouseX = 0; var mouseY = 0; game.move = function (x, y) { mouseX = x; mouseY = y; }; var score = 0; var scoreTxt; function updateScoreDisplay() { if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('High Score: ' + highScore); } 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); 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); /**** * Persistent Power Helmet HUD (for filling up) ****/ // Global variables for helmet meter. var helmetMeter = 0; var helmetMeterMax = 100; // Create a persistent helmet at the opposite side (left side) of the high score. var powerHelmet = new Container(); powerHelmet.name = "powerHelmet"; // Position it at the same Y as the high score and at a fixed X (e.g., 100) powerHelmet.x = 100; powerHelmet.y = highScoreTxt.y - 50; var helmetSprite = powerHelmet.attachAsset('helmet', { anchorX: 0.5, anchorY: 0.5 }); // Create a fill bar to display the meter. We use a simple colored shape. var helmetFillContainer = new Container(); helmetFillContainer.name = "helmetFillContainer"; // Create a fill rectangle using our Shape helper. var fillBar = new Shape({ width: 0, height: 10, color: 0xFFFF00, alpha: 0.7 }); fillBar.anchorX = 0; fillBar.anchorY = 0.5; // Position the fill bar at the bottom of the helmet sprite. fillBar.y = helmetSprite.height / 2 + 10; helmetFillContainer.addChild(fillBar); powerHelmet.addChild(helmetFillContainer); game.addChild(powerHelmet); function updateHelmetDisplay() { var fraction = helmetMeter / helmetMeterMax; if (fraction > 1) { fraction = 1; } fillBar.width = fraction * helmetSprite.width; // Fill up to the full width of the helmet. } /**** * 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 (Now the helmet is permanent as HUD) ****/ // We remove any interval spawn of helmet because powerHelmet is permanent. // We also remove the collision-based trigger (previously the helmet was collected by mouse) so we omit that here. // Instead, we fill the helmet meter as enemies are killed via handleEnemyHit/JumpHit. var featherEffects = []; // For any feather effects spawned during special // New function to spawn feather finishing moves (for the special attack) function spawnFeatherMove() { if (!specialIdleActive) { return; } for (var i = -2; i <= 2; i++) { var feather = new Container(); feather.attachAsset('feather', { anchorX: 0.5, anchorY: 0.5 }); feather.x = player.x + i * 50; feather.y = player.y; game.addChild(feather); featherEffects.push(feather); tween(feather, { x: feather.x + i * 500, y: feather.y + (Math.random() * 200 - 100), alpha: 0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { feather.destroy(); } }); } } // We still use the existing activateHelmetPowerUp function (triggered when helmetMeter is full) var helmetActive = false; var specialIdleActive = false; function activateHelmetPowerUp() { if (helmetActive) { return; } helmetActive = true; swapPlayerVisual('special_idle', player.x, player.y, visualContainer.scaleX); specialIdleActive = true; LK.getSound('warcry').play(); LK.effects.flashScreen(0xFFFFFF, 100); // Custom screen shake effect var shakeIntensity = 10, shakeDuration = 500; var shakeStartTime = Date.now(); var originalPosition = { x: game.x, y: game.y }; function shakeScreen() { var elapsed = Date.now() - shakeStartTime; if (elapsed < shakeDuration) { var offsetX = (Math.random() - 0.5) * shakeIntensity; var offsetY = (Math.random() - 0.5) * shakeIntensity; game.x = originalPosition.x + offsetX; game.y = originalPosition.y + offsetY; LK.setTimeout(shakeScreen, 16); } else { game.x = originalPosition.x; game.y = originalPosition.y; } } shakeScreen(); // For this example, trigger the feather finishing move once immediately. spawnFeatherMove(); // After a set time, revert the player LK.setTimeout(function () { // Clear any active feather effects while (featherEffects.length) { featherEffects.pop().destroy(); } // Only revert to player_idle if not mid-air. if (!isJumping) { swapPlayerVisual('player_idle', player.x, player.y, visualContainer.scaleX, function () { startBreathingAnimation(); startTiltAnimation(); }); } specialIdleActive = false; LK.effects.flashScreen(0xFFFFFF, 100); helmetActive = false; helmetMeter = 0; // Reset the meter after triggering updateHelmetDisplay(); }, 6000); } /**** * 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, y: newVisualId === 'special_idle' ? -100 : 0, scaleX: newVisualId === 'special_idle' ? 1.25 : 1, scaleY: newVisualId === 'special_idle' ? 1.25 : 1 }); 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) { // Prevent new input if a sequence is running or special power-up is active. if (isSequenceRunning || specialIdleActive) { 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; // If power-up is active, keep the special_idle visual; otherwise revert. if (specialIdleActive) { swapPlayerVisual('special_idle', 1024, 2732 - 250, landingFlip); } else { 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); // Start an infinite tween loop for the coin using its original y as baseY. loopCoinTween(coin, y); } 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); } } /**** * Looping Tween Functions (for coins and helmet) ****/ function loopCoinTween(coin, baseY) { tween(coin, { y: baseY - 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(coin, { y: baseY + 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { loopCoinTween(coin, baseY); } }); } }); } /**** * Enemy Hit Logic – Also fills the helmet meter ****/ 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; } // Increase helmet meter based on kill type. if (attackType === 'melee') { helmetMeter += 10; } else if (attackType === 'throw') { helmetMeter += 5; } else if (attackType === 'special_idle') { helmetMeter += 15; } else { helmetMeter += 5; } if (helmetMeter >= helmetMeterMax) { helmetMeter = helmetMeterMax; activateHelmetPowerUp(); helmetMeter = 0; } updateHelmetDisplay(); 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; } // Increase helmet meter for jump kills too. helmetMeter += 10; if (helmetMeter >= helmetMeterMax) { helmetMeter = helmetMeterMax; activateHelmetPowerUp(); helmetMeter = 0; } updateHelmetDisplay(); 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 () { if (isPressHeld) { var holdDuration = Date.now() - pressHoldStartTime; if (holdDuration > 500) { console.log("Long press detected, spawn projectile!"); isPressHeld = false; spawnProjectile(pressDownX, pressDownY); } } 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; } } } for (var f = featherEffects.length - 1; f >= 0; f--) { var feather = featherEffects[f]; for (var ei = enemies.length - 1; ei >= 0; ei--) { var enemy = enemies[ei]; if (feather.intersects(enemy)) { handleEnemyHit(enemy, ei, 'feather'); featherEffects.splice(f, 1); feather.destroy(); break; } } } 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)) { if (specialIdleActive) { handleEnemyHit(e, i, 'special_idle'); continue; } else { storage.lastScore = score; LK.showGameOver(); } } } 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(); } }); } } // We removed the old helmet collision logic since the helmet HUD is permanent. };
===================================================================
--- original.js
+++ change.js
@@ -29,8 +29,10 @@
/****
* Game Code
****/
+/* Note: We are now using a “helmet” asset that is permanently displayed.
+ Its dimensions in this example are 100 x 138.65 */
function findChildByName(container, name) {
for (var i = 0; i < container.children.length; i++) {
if (container.children[i].name === name) {
return container.children[i];
@@ -131,8 +133,48 @@
highScoreTxt.x = 1900;
highScoreTxt.y = 2720;
game.addChild(highScoreTxt);
/****
+* Persistent Power Helmet HUD (for filling up)
+****/
+// Global variables for helmet meter.
+var helmetMeter = 0;
+var helmetMeterMax = 100;
+// Create a persistent helmet at the opposite side (left side) of the high score.
+var powerHelmet = new Container();
+powerHelmet.name = "powerHelmet";
+// Position it at the same Y as the high score and at a fixed X (e.g., 100)
+powerHelmet.x = 100;
+powerHelmet.y = highScoreTxt.y - 50;
+var helmetSprite = powerHelmet.attachAsset('helmet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+// Create a fill bar to display the meter. We use a simple colored shape.
+var helmetFillContainer = new Container();
+helmetFillContainer.name = "helmetFillContainer";
+// Create a fill rectangle using our Shape helper.
+var fillBar = new Shape({
+ width: 0,
+ height: 10,
+ color: 0xFFFF00,
+ alpha: 0.7
+});
+fillBar.anchorX = 0;
+fillBar.anchorY = 0.5;
+// Position the fill bar at the bottom of the helmet sprite.
+fillBar.y = helmetSprite.height / 2 + 10;
+helmetFillContainer.addChild(fillBar);
+powerHelmet.addChild(helmetFillContainer);
+game.addChild(powerHelmet);
+function updateHelmetDisplay() {
+ var fraction = helmetMeter / helmetMeterMax;
+ if (fraction > 1) {
+ fraction = 1;
+ }
+ fillBar.width = fraction * helmetSprite.width; // Fill up to the full width of the helmet.
+}
+/****
* Petals
****/
var petals = [];
for (var i = 0; i < 50; i++) {
@@ -231,102 +273,15 @@
game.addChild(attackCol);
attackCol.visible = false;
attackCol.alpha = 0;
/****
-* Power-Up: Helmet
+* Power-Up: Helmet (Now the helmet is permanent as HUD)
****/
-var helmets = [];
-var featherEffects = [];
-function spawnHelmet() {
- if (helmets.length > 0) {
- return;
- }
- var helmet = new Container();
- helmet.attachAsset('helmet', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- helmet.x = Math.random() * 2048;
- helmet.y = 2732 * 2 / 3;
- tween(helmet, {
- scaleX: 1.5,
- scaleY: 1.5
- }, {
- duration: 500,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(helmet, {
- scaleX: 1.0,
- scaleY: 1.0
- }, {
- duration: 500,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(helmet, {
- scaleX: 1.5,
- scaleY: 1.5
- }, {
- duration: 500,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(helmet, {
- scaleX: 1.0,
- scaleY: 1.0
- }, {
- duration: 500,
- easing: tween.easeInOut
- });
- }
- });
- }
- });
- }
- });
- game.addChild(helmet);
- helmets.push(helmet);
- tween(helmet, {
- y: helmet.y - 20
- }, {
- duration: 1000,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(helmet, {
- y: helmet.y + 20
- }, {
- duration: 1000,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(helmet, {
- y: helmet.y - 20
- }, {
- duration: 1000,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(helmet, {
- y: helmet.y + 20
- }, {
- duration: 1000,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(helmet, {
- y: helmet.y - 20
- }, {
- duration: 1000,
- easing: tween.easeInOut
- });
- }
- });
- }
- });
- }
- });
- }
- });
-}
-LK.setInterval(spawnHelmet, 20000);
-var helmetActive = false;
-var specialIdleActive = false;
-// New function to spawn feather finishing moves.
+// We remove any interval spawn of helmet because powerHelmet is permanent.
+// We also remove the collision-based trigger (previously the helmet was collected by mouse) so we omit that here.
+// Instead, we fill the helmet meter as enemies are killed via handleEnemyHit/JumpHit.
+var featherEffects = []; // For any feather effects spawned during special
+// New function to spawn feather finishing moves (for the special attack)
function spawnFeatherMove() {
if (!specialIdleActive) {
return;
}
@@ -352,8 +307,11 @@
}
});
}
}
+// We still use the existing activateHelmetPowerUp function (triggered when helmetMeter is full)
+var helmetActive = false;
+var specialIdleActive = false;
function activateHelmetPowerUp() {
if (helmetActive) {
return;
}
@@ -361,8 +319,9 @@
swapPlayerVisual('special_idle', player.x, player.y, visualContainer.scaleX);
specialIdleActive = true;
LK.getSound('warcry').play();
LK.effects.flashScreen(0xFFFFFF, 100);
+ // Custom screen shake effect
var shakeIntensity = 10,
shakeDuration = 500;
var shakeStartTime = Date.now();
var originalPosition = {
@@ -382,40 +341,28 @@
game.y = originalPosition.y;
}
}
shakeScreen();
- var featherInterval = LK.setInterval(function () {
- spawnFeatherMove();
- }, 1500);
- // Remain for 5 seconds, then clean up feather effects.
+ // For this example, trigger the feather finishing move once immediately.
+ spawnFeatherMove();
+ // After a set time, revert the player
LK.setTimeout(function () {
- LK.clearInterval(featherInterval);
+ // Clear any active feather effects
while (featherEffects.length) {
featherEffects.pop().destroy();
}
// Only revert to player_idle if not mid-air.
if (!isJumping) {
- swapPlayerVisual('player_idle', player.x, player.y, visualContainer.scaleX);
+ swapPlayerVisual('player_idle', player.x, player.y, visualContainer.scaleX, function () {
+ startBreathingAnimation();
+ startTiltAnimation();
+ });
}
- // Otherwise, keep special_idle visible.
specialIdleActive = false;
LK.effects.flashScreen(0xFFFFFF, 100);
- shakeStartTime = Date.now();
- function shakeScreen2() {
- var elapsed = Date.now() - shakeStartTime;
- if (elapsed < shakeDuration) {
- var offsetX = (Math.random() - 0.5) * shakeIntensity;
- var offsetY = (Math.random() - 0.5) * shakeIntensity;
- game.x = originalPosition.x + offsetX;
- game.y = originalPosition.y + offsetY;
- LK.setTimeout(shakeScreen2, 16);
- } else {
- game.x = originalPosition.x;
- game.y = originalPosition.y;
- }
- }
- shakeScreen2();
helmetActive = false;
+ helmetMeter = 0; // Reset the meter after triggering
+ updateHelmetDisplay();
}, 6000);
}
/****
* Swap Player Sprite Function
@@ -485,9 +432,9 @@
var isSequenceRunning = false;
var isJumping = false;
var playerState = 'idle';
game.down = function (x, y) {
- // Prevent any new input if a sequence is running or during special idle.
+ // Prevent new input if a sequence is running or special power-up is active.
if (isSequenceRunning || specialIdleActive) {
return;
}
isPressHeld = true;
@@ -552,13 +499,11 @@
});
}
isJumping = false;
var landingFlip = Math.random() < 0.5 ? -1 : 1;
- // If the power-up is active, keep the special_idle visual; otherwise, revert to player_idle.
+ // If power-up is active, keep the special_idle visual; otherwise revert.
if (specialIdleActive) {
- swapPlayerVisual('special_idle', 1024, 2732 - 250, landingFlip, function () {
- // Optionally, add animations for special_idle
- });
+ swapPlayerVisual('special_idle', 1024, 2732 - 250, landingFlip);
} else {
swapPlayerVisual('player_idle', 1024, 2732 - 250, landingFlip, function () {
startBreathingAnimation();
startTiltAnimation();
@@ -746,30 +691,10 @@
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
- });
- }
- });
- }
- });
+ // Start an infinite tween loop for the coin using its original y as baseY.
+ loopCoinTween(coin, y);
} else if (rand < 0.6) {
var coin = new Container();
coin.type = 'gold';
coin.attachAsset('gold_coin', {
@@ -782,10 +707,32 @@
coins.push(coin);
}
}
/****
-* Enemy Hit Logic
+* Looping Tween Functions (for coins and helmet)
****/
+function loopCoinTween(coin, baseY) {
+ tween(coin, {
+ y: baseY - 20
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(coin, {
+ y: baseY + 20
+ }, {
+ duration: 1000,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ loopCoinTween(coin, baseY);
+ }
+ });
+ }
+ });
+}
+/****
+* Enemy Hit Logic – Also fills the helmet meter
+****/
function handleEnemyHit(enemy, index, attackType) {
if (!enemies.includes(enemy)) {
return;
}
@@ -819,8 +766,24 @@
if (!enemy.coinsDropped) {
dropCoin(enemy.x, enemy.y);
enemy.coinsDropped = true;
}
+ // Increase helmet meter based on kill type.
+ if (attackType === 'melee') {
+ helmetMeter += 10;
+ } else if (attackType === 'throw') {
+ helmetMeter += 5;
+ } else if (attackType === 'special_idle') {
+ helmetMeter += 15;
+ } else {
+ helmetMeter += 5;
+ }
+ if (helmetMeter >= helmetMeterMax) {
+ helmetMeter = helmetMeterMax;
+ activateHelmetPowerUp();
+ helmetMeter = 0;
+ }
+ updateHelmetDisplay();
if (!enemy.scoreCounted) {
if (attackType === 'melee') {
score += 2;
} else if (attackType === 'throw') {
@@ -869,8 +832,16 @@
if (!enemy.coinsDropped) {
dropCoin(enemy.x, enemy.y);
enemy.coinsDropped = true;
}
+ // Increase helmet meter for jump kills too.
+ helmetMeter += 10;
+ if (helmetMeter >= helmetMeterMax) {
+ helmetMeter = helmetMeterMax;
+ activateHelmetPowerUp();
+ helmetMeter = 0;
+ }
+ updateHelmetDisplay();
if (!enemy.scoreCounted) {
score += 3;
updateScoreDisplay();
enemy.scoreCounted = true;
@@ -901,18 +872,16 @@
/****
* 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;
@@ -937,9 +906,8 @@
break;
}
}
}
- // Process feather effect collisions
for (var f = featherEffects.length - 1; f >= 0; f--) {
var feather = featherEffects[f];
for (var ei = enemies.length - 1; ei >= 0; ei--) {
var enemy = enemies[ei];
@@ -950,9 +918,8 @@
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) {
@@ -979,9 +946,8 @@
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;
@@ -1009,30 +975,6 @@
}
});
}
}
- // Update helmets (power-up) by checking collision with player
- for (var i = helmets.length - 1; i >= 0; i--) {
- var helm = helmets[i];
- if (!helm.collecting && Math.abs(helm.x - mouseX) < 50 && Math.abs(helm.y - mouseY) < 50) {
- helm.collecting = true;
- tween(helm, {
- x: scoreTxt.x,
- y: scoreTxt.y,
- alpha: 0
- }, {
- duration: 500,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- var index = helmets.indexOf(helm);
- if (index !== -1) {
- helmets.splice(index, 1);
- }
- LK.getSound('warcry').play();
- activateHelmetPowerUp();
- updateScoreDisplay();
- helm.destroy();
- }
- });
- }
- }
+ // We removed the old helmet collision logic since the helmet HUD is permanent.
};
\ 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