User prompt
center game start message 200 pixels above hero
User prompt
Fix Bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'y')' in this line: 'centerCircle.y = centerLine.y;' Line Number: 217
User prompt
Fix Bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in this line: 'startMessage.x = centerCircle.x;' Line Number: 213
User prompt
center game start message with circle asset
User prompt
center game start message
User prompt
add message on game start
User prompt
remove blocked asset
Code edit (1 edits merged)
Please save this source code
User prompt
make success message appear 40 pixels closer to the top of the screen
User prompt
success asset should appear in the place it hits the goal
User prompt
success asset should appear 30 pixels closer to the top of the screen
User prompt
herobullets should go straight up
Code edit (1 edits merged)
Please save this source code
User prompt
change game over message color to red
User prompt
change game over message
User prompt
end game after 10 seconds
User prompt
en game after one minute
User prompt
add text to game over screen
User prompt
add text to game over message. show score.
Code edit (2 edits merged)
Please save this source code
User prompt
Instead of checking for a direct intersection of the hero's and enemy's graphical assets, you would check if the distance between the hero's center point and the enemy's center point is less than the sum of their collision radii.
User prompt
Define a larger collision radius for both the hero and the enemies. This radius will be used to create an invisible circular area around each entity that represents its collision surface.
User prompt
allow a fourth of second of collision before game over
Code edit (1 edits merged)
Please save this source code
User prompt
Make wavemessage font bolder
var BlockedFollower = Container.expand(function (enemy) { var self = Container.call(this); var blockedGraphics = self.createAsset('blocked', 'Blocked asset', 0.5, 0.5); self.enemy = enemy; self.followDuration = 500; self.followStartTime = LK.ticks; self.move = function () { self.x = self.enemy.x; self.y = self.enemy.y; LK.setTimeout(function () { if (self.parent) { self.move(); } }, LK.tickDuration); }; }); var Star = Container.expand(function () { var self = Container.call(this); var starGraphics = self.createAsset('star', 'Star asset', .5, .5); self.move = function () { this.x += 4; }; }); var WaveMessage = Container.expand(function (waveIndex) { var self = Container.call(this); var messageImage = self.createAsset('wave' + waveIndex, 'Wave ' + (waveIndex + 1) + ' Image', .5, .5); self.addChild(messageImage); this.setMessage = function (customMessage) { var messageText = new Text2(customMessage, { size: 60, fill: "#ffffff", font: "'Press Start 2P', monospace", fontWeight: 'bold', stroke: '#000000', strokeThickness: 5, dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 8, dropShadowAngle: Math.PI / 6, dropShadowDistance: 12 }); messageText.anchor.set(0, .5); messageText.x = messageImage.width / 1.5; messageText.y = messageImage.height * 0.1; self.addChild(messageText); }; }); var SpatialGrid = Container.expand(function (cellSize) { var self = Container.call(this); self.cellSize = cellSize; self.grid = {}; self._cellKey = function (x, y) { var cellX = Math.floor(x / self.cellSize); var cellY = Math.floor(y / self.cellSize); return cellX + ':' + cellY; }; self.insert = function (object) { var key = self._cellKey(object.x, object.y); if (!self.grid[key]) { self.grid[key] = []; } self.grid[key].push(object); }; self.retrieve = function (x, y) { var key = self._cellKey(x, y); return self.grid[key] || []; }; self.clear = function () { self.grid = {}; }; }); var Hero = Container.expand(function () { var self = Container.call(this); var heroGraphics = self.createAsset('hero', 'Hero character', .5, .5); self.targetPosition = null; self.setTargetPosition = function (x, y) { self.targetPosition = { x: x, y: Math.max(y, 250) }; }; self.move = function () { if (self.targetPosition) { var dx = self.targetPosition.x - this.x; var dy = self.targetPosition.y - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); if (magnitude > 5) { this.x += dx / magnitude * 10; this.y += dy / magnitude * 10; } else { this.x = self.targetPosition.x; this.y = self.targetPosition.y; self.targetPosition = null; } } }; self.shoot = function () {}; }); var EnemyWave0 = Container.expand(function (enemyCount) { var self = Container.call(this); self.enemyCount = 1; var enemyGraphics = self.createAsset('enemyWave0', 'Enemy Wave 0 character', .5, .5); self.move = function (heroX, heroY) { var dx = heroX - this.x; var dy = heroY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); var speed = 3 + enemySpeedIncrease; var newX = this.x + dx / magnitude * speed; var newY = this.y + dy / magnitude * speed; var minX = 600, maxX = 1500, minY = 100, maxY = 200; newX = Math.max(minX, Math.min(newX, maxX)); newY = Math.max(minY, Math.min(newY, maxY)); this.x = newX; this.y = newY; }; }); var EnemyWave1 = Container.expand(function (enemyCount) { var self = Container.call(this); self.enemyCount = 10; var enemyGraphics = self.createAsset('enemyWave1', 'Enemy Wave 1 character', .5, .5); self.move = function (heroX, heroY) { var dx = heroX - this.x; var dy = heroY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); var speed = 3 + enemySpeedIncrease; this.x += dx / magnitude * speed; this.y += dy / magnitude * speed; }; }); var EnemyWave2 = Container.expand(function (enemyCount) { var self = Container.call(this); self.enemyCount = 5; var enemyGraphics = self.createAsset('enemyWave2', 'Enemy Wave 2 character', .5, .5); self.move = function (heroX, heroY) { var dx = heroX - this.x; var dy = heroY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); var speed = 2 + enemySpeedIncrease; this.x += dx / magnitude * speed; this.y += dy / magnitude * speed; }; }); var EnemyWave3 = Container.expand(function (enemyCount) { var self = Container.call(this); self.enemyCount = 6; var enemyGraphics = self.createAsset('enemyWave3', 'Enemy Wave 3 character', .5, .5); self.move = function (heroX, heroY) { var dx = heroX - this.x; var dy = heroY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); var speed = 2.5 + enemySpeedIncrease; this.x += dx / magnitude * speed; this.y += dy / magnitude * speed; }; }); var EnemyWave4 = Container.expand(function (enemyCount) { var self = Container.call(this); self.enemyCount = 15; var enemyGraphics = self.createAsset('enemyWave4', 'Enemy Wave 4 character', .5, .5); self.move = function (heroX, heroY) { var dx = heroX - this.x; var dy = heroY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); var speed = 3.5 + enemySpeedIncrease; this.x += dx / magnitude * speed; this.y += dy / magnitude * speed; }; }); var EnemyWave5 = Container.expand(function (enemyCount) { var self = Container.call(this); self.enemyCount = 1; var enemyGraphics = self.createAsset('enemyWave5', 'Enemy Wave 5 character', .5, .5); self.move = function (heroX, heroY) { var dx = heroX - this.x; var dy = heroY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); var speed = 7 + enemySpeedIncrease; this.x += dx / magnitude * speed; this.y += dy / magnitude * speed; }; }); var HeroBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.createAsset('heroBullet', 'Hero Bullet', .5, .5); self.move = function (goalX, goalY) { var dx = goalX - this.x; var dy = goalY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); this.x += dx / magnitude * 5; this.y += dy / magnitude * 5; }; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.createAsset('enemyBullet', 'Enemy Bullet', .5, .5); self.move = function (heroX, heroY) { var dx = heroX - this.x; var dy = heroY - this.y; var magnitude = Math.sqrt(dx * dx + dy * dy); this.x += dx / magnitude * 2; this.y += dy / magnitude * 2; }; }); var enemySpeedIncrease = 0; var Game = Container.expand(function () { var self = Container.call(this); stage.on('down', function (obj) { var pos = obj.event.getLocalPosition(self); hero.setTargetPosition(pos.x, pos.y); }); var background = self.createAsset('background', 'Game Background', 0, 0); background.width = 2048; background.height = 2532; background.y = 200; self.addChild(background); var centerLine = self.createAsset('whiteLine', 'Center Line', 0, 0); centerLine.width = 2048; centerLine.height = 10; centerLine.y = 2732 / 2; self.addChild(centerLine); var centerCircle = self.createAsset('centerCircle', 'Center Circle', 0.5, 0.5); centerCircle.width = 100; centerCircle.height = 100; centerCircle.x = 2048 / 2; centerCircle.y = centerLine.y; self.addChild(centerCircle); var topArea = LK.getAsset('topArea', 'Top Area', 0, 0); topArea.width = 2048; topArea.height = 200; self.addChild(topArea); var horizontalLine = LK.getAsset('horizontalLine', 'Horizontal Line', 0, 0); horizontalLine.width = 2048; horizontalLine.height = 10; horizontalLine.y = 200; self.addChild(horizontalLine); self.getEnemyCountForWave = function (waveIndex) { switch (waveIndex % 6) { case 0: return 1; case 1: return 10; case 2: return 3; case 3: return 4; case 4: return 8; case 5: return 1; } }; var goal = self.createAsset('goal', 'Goal asset', 0.5, 0.5); goal.width = 1100; goal.height = 200; goal.x = 2048 / 2; goal.y = goal.height / 2; self.addChild(goal); var hero = self.addChild(new Hero()); var score = 0; var scoreIcon = LK.getAsset('scoreIcon', 'Score Icon', 0, 0); scoreIcon.x = 50; scoreIcon.y = 20; LK.gui.addChild(scoreIcon); var scoreTxt = new Text2('0', { size: 120, fill: "#ffffff", font: "'Press Start 2P', monospace", dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); scoreTxt.anchor.set(0, 0.5); scoreTxt.x = scoreIcon.x + scoreIcon.width + 10; scoreTxt.y = scoreIcon.y + scoreIcon.height / 2 + 5; LK.gui.addChild(scoreTxt); scoreTxt.parent.setChildIndex(scoreTxt, scoreTxt.parent.children.length - 1); var timerTxt = new Text2('00:00', { size: 120, fill: "#ffffff", font: "'Press Start 2P', monospace", dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); timerTxt.anchor.set(0.5, 0); timerTxt.x = 2048 / 2 + 210; timerTxt.y = 20; self.timerTxt = timerTxt; LK.setTimeout(function () { LK.gui.addChild(self.timerTxt); self.timerTxt.parent.setChildIndex(self.timerTxt, self.timerTxt.parent.children.length - 1); }, 1000); var enemies = []; var waveIndex = 0; var maxWaveCount = 6; var waveTimer = 600; var waveInterval = 600; var gameTime = 10; var gameTimer = LK.setInterval(function () { if (gameTime > 0) { gameTime--; var minutes = Math.floor(gameTime / 60); var seconds = gameTime % 60; var formattedTime = (minutes > 0 ? minutes.toString().padStart(2, '0') : '') + ':' + seconds.toString().padStart(2, '0'); timerTxt.setText(formattedTime); } else { LK.clearInterval(gameTimer); LK.showGameOver('Time is up! Final score: ' + score.toString()); } }, 1000); var heroBullets = []; self.messageTimeouts = []; var enemyBullets = []; hero.x = 2048 / 2; hero.y = 2732 - 700; var bulletTimer = 0; var bulletInterval = 100; LK.on('tick', function () { hero.move(); bulletTimer++; if (bulletTimer >= bulletInterval) { var newBullet = new HeroBullet(); newBullet.x = hero.x; newBullet.y = hero.y; heroBullets.push(newBullet); self.addChild(newBullet); bulletTimer = 0; } if (waveIndex < maxWaveCount) { waveTimer++; } if (waveTimer >= waveInterval && waveIndex < maxWaveCount) { var waveMessages = ['Kick off time!', 'EMPTY', 'Kids want a selfie!', 'Time for the press!', 'HOOLIGANS incoming!!', 'SIIIUU!']; var waveMessage = new WaveMessage(waveIndex); waveMessage.setMessage(waveMessages[waveIndex % waveMessages.length]); switch (waveIndex % 6) { case 0: waveMessage.x = 150; waveMessage.y = 1700; break; case 1: waveMessage.x = 150; waveMessage.y = 1700; break; case 2: waveMessage.x = 150; waveMessage.y = 1700; break; case 3: waveMessage.x = 150; waveMessage.y = 1700; break; case 4: waveMessage.x = 150; waveMessage.y = 1700; break; case 5: waveMessage.x = 150; waveMessage.y = 1700; break; } LK.gui.addChild(waveMessage); LK.gui.setChildIndex(waveMessage, LK.gui.children.length - 1); var messageTimeout = LK.setTimeout((function (waveMessageRef) { return function () { LK.gui.removeChild(waveMessageRef); waveMessageRef.destroy(); }; })(waveMessage), 4000); self.messageTimeouts.push(messageTimeout); if (waveIndex == 0) { for (var i = 0; i < self.getEnemyCountForWave(waveIndex); i++) { var newEnemy = new EnemyWave0(self.getEnemyCountForWave(waveIndex)); newEnemy.x = 1000; newEnemy.y = 300; enemies.push(newEnemy); self.addChild(newEnemy); } for (var i = 0; i < self.getEnemyCountForWave(waveIndex + 1); i++) { var newEnemy = new EnemyWave1(self.getEnemyCountForWave(waveIndex + 1)); newEnemy.x = Math.random() * 2048; newEnemy.y = 300; enemies.push(newEnemy); self.addChild(newEnemy); } waveIndex += 2; } else { for (var i = 0; i < self.getEnemyCountForWave(waveIndex); i++) { var newEnemy; var enemyCount = self.getEnemyCountForWave(waveIndex); switch (waveIndex % 6) { case 0: newEnemy = new EnemyWave0(enemyCount); newEnemy.x = 1000; newEnemy.y = 0; break; case 1: newEnemy = new EnemyWave1(enemyCount); newEnemy.x = Math.random() * 2048; newEnemy.y = 0; break; case 2: newEnemy = new EnemyWave2(enemyCount); newEnemy.x = Math.random() * 2048; newEnemy.y = 2732; break; case 3: newEnemy = new EnemyWave3(enemyCount); var side = Math.random() < 0.5 ? 0 : 2048; newEnemy.x = side; newEnemy.y = Math.random() * 2732; break; case 4: newEnemy = new EnemyWave4(enemyCount); var side = Math.floor(Math.random() * 3); switch (side) { case 0: newEnemy.x = 0; newEnemy.y = Math.random() * 2732; break; case 1: newEnemy.x = 2048; newEnemy.y = Math.random() * 2732; break; case 2: newEnemy.x = Math.random() * 2048; newEnemy.y = 2732; break; } break; case 5: newEnemy = new EnemyWave5(enemyCount); newEnemy.x = 1000; newEnemy.y = 2732; break; } enemies.push(newEnemy); self.addChild(newEnemy); } waveIndex++; } waveTimer = 0; } var spatialGrid = new SpatialGrid(100); for (var i = 0; i < enemies.length; i++) { spatialGrid.insert(enemies[i]); } for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var nearbyEnemies = spatialGrid.retrieve(enemy.x, enemy.y); enemy.move(hero.x, hero.y); var collisionThreshold = 20; var heroRadius = hero.width / 2; var enemyRadius = enemy.width / 2; var dx = hero.x - enemy.x; var dy = hero.y - enemy.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < heroRadius + enemyRadius) { self.messageTimeouts.forEach(function (timeout) { LK.clearTimeout(timeout); }); LK.gui.removeChild(self.timerTxt); LK.showGameOver('You were hit! Final score: ' + score.toString()); LK.gui.children.forEach(function (child) { if (child instanceof Text2) { child.destroy(); } }); LK.gui.removeChildren(); return; } for (var j = 0; j < nearbyEnemies.length; j++) { var otherEnemy = nearbyEnemies[j]; if (otherEnemy !== enemy && enemy.intersects(otherEnemy)) { var overlapX = enemy.x - otherEnemy.x; var overlapY = enemy.y - otherEnemy.y; var overlapMagnitude = Math.sqrt(overlapX * overlapX + overlapY * overlapY); var separationDistance = 100; for (var j = 0; j < nearbyEnemies.length; j++) { var otherEnemy = nearbyEnemies[j]; if (otherEnemy !== enemy && enemy.intersects(otherEnemy)) { var overlapX = enemy.x - otherEnemy.x; var overlapY = enemy.y - otherEnemy.y; var overlapMagnitude = Math.sqrt(overlapX * overlapX + overlapY * overlapY); if (overlapMagnitude < separationDistance) { var separationFactor = (separationDistance - overlapMagnitude) / overlapMagnitude; enemy.x += overlapX / overlapMagnitude * separationFactor; enemy.y += overlapY / overlapMagnitude * separationFactor; otherEnemy.x -= overlapX / overlapMagnitude * separationFactor; otherEnemy.y -= overlapY / overlapMagnitude * separationFactor; } } } } } } spatialGrid.clear(); for (var i = heroBullets.length - 1; i >= 0; i--) { heroBullets[i].move(goal.x, goal.y); if (heroBullets[i].intersects(goal)) { var successAsset = self.createAsset('success', 'Success Asset', .5, .5); var dx = goal.x - heroBullets[i].x; var dy = goal.y - heroBullets[i].y; var magnitude = Math.sqrt(dx * dx + dy * dy); successAsset.x = heroBullets[i].x + dx / magnitude * 75; successAsset.y = heroBullets[i].y + dy / magnitude * 75 - 50; self.addChild(successAsset); LK.setTimeout(function () { successAsset.destroy(); }, 1000); heroBullets[i].destroy(); heroBullets.splice(i, 1); score++; enemySpeedIncrease += 0.1; scoreTxt.setText(score.toString()); continue; } for (var j = 0; j < enemies.length; j++) { if (heroBullets[i] && heroBullets[i].intersects(enemies[j])) { var blockedFollower = new BlockedFollower(enemies[j]); blockedFollower.x = heroBullets[i].x; blockedFollower.y = heroBullets[i].y; self.addChild(blockedFollower); LK.setTimeout(function () { blockedFollower.destroy(); }, 250); heroBullets[i].destroy(); heroBullets.splice(i, 1); break; } } } for (var i = 0; i < enemyBullets.length; i++) { enemyBullets[i].move(); } }); });
===================================================================
--- original.js
+++ change.js
@@ -308,9 +308,9 @@
var formattedTime = (minutes > 0 ? minutes.toString().padStart(2, '0') : '') + ':' + seconds.toString().padStart(2, '0');
timerTxt.setText(formattedTime);
} else {
LK.clearInterval(gameTimer);
- LK.showGameOver('Game Over! Your score: ' + score.toString());
+ LK.showGameOver('Time is up! Final score: ' + score.toString());
}
}, 1000);
var heroBullets = [];
self.messageTimeouts = [];
@@ -463,9 +463,9 @@
self.messageTimeouts.forEach(function (timeout) {
LK.clearTimeout(timeout);
});
LK.gui.removeChild(self.timerTxt);
- LK.showGameOver('Game Over! Your score: ' + score.toString());
+ LK.showGameOver('You were hit! Final score: ' + score.toString());
LK.gui.children.forEach(function (child) {
if (child instanceof Text2) {
child.destroy();
}