/**** * 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.followSpeed = 0.04; // How fast brotato follows the cursor/touch (lower = slower, now even slower) 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; // 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; self.followSpeed = Math.min(self.followSpeed + 0.06, 0.35); // Increase follow speed, cap at 0.35 } 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 = 1; 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 ****/ // --- Map Border Setup --- // Potato hero (ellipse, brown) // Enemy (ellipse, red) // Bullet (box, yellow) // XP orb (ellipse, green) // Upgrade button (box, blue) 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; // Wave count UI (top right, avoid top left 100x100) var waveTxt = new Text2('Wave: 1', { size: 90, fill: "#fff" }); waveTxt.anchor.set(1, 0); // right aligned, top LK.gui.topRight.addChild(waveTxt); waveTxt.x = 0; waveTxt.y = 0; // 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); } // 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() { // Do not fire if there are no enemies if (enemies.length === 0) { return; } // 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]; } } 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); } LK.getSound('silah1').play(); } // 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(); for (var i = 0; i < xporbs.length; i++) xporbs[i].destroy(); enemies = []; bullets = []; xporbs = []; // 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; if (typeof waveTxt !== "undefined") { waveTxt.setText('Wave: ' + wave); } } // 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(); if (typeof waveTxt !== "undefined") { waveTxt.setText('Wave: ' + wave); } startWave(); // Touch drag logic // dragNode removed: brotato now follows cursor/touch directly function handleMove(x, y, obj) { if (inUpgrade) return; // Make brotato follow cursor/touch position, clamped to arena if (brotato) { var r = brotato.radius; // Target position clamped to arena var targetX = Math.max(r, Math.min(2048 - r, x)); var targetY = Math.max(r, Math.min(2732 - r, y)); // Move brotato towards target position with smoothing // The closer the factor is to 1, the faster the follow. Lower = slower. // Use brotato.followSpeed if defined, otherwise default to 0.04 (much slower than before) var followSpeed = typeof brotato.followSpeed === "number" ? brotato.followSpeed : 0.04; brotato.x += (targetX - brotato.x) * followSpeed; brotato.y += (targetY - brotato.y) * followSpeed; } } game.move = handleMove; game.down = function (x, y, obj) { if (inUpgrade) return; handleMove(x, y, obj); }; game.up = function (x, y, obj) { // dragNode logic removed: brotato follows cursor/touch directly }; // Main game loop game.update = function () { if (inUpgrade) return; // 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 (slower spawn) for (var i = 0; i < Math.min(2 + Math.floor(wave / 2), 6); 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');
/****
* 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.followSpeed = 0.04; // How fast brotato follows the cursor/touch (lower = slower, now even slower)
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;
// 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;
self.followSpeed = Math.min(self.followSpeed + 0.06, 0.35); // Increase follow speed, cap at 0.35
} 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 = 1;
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
****/
// --- Map Border Setup ---
// Potato hero (ellipse, brown)
// Enemy (ellipse, red)
// Bullet (box, yellow)
// XP orb (ellipse, green)
// Upgrade button (box, blue)
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;
// Wave count UI (top right, avoid top left 100x100)
var waveTxt = new Text2('Wave: 1', {
size: 90,
fill: "#fff"
});
waveTxt.anchor.set(1, 0); // right aligned, top
LK.gui.topRight.addChild(waveTxt);
waveTxt.x = 0;
waveTxt.y = 0;
// 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);
}
// 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() {
// Do not fire if there are no enemies
if (enemies.length === 0) {
return;
}
// 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];
}
}
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);
}
LK.getSound('silah1').play();
}
// 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();
for (var i = 0; i < xporbs.length; i++) xporbs[i].destroy();
enemies = [];
bullets = [];
xporbs = [];
// 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;
if (typeof waveTxt !== "undefined") {
waveTxt.setText('Wave: ' + wave);
}
}
// 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();
if (typeof waveTxt !== "undefined") {
waveTxt.setText('Wave: ' + wave);
}
startWave();
// Touch drag logic
// dragNode removed: brotato now follows cursor/touch directly
function handleMove(x, y, obj) {
if (inUpgrade) return;
// Make brotato follow cursor/touch position, clamped to arena
if (brotato) {
var r = brotato.radius;
// Target position clamped to arena
var targetX = Math.max(r, Math.min(2048 - r, x));
var targetY = Math.max(r, Math.min(2732 - r, y));
// Move brotato towards target position with smoothing
// The closer the factor is to 1, the faster the follow. Lower = slower.
// Use brotato.followSpeed if defined, otherwise default to 0.04 (much slower than before)
var followSpeed = typeof brotato.followSpeed === "number" ? brotato.followSpeed : 0.04;
brotato.x += (targetX - brotato.x) * followSpeed;
brotato.y += (targetY - brotato.y) * followSpeed;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (inUpgrade) return;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
// dragNode logic removed: brotato follows cursor/touch directly
};
// Main game loop
game.update = function () {
if (inUpgrade) return;
// 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 (slower spawn)
for (var i = 0; i < Math.min(2 + Math.floor(wave / 2), 6); 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');
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