User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(effect).to({' Line Number: 172
User prompt
Make the zombies be able to kill you and then add a jump scare.
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(effect).to({' Line Number: 170
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'to')' in or related to this line: 'tween(effect).to({' Line Number: 169
User prompt
Please fix the bug: 'TypeError: tween.to is not a function' in or related to this line: 'tween.to(effect, {' Line Number: 169
User prompt
Make a golden zombie segment
User prompt
Make sure the monsters can move around and also make them follow you and try and kill you.
User prompt
Add the skeleton, and the golden zombie, and the golden skeleton.
User prompt
Make the maze a lot harder
User prompt
Add the monsters back in
User prompt
i can't move can you like do it where like you when you tap on the place it moves to that place
User prompt
Make a way to move, please!
User prompt
Make it a maze instead of that. It's a big maze and the character moves through the maze and cannot pass through walls.
Code edit (1 edits merged)
Please save this source code
User prompt
Monster Mash: Undead Defense
User prompt
Monsters are the zombie, the skeleton, the golden zombie, the golden skeleton.
Initial prompt
It was like the first game but with a higher difficulty and also more monsters.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Initialize Game ****/ // No classes needed for maze logic var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; // Maze configuration // 0 = empty, 1 = wall, 2 = start, 3 = goal // Each cell is 128x128 px, so 16x21 grid fits in 2048x2688 var MAZE_CELL_SIZE = 128; var MAZE_COLS = 16; var MAZE_ROWS = 21; // Example maze: outer walls, a few inner walls, start at (1,1), goal at (14,19) var maze = []; for (var y = 0; y < MAZE_ROWS; y++) { maze[y] = []; for (var x = 0; x < MAZE_COLS; x++) { if (y === 0 || y === MAZE_ROWS - 1 || x === 0 || x === MAZE_COLS - 1) { maze[y][x] = 1; // border wall } else { maze[y][x] = 0; // empty } } } // Add some inner walls (example pattern) for (var i = 2; i < 14; i++) { maze[3][i] = 1; maze[7][i] = 1; maze[12][i] = 1; maze[16][i] = 1; } maze[1][1] = 2; // start maze[19][14] = 3; // goal // Score display var scoreTxt = new Text2('0', { size: 120, fill: 0xFFF700 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Draw maze walls var wallNodes = []; for (var y = 0; y < MAZE_ROWS; y++) { for (var x = 0; x < MAZE_COLS; x++) { if (maze[y][x] === 1) { var wall = LK.getAsset('base', { anchorX: 0.5, anchorY: 0.5, x: x * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2, y: y * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2, width: MAZE_CELL_SIZE, height: MAZE_CELL_SIZE }); wallNodes.push(wall); game.addChild(wall); } if (maze[y][x] === 3) { // Goal marker var goalNode = LK.getAsset('goldenZombie', { anchorX: 0.5, anchorY: 0.5, x: x * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2, y: y * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2, width: MAZE_CELL_SIZE, height: MAZE_CELL_SIZE }); game.addChild(goalNode); } } } // Character var charNode = LK.getAsset('zombie', { anchorX: 0.5, anchorY: 0.5, width: MAZE_CELL_SIZE * 0.8, height: MAZE_CELL_SIZE * 0.8 }); game.addChild(charNode); // Find start position var charCol = 1, charRow = 1; for (var y = 0; y < MAZE_ROWS; y++) { for (var x = 0; x < MAZE_COLS; x++) { if (maze[y][x] === 2) { charCol = x; charRow = y; } } } charNode.x = charCol * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2; charNode.y = charRow * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2; // Movement state var moveTargetCol = charCol; var moveTargetRow = charRow; var isMoving = false; var moveSpeed = 16; // px per frame // Touch/drag movement: tap or drag to adjacent cell function getCellFromPos(x, y) { var col = Math.floor(x / MAZE_CELL_SIZE); var row = Math.floor(y / MAZE_CELL_SIZE); return { col: col, row: row }; } game.down = function (x, y, obj) { var cell = getCellFromPos(x, y); // Only allow move to adjacent cell (no diagonals) var dx = cell.col - charCol; var dy = cell.row - charRow; if (Math.abs(dx) === 1 && dy === 0 || Math.abs(dy) === 1 && dx === 0) { // Check wall if (maze[cell.row] && maze[cell.row][cell.col] !== 1) { moveTargetCol = cell.col; moveTargetRow = cell.row; isMoving = true; } } }; game.move = function (x, y, obj) { // Optional: allow drag to move, same as tap game.down(x, y, obj); }; game.up = function (x, y, obj) { // No-op }; game.update = function () { // Move character toward target cell var targetX = moveTargetCol * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2; var targetY = moveTargetRow * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2; var dx = targetX - charNode.x; var dy = targetY - charNode.y; var dist = Math.sqrt(dx * dx + dy * dy); if (isMoving && dist > 2) { var step = Math.min(moveSpeed, dist); charNode.x += dx / dist * step; charNode.y += dy / dist * step; } else if (isMoving) { // Snap to cell charNode.x = targetX; charNode.y = targetY; charCol = moveTargetCol; charRow = moveTargetRow; isMoving = false; // Check for goal if (maze[charRow][charCol] === 3) { LK.effects.flashScreen(0x00ff00, 800); LK.showYouWin(); } } };
===================================================================
--- original.js
+++ change.js
@@ -3,324 +3,162 @@
****/
var tween = LK.import("@upit/tween.v1");
/****
-* Classes
-****/
-// Attack Effect (visual feedback)
-var AttackEffect = Container.expand(function () {
- var self = Container.call(this);
- var eff = self.attachAsset('attackEffect', {
- anchorX: 0.5,
- anchorY: 0.5,
- alpha: 0.7
- });
- self.alpha = 0.7;
- self.scaleX = 0.7;
- self.scaleY = 0.7;
- tween(self, {
- alpha: 0,
- scaleX: 1.5,
- scaleY: 1.5
- }, {
- duration: 250,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- self.destroy();
- }
- });
- return self;
-});
-// Monster base class
-var Monster = Container.expand(function () {
- var self = Container.call(this);
- self.type = 'monster';
- self.hp = 1;
- self.speed = 2;
- self.scoreValue = 1;
- self.isGolden = false;
- self.isDead = false;
- self.asset = null; // Will be set by subclasses
- self.update = function () {
- if (self.isDead) return;
- self.y += self.speed;
- };
- self.takeHit = function () {
- if (self.isDead) return;
- self.hp--;
- LK.getSound('hit').play();
- if (self.hp <= 0) {
- self.die();
- } else {
- // Flash red
- LK.effects.flashObject(self, 0xff0000, 200);
- }
- };
- self.die = function () {
- if (self.isDead) return;
- self.isDead = true;
- if (self.isGolden) {
- LK.getSound('goldenDie').play();
- } else {
- LK.getSound('monsterDie').play();
- }
- // Animate fade out and scale up
- tween(self, {
- alpha: 0,
- scaleX: 1.5,
- scaleY: 1.5
- }, {
- duration: 300,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- self.destroy();
- }
- });
- };
- return self;
-});
-// Zombie
-var Zombie = Monster.expand(function () {
- var self = Monster.call(this);
- self.asset = self.attachAsset('zombie', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.hp = 2;
- self.speed = 2 + Math.random() * 1.5;
- self.scoreValue = 1;
- self.isGolden = false;
- return self;
-});
-// Skeleton
-var Skeleton = Monster.expand(function () {
- var self = Monster.call(this);
- self.asset = self.attachAsset('skeleton', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.hp = 1;
- self.speed = 3 + Math.random() * 2;
- self.scoreValue = 2;
- self.isGolden = false;
- return self;
-});
-// Golden Zombie
-var GoldenZombie = Monster.expand(function () {
- var self = Monster.call(this);
- self.asset = self.attachAsset('goldenZombie', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.hp = 5;
- self.speed = 2.2 + Math.random() * 1.2;
- self.scoreValue = 10;
- self.isGolden = true;
- return self;
-});
-// Golden Skeleton
-var GoldenSkeleton = Monster.expand(function () {
- var self = Monster.call(this);
- self.asset = self.attachAsset('goldenSkeleton', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.hp = 3;
- self.speed = 4 + Math.random() * 1.5;
- self.scoreValue = 12;
- self.isGolden = true;
- return self;
-});
-
-/****
* Initialize Game
****/
+// No classes needed for maze logic
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
-// Zombies, skeletons, and their golden variants
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
-var BASE_Y = GAME_HEIGHT - 180;
-var MONSTER_SPAWN_X_MIN = 180;
-var MONSTER_SPAWN_X_MAX = GAME_WIDTH - 180;
-var MONSTER_SPAWN_Y = -120;
-// Game state
-var monsters = [];
-var wave = 1;
-var monstersToSpawn = 5;
-var monstersSpawned = 0;
-var monstersDefeated = 0;
-var spawnTimer = 0;
-var spawnInterval = 60; // frames
-var isSpawning = true;
-var base = null;
-var scoreTxt = null;
-var waveTxt = null;
-var dragAttack = false;
-var lastAttackX = null;
-var lastAttackY = null;
-// Add base
-base = game.addChild(LK.getAsset('base', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: GAME_WIDTH / 2,
- y: BASE_Y
-}));
+// Maze configuration
+// 0 = empty, 1 = wall, 2 = start, 3 = goal
+// Each cell is 128x128 px, so 16x21 grid fits in 2048x2688
+var MAZE_CELL_SIZE = 128;
+var MAZE_COLS = 16;
+var MAZE_ROWS = 21;
+// Example maze: outer walls, a few inner walls, start at (1,1), goal at (14,19)
+var maze = [];
+for (var y = 0; y < MAZE_ROWS; y++) {
+ maze[y] = [];
+ for (var x = 0; x < MAZE_COLS; x++) {
+ if (y === 0 || y === MAZE_ROWS - 1 || x === 0 || x === MAZE_COLS - 1) {
+ maze[y][x] = 1; // border wall
+ } else {
+ maze[y][x] = 0; // empty
+ }
+ }
+}
+// Add some inner walls (example pattern)
+for (var i = 2; i < 14; i++) {
+ maze[3][i] = 1;
+ maze[7][i] = 1;
+ maze[12][i] = 1;
+ maze[16][i] = 1;
+}
+maze[1][1] = 2; // start
+maze[19][14] = 3; // goal
// Score display
-scoreTxt = new Text2('0', {
+var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFF700
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
-// Wave display
-waveTxt = new Text2('Wave 1', {
- size: 70,
- fill: 0xFFFFFF
-});
-waveTxt.anchor.set(0.5, 0);
-LK.gui.top.addChild(waveTxt);
-waveTxt.y = 120;
-// Helper: spawn a monster
-function spawnMonster() {
- var monsterType;
- var goldenChance = Math.max(0, (wave - 2) * 0.08); // Golden monsters appear more often in later waves
- var r = Math.random();
- if (r < goldenChance / 2) {
- monsterType = 'goldenSkeleton';
- } else if (r < goldenChance) {
- monsterType = 'goldenZombie';
- } else if (Math.random() < 0.5) {
- monsterType = 'zombie';
- } else {
- monsterType = 'skeleton';
- }
- var m;
- if (monsterType === 'zombie') {
- m = new Zombie();
- } else if (monsterType === 'skeleton') {
- m = new Skeleton();
- } else if (monsterType === 'goldenZombie') {
- m = new GoldenZombie();
- } else {
- m = new GoldenSkeleton();
- }
- m.x = MONSTER_SPAWN_X_MIN + Math.random() * (MONSTER_SPAWN_X_MAX - MONSTER_SPAWN_X_MIN);
- m.y = MONSTER_SPAWN_Y;
- m.lastY = m.y;
- m.lastIntersectingBase = false;
- m.lastIntersectingAttack = false;
- monsters.push(m);
- game.addChild(m);
- monstersSpawned++;
-}
-// Helper: start next wave
-function startNextWave() {
- wave++;
- monstersToSpawn = 5 + Math.floor(wave * 1.5);
- monstersSpawned = 0;
- monstersDefeated = 0;
- spawnInterval = Math.max(24, 60 - wave * 3);
- isSpawning = true;
- waveTxt.setText('Wave ' + wave);
-}
-// Helper: handle attack at (x, y)
-function handleAttack(x, y) {
- // Visual effect
- var eff = new AttackEffect();
- eff.x = x;
- eff.y = y;
- game.addChild(eff);
- // Check for monsters hit
- for (var i = monsters.length - 1; i >= 0; i--) {
- var m = monsters[i];
- if (m.isDead) continue;
- // Simple hitbox: if tap/drag is within 90px of monster center
- var dx = m.x - x;
- var dy = m.y - y;
- if (dx * dx + dy * dy < 90 * 90) {
- m.takeHit();
- if (m.hp <= 0) {
- LK.setScore(LK.getScore() + m.scoreValue);
- scoreTxt.setText(LK.getScore());
- monstersDefeated++;
- }
- break; // Only hit one monster per attack
+// Draw maze walls
+var wallNodes = [];
+for (var y = 0; y < MAZE_ROWS; y++) {
+ for (var x = 0; x < MAZE_COLS; x++) {
+ if (maze[y][x] === 1) {
+ var wall = LK.getAsset('base', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: x * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2,
+ y: y * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2,
+ width: MAZE_CELL_SIZE,
+ height: MAZE_CELL_SIZE
+ });
+ wallNodes.push(wall);
+ game.addChild(wall);
}
+ if (maze[y][x] === 3) {
+ // Goal marker
+ var goalNode = LK.getAsset('goldenZombie', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: x * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2,
+ y: y * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2,
+ width: MAZE_CELL_SIZE,
+ height: MAZE_CELL_SIZE
+ });
+ game.addChild(goalNode);
+ }
}
}
-// Game move handler (for drag attacks)
-function handleMove(x, y, obj) {
- if (dragAttack) {
- // Only attack if moved a minimum distance from last attack
- if (lastAttackX === null || lastAttackY === null || Math.abs(x - lastAttackX) > 60 || Math.abs(y - lastAttackY) > 60) {
- handleAttack(x, y);
- lastAttackX = x;
- lastAttackY = y;
+// Character
+var charNode = LK.getAsset('zombie', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: MAZE_CELL_SIZE * 0.8,
+ height: MAZE_CELL_SIZE * 0.8
+});
+game.addChild(charNode);
+// Find start position
+var charCol = 1,
+ charRow = 1;
+for (var y = 0; y < MAZE_ROWS; y++) {
+ for (var x = 0; x < MAZE_COLS; x++) {
+ if (maze[y][x] === 2) {
+ charCol = x;
+ charRow = y;
}
}
}
-// Game down handler (tap or drag start)
+charNode.x = charCol * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2;
+charNode.y = charRow * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2;
+// Movement state
+var moveTargetCol = charCol;
+var moveTargetRow = charRow;
+var isMoving = false;
+var moveSpeed = 16; // px per frame
+// Touch/drag movement: tap or drag to adjacent cell
+function getCellFromPos(x, y) {
+ var col = Math.floor(x / MAZE_CELL_SIZE);
+ var row = Math.floor(y / MAZE_CELL_SIZE);
+ return {
+ col: col,
+ row: row
+ };
+}
game.down = function (x, y, obj) {
- dragAttack = true;
- lastAttackX = x;
- lastAttackY = y;
- handleAttack(x, y);
+ var cell = getCellFromPos(x, y);
+ // Only allow move to adjacent cell (no diagonals)
+ var dx = cell.col - charCol;
+ var dy = cell.row - charRow;
+ if (Math.abs(dx) === 1 && dy === 0 || Math.abs(dy) === 1 && dx === 0) {
+ // Check wall
+ if (maze[cell.row] && maze[cell.row][cell.col] !== 1) {
+ moveTargetCol = cell.col;
+ moveTargetRow = cell.row;
+ isMoving = true;
+ }
+ }
};
-// Game up handler (drag end)
+game.move = function (x, y, obj) {
+ // Optional: allow drag to move, same as tap
+ game.down(x, y, obj);
+};
game.up = function (x, y, obj) {
- dragAttack = false;
- lastAttackX = null;
- lastAttackY = null;
+ // No-op
};
-// Game move handler
-game.move = handleMove;
-// Main game update loop
game.update = function () {
- // Spawn monsters
- if (isSpawning && monstersSpawned < monstersToSpawn) {
- spawnTimer++;
- if (spawnTimer >= spawnInterval) {
- spawnMonster();
- spawnTimer = 0;
+ // Move character toward target cell
+ var targetX = moveTargetCol * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2;
+ var targetY = moveTargetRow * MAZE_CELL_SIZE + MAZE_CELL_SIZE / 2;
+ var dx = targetX - charNode.x;
+ var dy = targetY - charNode.y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (isMoving && dist > 2) {
+ var step = Math.min(moveSpeed, dist);
+ charNode.x += dx / dist * step;
+ charNode.y += dy / dist * step;
+ } else if (isMoving) {
+ // Snap to cell
+ charNode.x = targetX;
+ charNode.y = targetY;
+ charCol = moveTargetCol;
+ charRow = moveTargetRow;
+ isMoving = false;
+ // Check for goal
+ if (maze[charRow][charCol] === 3) {
+ LK.effects.flashScreen(0x00ff00, 800);
+ LK.showYouWin();
}
}
- // End wave if all monsters defeated
- if (monstersDefeated >= monstersToSpawn && monstersToSpawn > 0 && monstersSpawned >= monstersToSpawn) {
- isSpawning = false;
- LK.setTimeout(function () {
- startNextWave();
- }, 1200);
- monstersToSpawn = 0; // Prevent retrigger
- }
- // Update monsters
- for (var i = monsters.length - 1; i >= 0; i--) {
- var m = monsters[i];
- m.update();
- // Check if monster reached base
- var intersectingBase = m.intersects(base);
- if (!m.lastIntersectingBase && intersectingBase && !m.isDead) {
- // Monster reached base: game over
- LK.effects.flashScreen(0xff0000, 1000);
- LK.showGameOver();
- return;
- }
- m.lastIntersectingBase = intersectingBase;
- // Remove dead monsters
- if (m.isDead && m.alpha <= 0.01) {
- m.destroy();
- monsters.splice(i, 1);
- }
- }
-};
-// Initialize score and wave
-LK.setScore(0);
-scoreTxt.setText('0');
-waveTxt.setText('Wave 1');
-// Start first wave
-startNextWave();
\ No newline at end of file
+};
\ No newline at end of file
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Monster Mash: Undead Defense" and with the description "Defend your base from zombies, skeletons, and their golden counterparts by tapping or dragging to attack. Survive waves and score points!". No text on banner!
Zombie with long red eyes. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A zombie with long eyes but everything is golden. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A golden terrifying skeleton. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A zombie fixed with a skeleton. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Ghost. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Heart. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Monster with big hands and ginger hair. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat