User prompt
The chest should appear in a random location on the map for the first time after 10 seconds of play
User prompt
the chest should appear in a random place on the map every 10 seconds of the game and disappear after 10 seconds.
User prompt
the chest should be born 10 seconds after the start of the game, once 10 seconds and disappear after 10 seconds of being on the screen
User prompt
make the first birth of the chest to be after 10 seconds after the game starts
User prompt
make the first birth of the chest to be after 10 seconds after the game starts
User prompt
the first birth of a chest after 10 seconds of play
User prompt
a chest can only be born 10 seconds after the start of the game
User prompt
a chest can only be born 10 seconds after the start of the game
User prompt
the chest should not be spawned closer than 500 pixels to the edges of the screen
User prompt
the chest should not be born where the balls are currently located
User prompt
the chest should be spawned further from the balls, but no closer than 500 pixels from the edges of the screen
User prompt
the chest should be spawned further from the balls, but no closer than 500 pixels from the edges of the screen
User prompt
the chest should be spawned further from the balls
User prompt
the chest should be born immediately without changing transparency
User prompt
when the balls interact with the cannonball, show an explosion next to the balls for 2 seconds
User prompt
the chest should not be spawned closer than 500 pixels to the edges of the screen
User prompt
Fix Bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var moveStepX = ball.velocity.x / moveDuration;' Line Number: 140
User prompt
the coin must move next to the balls before it disappears
User prompt
when the balls interact with the chest, show a coin next to the balls for 2 second
User prompt
when the balls interact with the chest, show a coin next to the balls for half a second
User prompt
the cannonball must be born no closer than 500 pixels to the side edges of the screen
User prompt
balls should not change position when interacting with a chest or a cannonball
User prompt
fix the situation when the balls endlessly move between the rackets without changing the rebound angle
User prompt
make the initial amount of health 3
User prompt
When adding new health, align all health in the middle of the screen
/****
* Classes
****/
// RightPaddle class
var RightPaddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('rightPaddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.moveUp = function () {
self.y -= self.speed;
};
self.moveDown = function () {
self.y += self.speed;
};
});
// LeftPaddle class
var LeftPaddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('leftPaddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.moveUp = function () {
self.y -= self.speed;
};
self.moveDown = function () {
self.y += self.speed;
};
});
// Ball class
var Ball = Container.expand(function () {
var self = Container.call(this);
this.ballGraphics = null;
var ballAsset = Math.random() < 0.5 ? 'ball' : 'ball2';
this.ballGraphics = self.attachAsset(ballAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = {
x: 5,
y: 5
};
self.move = function () {
self.x += self.velocity.x;
self.y += self.velocity.y;
};
self.reset = function () {
self.x = 2048 / 2;
self.y = 2732 / 2;
var randomDirection = Math.random() < 0.5 ? -1 : 1;
self.velocity = {
x: 5 * randomDirection,
y: Math.random() * 8 - 4
};
// Smoothly swap the ball asset with a fade out and fade in effect
self.removeChild(self.ballGraphics);
var newBallAsset = self.velocity.x < 0 ? 'ball' : 'ball2';
self.ballGraphics = self.attachAsset(newBallAsset, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0 // Start fully transparent
});
// Animate the alpha property to fade in the new ball
var fadeDuration = 30; // Duration in ticks
var fadeStep = 1 / fadeDuration;
var currentTick = 0;
var fadeIn = function fadeIn() {
if (currentTick < fadeDuration) {
self.ballGraphics.alpha += fadeStep;
currentTick++;
} else {
LK.off('tick', fadeIn); // Stop the animation when done
}
};
LK.on('tick', fadeIn);
};
});
// Background class
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = self.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
// Set background to cover the entire game area
backgroundGraphics.width = 2048;
backgroundGraphics.height = 2732;
// Position the background in the center
self.x = 2048 / 2;
self.y = 2732 / 2;
});
// Health class
var Health = Container.expand(function () {
var self = Container.call(this);
var healthGraphics = self.attachAsset('health', {
anchorX: 0.5,
anchorY: 0.5
});
// Set the initial alpha to fully visible
self.alpha = 1;
// Position the health icon based on its index
self.setPosition = function (index, totalIcons) {
var iconWidth = healthGraphics.width;
var spacing = 10;
var totalWidth = totalIcons * (iconWidth + spacing) - spacing;
self.x = (2048 - totalWidth) / 2 + index * (iconWidth + spacing);
self.y = 100;
};
});
// Cannonball class
var Cannonball = Container.expand(function () {
var self = Container.call(this);
var cannonballGraphics = self.attachAsset('cannonball', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -10;
self.move = function () {
self.y += self.speed;
// Start fading the cannonball 1000 pixels before the top edge of the screen
if (self.y < 1000) {
var fadeOutStep = self.alpha / (1000 / Math.abs(self.speed));
self.alpha -= fadeOutStep;
if (self.alpha < 0) {
self.alpha = 0;
} // Ensure alpha doesn't go below 0
}
};
self.reset = function () {
self.x = Math.random() * (2048 - cannonballGraphics.width) + cannonballGraphics.width / 2;
self.y = 2732 - cannonballGraphics.height / 2;
self.alpha = 0; // Start fully transparent
var fadeInDuration = 60; // Duration in ticks (1 second at 60FPS)
var fadeStep = 1 / fadeInDuration;
var fadeInTick = 0;
var fadeIn = function fadeIn() {
if (fadeInTick < fadeInDuration) {
self.alpha += fadeStep;
fadeInTick++;
} else {
LK.off('tick', fadeIn); // Stop the animation when done
}
};
LK.on('tick', fadeIn);
};
});
// InteractableChest class
var InteractableChest = Container.expand(function () {
var self = Container.call(this);
var chestGraphics = self.attachAsset('chest', {
anchorX: 0.5,
anchorY: 0.5
});
self.isVisible = false;
self.showChest = function () {
self.isVisible = true;
self.x = Math.random() * (2048 - chestGraphics.width) + chestGraphics.width / 2;
self.y = Math.random() * (2732 - chestGraphics.height) + chestGraphics.height / 2;
self.alpha = 0;
var fadeInDuration = 60; // 1 second at 60FPS
var fadeStep = 1 / fadeInDuration;
var fadeInTick = 0;
var fadeIn = function fadeIn() {
if (fadeInTick < fadeInDuration) {
self.alpha += fadeStep;
fadeInTick++;
} else {
LK.off('tick', fadeIn);
}
};
LK.on('tick', fadeIn);
};
self.interactWithBall = function (ball) {
if (self.isVisible && self.intersects(ball)) {
// Interaction logic here
self.isVisible = false;
self.alpha = 0;
// Add one health icon
var newHealthIcon = game.addChild(new Health());
healthIcons.push(newHealthIcon);
// Realign all health icons
for (var i = 0; i < healthIcons.length; i++) {
healthIcons[i].setPosition(i, healthIcons.length);
}
// Reset the ball or other interaction effects
ball.reset();
}
};
});
/****
* Initialize Game
****/
// Initialize paddles and ball
// Define the paddle asset
// Define the ball asset
var game = new LK.Game({
backgroundColor: 0x92c7f3 // Init game with blue background
});
/****
* Game Code
****/
// Instantiate and add background to the game
var background = game.addChild(new Background());
// Define the ball asset
// Define the paddle asset
// Initialize paddles
var leftPaddle = game.addChild(new LeftPaddle());
var rightPaddle = game.addChild(new RightPaddle());
var ball = game.addChild(new Ball());
// Set initial positions
leftPaddle.x = 50;
leftPaddle.y = 2732 / 2;
rightPaddle.x = 2048 - 50;
rightPaddle.y = 2732 / 2;
// Initialize health icons
var healthIcons = [];
var totalHealthIcons = 5; // Increase the initial total health icons to 5
for (var i = 0; i < totalHealthIcons; i++) {
var healthIcon = game.addChild(new Health());
healthIcon.setPosition(i, totalHealthIcons);
healthIcons.push(healthIcon);
}
// Instantiate and add interactable chest to the game
var interactableChest = game.addChild(new InteractableChest());
// Initial visibility of the chest is handled within the class
ball.reset();
// Game tick event
LK.on('tick', function () {
// Move the ball
ball.move();
// Ball collision with top and bottom
if (ball.y <= 0 || ball.y >= 2732) {
ball.velocity.y *= -1;
}
// Ball collision with paddles and initiate a smoother ball asset transition
if (ball.intersects(leftPaddle) && ball.velocity.x < 0 || ball.intersects(rightPaddle) && ball.velocity.x > 0) {
ball.velocity.x *= -1;
// Initiate fade out of the current ball asset
ball.ballGraphics.alpha = 1;
var fadeOutDuration = 15; // Duration in ticks for fade out
var fadeStep = 1 / fadeOutDuration;
var fadeOutTick = 0;
var fadeOut = function fadeOut() {
if (fadeOutTick < fadeOutDuration) {
ball.ballGraphics.alpha -= fadeStep;
fadeOutTick++;
} else {
LK.off('tick', fadeOut);
// After fade out, swap the ball asset and fade it in
ball.removeChild(ball.ballGraphics);
var newBallAsset = ball.velocity.x < 0 ? 'ball' : 'ball2';
ball.ballGraphics = ball.attachAsset(newBallAsset, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0 // Start fully transparent
});
// Animate the alpha property to fade in the new ball
var fadeInDuration = 15; // Duration in ticks for fade in
var fadeInStep = 1 / fadeInDuration;
var fadeInTick = 0;
var fadeIn = function fadeIn() {
if (fadeInTick < fadeInDuration) {
ball.ballGraphics.alpha += fadeInStep;
fadeInTick++;
} else {
LK.off('tick', fadeIn); // Stop the animation when done
}
};
LK.on('tick', fadeIn);
}
};
LK.on('tick', fadeOut);
}
// Ball out of bounds
if (ball.x <= 0 || ball.x >= 2048) {
ball.reset();
}
// Chest appearance and interaction logic
if (LK.ticks % (10 * 60) === 0 && !interactableChest.isVisible) {
interactableChest.showChest();
}
interactableChest.interactWithBall(ball);
// Cannonball collision with ball
var cannonballs = game.children.filter(function (child) {
return child instanceof Cannonball;
});
cannonballs.forEach(function (cannonball) {
if (cannonball.intersects(ball)) {
// Remove one health
if (healthIcons.length > 0) {
var lastHealthIcon = healthIcons.pop();
lastHealthIcon.destroy();
}
// Destroy the cannonball
if (cannonball) {
cannonball.destroy();
}
// Reset the ball
ball.reset();
}
});
}); // Game tick event
LK.on('tick', function () {
// Move the ball
ball.move();
// Ball collision with top and bottom
if (ball.y <= 0 || ball.y >= 2732) {
ball.velocity.y *= -1;
}
// Ball collision with paddles and initiate a smoother ball asset transition
if (ball.intersects(leftPaddle) && ball.velocity.x < 0 || ball.intersects(rightPaddle) && ball.velocity.x > 0) {
ball.velocity.x *= -1;
// Initiate fade out of the current ball asset
ball.ballGraphics.alpha = 1;
var fadeOutDuration = 15; // Duration in ticks for fade out
var fadeStep = 1 / fadeOutDuration;
var fadeOutTick = 0;
var fadeOut = function fadeOut() {
if (fadeOutTick < fadeOutDuration) {
ball.ballGraphics.alpha -= fadeStep;
fadeOutTick++;
} else {
LK.off('tick', fadeOut);
// After fade out, swap the ball asset and fade it in
ball.removeChild(ball.ballGraphics);
var newBallAsset = ball.velocity.x < 0 ? 'ball' : 'ball2';
ball.ballGraphics = ball.attachAsset(newBallAsset, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0 // Start fully transparent
});
// Animate the alpha property to fade in the new ball
var fadeInDuration = 15; // Duration in ticks for fade in
var fadeInStep = 1 / fadeInDuration;
var fadeInTick = 0;
var fadeIn = function fadeIn() {
if (fadeInTick < fadeInDuration) {
ball.ballGraphics.alpha += fadeInStep;
fadeInTick++;
} else {
LK.off('tick', fadeIn); // Stop the animation when done
}
};
LK.on('tick', fadeIn);
}
};
LK.on('tick', fadeOut);
}
// Ball out of bounds
if (ball.x <= 0 || ball.x >= 2048) {
ball.reset();
}
// Chest appearance logic
if (LK.ticks % (10 * 60) === 0 && !interactableChest.isVisible) {
interactableChest.showChest();
}
// Move cannonballs
game.children.forEach(function (child) {
if (child instanceof Cannonball) {
child.move();
// Remove cannonball if it goes off the top of the screen
if (child.y + child.height / 2 < 0) {
child.destroy();
}
}
});
});
// Touch event listeners for paddles
game.on('down', function (obj) {
var event = obj.event;
var pos = event.getLocalPosition(game);
// Determine which paddle to control based on touch position
if (pos.x < 2048 / 2) {
leftPaddle.y = pos.y;
} else {
rightPaddle.y = pos.y;
}
});
game.on('move', function (obj) {
var event = obj.event;
var pos = event.getLocalPosition(game);
// Update paddle position based on touch movement
if (pos.x < 2048 / 2) {
leftPaddle.y = pos.y;
} else {
rightPaddle.y = pos.y;
}
}); // Timer to launch a cannonball every 10 seconds
var cannonballTimer = LK.setInterval(function () {
var newCannonball = new Cannonball();
newCannonball.reset();
game.addChild(newCannonball);
}, 10000);
ancient nautical chart. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
head of the wind god that blows wind on ancient maps, Middle Ages, black and white, wind from the mouth. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
scrub
pirate treasure chest. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
anchor. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cannonball. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
explosion, black and white. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.