User prompt
Let the bounce variable start from 0 when you start a new game. When the 0 (bounce) variable is 10, get the bouncy rabbit achievement
User prompt
No, the counter starts at 0, but the 25 hops required for the jumping bunny will take 10 hops, so 19 hops should get you this achievement
User prompt
Perform 10 hops out of the 25 hops required for the jumping bunny achievement
User prompt
If the ball goes more than 300 metres high in a game, the "eyes up" achievement will appear on the side (stays until the next game) if there are 5 atw in a game, the "orbit of the earth" achievement will appear (below the "eyes up" achievement) if there are more than 25 bounces in a game, the "hopscotch bunny" achievement will appear (below the "orbit of the earth" achievement) these 3 achievements will have 3 different sub-slots on the screen and on the finish screen the number of achievements will be .../3 (for example 1/3) ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Now it is much better, but sometimes it does not fall exactly, it can fall from the right or left side, can you fix it?
User prompt
It is still on the right, e.g. the arrow is on the right when the ball falls from the centre and in the centre when it falls from the left. If it falls in the middle, let it fall in the middle. So the ball and the arrow have the same X coordinate
User prompt
I think I confused the planes, the arrow is too far to the right towards the ball, it will be right under it as speed
User prompt
The arrow will not come out of the screen after the game starts, and the arrow will be under the ball when the ball leaves the screen, but it will be visible, but it will be under the ball (not just under it), the arrow will be above the screen, (not right or left up)
User prompt
When your ball rises and lands at 100, the game continues, only the arrow disappears.
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'arrowIndicator.style.fill = redIntensity << 16 | greenBlue << 8 | greenBlue;' Line Number: 250
User prompt
When the ball rises out of the screen, at 50 metres to 100 metres, the vertical plane where the ball is is shown as an arrow on the top of the screen (for example, when the ball slides to the left, the arrow follows it and goes to the left), grows as 100 approaches, and when 100 is reached, you are lost, when you rise again, the same thing happens again. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let that counter be 0 on the ground, 100 right above the screen, but if it falls from the screen to the ground, it decreases and ends as 0 on the ground.
User prompt
Put a metre counter on the side to show how high the ball has risen (e.g. the length of the screen is 100 metres),
User prompt
Reduce the bounce of the ball a little and 270 degrees for atw instead of 360 degrees for atw
User prompt
The faster we move the foot to the ball and touch the ball, the faster the ball will go, if after touching the ball the foot turns around the ball once until the foot touches the ball again and touches the ball again, 5 bounces are counted and there is an ATW counter next to the bounce, each time this movement is done, the atw counter increases by one. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Boot Kick Ball
Initial prompt
Make me a ball bouncing game, with gravity like in the world, with a foot wearing a boot and we can take this foot anywhere by touching or dragging it. The ball can leave the screen with the ball up, but when it touches the ground, the game ends and the play screen appears again. Do not start the game until something is touched. There should be a number at the top showing how many times the ball was not touched, and it should be written on the end screen, and our best score should be written on the end screen
/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.8;
self.bounceReduction = 0.75;
self.lastY = 0;
self.update = function () {
self.lastY = self.y;
// Apply gravity
self.velocityY += self.gravity;
// Update position
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off sides
if (self.x <= 40 || self.x >= 2008) {
self.velocityX *= -0.7;
self.x = self.x <= 40 ? 40 : 2008;
}
};
self.bounceOffBoot = function (bootY, bootSpeed) {
var baseForce = Math.abs(self.velocityY) * 0.8 + 8;
var speedBonus = bootSpeed * 0.3;
var impactForce = baseForce + speedBonus;
self.velocityY = -impactForce;
self.velocityX += (Math.random() - 0.5) * 4 + bootSpeed * 0.1;
self.y = bootY - 100;
// Clamp horizontal velocity with higher limits for speed
var maxVel = 12 + speedBonus * 0.2;
self.velocityX = Math.max(-maxVel, Math.min(maxVel, self.velocityX));
};
return self;
});
var Boot = Container.expand(function () {
var self = Container.call(this);
var bootGraphics = self.attachAsset('boot', {
anchorX: 0.5,
anchorY: 0.5
});
self.lastX = 0;
self.lastY = 0;
self.speed = 0;
self.angleFromBall = 0;
self.lastAngleFromBall = 0;
self.angleSum = 0;
self.lastBounceTime = 0;
self.update = function () {
// Calculate speed
var deltaX = self.x - self.lastX;
var deltaY = self.y - self.lastY;
self.speed = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var ball = game.addChild(new Ball());
var boot = game.addChild(new Boot());
// Game state variables
var bounceCount = 0;
var atwCount = 0;
var bestScore = storage.bestScore || 0;
var gameStarted = false;
var dragNode = null;
var maxHeight = 0;
var ballStartY = 400;
// Initialize positions
ball.x = 1024;
ball.y = 400;
ball.velocityY = 2;
boot.x = 1024;
boot.y = 2200;
// UI Elements
var bounceText = new Text2('Bounces: 0', {
size: 80,
fill: 0xFFFFFF
});
bounceText.anchor.set(0.5, 0);
LK.gui.top.addChild(bounceText);
var atwText = new Text2('ATW: 0', {
size: 60,
fill: 0x00FF00
});
atwText.anchor.set(0, 0);
atwText.y = 100;
LK.gui.topLeft.addChild(atwText);
var instructionText = new Text2('Drag boot to keep ball up!', {
size: 60,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionText);
var bestText = new Text2('Best: ' + bestScore, {
size: 50,
fill: 0xFFFF88
});
bestText.anchor.set(1, 0);
LK.gui.topRight.addChild(bestText);
var heightText = new Text2('Height: 0m', {
size: 60,
fill: 0xFFFFFF
});
heightText.anchor.set(1, 0);
heightText.x = -10;
heightText.y = 100;
LK.gui.topRight.addChild(heightText);
// Arrow indicator for ball position above screen
var arrowIndicator = new Text2('▼', {
size: 80,
fill: 0xFF4444
});
arrowIndicator.anchor.set(0.5, 0);
arrowIndicator.alpha = 0;
LK.gui.top.addChild(arrowIndicator);
// Game interaction
game.down = function (x, y, obj) {
if (!gameStarted) {
gameStarted = true;
instructionText.alpha = 0;
maxHeight = 0;
heightText.setText('Height: 0m');
}
dragNode = boot;
boot.x = x;
boot.y = y;
};
game.move = function (x, y, obj) {
if (dragNode && gameStarted) {
boot.x = x;
boot.y = y;
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
if (!gameStarted) {
return;
}
// Calculate angle from boot to ball for ATW detection
var deltaX = ball.x - boot.x;
var deltaY = ball.y - boot.y;
var currentAngle = Math.atan2(deltaY, deltaX);
// Normalize angle difference
var angleDiff = currentAngle - boot.lastAngleFromBall;
if (angleDiff > Math.PI) angleDiff -= 2 * Math.PI;
if (angleDiff < -Math.PI) angleDiff += 2 * Math.PI;
// Track cumulative angle change
boot.angleSum += angleDiff;
boot.lastAngleFromBall = currentAngle;
// Check collision between ball and boot
if (ball.intersects(boot)) {
if (ball.velocityY > 0) {
// Only bounce if ball is falling
var currentTime = LK.ticks;
// Check for ATW (3/4 rotation around ball between bounces)
if (Math.abs(boot.angleSum) >= 1.5 * Math.PI && currentTime - boot.lastBounceTime > 30) {
atwCount++;
bounceCount += 5; // ATW gives 5 bounces
atwText.setText('ATW: ' + atwCount);
// Visual feedback for ATW
tween(boot, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(boot, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
LK.effects.flashScreen(0x00FF00, 500);
} else {
bounceCount++;
}
ball.bounceOffBoot(boot.y, boot.speed);
bounceText.setText('Bounces: ' + bounceCount);
LK.getSound('bounce').play();
// Update score
LK.setScore(bounceCount);
// Reset ATW tracking
boot.angleSum = 0;
boot.lastBounceTime = currentTime;
}
}
// Track current height (convert screen coordinates to meters)
// Screen height is 2732px = 100 meters, so 1 meter = 27.32px
// Height 0 = ground (bottom), Height 100 = top of screen
var currentHeightInMeters = Math.max(0, (2732 - ball.y) / 27.32);
heightText.setText('Height: ' + Math.round(currentHeightInMeters) + 'm');
if (currentHeightInMeters > maxHeight) {
maxHeight = currentHeightInMeters;
}
// Handle arrow indicator when ball is between 50m and 100m height
if (currentHeightInMeters >= 50 && currentHeightInMeters <= 100) {
// Show arrow and position it based on ball's X coordinate
arrowIndicator.alpha = 1;
// Convert ball's game X position to GUI coordinates (2048 game width maps to GUI width)
var guiX = ball.x / 2048 * LK.gui.width;
arrowIndicator.x = Math.max(50, Math.min(LK.gui.width - 50, guiX));
// Scale arrow size as it approaches 100m (grows from 50m to 100m)
var scaleProgress = (currentHeightInMeters - 50) / 50;
var arrowScale = 1 + scaleProgress * 0.8;
arrowIndicator.scale.set(arrowScale, arrowScale);
// Change color as it approaches danger zone
var redIntensity = Math.floor(255 * scaleProgress);
var greenBlue = Math.floor(68 * (1 - scaleProgress));
arrowIndicator.tint = redIntensity << 16 | greenBlue << 8 | greenBlue;
} else {
arrowIndicator.alpha = 0;
}
// Check if ball hits bottom (game over)
if (ball.y > 2732) {
// Update best score
if (bounceCount > bestScore) {
bestScore = bounceCount;
storage.bestScore = bestScore;
bestText.setText('Best: ' + bestScore);
}
LK.showGameOver();
}
// Hide arrow when ball lands back down below 50m
if (currentHeightInMeters < 50) {
arrowIndicator.alpha = 0;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -249,15 +249,9 @@
bestText.setText('Best: ' + bestScore);
}
LK.showGameOver();
}
- // Check if ball reaches 100m height (game over)
- if (currentHeightInMeters >= 100) {
- // Update best score
- if (bounceCount > bestScore) {
- bestScore = bounceCount;
- storage.bestScore = bestScore;
- bestText.setText('Best: ' + bestScore);
- }
- LK.showGameOver();
+ // Hide arrow when ball lands back down below 50m
+ if (currentHeightInMeters < 50) {
+ arrowIndicator.alpha = 0;
}
};
\ No newline at end of file