User prompt
add back ground asset
User prompt
buat bola jatuh sesuai gaya gravitasi
User prompt
make realistik βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat pergerakkan ball halus βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
ball jangan bergetar
User prompt
buat pantulan diding maze lemah
User prompt
buat bola tidak berat agar bisa melayang
User prompt
buat ball terlihat berat dan tidak ada animasi getaran βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
perbaiko musik background
User prompt
jangan buat bola bergetar. buat kaku bulat
User prompt
buat bola terlihat solid dan berat βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat black hole harus berada dalam maze jangan di luar maze
User prompt
buat bola berat pantulan βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
buat bola tidak bisa ke luar jalur
User prompt
posisikan black hold di dalam jalur
User prompt
buat control tap. tap layar kiri mantul ke kiri. tap layar tengah pantul vertikal. tap layar kanan mantul ke kanan.
User prompt
black hole diletakkan di ujung jalur maze paling bawah
User prompt
black hold selalu di tempat paling bawah
User prompt
tap untuk loncat memantul
User prompt
buat maze yang bagus
Code edit (1 edits merged)
Please save this source code
User prompt
Bounce Quest: Dynamic Maze Runner
Initial prompt
buat game control tap. tap bola pantul dalam labirinth acak yang berubah setiap satu menit. sebagai player mencari lubang hitam untuk finish game.
/****
* Plugins
****/
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.5;
self.friction = 0.98;
self.bounceForce = 0.8;
self.maxSpeed = 15;
self.update = function () {
// Apply gravity
self.velocityY += self.gravity;
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
// Limit max speed
var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (speed > self.maxSpeed) {
self.velocityX = self.velocityX / speed * self.maxSpeed;
self.velocityY = self.velocityY / speed * self.maxSpeed;
}
// Update position
self.x += self.velocityX;
self.y += self.velocityY;
// Check maze boundaries and collisions
checkBallCollisions();
};
self.addForce = function (forceX, forceY) {
self.velocityX += forceX;
self.velocityY += forceY;
};
return self;
});
var MazeCell = Container.expand(function (cellType) {
var self = Container.call(this);
self.cellType = cellType || 'wall';
var cellGraphics;
if (self.cellType === 'wall') {
cellGraphics = self.attachAsset('wall', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.cellType === 'path') {
cellGraphics = self.attachAsset('path', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (self.cellType === 'blackhole') {
cellGraphics = self.attachAsset('blackhole', {
anchorX: 0.5,
anchorY: 0.5
});
}
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
var ball;
var maze = [];
var mazeWidth = 20;
var mazeHeight = 30;
var cellSize = 60;
var mazeContainer;
var blackholeX, blackholeY;
var timeLeft = 60;
var gameWon = false;
// UI Elements
var timerText = new Text2('60', {
size: 80,
fill: 0xFFFFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
var scoreText = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 150;
scoreText.y = 20;
LK.gui.topLeft.addChild(scoreText);
// Initialize maze container
mazeContainer = game.addChild(new Container());
mazeContainer.x = (2048 - mazeWidth * cellSize) / 2;
mazeContainer.y = (2732 - mazeHeight * cellSize) / 2;
// Generate initial maze
function generateMaze() {
// Clear existing maze
for (var i = 0; i < maze.length; i++) {
for (var j = 0; j < maze[i].length; j++) {
if (maze[i][j]) {
maze[i][j].destroy();
}
}
}
maze = [];
// Initialize maze with walls
for (var y = 0; y < mazeHeight; y++) {
maze[y] = [];
for (var x = 0; x < mazeWidth; x++) {
maze[y][x] = null;
}
}
// Create simple maze pattern with random paths
for (var y = 0; y < mazeHeight; y++) {
for (var x = 0; x < mazeWidth; x++) {
var cellType = 'wall';
// Create borders
if (x === 0 || x === mazeWidth - 1 || y === 0 || y === mazeHeight - 1) {
cellType = 'wall';
}
// Create random paths
else if (Math.random() < 0.4) {
cellType = 'path';
}
var cell = new MazeCell(cellType);
cell.x = x * cellSize + cellSize / 2;
cell.y = y * cellSize + cellSize / 2;
maze[y][x] = cell;
mazeContainer.addChild(cell);
}
}
// Ensure there's a path from start to end
createPath();
// Place black hole exit
placeBlackHole();
}
function createPath() {
// Create a guaranteed path from top to bottom
var currentX = Math.floor(mazeWidth / 2);
for (var y = 1; y < mazeHeight - 1; y++) {
// Clear current position
maze[y][currentX].destroy();
var newCell = new MazeCell('path');
newCell.x = currentX * cellSize + cellSize / 2;
newCell.y = y * cellSize + cellSize / 2;
maze[y][currentX] = newCell;
mazeContainer.addChild(newCell);
// Randomly branch left or right
if (Math.random() < 0.3) {
var branchDir = Math.random() < 0.5 ? -1 : 1;
var branchX = currentX + branchDir;
if (branchX > 0 && branchX < mazeWidth - 1) {
maze[y][branchX].destroy();
var branchCell = new MazeCell('path');
branchCell.x = branchX * cellSize + cellSize / 2;
branchCell.y = y * cellSize + cellSize / 2;
maze[y][branchX] = branchCell;
mazeContainer.addChild(branchCell);
}
}
// Randomly change direction
if (Math.random() < 0.3) {
var newDir = Math.random() < 0.5 ? -1 : 1;
var newX = currentX + newDir;
if (newX > 0 && newX < mazeWidth - 1) {
currentX = newX;
}
}
}
}
function placeBlackHole() {
// Find all path cells in bottom half
var pathCells = [];
for (var y = Math.floor(mazeHeight / 2); y < mazeHeight - 1; y++) {
for (var x = 1; x < mazeWidth - 1; x++) {
if (maze[y][x].cellType === 'path') {
pathCells.push({
x: x,
y: y
});
}
}
}
if (pathCells.length > 0) {
var randomPath = pathCells[Math.floor(Math.random() * pathCells.length)];
blackholeX = randomPath.x;
blackholeY = randomPath.y;
// Replace path with black hole
maze[blackholeY][blackholeX].destroy();
var blackhole = new MazeCell('blackhole');
blackhole.x = blackholeX * cellSize + cellSize / 2;
blackhole.y = blackholeY * cellSize + cellSize / 2;
maze[blackholeY][blackholeX] = blackhole;
mazeContainer.addChild(blackhole);
}
}
function checkBallCollisions() {
var ballMazeX = Math.floor((ball.x - mazeContainer.x) / cellSize);
var ballMazeY = Math.floor((ball.y - mazeContainer.y) / cellSize);
// Check bounds
if (ballMazeX < 0 || ballMazeX >= mazeWidth || ballMazeY < 0 || ballMazeY >= mazeHeight) {
// Bounce off screen edges
if (ball.x < mazeContainer.x) {
ball.x = mazeContainer.x;
ball.velocityX = Math.abs(ball.velocityX) * ball.bounceForce;
}
if (ball.x > mazeContainer.x + mazeWidth * cellSize) {
ball.x = mazeContainer.x + mazeWidth * cellSize;
ball.velocityX = -Math.abs(ball.velocityX) * ball.bounceForce;
}
if (ball.y < mazeContainer.y) {
ball.y = mazeContainer.y;
ball.velocityY = Math.abs(ball.velocityY) * ball.bounceForce;
}
if (ball.y > mazeContainer.y + mazeHeight * cellSize) {
ball.y = mazeContainer.y + mazeHeight * cellSize;
ball.velocityY = -Math.abs(ball.velocityY) * ball.bounceForce;
}
return;
}
var currentCell = maze[ballMazeY][ballMazeX];
if (currentCell && currentCell.cellType === 'wall') {
// Bounce off wall
var cellCenterX = mazeContainer.x + ballMazeX * cellSize + cellSize / 2;
var cellCenterY = mazeContainer.y + ballMazeY * cellSize + cellSize / 2;
var deltaX = ball.x - cellCenterX;
var deltaY = ball.y - cellCenterY;
if (Math.abs(deltaX) > Math.abs(deltaY)) {
ball.velocityX = deltaX > 0 ? Math.abs(ball.velocityX) * ball.bounceForce : -Math.abs(ball.velocityX) * ball.bounceForce;
ball.x = cellCenterX + (deltaX > 0 ? cellSize / 2 + 20 : -cellSize / 2 - 20);
} else {
ball.velocityY = deltaY > 0 ? Math.abs(ball.velocityY) * ball.bounceForce : -Math.abs(ball.velocityY) * ball.bounceForce;
ball.y = cellCenterY + (deltaY > 0 ? cellSize / 2 + 20 : -cellSize / 2 - 20);
}
LK.getSound('bounce').play();
} else if (currentCell && currentCell.cellType === 'blackhole') {
// Check if ball is close enough to black hole center
var blackholeCenterX = mazeContainer.x + blackholeX * cellSize + cellSize / 2;
var blackholeCenterY = mazeContainer.y + blackholeY * cellSize + cellSize / 2;
var distance = Math.sqrt(Math.pow(ball.x - blackholeCenterX, 2) + Math.pow(ball.y - blackholeCenterY, 2));
if (distance < 30 && !gameWon) {
gameWon = true;
LK.getSound('win').play();
LK.setScore(LK.getScore() + 1);
scoreText.setText('Level: ' + (LK.getScore() + 1));
// Flash effect
LK.effects.flashScreen(0x00ff00, 1000);
// Reset for next level
LK.setTimeout(function () {
resetLevel();
}, 1000);
}
}
}
function resetLevel() {
gameWon = false;
timeLeft = 60;
// Reset ball position
ball.x = mazeContainer.x + cellSize * 1.5;
ball.y = mazeContainer.y + cellSize * 1.5;
ball.velocityX = 0;
ball.velocityY = 0;
// Generate new maze
generateMaze();
}
// Initialize ball
ball = game.addChild(new Ball());
ball.x = mazeContainer.x + cellSize * 1.5;
ball.y = mazeContainer.y + cellSize * 1.5;
// Touch controls
game.down = function (x, y, obj) {
if (gameWon) return;
// Calculate direction from ball to touch point
var deltaX = x - ball.x;
var deltaY = y - ball.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 0) {
// Normalize and apply force
var forceMultiplier = 8;
ball.addForce(deltaX / distance * forceMultiplier, deltaY / distance * forceMultiplier);
}
};
// Generate initial maze
generateMaze();
// Timer countdown
var timerInterval = LK.setInterval(function () {
if (gameWon) return;
timeLeft--;
timerText.setText(timeLeft.toString());
if (timeLeft <= 0) {
timeLeft = 60;
generateMaze();
timerText.setText('60');
// Flash red to indicate maze change
LK.effects.flashScreen(0xff0000, 500);
}
}, 1000);
game.update = function () {
// Game updates are handled by individual object update methods
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,311 @@
-/****
+/****
+* Plugins
+****/
+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.5;
+ self.friction = 0.98;
+ self.bounceForce = 0.8;
+ self.maxSpeed = 15;
+ self.update = function () {
+ // Apply gravity
+ self.velocityY += self.gravity;
+ // Apply friction
+ self.velocityX *= self.friction;
+ self.velocityY *= self.friction;
+ // Limit max speed
+ var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
+ if (speed > self.maxSpeed) {
+ self.velocityX = self.velocityX / speed * self.maxSpeed;
+ self.velocityY = self.velocityY / speed * self.maxSpeed;
+ }
+ // Update position
+ self.x += self.velocityX;
+ self.y += self.velocityY;
+ // Check maze boundaries and collisions
+ checkBallCollisions();
+ };
+ self.addForce = function (forceX, forceY) {
+ self.velocityX += forceX;
+ self.velocityY += forceY;
+ };
+ return self;
+});
+var MazeCell = Container.expand(function (cellType) {
+ var self = Container.call(this);
+ self.cellType = cellType || 'wall';
+ var cellGraphics;
+ if (self.cellType === 'wall') {
+ cellGraphics = self.attachAsset('wall', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (self.cellType === 'path') {
+ cellGraphics = self.attachAsset('path', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ } else if (self.cellType === 'blackhole') {
+ cellGraphics = self.attachAsset('blackhole', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ }
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+var ball;
+var maze = [];
+var mazeWidth = 20;
+var mazeHeight = 30;
+var cellSize = 60;
+var mazeContainer;
+var blackholeX, blackholeY;
+var timeLeft = 60;
+var gameWon = false;
+// UI Elements
+var timerText = new Text2('60', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+timerText.anchor.set(0.5, 0);
+LK.gui.top.addChild(timerText);
+var scoreText = new Text2('Level: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0, 0);
+scoreText.x = 150;
+scoreText.y = 20;
+LK.gui.topLeft.addChild(scoreText);
+// Initialize maze container
+mazeContainer = game.addChild(new Container());
+mazeContainer.x = (2048 - mazeWidth * cellSize) / 2;
+mazeContainer.y = (2732 - mazeHeight * cellSize) / 2;
+// Generate initial maze
+function generateMaze() {
+ // Clear existing maze
+ for (var i = 0; i < maze.length; i++) {
+ for (var j = 0; j < maze[i].length; j++) {
+ if (maze[i][j]) {
+ maze[i][j].destroy();
+ }
+ }
+ }
+ maze = [];
+ // Initialize maze with walls
+ for (var y = 0; y < mazeHeight; y++) {
+ maze[y] = [];
+ for (var x = 0; x < mazeWidth; x++) {
+ maze[y][x] = null;
+ }
+ }
+ // Create simple maze pattern with random paths
+ for (var y = 0; y < mazeHeight; y++) {
+ for (var x = 0; x < mazeWidth; x++) {
+ var cellType = 'wall';
+ // Create borders
+ if (x === 0 || x === mazeWidth - 1 || y === 0 || y === mazeHeight - 1) {
+ cellType = 'wall';
+ }
+ // Create random paths
+ else if (Math.random() < 0.4) {
+ cellType = 'path';
+ }
+ var cell = new MazeCell(cellType);
+ cell.x = x * cellSize + cellSize / 2;
+ cell.y = y * cellSize + cellSize / 2;
+ maze[y][x] = cell;
+ mazeContainer.addChild(cell);
+ }
+ }
+ // Ensure there's a path from start to end
+ createPath();
+ // Place black hole exit
+ placeBlackHole();
+}
+function createPath() {
+ // Create a guaranteed path from top to bottom
+ var currentX = Math.floor(mazeWidth / 2);
+ for (var y = 1; y < mazeHeight - 1; y++) {
+ // Clear current position
+ maze[y][currentX].destroy();
+ var newCell = new MazeCell('path');
+ newCell.x = currentX * cellSize + cellSize / 2;
+ newCell.y = y * cellSize + cellSize / 2;
+ maze[y][currentX] = newCell;
+ mazeContainer.addChild(newCell);
+ // Randomly branch left or right
+ if (Math.random() < 0.3) {
+ var branchDir = Math.random() < 0.5 ? -1 : 1;
+ var branchX = currentX + branchDir;
+ if (branchX > 0 && branchX < mazeWidth - 1) {
+ maze[y][branchX].destroy();
+ var branchCell = new MazeCell('path');
+ branchCell.x = branchX * cellSize + cellSize / 2;
+ branchCell.y = y * cellSize + cellSize / 2;
+ maze[y][branchX] = branchCell;
+ mazeContainer.addChild(branchCell);
+ }
+ }
+ // Randomly change direction
+ if (Math.random() < 0.3) {
+ var newDir = Math.random() < 0.5 ? -1 : 1;
+ var newX = currentX + newDir;
+ if (newX > 0 && newX < mazeWidth - 1) {
+ currentX = newX;
+ }
+ }
+ }
+}
+function placeBlackHole() {
+ // Find all path cells in bottom half
+ var pathCells = [];
+ for (var y = Math.floor(mazeHeight / 2); y < mazeHeight - 1; y++) {
+ for (var x = 1; x < mazeWidth - 1; x++) {
+ if (maze[y][x].cellType === 'path') {
+ pathCells.push({
+ x: x,
+ y: y
+ });
+ }
+ }
+ }
+ if (pathCells.length > 0) {
+ var randomPath = pathCells[Math.floor(Math.random() * pathCells.length)];
+ blackholeX = randomPath.x;
+ blackholeY = randomPath.y;
+ // Replace path with black hole
+ maze[blackholeY][blackholeX].destroy();
+ var blackhole = new MazeCell('blackhole');
+ blackhole.x = blackholeX * cellSize + cellSize / 2;
+ blackhole.y = blackholeY * cellSize + cellSize / 2;
+ maze[blackholeY][blackholeX] = blackhole;
+ mazeContainer.addChild(blackhole);
+ }
+}
+function checkBallCollisions() {
+ var ballMazeX = Math.floor((ball.x - mazeContainer.x) / cellSize);
+ var ballMazeY = Math.floor((ball.y - mazeContainer.y) / cellSize);
+ // Check bounds
+ if (ballMazeX < 0 || ballMazeX >= mazeWidth || ballMazeY < 0 || ballMazeY >= mazeHeight) {
+ // Bounce off screen edges
+ if (ball.x < mazeContainer.x) {
+ ball.x = mazeContainer.x;
+ ball.velocityX = Math.abs(ball.velocityX) * ball.bounceForce;
+ }
+ if (ball.x > mazeContainer.x + mazeWidth * cellSize) {
+ ball.x = mazeContainer.x + mazeWidth * cellSize;
+ ball.velocityX = -Math.abs(ball.velocityX) * ball.bounceForce;
+ }
+ if (ball.y < mazeContainer.y) {
+ ball.y = mazeContainer.y;
+ ball.velocityY = Math.abs(ball.velocityY) * ball.bounceForce;
+ }
+ if (ball.y > mazeContainer.y + mazeHeight * cellSize) {
+ ball.y = mazeContainer.y + mazeHeight * cellSize;
+ ball.velocityY = -Math.abs(ball.velocityY) * ball.bounceForce;
+ }
+ return;
+ }
+ var currentCell = maze[ballMazeY][ballMazeX];
+ if (currentCell && currentCell.cellType === 'wall') {
+ // Bounce off wall
+ var cellCenterX = mazeContainer.x + ballMazeX * cellSize + cellSize / 2;
+ var cellCenterY = mazeContainer.y + ballMazeY * cellSize + cellSize / 2;
+ var deltaX = ball.x - cellCenterX;
+ var deltaY = ball.y - cellCenterY;
+ if (Math.abs(deltaX) > Math.abs(deltaY)) {
+ ball.velocityX = deltaX > 0 ? Math.abs(ball.velocityX) * ball.bounceForce : -Math.abs(ball.velocityX) * ball.bounceForce;
+ ball.x = cellCenterX + (deltaX > 0 ? cellSize / 2 + 20 : -cellSize / 2 - 20);
+ } else {
+ ball.velocityY = deltaY > 0 ? Math.abs(ball.velocityY) * ball.bounceForce : -Math.abs(ball.velocityY) * ball.bounceForce;
+ ball.y = cellCenterY + (deltaY > 0 ? cellSize / 2 + 20 : -cellSize / 2 - 20);
+ }
+ LK.getSound('bounce').play();
+ } else if (currentCell && currentCell.cellType === 'blackhole') {
+ // Check if ball is close enough to black hole center
+ var blackholeCenterX = mazeContainer.x + blackholeX * cellSize + cellSize / 2;
+ var blackholeCenterY = mazeContainer.y + blackholeY * cellSize + cellSize / 2;
+ var distance = Math.sqrt(Math.pow(ball.x - blackholeCenterX, 2) + Math.pow(ball.y - blackholeCenterY, 2));
+ if (distance < 30 && !gameWon) {
+ gameWon = true;
+ LK.getSound('win').play();
+ LK.setScore(LK.getScore() + 1);
+ scoreText.setText('Level: ' + (LK.getScore() + 1));
+ // Flash effect
+ LK.effects.flashScreen(0x00ff00, 1000);
+ // Reset for next level
+ LK.setTimeout(function () {
+ resetLevel();
+ }, 1000);
+ }
+ }
+}
+function resetLevel() {
+ gameWon = false;
+ timeLeft = 60;
+ // Reset ball position
+ ball.x = mazeContainer.x + cellSize * 1.5;
+ ball.y = mazeContainer.y + cellSize * 1.5;
+ ball.velocityX = 0;
+ ball.velocityY = 0;
+ // Generate new maze
+ generateMaze();
+}
+// Initialize ball
+ball = game.addChild(new Ball());
+ball.x = mazeContainer.x + cellSize * 1.5;
+ball.y = mazeContainer.y + cellSize * 1.5;
+// Touch controls
+game.down = function (x, y, obj) {
+ if (gameWon) return;
+ // Calculate direction from ball to touch point
+ var deltaX = x - ball.x;
+ var deltaY = y - ball.y;
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ if (distance > 0) {
+ // Normalize and apply force
+ var forceMultiplier = 8;
+ ball.addForce(deltaX / distance * forceMultiplier, deltaY / distance * forceMultiplier);
+ }
+};
+// Generate initial maze
+generateMaze();
+// Timer countdown
+var timerInterval = LK.setInterval(function () {
+ if (gameWon) return;
+ timeLeft--;
+ timerText.setText(timeLeft.toString());
+ if (timeLeft <= 0) {
+ timeLeft = 60;
+ generateMaze();
+ timerText.setText('60');
+ // Flash red to indicate maze change
+ LK.effects.flashScreen(0xff0000, 500);
+ }
+}, 1000);
+game.update = function () {
+ // Game updates are handled by individual object update methods
+};
\ No newline at end of file
lubang warp penuh warna. In-Game asset. 2d. High contrast. No shadows
warna pink dinding In-Game asset. 2d. High contrast. No shadows
bola penuh hitam. In-Game asset. 2d. High contrast. No shadows
malam bulan purnama diatas hutan dataran tinggi. di kejauhan nampak kota di malam hari. In-Game asset. 2d. High contrast. No shadows