User prompt
make character follow cursor slower
User prompt
make character follow cursor
User prompt
make enemies more weak
User prompt
make enemies spawn slower
User prompt
make more enemies spawn
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var dx = enemy.x - brotato.x;' Line Number: 616
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var dx = enemy.x - brotato.x;' Line Number: 614
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'fireCooldown')' in or related to this line: 'if (brotato.fireCooldown > 0) {' Line Number: 603
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'fireCooldown')' in or related to this line: 'if (brotato.fireCooldown > 0) {' Line Number: 603
User prompt
add a start screen
User prompt
if there is no enemy in the map dont shoot
User prompt
make our character shootable only there is an enemy in our range
User prompt
make range smaller
User prompt
make the range circle
User prompt
make our shoot range bigger
User prompt
make our character only shootable if there is an enemy in our range
User prompt
make range round and make smaller
User prompt
make range bigger and visible
User prompt
add range to our character if there is no enemy in range dont shoot
User prompt
make less enemies spawn
User prompt
make bullets auto aim enemie
User prompt
make bullet follow straight
User prompt
Make enemies spawn inside the borders
User prompt
Add a border to map
User prompt
make bullet following enemies
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Brotato (player) class
var Brotato = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('brotato', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = body.width * 0.5;
self.speed = 18; // Movement speed
self.fireCooldown = 0; // Ticks until next shot
self.fireRate = 30; // Ticks between shots (lower = faster)
self.bulletSpeed = 32;
self.bulletCount = 1;
self.bulletSpread = 0.2; // radians
self.damage = 1;
self.xp = 0;
self.level = 1;
self.hp = 5;
self.maxHp = 5;
// Range for auto-fire (in px)
self.range = 1200; // Increased range for Brotato
// For touch drag
self.isDragging = false;
// For upgrades
self.applyUpgrade = function (upgrade) {
if (upgrade === 'firerate') {
self.fireRate = Math.max(8, self.fireRate - 4);
} else if (upgrade === 'speed') {
self.speed += 3;
} else if (upgrade === 'damage') {
self.damage += 1;
} else if (upgrade === 'bullets') {
self.bulletCount = Math.min(6, self.bulletCount + 1);
} else if (upgrade === 'hp') {
self.maxHp += 2;
self.hp = self.maxHp;
}
};
return self;
});
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = Math.max(body.width, body.height) * 0.5;
self.speed = 32;
self.dx = 0;
self.dy = 0;
self.damage = 1;
self.update = function () {
// Bullets fly straight in their initial direction
self.x += self.dx * self.speed;
self.y += self.dy * self.speed;
};
return self;
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = body.width * 0.5;
self.speed = 6 + Math.random() * 4;
self.hp = 2;
self.damage = 1;
self.xpValue = 1;
// Target to chase (brotato)
self.target = null;
self.update = function () {
if (!self.target) return;
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
};
return self;
});
// Upgrade Button class
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var btn = self.attachAsset('upgradeBtn', {
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
self.upgradeType = '';
self.onSelect = null;
self.down = function (x, y, obj) {
if (typeof self.onSelect === 'function') {
self.onSelect(self.upgradeType);
}
};
return self;
});
// XP orb class
var XPOrb = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('xp', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = body.width * 0.5;
self.value = 1;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Upgrade button (box, blue)
// XP orb (ellipse, green)
// Bullet (box, yellow)
// Enemy (ellipse, red)
// Potato hero (ellipse, brown)
// --- Map Border Setup ---
var borderThickness = 24;
var borderColor = 0xffffff;
// Top border
var borderTop = LK.getAsset('borderTop', {
width: 2048,
height: borderThickness,
color: borderColor,
shape: 'box',
x: 0,
y: 0,
anchorX: 0,
anchorY: 0
});
game.addChild(borderTop);
// Bottom border
var borderBottom = LK.getAsset('borderBottom', {
width: 2048,
height: borderThickness,
color: borderColor,
shape: 'box',
x: 0,
y: 2732 - borderThickness,
anchorX: 0,
anchorY: 0
});
game.addChild(borderBottom);
// Left border
var borderLeft = LK.getAsset('borderLeft', {
width: borderThickness,
height: 2732,
color: borderColor,
shape: 'box',
x: 0,
y: 0,
anchorX: 0,
anchorY: 0
});
game.addChild(borderLeft);
// Right border
var borderRight = LK.getAsset('borderRight', {
width: borderThickness,
height: 2732,
color: borderColor,
shape: 'box',
x: 2048 - borderThickness,
y: 0,
anchorX: 0,
anchorY: 0
});
game.addChild(borderRight);
// Game state
var brotato;
var enemies = [];
var bullets = [];
var xporbs = [];
var wave = 1;
var waveTimer = 0;
var waveDuration = 900; // 15 seconds per wave (60*15)
var inUpgrade = false;
var upgradeButtons = [];
var score = 0;
// UI
var scoreTxt = new Text2('Score: 0', {
size: 100,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var hpTxt = new Text2('HP: 5/5', {
size: 80,
fill: "#fff"
});
hpTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(hpTxt);
hpTxt.y = 120;
// Level up text
var levelTxt = new Text2('', {
size: 100,
fill: 0xFFE066
});
levelTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(levelTxt);
// Helper: spawn brotato in center
function spawnBrotato() {
brotato = new Brotato();
brotato.x = 2048 / 2;
brotato.y = 2732 / 2;
game.addChild(brotato);
// Add visible range indicator (semi-transparent ellipse)
var rangeCircle = LK.getAsset('centerCircle', {
width: brotato.range * 2,
height: brotato.range * 2,
color: 0x00ffcc,
shape: 'ellipse',
anchorX: 0.5,
anchorY: 0.5,
x: brotato.x,
y: brotato.y,
alpha: 0.13
});
// Attach to game, but below brotato
game.addChild(rangeCircle);
// Keep rangeCircle following brotato
brotato._rangeCircle = rangeCircle;
}
// Helper: spawn enemy at random edge
function spawnEnemy() {
var enemy = new Enemy();
var border = 24; // borderThickness
var minX = border + enemy.radius;
var maxX = 2048 - border - enemy.radius;
var minY = border + enemy.radius;
var maxY = 2732 - border - enemy.radius;
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
// Top
enemy.x = minX + Math.random() * (maxX - minX);
enemy.y = minY;
} else if (edge === 1) {
// Bottom
enemy.x = minX + Math.random() * (maxX - minX);
enemy.y = maxY;
} else if (edge === 2) {
// Left
enemy.x = minX;
enemy.y = minY + Math.random() * (maxY - minY);
} else {
// Right
enemy.x = maxX;
enemy.y = minY + Math.random() * (maxY - minY);
}
enemy.target = brotato;
enemies.push(enemy);
game.addChild(enemy);
}
// Helper: spawn XP orb at (x, y)
function spawnXP(x, y, value) {
var orb = new XPOrb();
orb.x = x;
orb.y = y;
orb.value = value || 1;
xporbs.push(orb);
game.addChild(orb);
}
// Helper: fire bullets from brotato
function fireBullets() {
// Find nearest enemy to brotato
var nearestEnemy = null;
var minDist = Infinity;
for (var i = 0; i < enemies.length; i++) {
var dx = enemies[i].x - brotato.x;
var dy = enemies[i].y - brotato.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
nearestEnemy = enemies[i];
}
}
// Only fire if an enemy is within range
if (!nearestEnemy || minDist > brotato.range) {
return;
}
var angleBase = 0;
// If there is a nearest enemy, aim at it
if (nearestEnemy) {
var dx = nearestEnemy.x - brotato.x;
var dy = nearestEnemy.y - brotato.y;
angleBase = Math.atan2(dy, dx);
}
for (var i = 0; i < brotato.bulletCount; i++) {
var spread = brotato.bulletCount > 1 ? (i - (brotato.bulletCount - 1) / 2) * brotato.bulletSpread : 0;
var angle = angleBase + spread;
var bullet = new Bullet();
bullet.x = brotato.x;
bullet.y = brotato.y;
bullet.dx = Math.cos(angle);
bullet.dy = Math.sin(angle);
bullet.damage = brotato.damage;
bullets.push(bullet);
game.addChild(bullet);
}
}
// Helper: show upgrade selection
function showUpgradeSelection() {
inUpgrade = true;
// Remove all enemies and bullets
for (var i = 0; i < enemies.length; i++) enemies[i].destroy();
for (var i = 0; i < bullets.length; i++) bullets[i].destroy();
enemies = [];
bullets = [];
// Show 3 random upgrades
var upgrades = [{
type: 'firerate',
label: 'Faster Fire Rate'
}, {
type: 'speed',
label: 'Move Speed Up'
}, {
type: 'damage',
label: 'Bullet Damage Up'
}, {
type: 'bullets',
label: 'More Bullets'
}, {
type: 'hp',
label: 'Max HP Up'
}];
// Shuffle upgrades
for (var i = upgrades.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = upgrades[i];
upgrades[i] = upgrades[j];
upgrades[j] = temp;
}
// Show 3
for (var k = 0; k < 3; k++) {
var btn = new UpgradeButton();
btn.x = 2048 / 2;
btn.y = 900 + k * 350;
btn.text.setText(upgrades[k].label);
btn.upgradeType = upgrades[k].type;
btn.onSelect = function (type) {
// Remove buttons
for (var b = 0; b < upgradeButtons.length; b++) {
upgradeButtons[b].destroy();
}
upgradeButtons = [];
brotato.applyUpgrade(type);
inUpgrade = false;
levelTxt.setText('');
// Start next wave
startWave();
};
upgradeButtons.push(btn);
game.addChild(btn);
}
levelTxt.setText('Choose an Upgrade!');
}
// Helper: start a wave
function startWave() {
waveTimer = 0;
wave += 1;
}
// Helper: update UI
function updateUI() {
scoreTxt.setText('Score: ' + score);
hpTxt.setText('HP: ' + brotato.hp + '/' + brotato.maxHp);
}
// Helper: handle brotato damage
function brotatoHit(dmg) {
brotato.hp -= dmg;
LK.effects.flashObject(brotato, 0xff0000, 400);
updateUI();
if (brotato.hp <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
}
// Helper: handle brotato level up
function brotatoLevelUp() {
brotato.level += 1;
brotato.xp = 0;
levelTxt.setText('Level Up!');
showUpgradeSelection();
}
// Helper: get XP needed for next level
function xpForLevel(level) {
return 5 + Math.floor(level * 2.5);
}
// Initialize game
spawnBrotato();
updateUI();
startWave();
// Touch drag logic
var dragNode = null;
function handleMove(x, y, obj) {
if (inUpgrade) return;
if (dragNode) {
// Clamp to arena
var r = brotato.radius;
dragNode.x = Math.max(r, Math.min(2048 - r, x));
dragNode.y = Math.max(r, Math.min(2732 - r, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (inUpgrade) return;
dragNode = brotato;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
if (inUpgrade) return;
// Keep range indicator following Brotato
if (brotato && brotato._rangeCircle) {
brotato._rangeCircle.x = brotato.x;
brotato._rangeCircle.y = brotato.y;
}
// Wave timer
waveTimer++;
if (waveTimer >= waveDuration) {
// End of wave: show upgrade
showUpgradeSelection();
return;
}
// Spawn enemies
if (LK.ticks % Math.max(40, 120 - wave * 4) === 0) {
// More enemies per wave (reduced)
for (var i = 0; i < Math.min(1 + Math.floor(wave / 3), 3); i++) {
spawnEnemy();
}
}
// Brotato auto-fire
if (brotato.fireCooldown > 0) {
brotato.fireCooldown--;
} else {
fireBullets();
brotato.fireCooldown = brotato.fireRate;
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Check collision with brotato
var dx = enemy.x - brotato.x;
var dy = enemy.y - brotato.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < enemy.radius + brotato.radius - 10) {
brotatoHit(enemy.damage);
// Destroy enemy
spawnXP(enemy.x, enemy.y, enemy.xpValue);
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Remove if off screen (failsafe)
if (enemy.x < -200 || enemy.x > 2248 || enemy.y < -200 || enemy.y > 2932) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update bullets
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
bullet.update();
// Remove if off screen
if (bullet.x < -100 || bullet.x > 2148 || bullet.y < -100 || bullet.y > 2832) {
bullet.destroy();
bullets.splice(j, 1);
continue;
}
// Check collision with enemies
var hit = false;
for (var k = enemies.length - 1; k >= 0; k--) {
var enemy = enemies[k];
var dx = bullet.x - enemy.x;
var dy = bullet.y - enemy.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < bullet.radius + enemy.radius - 10) {
enemy.hp -= bullet.damage;
hit = true;
if (enemy.hp <= 0) {
spawnXP(enemy.x, enemy.y, enemy.xpValue);
enemy.destroy();
enemies.splice(k, 1);
score += 1;
updateUI();
}
break;
}
}
if (hit) {
bullet.destroy();
bullets.splice(j, 1);
}
}
// Update XP orbs
for (var m = xporbs.length - 1; m >= 0; m--) {
var orb = xporbs[m];
// Attract to brotato if close
var dx = orb.x - brotato.x;
var dy = orb.y - brotato.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 300) {
var pull = 18;
orb.x -= dx / dist * pull;
orb.y -= dy / dist * pull;
}
// Collect
if (dist < orb.radius + brotato.radius) {
brotato.xp += orb.value;
orb.destroy();
xporbs.splice(m, 1);
// Level up?
if (brotato.xp >= xpForLevel(brotato.level)) {
brotatoLevelUp();
return;
}
}
}
};
// Play music (if you have a music asset, e.g. 'bgmusic')
// LK.playMusic('bgmusic'); ===================================================================
--- original.js
+++ change.js
@@ -25,9 +25,9 @@
self.level = 1;
self.hp = 5;
self.maxHp = 5;
// Range for auto-fire (in px)
- self.range = 700; // You can tweak this value for balance
+ self.range = 1200; // Increased range for Brotato
// For touch drag
self.isDragging = false;
// For upgrades
self.applyUpgrade = function (upgrade) {
@@ -228,8 +228,24 @@
brotato = new Brotato();
brotato.x = 2048 / 2;
brotato.y = 2732 / 2;
game.addChild(brotato);
+ // Add visible range indicator (semi-transparent ellipse)
+ var rangeCircle = LK.getAsset('centerCircle', {
+ width: brotato.range * 2,
+ height: brotato.range * 2,
+ color: 0x00ffcc,
+ shape: 'ellipse',
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: brotato.x,
+ y: brotato.y,
+ alpha: 0.13
+ });
+ // Attach to game, but below brotato
+ game.addChild(rangeCircle);
+ // Keep rangeCircle following brotato
+ brotato._rangeCircle = rangeCircle;
}
// Helper: spawn enemy at random edge
function spawnEnemy() {
var enemy = new Enemy();
@@ -420,8 +436,13 @@
};
// Main game loop
game.update = function () {
if (inUpgrade) return;
+ // Keep range indicator following Brotato
+ if (brotato && brotato._rangeCircle) {
+ brotato._rangeCircle.x = brotato.x;
+ brotato._rangeCircle.y = brotato.y;
+ }
// Wave timer
waveTimer++;
if (waveTimer >= waveDuration) {
// End of wave: show upgrade
gray bullet. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Lazy bad kid. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
yellow shining star. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Brown box with golden corners. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
gray and light gray squares . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
2d pickle like brotato character with no legs and no arms. In-Game asset. 2d. High contrast. brotato