User prompt
Now i want to flash ninja with red color, when obstacle are interset.
User prompt
Remve the sheild bubble logic and convert the sheild bubble logic to same as dash ( how dash is following the ninja ), but sheild bubble is not always visible, it will be visible when the sheild is intersect with the ninja
User prompt
i think may you missunderstoo, so the logic should be like: when player collects sheild - 1st Thing show the sheild bubble around the ninja ( working ) - 2nd if the ninja is on lower path and it jumps to a upper path then change the location of the sheild bubble to ninja location after ninja changes the path, only if the sheild cooldown time is not over ( which is 10s after collecting the sheild ). And same thing when ninja is on upper path and it jumps to a lower path.
User prompt
i don't know why, but the logic for sheild bubble to change location on jump is not working, find some way to fix the bug or try some new logic to make that happen.
User prompt
still the issue persist, now what we can do instead of previous logic, do the check for bubble on click as i mentioned but when the check is true, destroy the bubble and spawn the new bubble at the ninja location( after ninja change the location ).
User prompt
You can do one thing to fix the issue, whenever player clicks on the screen, check if the sheild bubble is still there ( mean the 10sec sheild timer is not finished ) then move the sheild bubble to inverse path of the current path ( or at the new location of the ninja )
User prompt
Sheild bubble is not updating the location when ninja jumps to another path.
User prompt
Remove the tint logic, instead add the sheild bubble around the ninja, and sheild bubble should move along with ninja, whenever the ninja jumps to other path, after 10s remove the sheild bubble, size of sheild bubble should be bigger than the ninja.
User prompt
Now whenever the sheild intersects with ninja, Change the color or tint of the ninja sprites to blue, and make ninja invincible for 10 sec, also play a sheild collection sound effect. After 10sec reset everything back to normal.
User prompt
Now whenever the sheild intersects with ninja, Change the tint of the ninja for upcoming sprites to blue, and make ninja invincible, also play a sheild collection sound effect.
User prompt
Now add check in lives ( collectible ) with ninja, and when interacted : Add one life in the display life and destroy the spawned life.
User prompt
Speed of Lives spawn should be same as the sheild.
User prompt
Now remove the check for the interaction of ninja with lives from the code.
User prompt
Now add check in sheild for interaction with ninja, and perform the logic of sheild.
User prompt
Remove the check for interaction of ninja with sheild from the code.
User prompt
Please fix the bug: 'ReferenceError: ninjaGraphics is not defined' in or related to this line: 'ninjaGraphics.tint = 0x0000ff; // Change tint to blue' Line Number: 408
User prompt
Use the same collision detection logic as of Coin Container. inside the Sheild Container.
User prompt
Z order of the sheild and lives should be same as coin.
User prompt
Still not working, Check Collision Logic to fix the issue.
User prompt
check for Z-Index and Layering, to fix the issue.
Code edit (1 edits merged)
Please save this source code
User prompt
whenever the ninja collides with sheild print "Sheild" in console.
User prompt
Remove the progress bar logic from sheild
User prompt
No, still ninja is not able to get the sheild. fix this
User prompt
Fix all the bugs and issues.
/****
* 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 -= 2;
if (self.x < -self.width / 2) {
self.destroy();
}
};
});
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();
}
// No transition effect
}
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 = lives.length - 1; i >= 0; i--) {
if (self.intersects(lives[i])) {
self.lives++;
lives[i].destroy();
lives.splice(i, 1);
// Update the display lives
updateDisplayLives();
}
}
for (var i = shields.length - 1; i >= 0; i--) {
var shield = shields[i];
if (self.intersects(shield)) {
self.invincible = true;
ninjaGraphics.tint = 0x0000ff; // Change tint to blue
// Add shield icon and timer display
if (!self.shieldIcon) {
self.shieldIcon = new Text2('10s', {
size: 100,
fill: "#ffffff"
});
self.shieldIcon.anchor.set(0.5, 0.5);
self.shieldIcon.x = 100;
self.shieldIcon.y = 2732 / 2;
LK.gui.left.addChild(self.shieldIcon);
}
var shieldTimeLeft = 10;
self.shieldInterval = LK.setInterval(function () {
shieldTimeLeft--;
self.shieldIcon.setText(shieldTimeLeft + 's');
if (shieldTimeLeft <= 0) {
LK.clearInterval(self.shieldInterval);
self.shieldIcon.destroy();
self.shieldIcon = null;
}
}, 1000);
if (self.shieldTimeout) {
LK.clearTimeout(self.shieldTimeout);
}
self.shieldTimeout = LK.setTimeout(function () {
self.invincible = false;
ninjaGraphics.tint = 0xffffff; // Reset tint to default
self.shieldTimeout = null;
if (self.shieldIcon) {
self.shieldIcon.destroy();
self.shieldIcon = null;
}
LK.clearInterval(self.shieldInterval);
}, 10000);
// Add circular progress bar
var progressBar = new Container();
var progressCircle = new Graphics();
progressCircle.beginFill(0x0000ff);
progressCircle.drawCircle(0, 0, 50);
progressCircle.endFill();
progressBar.addChild(progressCircle);
progressBar.x = 100;
progressBar.y = 2732 * 2 / 3 + 100;
game.addChild(progressBar);
var progress = 1;
var progressInterval = LK.setInterval(function () {
progress -= 0.1;
progressCircle.scale.set(progress);
if (progress <= 0) {
LK.clearInterval(progressInterval);
progressBar.destroy();
}
}, 1000);
shield.destroy();
shields.splice(i, 1);
i--;
break;
}
}
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();
continue; // Skip the rest of the loop for this obstacle
}
// Reduce the lives by one
self.lives--;
// Update the display
updateDisplayLives();
// If no lives left, game over
if (self.lives === 0) {
// Flash screen red for 1 second (1000ms) to show we are dead.
LK.effects.flashScreen(0xff0000, 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;
if (self.x < -self.width) {
self.destroy();
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
var shieldIcon = 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.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.children.length - 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
}
};
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