User prompt
buat lorong maze sedikit besar
User prompt
kecilkan ukuran maze menjadi setengah
User prompt
besarkan size maze setengah layar
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'toGlobal')' in or related to this line: 'var localPos = game.toLocal(obj.parent.toGlobal(obj.position));' Line Number: 409
Code edit (1 edits merged)
Please save this source code
User prompt
Maze Shooter: Enemy Hunt
Initial prompt
buat game random generation maze. shooter game. kill all enemy. after kill all enemy menuju level selanjutnya
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.directionX = 0;
self.directionY = 0;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.moveTimer = 0;
self.moveDirection = 0; // 0=up, 1=right, 2=down, 3=left
self.speed = 1;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
// Simple AI movement
self.moveTimer++;
if (self.moveTimer > 60) {
self.moveDirection = Math.floor(Math.random() * 4);
self.moveTimer = 0;
}
var newX = self.x;
var newY = self.y;
if (self.moveDirection === 0) newY -= self.speed; // up
else if (self.moveDirection === 1) newX += self.speed; // right
else if (self.moveDirection === 2) newY += self.speed; // down
else if (self.moveDirection === 3) newX -= self.speed; // left
// Check if new position would collide with walls
if (!checkWallCollision(newX, newY)) {
self.x = newX;
self.y = newY;
} else {
self.moveDirection = Math.floor(Math.random() * 4);
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.speed = 3;
self.shootCooldown = 0;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
self.shoot = function (targetX, targetY) {
if (self.shootCooldown > 0) return;
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.directionX = dx / distance;
bullet.directionY = dy / distance;
bullet.lastX = bullet.x;
bullet.lastY = bullet.y;
bullets.push(bullet);
game.addChild(bullet);
self.shootCooldown = 15;
LK.getSound('shoot').play();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Game variables
var player;
var enemies = [];
var bullets = [];
var walls = [];
var currentLevel = 1;
var mazeWidth = 25;
var mazeHeight = 33;
var cellSize = 40;
var maze = [];
// UI elements
var levelText = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var healthText = new Text2('Health: 3', {
size: 50,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
healthText.x = 150;
healthText.y = 20;
LK.gui.topLeft.addChild(healthText);
var enemyCountText = new Text2('Enemies: 0', {
size: 50,
fill: 0xFFFF00
});
enemyCountText.anchor.set(1, 0);
LK.gui.topRight.addChild(enemyCountText);
// Maze generation
function generateMaze() {
// Initialize maze with walls
maze = [];
for (var y = 0; y < mazeHeight; y++) {
maze[y] = [];
for (var x = 0; x < mazeWidth; x++) {
maze[y][x] = 1; // 1 = wall, 0 = floor
}
}
// Simple maze generation - create random paths
function carvePath(x, y) {
maze[y][x] = 0;
var directions = [[0, -2], [2, 0], [0, 2], [-2, 0]];
// Shuffle directions
for (var i = directions.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = directions[i];
directions[i] = directions[j];
directions[j] = temp;
}
for (var i = 0; i < directions.length; i++) {
var nx = x + directions[i][0];
var ny = y + directions[i][1];
if (nx > 0 && nx < mazeWidth - 1 && ny > 0 && ny < mazeHeight - 1 && maze[ny][nx] === 1) {
maze[y + directions[i][1] / 2][x + directions[i][0] / 2] = 0;
carvePath(nx, ny);
}
}
}
// Start carving from top-left area
carvePath(1, 1);
// Add some random openings
for (var i = 0; i < currentLevel * 5; i++) {
var rx = Math.floor(Math.random() * (mazeWidth - 2)) + 1;
var ry = Math.floor(Math.random() * (mazeHeight - 2)) + 1;
maze[ry][rx] = 0;
}
}
function createMazeWalls() {
// Clear existing walls
for (var i = walls.length - 1; i >= 0; i--) {
walls[i].destroy();
}
walls = [];
// Create wall objects
for (var y = 0; y < mazeHeight; y++) {
for (var x = 0; x < mazeWidth; x++) {
if (maze[y][x] === 1) {
var wall = LK.getAsset('wall', {
x: x * cellSize + cellSize / 2,
y: y * cellSize + cellSize / 2,
anchorX: 0.5,
anchorY: 0.5
});
walls.push(wall);
game.addChild(wall);
}
}
}
}
function findFloorPosition() {
var attempts = 0;
while (attempts < 100) {
var x = Math.floor(Math.random() * mazeWidth);
var y = Math.floor(Math.random() * mazeHeight);
if (maze[y][x] === 0) {
return {
x: x * cellSize + cellSize / 2,
y: y * cellSize + cellSize / 2
};
}
attempts++;
}
// Fallback to a guaranteed floor position
return {
x: cellSize + cellSize / 2,
y: cellSize + cellSize / 2
};
}
function checkWallCollision(x, y) {
var gridX = Math.floor(x / cellSize);
var gridY = Math.floor(y / cellSize);
if (gridX < 0 || gridX >= mazeWidth || gridY < 0 || gridY >= mazeHeight) {
return true;
}
return maze[gridY][gridX] === 1;
}
function spawnEnemies() {
// Clear existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
var enemyCount = Math.min(currentLevel + 2, 15);
for (var i = 0; i < enemyCount; i++) {
var pos = findFloorPosition();
var enemy = new Enemy();
enemy.x = pos.x;
enemy.y = pos.y;
enemy.lastX = enemy.x;
enemy.lastY = enemy.y;
enemies.push(enemy);
game.addChild(enemy);
}
updateEnemyCount();
}
function initLevel() {
generateMaze();
createMazeWalls();
// Position player
var playerPos = findFloorPosition();
player.x = playerPos.x;
player.y = playerPos.y;
player.lastX = player.x;
player.lastY = player.y;
spawnEnemies();
levelText.setText('Level: ' + currentLevel);
}
function updateEnemyCount() {
enemyCountText.setText('Enemies: ' + enemies.length);
}
function updateHealthText() {
healthText.setText('Health: ' + player.health);
}
function nextLevel() {
currentLevel++;
// Clear bullets
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].destroy();
bullets.splice(i, 1);
}
initLevel();
}
// Initialize player
player = new Player();
game.addChild(player);
// Initialize first level
initLevel();
updateHealthText();
// Input handling
var moveX = 0;
var moveY = 0;
var isMoving = false;
game.down = function (x, y, obj) {
var localPos = game.toLocal(obj.parent.toGlobal(obj.position));
player.shoot(localPos.x, localPos.y);
};
game.move = function (x, y, obj) {
if (isMoving) {
var localPos = game.toLocal(obj.parent.toGlobal(obj.position));
var targetX = localPos.x;
var targetY = localPos.y;
var dx = targetX - player.x;
var dy = targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 20) {
moveX = dx / distance * player.speed;
moveY = dy / distance * player.speed;
} else {
moveX = 0;
moveY = 0;
}
}
};
game.up = function (x, y, obj) {
isMoving = false;
moveX = 0;
moveY = 0;
};
// Main game loop
game.update = function () {
// Move player
if (moveX !== 0 || moveY !== 0) {
var newX = player.x + moveX;
var newY = player.y + moveY;
if (!checkWallCollision(newX, newY)) {
player.x = newX;
player.y = newY;
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check wall collision
if (checkWallCollision(bullet.x, bullet.y)) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bounds
if (bullet.x < 0 || bullet.x > mazeWidth * cellSize || bullet.y < 0 || bullet.y > mazeHeight * cellSize) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check enemy collision
var hitEnemy = false;
for (var j = enemies.length - 1; j >= 0; j--) {
if (bullet.intersects(enemies[j])) {
LK.getSound('enemyHit').play();
LK.effects.flashObject(enemies[j], 0xffffff, 200);
enemies[j].destroy();
enemies.splice(j, 1);
bullet.destroy();
bullets.splice(i, 1);
hitEnemy = true;
updateEnemyCount();
break;
}
}
if (hitEnemy) continue;
}
// Check player-enemy collision
for (var i = enemies.length - 1; i >= 0; i--) {
if (player.intersects(enemies[i])) {
LK.getSound('playerHit').play();
LK.effects.flashObject(player, 0xff0000, 500);
player.health--;
updateHealthText();
// Move enemy away to prevent multiple hits
enemies[i].x += (Math.random() - 0.5) * 60;
enemies[i].y += (Math.random() - 0.5) * 60;
if (player.health <= 0) {
LK.showGameOver();
return;
}
}
}
// Check win condition
if (enemies.length === 0) {
LK.setTimeout(function () {
nextLevel();
}, 500);
}
};
// Touch/drag controls
game.down = function (x, y, obj) {
isMoving = true;
var localPos = game.toLocal(obj.parent.toGlobal(obj.position));
player.shoot(localPos.x, localPos.y);
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,387 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Bullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.attachAsset('bullet', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 8;
+ self.directionX = 0;
+ self.directionY = 0;
+ self.lastX = 0;
+ self.lastY = 0;
+ self.update = function () {
+ self.lastX = self.x;
+ self.lastY = self.y;
+ self.x += self.directionX * self.speed;
+ self.y += self.directionY * self.speed;
+ };
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ var enemyGraphics = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 1;
+ self.moveTimer = 0;
+ self.moveDirection = 0; // 0=up, 1=right, 2=down, 3=left
+ self.speed = 1;
+ self.lastX = 0;
+ self.lastY = 0;
+ self.update = function () {
+ self.lastX = self.x;
+ self.lastY = self.y;
+ // Simple AI movement
+ self.moveTimer++;
+ if (self.moveTimer > 60) {
+ self.moveDirection = Math.floor(Math.random() * 4);
+ self.moveTimer = 0;
+ }
+ var newX = self.x;
+ var newY = self.y;
+ if (self.moveDirection === 0) newY -= self.speed; // up
+ else if (self.moveDirection === 1) newX += self.speed; // right
+ else if (self.moveDirection === 2) newY += self.speed; // down
+ else if (self.moveDirection === 3) newX -= self.speed; // left
+ // Check if new position would collide with walls
+ if (!checkWallCollision(newX, newY)) {
+ self.x = newX;
+ self.y = newY;
+ } else {
+ self.moveDirection = Math.floor(Math.random() * 4);
+ }
+ };
+ return self;
+});
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ var playerGraphics = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 3;
+ self.speed = 3;
+ self.shootCooldown = 0;
+ self.lastX = 0;
+ self.lastY = 0;
+ self.update = function () {
+ self.lastX = self.x;
+ self.lastY = self.y;
+ if (self.shootCooldown > 0) {
+ self.shootCooldown--;
+ }
+ };
+ self.shoot = function (targetX, targetY) {
+ if (self.shootCooldown > 0) return;
+ var dx = targetX - self.x;
+ var dy = targetY - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > 0) {
+ var bullet = new Bullet();
+ bullet.x = self.x;
+ bullet.y = self.y;
+ bullet.directionX = dx / distance;
+ bullet.directionY = dy / distance;
+ bullet.lastX = bullet.x;
+ bullet.lastY = bullet.y;
+ bullets.push(bullet);
+ game.addChild(bullet);
+ self.shootCooldown = 15;
+ LK.getSound('shoot').play();
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var player;
+var enemies = [];
+var bullets = [];
+var walls = [];
+var currentLevel = 1;
+var mazeWidth = 25;
+var mazeHeight = 33;
+var cellSize = 40;
+var maze = [];
+// UI elements
+var levelText = new Text2('Level: 1', {
+ size: 60,
+ fill: 0xFFFFFF
+});
+levelText.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelText);
+var healthText = new Text2('Health: 3', {
+ size: 50,
+ fill: 0xFF0000
+});
+healthText.anchor.set(0, 0);
+healthText.x = 150;
+healthText.y = 20;
+LK.gui.topLeft.addChild(healthText);
+var enemyCountText = new Text2('Enemies: 0', {
+ size: 50,
+ fill: 0xFFFF00
+});
+enemyCountText.anchor.set(1, 0);
+LK.gui.topRight.addChild(enemyCountText);
+// Maze generation
+function generateMaze() {
+ // Initialize maze with walls
+ maze = [];
+ for (var y = 0; y < mazeHeight; y++) {
+ maze[y] = [];
+ for (var x = 0; x < mazeWidth; x++) {
+ maze[y][x] = 1; // 1 = wall, 0 = floor
+ }
+ }
+ // Simple maze generation - create random paths
+ function carvePath(x, y) {
+ maze[y][x] = 0;
+ var directions = [[0, -2], [2, 0], [0, 2], [-2, 0]];
+ // Shuffle directions
+ for (var i = directions.length - 1; i > 0; i--) {
+ var j = Math.floor(Math.random() * (i + 1));
+ var temp = directions[i];
+ directions[i] = directions[j];
+ directions[j] = temp;
+ }
+ for (var i = 0; i < directions.length; i++) {
+ var nx = x + directions[i][0];
+ var ny = y + directions[i][1];
+ if (nx > 0 && nx < mazeWidth - 1 && ny > 0 && ny < mazeHeight - 1 && maze[ny][nx] === 1) {
+ maze[y + directions[i][1] / 2][x + directions[i][0] / 2] = 0;
+ carvePath(nx, ny);
+ }
+ }
+ }
+ // Start carving from top-left area
+ carvePath(1, 1);
+ // Add some random openings
+ for (var i = 0; i < currentLevel * 5; i++) {
+ var rx = Math.floor(Math.random() * (mazeWidth - 2)) + 1;
+ var ry = Math.floor(Math.random() * (mazeHeight - 2)) + 1;
+ maze[ry][rx] = 0;
+ }
+}
+function createMazeWalls() {
+ // Clear existing walls
+ for (var i = walls.length - 1; i >= 0; i--) {
+ walls[i].destroy();
+ }
+ walls = [];
+ // Create wall objects
+ for (var y = 0; y < mazeHeight; y++) {
+ for (var x = 0; x < mazeWidth; x++) {
+ if (maze[y][x] === 1) {
+ var wall = LK.getAsset('wall', {
+ x: x * cellSize + cellSize / 2,
+ y: y * cellSize + cellSize / 2,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ walls.push(wall);
+ game.addChild(wall);
+ }
+ }
+ }
+}
+function findFloorPosition() {
+ var attempts = 0;
+ while (attempts < 100) {
+ var x = Math.floor(Math.random() * mazeWidth);
+ var y = Math.floor(Math.random() * mazeHeight);
+ if (maze[y][x] === 0) {
+ return {
+ x: x * cellSize + cellSize / 2,
+ y: y * cellSize + cellSize / 2
+ };
+ }
+ attempts++;
+ }
+ // Fallback to a guaranteed floor position
+ return {
+ x: cellSize + cellSize / 2,
+ y: cellSize + cellSize / 2
+ };
+}
+function checkWallCollision(x, y) {
+ var gridX = Math.floor(x / cellSize);
+ var gridY = Math.floor(y / cellSize);
+ if (gridX < 0 || gridX >= mazeWidth || gridY < 0 || gridY >= mazeHeight) {
+ return true;
+ }
+ return maze[gridY][gridX] === 1;
+}
+function spawnEnemies() {
+ // Clear existing enemies
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ enemies[i].destroy();
+ }
+ enemies = [];
+ var enemyCount = Math.min(currentLevel + 2, 15);
+ for (var i = 0; i < enemyCount; i++) {
+ var pos = findFloorPosition();
+ var enemy = new Enemy();
+ enemy.x = pos.x;
+ enemy.y = pos.y;
+ enemy.lastX = enemy.x;
+ enemy.lastY = enemy.y;
+ enemies.push(enemy);
+ game.addChild(enemy);
+ }
+ updateEnemyCount();
+}
+function initLevel() {
+ generateMaze();
+ createMazeWalls();
+ // Position player
+ var playerPos = findFloorPosition();
+ player.x = playerPos.x;
+ player.y = playerPos.y;
+ player.lastX = player.x;
+ player.lastY = player.y;
+ spawnEnemies();
+ levelText.setText('Level: ' + currentLevel);
+}
+function updateEnemyCount() {
+ enemyCountText.setText('Enemies: ' + enemies.length);
+}
+function updateHealthText() {
+ healthText.setText('Health: ' + player.health);
+}
+function nextLevel() {
+ currentLevel++;
+ // Clear bullets
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ bullets[i].destroy();
+ bullets.splice(i, 1);
+ }
+ initLevel();
+}
+// Initialize player
+player = new Player();
+game.addChild(player);
+// Initialize first level
+initLevel();
+updateHealthText();
+// Input handling
+var moveX = 0;
+var moveY = 0;
+var isMoving = false;
+game.down = function (x, y, obj) {
+ var localPos = game.toLocal(obj.parent.toGlobal(obj.position));
+ player.shoot(localPos.x, localPos.y);
+};
+game.move = function (x, y, obj) {
+ if (isMoving) {
+ var localPos = game.toLocal(obj.parent.toGlobal(obj.position));
+ var targetX = localPos.x;
+ var targetY = localPos.y;
+ var dx = targetX - player.x;
+ var dy = targetY - player.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > 20) {
+ moveX = dx / distance * player.speed;
+ moveY = dy / distance * player.speed;
+ } else {
+ moveX = 0;
+ moveY = 0;
+ }
+ }
+};
+game.up = function (x, y, obj) {
+ isMoving = false;
+ moveX = 0;
+ moveY = 0;
+};
+// Main game loop
+game.update = function () {
+ // Move player
+ if (moveX !== 0 || moveY !== 0) {
+ var newX = player.x + moveX;
+ var newY = player.y + moveY;
+ if (!checkWallCollision(newX, newY)) {
+ player.x = newX;
+ player.y = newY;
+ }
+ }
+ // Update bullets
+ for (var i = bullets.length - 1; i >= 0; i--) {
+ var bullet = bullets[i];
+ // Check wall collision
+ if (checkWallCollision(bullet.x, bullet.y)) {
+ bullet.destroy();
+ bullets.splice(i, 1);
+ continue;
+ }
+ // Check bounds
+ if (bullet.x < 0 || bullet.x > mazeWidth * cellSize || bullet.y < 0 || bullet.y > mazeHeight * cellSize) {
+ bullet.destroy();
+ bullets.splice(i, 1);
+ continue;
+ }
+ // Check enemy collision
+ var hitEnemy = false;
+ for (var j = enemies.length - 1; j >= 0; j--) {
+ if (bullet.intersects(enemies[j])) {
+ LK.getSound('enemyHit').play();
+ LK.effects.flashObject(enemies[j], 0xffffff, 200);
+ enemies[j].destroy();
+ enemies.splice(j, 1);
+ bullet.destroy();
+ bullets.splice(i, 1);
+ hitEnemy = true;
+ updateEnemyCount();
+ break;
+ }
+ }
+ if (hitEnemy) continue;
+ }
+ // Check player-enemy collision
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ if (player.intersects(enemies[i])) {
+ LK.getSound('playerHit').play();
+ LK.effects.flashObject(player, 0xff0000, 500);
+ player.health--;
+ updateHealthText();
+ // Move enemy away to prevent multiple hits
+ enemies[i].x += (Math.random() - 0.5) * 60;
+ enemies[i].y += (Math.random() - 0.5) * 60;
+ if (player.health <= 0) {
+ LK.showGameOver();
+ return;
+ }
+ }
+ }
+ // Check win condition
+ if (enemies.length === 0) {
+ LK.setTimeout(function () {
+ nextLevel();
+ }, 500);
+ }
+};
+// Touch/drag controls
+game.down = function (x, y, obj) {
+ isMoving = true;
+ var localPos = game.toLocal(obj.parent.toGlobal(obj.position));
+ player.shoot(localPos.x, localPos.y);
+};
\ No newline at end of file
2d big size side scroller wild warthog image. In-Game asset. 2d. High contrast. No shadows
2d hroizontal sidescroller average year country man is the hunter. holld shootgun and ready shoot. In-Game asset. 2d. High contrast. No shadows
2d side scroller anime green bushs asset. In-Game asset. 2d. High contrast. No shadows