Code edit (1 edits merged)
Please save this source code
User prompt
Berzerk Ball: Homerun Smash
Initial prompt
copy Berzerk Ball game, this game The sequel to Homerun in Berzerk Land will probably show up sometime in 2011, but since we really appreciate your support, we've decided to give you something to sink your teeth into in the meantime. Behold Berzerk Ball, the expansion pack of the original Homerun game. A brand new look for the game, new weapons, new items and a sexy new character are all bundled in for you so you get the chance to beat your friends' high scores all over again! Oh yeah, and make sure to check out the iPhone and iPod version of it at: We also would like to take the occasion to wish you a merry Christmas and a happy, super-sharp New Year 2011! Thanks for all your support and we hope to see you guys back as top-shape as ever next year (aka in a couple of days from now)!
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { bestDistance: 0, coins: 0, upgrades: { power: 1, bounce: 1 } }); /**** * Classes ****/ // Bat class: the weapon to hit the geek var Bat = Container.expand(function () { var self = Container.call(this); var batSprite = self.attachAsset('bat', { anchorX: 0.1, anchorY: 0.5 }); self.swinging = false; self.angle = -Math.PI / 4; // resting angle self.power = 0; self.maxPower = 1; self.swingTween = null; self.setAngle = function (a) { self.rotation = a; self.angle = a; }; self.swing = function (onHit) { if (self.swinging) return; self.swinging = true; // Animate swing tween(self, { rotation: Math.PI / 2 }, { duration: 180, easing: tween.cubicOut, onFinish: function onFinish() { self.swinging = false; self.setAngle(-Math.PI / 4); if (onHit) onHit(); } }); }; return self; }); // Geek class: the character to launch var Geek = Container.expand(function () { var self = Container.call(this); var geekSprite = self.attachAsset('geek', { anchorX: 0.5, anchorY: 0.5 }); self.radius = geekSprite.width / 2; self.vx = 0; // velocity x self.vy = 0; // velocity y self.rotationSpeed = 0; self.isFlying = false; self.isStopped = false; self.distance = 0; self.bounceCount = 0; // For collision detection self.getBounds = function () { return { x: self.x - self.radius, y: self.y - self.radius, width: self.radius * 2, height: self.radius * 2 }; }; // Called every tick self.update = function () { if (!self.isFlying || self.isStopped) return; // Physics self.x += self.vx; self.y += self.vy; self.vy += 1.2; // gravity // Air friction self.vx *= 0.995; self.vy *= 0.995; // Rotation self.rotation += self.rotationSpeed; // Distance tracking self.distance += self.vx; // Ground collision if (self.y + self.radius >= groundY) { self.y = groundY - self.radius; if (Math.abs(self.vy) > 8) { // Bounce self.vy = -Math.abs(self.vy) * (0.45 + 0.05 * upgrades.bounce); self.vx *= 0.92; self.rotationSpeed *= 0.7; self.bounceCount++; LK.getSound('bounce').play(); // Small upward nudge to avoid sticking self.y -= 2; } else { // Stop self.vy = 0; self.vx = 0; self.isStopped = true; self.isFlying = false; onGeekStopped(); } } }; return self; }); // Obstacle (rock) var Rock = Container.expand(function () { var self = Container.call(this); var rockSprite = self.attachAsset('rock', { anchorX: 0.5, anchorY: 0.5 }); self.radius = rockSprite.width / 2; self.getBounds = function () { return { x: self.x - self.radius, y: self.y - self.radius, width: self.radius * 2, height: self.radius * 2 }; }; return self; }); // Power-up (spring) var Spring = Container.expand(function () { var self = Container.call(this); var springSprite = self.attachAsset('spring', { anchorX: 0.5, anchorY: 0.5 }); self.radius = springSprite.width / 2; self.getBounds = function () { return { x: self.x - self.radius, y: self.y - self.radius, width: self.radius * 2, height: self.radius * 2 }; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // Music // Sound effects // Power-up (spring) // Obstacle (rock) // Ground // Bat (the weapon) // Geek (the character to launch) // --- Global variables --- var groundY = 2732 - 80; // ground top var geek, bat; var rocks = []; var springs = []; var upgrades = storage.upgrades || { power: 1, bounce: 1 }; var coins = storage.coins || 0; var bestDistance = storage.bestDistance || 0; var runDistance = 0; var runCoins = 0; var isAiming = false; var aimPower = 0; var aimAngle = -Math.PI / 4; var aimMaxPower = 1.5 + 0.2 * upgrades.power; var aimMinAngle = -Math.PI / 3; var aimMaxAngle = -Math.PI / 8; var aimDir = 1; var aimTimer = 0; var gameState = 'aim'; // 'aim', 'flying', 'stopped' // --- GUI --- var scoreTxt = new Text2('0 m', { size: 100, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var coinTxt = new Text2('0', { size: 70, fill: 0xFFD700 }); coinTxt.anchor.set(1, 0); LK.gui.topRight.addChild(coinTxt); var bestTxt = new Text2('Best: 0 m', { size: 60, fill: "#fff" }); bestTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(bestTxt); var upgradeTxt = new Text2('', { size: 60, fill: "#fff" }); upgradeTxt.anchor.set(0.5, 1); LK.gui.bottom.addChild(upgradeTxt); // --- Ground --- var ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: groundY }); game.addChild(ground); // --- Functions --- function resetRun() { // Remove old objects if (geek) geek.destroy(); if (bat) bat.destroy(); for (var i = 0; i < rocks.length; i++) rocks[i].destroy(); for (var i = 0; i < springs.length; i++) springs[i].destroy(); rocks = []; springs = []; runDistance = 0; runCoins = 0; aimPower = 0; aimAngle = -Math.PI / 4; aimDir = 1; aimTimer = 0; gameState = 'aim'; // Geek geek = new Geek(); geek.x = 350; geek.y = groundY - 120; geek.rotation = 0; game.addChild(geek); // Bat bat = new Bat(); bat.x = geek.x - 80; bat.y = groundY - 120; bat.setAngle(-Math.PI / 4); game.addChild(bat); // Obstacles for (var i = 0; i < 3; i++) { var rock = new Rock(); rock.x = 900 + 700 * i + Math.random() * 200; rock.y = groundY - 30; rocks.push(rock); game.addChild(rock); } // Power-ups for (var i = 0; i < 2; i++) { var spring = new Spring(); spring.x = 1200 + 1000 * i + Math.random() * 300; spring.y = groundY - 20; springs.push(spring); game.addChild(spring); } // GUI scoreTxt.setText('0 m'); coinTxt.setText('' + coins); bestTxt.setText('Best: ' + bestDistance + ' m'); upgradeTxt.setText('Tap bottom to upgrade: Power(' + upgrades.power + '), Bounce(' + upgrades.bounce + ')'); } function onGeekStopped() { // End of run runDistance = Math.floor(geek.distance / 10); if (runDistance > bestDistance) { bestDistance = runDistance; storage.bestDistance = bestDistance; } coins += Math.floor(runDistance / 10) + runCoins; storage.coins = coins; // Show game over LK.effects.flashScreen(0x000000, 600); LK.showGameOver(); } function launchGeek(power, angle) { // Bat swing animation bat.swing(function () { // Launch var p = 38 * power * (1 + 0.15 * upgrades.power); geek.vx = p * Math.cos(angle); geek.vy = p * Math.sin(angle) - 10; geek.rotationSpeed = 0.2 + 0.1 * power; geek.isFlying = true; gameState = 'flying'; LK.getSound('hit').play(); // Remove bat after swing LK.setTimeout(function () { bat.destroy(); }, 300); }); } // --- Input handling --- game.down = function (x, y, obj) { if (gameState === 'aim') { isAiming = true; aimTimer = 0; } else if (gameState === 'stopped') { // Check if bottom area tapped for upgrades if (y > 2732 - 300) { // Alternate upgrades: tap left half for power, right half for bounce if (x < 2048 / 2) { // Power upgrade var cost = 10 + upgrades.power * 10; if (coins >= cost) { upgrades.power++; coins -= cost; storage.upgrades = upgrades; storage.coins = coins; LK.effects.flashObject(upgradeTxt, 0x00ff00, 400); } else { LK.effects.flashObject(upgradeTxt, 0xff0000, 400); } } else { // Bounce upgrade var cost = 10 + upgrades.bounce * 10; if (coins >= cost) { upgrades.bounce++; coins -= cost; storage.upgrades = upgrades; storage.coins = coins; LK.effects.flashObject(upgradeTxt, 0x00ff00, 400); } else { LK.effects.flashObject(upgradeTxt, 0xff0000, 400); } } upgradeTxt.setText('Tap bottom to upgrade: Power(' + upgrades.power + '), Bounce(' + upgrades.bounce + ')'); coinTxt.setText('' + coins); } } }; game.up = function (x, y, obj) { if (gameState === 'aim' && isAiming) { isAiming = false; // Launch! launchGeek(aimPower, aimAngle); } }; function checkCollision(a, b) { var ab = a.getBounds(); var bb = b.getBounds(); return ab.x < bb.x + bb.width && ab.x + ab.width > bb.x && ab.y < bb.y + bb.height && ab.y + ab.height > bb.y; } // --- Main update loop --- game.update = function () { // Aiming phase if (gameState === 'aim' && isAiming) { // Power oscillates up and down aimTimer++; aimPower = 0.5 + 0.5 * Math.abs(Math.sin(aimTimer * 0.05)); // Angle oscillates between min and max aimAngle += aimDir * 0.012; if (aimAngle > aimMaxAngle) aimDir = -1; if (aimAngle < aimMinAngle) aimDir = 1; bat.setAngle(aimAngle); // Bat color flashes with power var color = 0x964b00 + Math.floor(aimPower * 0x002200); bat.children[0].tint = color; } // Update geek if (geek) geek.update(); // Camera follow: move all objects left as geek moves if (geek && geek.isFlying) { var camX = Math.max(0, geek.x - 350); // Move all except GUI and ground for (var i = 0; i < rocks.length; i++) rocks[i].x -= camX - (rocks[i].camX || 0); for (var i = 0; i < springs.length; i++) springs[i].x -= camX - (springs[i].camX || 0); if (bat && !bat.destroyed) bat.x -= camX - (bat.camX || 0); geek.x -= camX - (geek.camX || 0); // Store camX for next frame for (var i = 0; i < rocks.length; i++) rocks[i].camX = camX; for (var i = 0; i < springs.length; i++) springs[i].camX = camX; if (bat && !bat.destroyed) bat.camX = camX; geek.camX = camX; } // Collisions: obstacles if (geek && geek.isFlying && !geek.isStopped) { for (var i = 0; i < rocks.length; i++) { var rock = rocks[i]; if (!rock.hit && checkCollision(geek, rock)) { // Hit rock: lose speed, bounce up geek.vx *= 0.6; geek.vy = -Math.abs(geek.vy) * 0.7 - 8; geek.rotationSpeed *= 0.7; rock.hit = true; LK.effects.flashObject(rock, 0xff0000, 400); LK.getSound('bounce').play(); } } // Collisions: power-ups for (var i = 0; i < springs.length; i++) { var spring = springs[i]; if (!spring.used && checkCollision(geek, spring)) { // Hit spring: big bounce, gain coins geek.vy = -32 - 8 * upgrades.bounce; geek.vx *= 1.12; geek.rotationSpeed += 0.2; spring.used = true; runCoins += 5; LK.effects.flashObject(spring, 0xffd700, 500); LK.getSound('powerup').play(); } } } // Update GUI if (geek) { var dist = Math.floor(geek.distance / 10); scoreTxt.setText(dist + ' m'); } coinTxt.setText('' + coins); // If geek stopped, allow upgrades and restart if (geek && geek.isStopped && gameState !== 'stopped') { gameState = 'stopped'; upgradeTxt.setText('Tap bottom to upgrade: Power(' + upgrades.power + '), Bounce(' + upgrades.bounce + ')'); } }; // --- Game over handler --- LK.on('gameover', function () { // Reset run for next play resetRun(); }); // --- Music --- LK.playMusic('bgmusic', { fade: { start: 0, end: 1, duration: 1000 } }); // --- Start game --- resetRun();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
bestDistance: 0,
coins: 0,
upgrades: {
power: 1,
bounce: 1
}
});
/****
* Classes
****/
// Bat class: the weapon to hit the geek
var Bat = Container.expand(function () {
var self = Container.call(this);
var batSprite = self.attachAsset('bat', {
anchorX: 0.1,
anchorY: 0.5
});
self.swinging = false;
self.angle = -Math.PI / 4; // resting angle
self.power = 0;
self.maxPower = 1;
self.swingTween = null;
self.setAngle = function (a) {
self.rotation = a;
self.angle = a;
};
self.swing = function (onHit) {
if (self.swinging) return;
self.swinging = true;
// Animate swing
tween(self, {
rotation: Math.PI / 2
}, {
duration: 180,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.swinging = false;
self.setAngle(-Math.PI / 4);
if (onHit) onHit();
}
});
};
return self;
});
// Geek class: the character to launch
var Geek = Container.expand(function () {
var self = Container.call(this);
var geekSprite = self.attachAsset('geek', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = geekSprite.width / 2;
self.vx = 0; // velocity x
self.vy = 0; // velocity y
self.rotationSpeed = 0;
self.isFlying = false;
self.isStopped = false;
self.distance = 0;
self.bounceCount = 0;
// For collision detection
self.getBounds = function () {
return {
x: self.x - self.radius,
y: self.y - self.radius,
width: self.radius * 2,
height: self.radius * 2
};
};
// Called every tick
self.update = function () {
if (!self.isFlying || self.isStopped) return;
// Physics
self.x += self.vx;
self.y += self.vy;
self.vy += 1.2; // gravity
// Air friction
self.vx *= 0.995;
self.vy *= 0.995;
// Rotation
self.rotation += self.rotationSpeed;
// Distance tracking
self.distance += self.vx;
// Ground collision
if (self.y + self.radius >= groundY) {
self.y = groundY - self.radius;
if (Math.abs(self.vy) > 8) {
// Bounce
self.vy = -Math.abs(self.vy) * (0.45 + 0.05 * upgrades.bounce);
self.vx *= 0.92;
self.rotationSpeed *= 0.7;
self.bounceCount++;
LK.getSound('bounce').play();
// Small upward nudge to avoid sticking
self.y -= 2;
} else {
// Stop
self.vy = 0;
self.vx = 0;
self.isStopped = true;
self.isFlying = false;
onGeekStopped();
}
}
};
return self;
});
// Obstacle (rock)
var Rock = Container.expand(function () {
var self = Container.call(this);
var rockSprite = self.attachAsset('rock', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = rockSprite.width / 2;
self.getBounds = function () {
return {
x: self.x - self.radius,
y: self.y - self.radius,
width: self.radius * 2,
height: self.radius * 2
};
};
return self;
});
// Power-up (spring)
var Spring = Container.expand(function () {
var self = Container.call(this);
var springSprite = self.attachAsset('spring', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = springSprite.width / 2;
self.getBounds = function () {
return {
x: self.x - self.radius,
y: self.y - self.radius,
width: self.radius * 2,
height: self.radius * 2
};
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Sky blue
});
/****
* Game Code
****/
// Music
// Sound effects
// Power-up (spring)
// Obstacle (rock)
// Ground
// Bat (the weapon)
// Geek (the character to launch)
// --- Global variables ---
var groundY = 2732 - 80; // ground top
var geek, bat;
var rocks = [];
var springs = [];
var upgrades = storage.upgrades || {
power: 1,
bounce: 1
};
var coins = storage.coins || 0;
var bestDistance = storage.bestDistance || 0;
var runDistance = 0;
var runCoins = 0;
var isAiming = false;
var aimPower = 0;
var aimAngle = -Math.PI / 4;
var aimMaxPower = 1.5 + 0.2 * upgrades.power;
var aimMinAngle = -Math.PI / 3;
var aimMaxAngle = -Math.PI / 8;
var aimDir = 1;
var aimTimer = 0;
var gameState = 'aim'; // 'aim', 'flying', 'stopped'
// --- GUI ---
var scoreTxt = new Text2('0 m', {
size: 100,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var coinTxt = new Text2('0', {
size: 70,
fill: 0xFFD700
});
coinTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(coinTxt);
var bestTxt = new Text2('Best: 0 m', {
size: 60,
fill: "#fff"
});
bestTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(bestTxt);
var upgradeTxt = new Text2('', {
size: 60,
fill: "#fff"
});
upgradeTxt.anchor.set(0.5, 1);
LK.gui.bottom.addChild(upgradeTxt);
// --- Ground ---
var ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: groundY
});
game.addChild(ground);
// --- Functions ---
function resetRun() {
// Remove old objects
if (geek) geek.destroy();
if (bat) bat.destroy();
for (var i = 0; i < rocks.length; i++) rocks[i].destroy();
for (var i = 0; i < springs.length; i++) springs[i].destroy();
rocks = [];
springs = [];
runDistance = 0;
runCoins = 0;
aimPower = 0;
aimAngle = -Math.PI / 4;
aimDir = 1;
aimTimer = 0;
gameState = 'aim';
// Geek
geek = new Geek();
geek.x = 350;
geek.y = groundY - 120;
geek.rotation = 0;
game.addChild(geek);
// Bat
bat = new Bat();
bat.x = geek.x - 80;
bat.y = groundY - 120;
bat.setAngle(-Math.PI / 4);
game.addChild(bat);
// Obstacles
for (var i = 0; i < 3; i++) {
var rock = new Rock();
rock.x = 900 + 700 * i + Math.random() * 200;
rock.y = groundY - 30;
rocks.push(rock);
game.addChild(rock);
}
// Power-ups
for (var i = 0; i < 2; i++) {
var spring = new Spring();
spring.x = 1200 + 1000 * i + Math.random() * 300;
spring.y = groundY - 20;
springs.push(spring);
game.addChild(spring);
}
// GUI
scoreTxt.setText('0 m');
coinTxt.setText('' + coins);
bestTxt.setText('Best: ' + bestDistance + ' m');
upgradeTxt.setText('Tap bottom to upgrade: Power(' + upgrades.power + '), Bounce(' + upgrades.bounce + ')');
}
function onGeekStopped() {
// End of run
runDistance = Math.floor(geek.distance / 10);
if (runDistance > bestDistance) {
bestDistance = runDistance;
storage.bestDistance = bestDistance;
}
coins += Math.floor(runDistance / 10) + runCoins;
storage.coins = coins;
// Show game over
LK.effects.flashScreen(0x000000, 600);
LK.showGameOver();
}
function launchGeek(power, angle) {
// Bat swing animation
bat.swing(function () {
// Launch
var p = 38 * power * (1 + 0.15 * upgrades.power);
geek.vx = p * Math.cos(angle);
geek.vy = p * Math.sin(angle) - 10;
geek.rotationSpeed = 0.2 + 0.1 * power;
geek.isFlying = true;
gameState = 'flying';
LK.getSound('hit').play();
// Remove bat after swing
LK.setTimeout(function () {
bat.destroy();
}, 300);
});
}
// --- Input handling ---
game.down = function (x, y, obj) {
if (gameState === 'aim') {
isAiming = true;
aimTimer = 0;
} else if (gameState === 'stopped') {
// Check if bottom area tapped for upgrades
if (y > 2732 - 300) {
// Alternate upgrades: tap left half for power, right half for bounce
if (x < 2048 / 2) {
// Power upgrade
var cost = 10 + upgrades.power * 10;
if (coins >= cost) {
upgrades.power++;
coins -= cost;
storage.upgrades = upgrades;
storage.coins = coins;
LK.effects.flashObject(upgradeTxt, 0x00ff00, 400);
} else {
LK.effects.flashObject(upgradeTxt, 0xff0000, 400);
}
} else {
// Bounce upgrade
var cost = 10 + upgrades.bounce * 10;
if (coins >= cost) {
upgrades.bounce++;
coins -= cost;
storage.upgrades = upgrades;
storage.coins = coins;
LK.effects.flashObject(upgradeTxt, 0x00ff00, 400);
} else {
LK.effects.flashObject(upgradeTxt, 0xff0000, 400);
}
}
upgradeTxt.setText('Tap bottom to upgrade: Power(' + upgrades.power + '), Bounce(' + upgrades.bounce + ')');
coinTxt.setText('' + coins);
}
}
};
game.up = function (x, y, obj) {
if (gameState === 'aim' && isAiming) {
isAiming = false;
// Launch!
launchGeek(aimPower, aimAngle);
}
};
function checkCollision(a, b) {
var ab = a.getBounds();
var bb = b.getBounds();
return ab.x < bb.x + bb.width && ab.x + ab.width > bb.x && ab.y < bb.y + bb.height && ab.y + ab.height > bb.y;
}
// --- Main update loop ---
game.update = function () {
// Aiming phase
if (gameState === 'aim' && isAiming) {
// Power oscillates up and down
aimTimer++;
aimPower = 0.5 + 0.5 * Math.abs(Math.sin(aimTimer * 0.05));
// Angle oscillates between min and max
aimAngle += aimDir * 0.012;
if (aimAngle > aimMaxAngle) aimDir = -1;
if (aimAngle < aimMinAngle) aimDir = 1;
bat.setAngle(aimAngle);
// Bat color flashes with power
var color = 0x964b00 + Math.floor(aimPower * 0x002200);
bat.children[0].tint = color;
}
// Update geek
if (geek) geek.update();
// Camera follow: move all objects left as geek moves
if (geek && geek.isFlying) {
var camX = Math.max(0, geek.x - 350);
// Move all except GUI and ground
for (var i = 0; i < rocks.length; i++) rocks[i].x -= camX - (rocks[i].camX || 0);
for (var i = 0; i < springs.length; i++) springs[i].x -= camX - (springs[i].camX || 0);
if (bat && !bat.destroyed) bat.x -= camX - (bat.camX || 0);
geek.x -= camX - (geek.camX || 0);
// Store camX for next frame
for (var i = 0; i < rocks.length; i++) rocks[i].camX = camX;
for (var i = 0; i < springs.length; i++) springs[i].camX = camX;
if (bat && !bat.destroyed) bat.camX = camX;
geek.camX = camX;
}
// Collisions: obstacles
if (geek && geek.isFlying && !geek.isStopped) {
for (var i = 0; i < rocks.length; i++) {
var rock = rocks[i];
if (!rock.hit && checkCollision(geek, rock)) {
// Hit rock: lose speed, bounce up
geek.vx *= 0.6;
geek.vy = -Math.abs(geek.vy) * 0.7 - 8;
geek.rotationSpeed *= 0.7;
rock.hit = true;
LK.effects.flashObject(rock, 0xff0000, 400);
LK.getSound('bounce').play();
}
}
// Collisions: power-ups
for (var i = 0; i < springs.length; i++) {
var spring = springs[i];
if (!spring.used && checkCollision(geek, spring)) {
// Hit spring: big bounce, gain coins
geek.vy = -32 - 8 * upgrades.bounce;
geek.vx *= 1.12;
geek.rotationSpeed += 0.2;
spring.used = true;
runCoins += 5;
LK.effects.flashObject(spring, 0xffd700, 500);
LK.getSound('powerup').play();
}
}
}
// Update GUI
if (geek) {
var dist = Math.floor(geek.distance / 10);
scoreTxt.setText(dist + ' m');
}
coinTxt.setText('' + coins);
// If geek stopped, allow upgrades and restart
if (geek && geek.isStopped && gameState !== 'stopped') {
gameState = 'stopped';
upgradeTxt.setText('Tap bottom to upgrade: Power(' + upgrades.power + '), Bounce(' + upgrades.bounce + ')');
}
};
// --- Game over handler ---
LK.on('gameover', function () {
// Reset run for next play
resetRun();
});
// --- Music ---
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
// --- Start game ---
resetRun();