User prompt
random target positioning on upper
User prompt
super speed wall
User prompt
more walls
User prompt
increase wall more speed
User prompt
increase wall speed
User prompt
increase wall speed
User prompt
wall random position
User prompt
add multiple walls
User prompt
delete level display
User prompt
Please fix the bug: 'levelText is not defined' in or related to this line: 'levelText.setText('Level: ' + levelManager.currentLevel);' Line Number: 393
User prompt
erase level display
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'ballStart')' in or related to this line: 'ball.x = currentLevel.ballStart.x;' Line Number: 342
User prompt
erase level asset
User prompt
fix bounce
User prompt
move the time display down
User prompt
the ball bounces until it collides with the wall
User prompt
make game levels
User prompt
add moving wall asset
User prompt
erase wall
User prompt
fix game
User prompt
make easy
User prompt
300 second time race
User prompt
reverse aim line
User prompt
repair aim line
User prompt
infinite shoot
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
currentLevel: 1,
highScores: {}
});
/****
* Classes
****/
var AimLine = Container.expand(function () {
var self = Container.call(this);
var line = self.attachAsset('aimLine', {
anchorX: 0.5,
anchorY: 1,
alpha: 0.7
});
self.setAngle = function (degrees) {
line.rotation = degrees * (Math.PI / 180);
};
self.setLength = function (length) {
line.height = length;
};
self.hide = function () {
self.visible = false;
};
self.show = function () {
self.visible = true;
};
return self;
});
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphic = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = {
x: 0,
y: 0
};
self.moving = false;
self.bounceCount = 0;
self.friction = 0.98;
self.bounceFactor = 0.9;
self.maxSpeed = 50;
self.launch = function (power, angle) {
// Convert angle from degrees to radians
var radians = angle * (Math.PI / 180);
// Set velocity based on power and angle
self.velocity.x = Math.cos(radians) * power * 0.3;
self.velocity.y = Math.sin(radians) * power * 0.3;
// Clamp velocity to max speed
var speed = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y);
if (speed > self.maxSpeed) {
var ratio = self.maxSpeed / speed;
self.velocity.x *= ratio;
self.velocity.y *= ratio;
}
self.moving = true;
self.bounceCount = 0;
LK.getSound('launch').play();
};
self.update = function () {
if (!self.moving) {
return;
}
// Apply physics
self.x += self.velocity.x;
self.y += self.velocity.y;
// Apply friction
self.velocity.x *= self.friction;
self.velocity.y *= self.friction;
// Check if ball has stopped
if (Math.abs(self.velocity.x) < 0.1 && Math.abs(self.velocity.y) < 0.1) {
self.velocity.x = 0;
self.velocity.y = 0;
self.moving = false;
}
// Check boundaries
var halfWidth = ballGraphic.width / 2;
var halfHeight = ballGraphic.height / 2;
if (self.x < halfWidth) {
self.x = halfWidth;
self.velocity.x = -self.velocity.x * self.bounceFactor;
self.bounceWall();
} else if (self.x > 2048 - halfWidth) {
self.x = 2048 - halfWidth;
self.velocity.x = -self.velocity.x * self.bounceFactor;
self.bounceWall();
}
if (self.y < halfHeight) {
self.y = halfHeight;
self.velocity.y = -self.velocity.y * self.bounceFactor;
self.bounceWall();
} else if (self.y > 2732 - halfHeight) {
self.y = 2732 - halfHeight;
self.velocity.y = -self.velocity.y * self.bounceFactor;
self.bounceWall();
}
};
self.bounceWall = function () {
self.bounceCount++;
LK.getSound('bounce').play();
};
self.bounceOffWall = function (wall) {
// Calculate the center of the wall
var wallCenterX = wall.x;
var wallCenterY = wall.y;
// Calculate the normal vector from the wall
var dx = self.x - wallCenterX;
var dy = self.y - wallCenterY;
// Determine if collision is mainly horizontal or vertical based on wall dimensions
if (Math.abs(dx) > Math.abs(dy)) {
// Horizontal collision, bounce horizontally
self.velocity.x = -self.velocity.x * self.bounceFactor;
// Reposition to avoid sticking
if (self.x < wallCenterX) {
self.x = wallCenterX - wall.width / 2 - ballGraphic.width / 2;
} else {
self.x = wallCenterX + wall.width / 2 + ballGraphic.width / 2;
}
} else {
// Vertical collision, bounce vertically
self.velocity.y = -self.velocity.y * self.bounceFactor;
// Reposition to avoid sticking
if (self.y < wallCenterY) {
self.y = wallCenterY - wall.height / 2 - ballGraphic.height / 2;
} else {
self.y = wallCenterY + wall.height / 2 + ballGraphic.height / 2;
}
}
self.bounceWall();
};
return self;
});
var LevelManager = Container.expand(function () {
var self = Container.call(this);
self.currentLevel = storage.currentLevel || 1;
self.levels = [];
self.initializeLevels = function () {
// Level 1 - Simple intro level
self.levels.push({
ballStart: {
x: 1024,
y: 1366
},
targets: [{
x: 500,
y: 500
}, {
x: 1500,
y: 500
}],
walls: Array.from({
length: 5
}, function () {
return {
x: Math.random() * 2048,
y: Math.random() * 2732
};
})
});
};
self.getCurrentLevel = function () {
return self.levels[self.currentLevel - 1] || self.levels[0];
};
self.advanceLevel = function () {
if (self.currentLevel < self.levels.length) {
self.currentLevel++;
storage.currentLevel = self.currentLevel;
return true;
}
return false;
};
self.resetLevel = function () {
// Just reset the current level (no change in level number)
};
self.saveScore = function (level, shots) {
var currentHighScore = storage.highScores[level] || 999;
if (shots < currentHighScore) {
storage.highScores[level] = shots;
}
};
self.getHighScore = function (level) {
return storage.highScores[level] || "-";
};
return self;
});
var MovingWall = Container.expand(function () {
var self = Container.call(this);
var wallGraphic = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20; // Super speed for walls
self.direction = 1; // 1 for right, -1 for left
self.update = function () {
self.x += self.speed * self.direction;
if (self.x > 2048 - wallGraphic.width / 2 || self.x < wallGraphic.width / 2) {
self.direction *= -1; // Reverse direction
}
};
return self;
});
var PowerMeter = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('powerMeter', {
anchorX: 0.5,
anchorY: 1,
alpha: 0.3
});
var meter = self.attachAsset('powerMeter', {
anchorX: 0.5,
anchorY: 1,
tint: 0xFF3333
});
self.power = 0;
self.maxPower = 100;
meter.height = 0;
self.setPower = function (percent) {
self.power = Math.max(0, Math.min(100, percent));
meter.height = self.power / 100 * background.height;
// Change color based on power
if (self.power < 33) {
meter.tint = 0x33FF33; // Green for low power
} else if (self.power < 66) {
meter.tint = 0xFFFF33; // Yellow for medium power
} else {
meter.tint = 0xFF3333; // Red for high power
}
};
self.hide = function () {
self.visible = false;
};
self.show = function () {
self.visible = true;
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var targetGraphic = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.active = true;
self.hit = false;
self.update = function () {
// This would be where we'd add movement or animation if needed
};
self.onHit = function () {
if (!self.hit && self.active) {
self.hit = true;
LK.getSound('hitTarget').play();
// Visual feedback
tween(targetGraphic, {
alpha: 0.3,
scaleX: 0.7,
scaleY: 0.7
}, {
duration: 300,
easing: tween.easeOut
});
return true;
}
return false;
};
self.reset = function () {
self.hit = false;
targetGraphic.alpha = 1;
tween(targetGraphic, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game state variables
var gameActive = false;
var isDragging = false;
var startX, startY;
var shotsUsed = 0;
var targetsHit = 0;
var totalTargets = 0;
var timeRemaining = 300; // 300 seconds timer
var timerText = new Text2('Time: 300', {
size: 70,
fill: 0xFFFFFF
});
timerText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(timerText);
// Create UI elements
var scoreText = new Text2('Shots: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var instructionText = new Text2('Swipe to launch the ball', {
size: 60,
fill: 0xFFFFFF,
alpha: 0.8
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 150;
LK.gui.top.addChild(instructionText);
// Create game objects
var levelManager = new LevelManager();
levelManager.initializeLevels();
var ball = new Ball();
var aimLine = new AimLine();
var powerMeter = new PowerMeter();
var targets = [];
// Initialize level
function initializeLevel() {
// Clear old objects
for (var i = targets.length - 1; i >= 0; i--) {
game.removeChild(targets[i]);
}
targets = [];
// Get current level data
var currentLevel = levelManager.getCurrentLevel();
// Set ball position
ball.x = currentLevel.ballStart.x;
ball.y = currentLevel.ballStart.y;
ball.velocity = {
x: 0,
y: 0
};
ball.moving = false;
// Create targets
totalTargets = currentLevel.targets.length;
for (var i = 0; i < currentLevel.targets.length; i++) {
var targetData = currentLevel.targets[i];
var target = new Target();
// Randomize target position on the upper half of the screen
target.x = Math.random() * 2048;
target.y = Math.random() * (1366 - target.height / 2);
target.reset();
targets.push(target);
game.addChild(target);
}
// Create moving walls
for (var i = 0; i < currentLevel.walls.length; i++) {
var wallData = currentLevel.walls[i];
var movingWall = new MovingWall();
movingWall.x = wallData.x;
movingWall.y = wallData.y;
game.addChild(movingWall);
}
// Set up aiming tools
aimLine.x = ball.x;
aimLine.y = ball.y;
aimLine.hide();
game.addChild(aimLine);
powerMeter.x = 100;
powerMeter.y = 2600;
powerMeter.setPower(0);
powerMeter.hide();
game.addChild(powerMeter);
// Reset game state
shotsUsed = 0;
targetsHit = 0;
gameActive = true;
// Update UI
scoreText.setText('Shots: ' + shotsUsed);
var highScore = levelManager.getHighScore(levelManager.currentLevel);
instructionText.setText('Best: ' + (highScore === 999 ? "-" : highScore) + ' shots - Swipe to launch');
}
// Add ball to game
game.addChild(ball);
// Start the first level
initializeLevel();
// Play background music
LK.playMusic('gameMusic', {
volume: 0.5
});
// Event handlers
function handleDown(x, y, obj) {
if (!gameActive || ball.moving) {
return;
}
startX = x;
startY = y;
isDragging = true;
aimLine.x = ball.x;
aimLine.y = ball.y;
aimLine.show();
powerMeter.show();
powerMeter.setPower(0);
}
function handleMove(x, y, obj) {
if (!isDragging) {
return;
}
// Calculate angle and power
var dx = x - startX;
var dy = y - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var power = Math.min(100, distance / 10);
var angle = Math.atan2(-dy, -dx) * (180 / Math.PI);
// Update visual aids
aimLine.setAngle(angle);
aimLine.setLength(distance);
powerMeter.setPower(power);
}
function handleUp(x, y, obj) {
if (!isDragging) {
return;
}
isDragging = false;
aimLine.hide();
powerMeter.hide();
if (!gameActive || ball.moving) {
return;
}
// Calculate launch parameters
var dx = x - startX;
var dy = y - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
// Only launch if the swipe was long enough
if (distance > 20) {
var power = Math.min(100, distance / 10);
var angle = Math.atan2(-dy, -dx) * (180 / Math.PI);
// Launch the ball
ball.launch(power, angle);
shotsUsed++;
// Update UI
var currentLevel = levelManager.getCurrentLevel();
scoreText.setText('Shots: ' + shotsUsed);
}
}
// Attach event handlers
game.down = handleDown;
game.move = handleMove;
game.up = handleUp;
// Main update loop
game.update = function () {
// Check for level completion
if (gameActive && targetsHit === totalTargets) {
// Level completed
gameActive = false;
levelManager.saveScore(levelManager.currentLevel, shotsUsed);
// Show level complete message
var completeText = new Text2('Level Complete!', {
size: 120,
fill: 0xFFFF00
});
completeText.anchor.set(0.5, 0.5);
completeText.x = 1024;
completeText.y = 1366;
game.addChild(completeText);
// Play level complete sound
LK.getSound('levelComplete').play();
// Flash screen for effect
LK.effects.flashScreen(0x33FF33, 1000);
// Advance to next level after delay
LK.setTimeout(function () {
game.removeChild(completeText);
var hasNextLevel = levelManager.advanceLevel();
if (hasNextLevel) {
initializeLevel();
} else {
// Game complete
var gameCompleteText = new Text2('Game Complete!\nCongratulations!', {
size: 100,
fill: 0xFFFF00
});
gameCompleteText.anchor.set(0.5, 0.5);
gameCompleteText.x = 1024;
gameCompleteText.y = 1366;
game.addChild(gameCompleteText);
// Show you win screen
LK.showYouWin();
}
}, 2000);
}
// Removed level failure check based on shot limit
// Update timer
if (gameActive) {
timeRemaining -= 1 / 60; // Decrease time by 1 second every 60 frames
timerText.setText('Time: ' + Math.max(0, Math.floor(timeRemaining)));
if (timeRemaining <= 0) {
// Time expired, end the game
gameActive = false;
LK.showGameOver();
}
}
// Update all game objects
if (ball.moving) {
ball.update();
// Check for collisions with targets
for (var i = 0; i < targets.length; i++) {
if (!targets[i].hit && targets[i].intersects(ball)) {
if (targets[i].onHit()) {
targetsHit++;
}
}
}
// Check for collisions with moving walls
for (var i = 0; i < game.children.length; i++) {
if (game.children[i] instanceof MovingWall) {
if (ball.intersects(game.children[i])) {
ball.bounceOffWall(game.children[i]);
}
}
}
}
// Update targets (for any that have movement)
for (var i = 0; i < targets.length; i++) {
targets[i].update();
}
// Update moving walls
for (var i = 0; i < game.children.length; i++) {
if (game.children[i] instanceof MovingWall) {
game.children[i].update();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -349,10 +349,11 @@
totalTargets = currentLevel.targets.length;
for (var i = 0; i < currentLevel.targets.length; i++) {
var targetData = currentLevel.targets[i];
var target = new Target();
- target.x = targetData.x;
- target.y = targetData.y;
+ // Randomize target position on the upper half of the screen
+ target.x = Math.random() * 2048;
+ target.y = Math.random() * (1366 - target.height / 2);
target.reset();
targets.push(target);
game.addChild(target);
}