User prompt
Whenever ninja collects sheild, make ninja invincible for 10sec.
User prompt
Only play sound when sheild bubble hits the obstacles.
User prompt
Now whenever obstacle hits the Sheild Play distruction sound effect.
User prompt
change the flash color to little bit darker red.
User prompt
instead of flashing ninja when lives reduce shake ninja when life is reduced
User prompt
Please fix the bug: 'Timeout.tick error: LK.effects.shake is not a function' in or related to this line: 'LK.effects.shake(ninja, 10, 500, "ease-out");' Line Number: 235
Code edit (1 edits merged)
Please save this source code
User prompt
i want continuous 3 flashes not single. also the flash opacity high i want it to be around 0.3
User prompt
Whenever ninja life is reduced flash screen to red for 3sec, flash opacity should be below 0.3
User prompt
i want the tint effect to be inserted for each new dash not only one dash, you can check that code between line 169 to 189
User prompt
When ninja's life is reduce make a tint of every spawned dash to red for 3 secs. and after 3 sec back to normal tint.
User prompt
When ninja's life is reduce make a tint of dash to red for 3 secs. and after 3 sec back to normal tint.
User prompt
Make ninja invincible when sheild is enabled.
User prompt
whenever obstacles collide with the sheild bubble, it will destroy them.
User prompt
When ninja is not having a sheild, and hits the obstacle play ninja grunt sound effect.
User prompt
currently the red flash is on the single sprite and it get destroyed when the animation change to another sprite, i want the flash to stay for 3 sec, no matter sprite is destroyed.
User prompt
Now i want to make ninja to flash red for 3 sec after intersecting with obstacles, but if the ninja have a sheild collected and sheild time is not over ( 10 sec ).
/**** * Classes ****/ var Background = Container.expand(function () { var self = Container.call(this); var backgroundGraphics = self.attachAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); backgroundGraphics.alpha = 0.5; var zoomDirection = 1; self.update = function () { if (this.scale.x >= 1.0025) { zoomDirection = -1; } else if (this.scale.x <= 0.9975) { zoomDirection = 1; } this.scale.x += 0.000025 * zoomDirection; this.scale.y += 0.000025 * zoomDirection; }; }); var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x -= 30; if (self.x < -self.width) { self.destroy(); } // Check for intersection with ninja if (self.intersects(ninja)) { coinCounter++; coinTxt.setText('Coins: ' + coinCounter); // Update the coin display text LK.getSound('coinCollect').play(); self.destroy(); } }; }); var Dash = Container.expand(function () { var self = Container.call(this); var dashGraphics = self.attachAsset('dash', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.opacity = 0.4; self.update = function () { self.x -= self.speed; self.alpha -= 0.01; if (self.alpha <= 0) { self.destroy(); } }; }); var DisplayLife = Container.expand(function () { var self = Container.call(this); var lifeGraphics = self.attachAsset('life', { anchorX: 0.5, anchorY: 0.5 }); }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.update = function () { self.x -= self.speed; self.x += Math.sin(LK.ticks / 10) * 2.5; if (self.x < -self.width) { self.destroy(); } }; }); var Life = Container.expand(function () { var self = Container.call(this); var lifeGraphics = self.attachAsset('life', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x -= 30; game.setChildIndex(self, game.getChildIndex(ninja) - 1); // Ensure life is on the same Z order as coin if (self.x < -self.width) { self.destroy(); } // Check for intersection with ninja if (self.intersects(ninja)) { ninja.lives++; // Add one life to ninja updateDisplayLives(); // Update the display lives self.destroy(); // Destroy the spawned life } }; }); var Ninja = Container.expand(function () { var self = Container.call(this); var ninjaGraphics = self.attachAsset('ninja_run1', { anchorX: 0.5, anchorY: 0.5 }); self.runFrames = ['ninja_run1', 'ninja_run2', 'ninja_run3', 'ninja_run4', 'ninja_run5']; self.currentFrame = 0; self.frameInterval = 3; // Change frame every 3 ticks self.ticks = 0; self.speed = 5; self.update = function () { self.ticks++; if (self.ticks % self.frameInterval === 0) { self.currentFrame = (self.currentFrame + 1) % self.runFrames.length; self.removeChild(ninjaGraphics); ninjaGraphics = self.attachAsset(self.runFrames[self.currentFrame], { anchorX: 0.5, anchorY: 0.5 }); if (self.currentFrame === 1) { var randomFootstep = Math.floor(Math.random() * 3) + 1; LK.getSound('footstepSound' + randomFootstep).play(); } } if (self.currentPath === 'lower' && self.y >= path2.y - self.height && !self.dashActive) { var dash = new Dash(); dash.x = self.x - self.width / 2; dash.y = self.y; game.addChildAt(dash, game.getChildIndex(ninja)); self.dashActive = true; LK.setTimeout(function () { dash.destroy(); self.dashActive = false; }, 100); } else if (self.currentPath === 'upper' && self.y <= path1.y - self.height && !self.dashActive) { var dash = new Dash(); dash.x = self.x - self.width / 2; dash.y = self.y; game.addChildAt(dash, game.getChildIndex(ninja)); self.dashActive = true; LK.setTimeout(function () { dash.destroy(); self.dashActive = false; }, 50); } if (self.currentPath === 'upper' && self.y > path1.y - self.height - 50) { self.y -= 10; if (self.y <= path1.y - self.height - 50) { self.y = path1.y - self.height - 50; } } else if (self.currentPath === 'lower' && self.y < path2.y - self.height + 50) { self.y += 10; if (self.y >= path2.y - self.height + 50) { self.y = path2.y - self.height + 50; } } scoreTxt.setText('Coins: ' + coinCounter); // Update the score display game.setChildIndex(self, game.children.length - 1); // Ensure ninja is always on top for (var i = coins.length - 1; i >= 0; i--) { if (self.intersects(coins[i])) { coinCounter++; scoreMultiplier = 2; LK.setTimeout(function () { scoreMultiplier = 1; }, 5000); coins[i].destroy(); coins.splice(i, 1); i--; coinTxt.setText('Coins: ' + coinCounter); // Update the coin display text } } for (var i = 0; i < game.children.length; i++) { if (game.children[i] instanceof Obstacle && self.intersects(game.children[i])) { if (self.invincible) { // Destroy the obstacle and show destruction effect LK.effects.flashObject(game.children[i], 0xff0000, 500); // Flash red before destroying game.children[i].destroy(); if (shieldBubble) { LK.getSound('destructorAttackSound').play(); // Play destruction sound effect only if shield bubble is active } continue; // Skip the rest of the loop for this obstacle } // Play ninja grunt sound effect if not invincible if (!self.invincible) { LK.getSound('ninjaGrunt').play(); } // Reduce the lives by one self.lives--; // Update the display updateDisplayLives(); // Flash screen red for 1 second, three times, to show life reduction. for (var i = 0; i < 3; i++) { LK.setTimeout(function () { LK.effects.flashScreen(0x8b0000, 1000, 0.01); }, i * 1000); } // If no lives left, game over if (self.lives === 0) { // Flash screen red for 1 second, three times, to show we are dead. for (var i = 0; i < 3; i++) { LK.setTimeout(function () { LK.effects.flashScreen(0x8b0000, 1000, 0.3); }, i * 1000); } // Show game over. The game will be automatically paused while game over is showing. LK.showGameOver(); // Calling this will destroy the 'Game' and reset entire game state. } // Make ninja invincible for 3 seconds if not already invincible if (!self.invincible) { self.invincible = true; ninjaGraphics.alpha = 1; var opacityDirection = -1; var _opacityChange = function opacityChange() { ninjaGraphics.alpha += 0.18 * opacityDirection; if (ninjaGraphics.alpha <= 0.1) { opacityDirection = 1; } else if (ninjaGraphics.alpha >= 1) { opacityDirection = -1; } if (self.invincible) { LK.setTimeout(_opacityChange, 60); } else { ninjaGraphics.alpha = 1; } }; LK.setTimeout(_opacityChange, 60); LK.setTimeout(function () { self.invincible = false; ninjaGraphics.alpha = 1; // Reset opacity to 1 when invincibility ends }, 3000); if (self.shieldTimeout) { LK.clearTimeout(self.shieldTimeout); self.shieldTimeout = null; } } } } }; self.down = function () { if (self.currentPath === 'lower') { targetPath = 'upper'; self.y -= 20; self.x += 10; } else { targetPath = 'lower'; self.y += 20; self.x -= 10; } game.setChildIndex(self, game.children.length - 1); // Ensure ninja is always on top LK.getSound('jumpSound').play(); LK.getSound('jumpSound').play(); }; self.up = function () { targetPath = null; }; }); var NinjaStar = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('ninjaStar', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -5; self.update = function () { self.y += self.speed; }; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 30; self.update = function () { self.x -= self.speed; if (self.x < -self.width) { self.destroy(); } }; }); var Path = Container.expand(function () { var self = Container.call(this); var pathGraphics = self.attachAsset('path', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 30; self.update = function () { self.x -= self.speed; if (self.x < -self.width) { self.destroy(); } }; }); var Shield = Container.expand(function () { var self = Container.call(this); var shieldGraphics = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x -= 30; game.setChildIndex(self, game.getChildIndex(ninja) - 1); // Ensure shield is on the same Z order as coin if (self.x < -self.width) { self.destroy(); } // Check for intersection with ninja if (self.intersects(ninja)) { // Activate shield effect ninja.invincible = true; shieldBubble = new ShieldBubble(); shieldBubble.x = ninja.x; shieldBubble.y = ninja.y; game.addChild(shieldBubble); LK.getSound('shieldCollectSound').play(); // Play shield collection sound ninja.shieldTimeout = LK.setTimeout(function () { ninja.invincible = false; game.removeChild(shieldBubble); shieldBubble = null; ninja.shieldTimeout = null; }, 10000); // Shield lasts for 10 seconds self.destroy(); } }; }); var ShieldBubble = Container.expand(function () { var self = Container.call(this); var shieldBubbleGraphics = self.attachAsset('shieldEffect', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x = ninja.x; self.y = ninja.y; }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ var shieldIcon = null; var shieldBubble = null; var shieldBubble = null; var shieldInterval = null; var shieldTimeout = null; var coinCounter = 0; // Initialize coin counter var backgroundMusic = LK.getSound('backgroundMusic'); backgroundMusic.volume = 1; function playBackgroundMusic() { backgroundMusic.play(); LK.setTimeout(playBackgroundMusic, 1991); } playBackgroundMusic(); // Play background music every 10000 ms // Display a test text at the bottom center of the screen LK.effects.linear = function (obj, duration) { var step = 1 / (duration * 60); // Assuming 60 FPS var progress = 0; var interval = LK.setInterval(function () { progress += step; obj.alpha = progress; if (progress >= 1) { obj.alpha = 1; LK.clearInterval(interval); } }, 1000 / 60); }; var testTxt = new Text2('Test Text', { resolution: 2, size: 100, fill: "#ffffff", font: "lexend" }); testTxt.anchor.set(0.5, 1); testTxt.x = 2048 / 2; testTxt.y = 2732 - 50; // Position 50 pixels from the bottom LK.gui.bottom.addChild(testTxt); function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) { throw o; } } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } // Game Variables var coins = []; var lives = []; var shields = []; var popupShown = false; // Track if the popup is already shown var scoreMultiplier = 1; var invincible = false; var lastSpawnedPath = 1; // Track the last path an obstacle was spawned on var background = game.addChild(new Background()); var path1 = game.addChild(new Path()); path1.y = 2732 / 3; var path2 = game.addChild(new Path()); path2.y = 2732 * 2 / 3; var ninja = game.addChild(new Ninja()); ninja.invincible = false; ninja.x = 1024; ninja.y = path2.y - ninja.height; ninja.currentPath = 'lower'; ninja.lives = 3; ninja.distanceTraveled = 0; // Initialize distance traveled to 0 var targetPath; // Display the lives a little bit more up in y axis from the upper path function updateDisplayLives() { for (var i = game.children.length - 1; i >= 0; i--) { if (game.children[i] instanceof DisplayLife) { game.children[i].destroy(); } } for (var i = 0; i < ninja.lives; i++) { var life = game.addChild(new DisplayLife()); life.x = 100 + i * 100; // Move the lives little bit right on x axis life.y = path1.y - 150; // Move lives a little bit more up game.setChildIndex(life, game.getChildIndex(ninja) - 1); } } updateDisplayLives(); // Display the score based on the distance traveled var scoreTxt = new Text2('0m', { resolution: 2, size: 100, fill: "#ffffff", font: "lexend" }); scoreTxt.anchor.set(0.5, 0); scoreTxt.y = path1.y - 450; // Move the score display a little bit more up, above the upper path LK.gui.top.addChild(scoreTxt); // Display the coin count on the same y location as the score, but on the right coinTxt = new Text2('Coins: 0', { resolution: 2, size: 100, fill: "#ffffff", font: "lexend" }); coinTxt.anchor.set(1, 0); coinTxt.x = 2048 - 20; coinTxt.y = path1.y - 450; // Align the coin text with the score text LK.gui.top.addChild(coinTxt); game.down = function (x, y, obj) { if (ninja.currentPath === 'lower' && ninja.y >= path2.y - ninja.height || ninja.currentPath === 'upper' && ninja.y <= path1.y - ninja.height) { if (ninja.currentPath === 'lower') { targetPath = 'upper'; ninja.y -= 500; // Increase the jump speed ninja.scale.y *= -1; // Flip vertically // No code to insert, we are removing the timeout that destroys the dash } else { targetPath = 'lower'; ninja.y += 500; // Increase the jump speed ninja.scale.y *= -1; // Flip vertically // No code to insert, we are removing the timeout that destroys the dash } ninja.currentPath = targetPath; } LK.getSound('jumpSound').play(); // Play sound effect on screen click }; game.update = function () { var lastPath = 0; if (LK.ticks % 50 == 0) { // Determine collectible type based on probabilities var collectibleType; var randomValue = Math.random() * 100; if (randomValue < 60) { collectibleType = 'coin'; } else if (randomValue < 95) { collectibleType = null; // 35% chance to not spawn anything } else if (randomValue < 99) { collectibleType = 'shield'; } else { collectibleType = 'life'; } // Spawn collectible on the opposite path of the last obstacle var collectiblePath = lastSpawnedPath === 1 ? 0 : 1; if (collectibleType === null) { // Do nothing } else if (collectibleType === 'coin') { var clusterSizes = [3, 5, 7]; var clusterSize = clusterSizes[Math.floor(Math.random() * clusterSizes.length)]; for (var i = 0; i < clusterSize; i++) { var newCoin = new Coin(); newCoin.x = 2048 + i * (newCoin.width + 60); // Increase spacing between coins newCoin.y = collectiblePath === 1 ? 2732 / 3 + 80 : 2732 * 2 / 3 - 80; game.addChild(newCoin); } } else if (collectibleType === 'shield') { var newShield = new Shield(); newShield.x = 2048; newShield.y = collectiblePath === 1 ? 2732 / 3 + 80 : 2732 * 2 / 3 - 80; game.addChild(newShield); } else if (collectibleType === 'life') { var newLife = new Life(); newLife.x = 2048; newLife.y = collectiblePath === 1 ? 2732 / 3 + 80 : 2732 * 2 / 3 - 80; game.addChild(newLife); } var randomPath = Math.random() > 0.5 ? 1 : 2; var spawnDistance = randomPath === lastPath ? 512 : 4096; var obstacleGroupSize = Math.floor(Math.random() * 3) + 1; for (var i = 0; i < obstacleGroupSize; i++) { var newObstacle = new Obstacle(); newObstacle.x = spawnDistance + i * newObstacle.width; if (randomPath === 1) { newObstacle.y = 2732 / 3 + 80; newObstacle.rotation = Math.PI; // Rotate 180 degrees lastSpawnedPath = 1; } else { newObstacle.y = 2732 * 2 / 3 - 80; newObstacle.rotation = 0; // No rotation lastSpawnedPath = 0; } game.addChildAt(newObstacle, game.children.length); } lastPath = randomPath; } if (LK.ticks % 20 == 0) { var newPath1 = new Path(); newPath1.x = 2048 + 100; // Increase the x-coordinate by 100 to create a gap newPath1.y = 2732 / 3; game.addChild(newPath1); var newPath2 = new Path(); newPath2.x = 2048 + 100; // Increase the x-coordinate by 100 to create a gap newPath2.y = 2732 * 2 / 3; game.addChild(newPath2); ninja.distanceTraveled += 100; // Increase distance traveled by 100 meters for each new path } };
===================================================================
--- original.js
+++ change.js
@@ -464,8 +464,9 @@
path1.y = 2732 / 3;
var path2 = game.addChild(new Path());
path2.y = 2732 * 2 / 3;
var ninja = game.addChild(new Ninja());
+ninja.invincible = false;
ninja.x = 1024;
ninja.y = path2.y - ninja.height;
ninja.currentPath = 'lower';
ninja.lives = 3;
Ninja Star. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A minimalist icon depicting a ninja head silhouette in black. The silhouette should be simple and recognizable, with a headband or mask detail. The background should be transparent or a contrasting color (e.g., red or white).. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Coin. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Shield. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Transparent sheild bubble. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Create a series of curved, tapered lines that originate from the ninja's body and extend outward in the direction of movement. The lines should vary in length and thickness, with a sense of energy and dynamism.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
backgroundMusic
Sound effect
coinCollect
Sound effect
jumpSound
Sound effect
footstepSound1
Sound effect
footstepSound2
Sound effect
footstepSound3
Sound effect
shooterSpawn
Sound effect
destructorSpawn
Sound effect
attackerSpawn
Sound effect
shooterAttack
Sound effect
destructorAttack
Sound effect
attackerAttack
Sound effect
enemyHit
Sound effect
shieldCollect
Sound effect
shieldCollectSound
Sound effect
ninjaGrunt
Sound effect
destructorAttackSound
Sound effect