/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BlackHole = Container.expand(function () {
var self = Container.call(this);
var blackholeGraphics = self.attachAsset('blackhole', {
anchorX: 0.5,
anchorY: 0.5
});
blackholeGraphics.tint = 0x1a1a1a;
self.type = 'blackhole';
self.pullForce = 0.3;
self.pullRadius = 400;
self.damageRadius = 120;
self.rotation = 0;
self.rotationSpeed = 0.02;
self.pulse = 0;
self.update = function () {
self.rotation += self.rotationSpeed;
self.pulse += 0.05;
var pulseScale = 1 + Math.sin(self.pulse) * 0.05;
blackholeGraphics.scaleX = pulseScale;
blackholeGraphics.scaleY = pulseScale;
};
self.getPullDirection = function (targetX, targetY) {
var dx = self.x - targetX;
var dy = self.y - targetY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.pullRadius && distance > 0) {
return {
angle: Math.atan2(dy, dx),
distance: distance,
force: (1 - distance / self.pullRadius) * self.pullForce
};
}
return null;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0x654321;
self.type = 'bullet';
self.speed = 6;
self.lastY = 0;
self.rotation = 0;
self.rotationSpeed = 0.08;
self.update = function () {
self.y += self.speed;
self.lastY = self.y;
self.rotation += self.rotationSpeed;
};
return self;
});
var Eye = Container.expand(function () {
var self = Container.call(this);
var eyeWhite = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var pupil = self.attachAsset('pupil', {
anchorX: 0.5,
anchorY: 0.5
});
pupil.x = 5;
pupil.y = 5;
self.setPupilPosition = function (targetX, targetY) {
var maxDistance = 8;
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var angle = Math.atan2(dy, dx);
pupil.x = Math.cos(angle) * maxDistance;
pupil.y = Math.sin(angle) * maxDistance;
}
};
return self;
});
var EyeBall = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
var leftEye = self.addChild(new Eye());
leftEye.x = -30;
leftEye.y = -20;
var rightEye = self.addChild(new Eye());
rightEye.x = 30;
rightEye.y = -20;
var mouth = self.attachAsset('mouth', {
anchorX: 0.5,
anchorY: 0.5
});
mouth.y = 35;
mouth.scaleX = 0.8;
mouth.scaleY = 0.6;
self.speed = 0;
self.maxSpeed = 8;
self.acceleration = 0.5;
self.friction = 0.92;
self.vx = 0;
self.vy = 0;
self.setTarget = function (targetX, targetY) {
leftEye.setPupilPosition(targetX, targetY);
rightEye.setPupilPosition(targetX, targetY);
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
var angle = Math.atan2(dy, dx);
self.vx += Math.cos(angle) * self.acceleration;
self.vy += Math.sin(angle) * self.acceleration;
}
};
self.update = function () {
self.vx *= self.friction;
self.vy *= self.friction;
var currentSpeed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
if (currentSpeed > self.maxSpeed) {
var scale = self.maxSpeed / currentSpeed;
self.vx *= scale;
self.vy *= scale;
}
self.x += self.vx;
self.y += self.vy;
if (self.x < 60) self.x = 60;
if (self.x > 2048 - 60) self.x = 2048 - 60;
if (self.y < 60) self.y = 60;
if (self.y > 2732 - 60) self.y = 2732 - 60;
};
return self;
});
var Goal = Container.expand(function () {
var self = Container.call(this);
var doorBody = self.attachAsset('goal', {
anchorX: 0.5,
anchorY: 0.5
});
doorBody.tint = 0x654321;
var doorHandle = self.attachAsset('doorHandle', {
anchorX: 0.5,
anchorY: 0.5
});
doorHandle.x = 25;
doorHandle.y = 0;
self.pulse = 0;
self.update = function () {
self.pulse += 0.05;
var scale = 1 + Math.sin(self.pulse) * 0.05;
doorBody.scaleX = scale;
doorBody.scaleY = scale;
doorHandle.scaleX = scale;
doorHandle.scaleY = scale;
};
return self;
});
var MovingObstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
obstacleGraphics.tint = 0xFF6666;
self.type = 'moving';
self.startX = 0;
self.startY = 0;
self.endX = 0;
self.endY = 0;
self.progress = 0;
self.speed = 0.01;
self.update = function () {
self.progress += self.speed;
if (self.progress > 1) self.progress = 0;
self.x = self.startX + (self.endX - self.startX) * self.progress;
self.y = self.startY + (self.endY - self.startY) * self.progress;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
obstacleGraphics.tint = 0xFF6600;
var flameFlicker = 0;
self.type = 'static';
self.update = function () {
flameFlicker += 0.15;
var flameScale = 1 + Math.sin(flameFlicker) * 0.1;
obstacleGraphics.scaleX = flameScale;
obstacleGraphics.scaleY = flameScale;
};
return self;
});
var Spike = Container.expand(function () {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
spikeGraphics.tint = 0xFF8800;
spikeGraphics.rotation = Math.PI / 4;
self.type = 'hazard';
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
starGraphics.tint = 0xFFFF00;
self.twinkle = 0;
self.lastWasIntersecting = false;
self.update = function () {
self.twinkle += 0.08;
var twinkleScale = 0.6 + Math.sin(self.twinkle) * 0.4;
starGraphics.scaleX = twinkleScale;
starGraphics.scaleY = twinkleScale;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1A1A2E
});
/****
* Game Code
****/
var eyeBall = game.addChild(new EyeBall());
eyeBall.x = 1024;
eyeBall.y = 1366;
var currentStage = storage.currentStage || 1;
var livesRemaining = 3;
var obstacles = [];
var goal = null;
var stageComplete = false;
var gameState = 'playing';
var dragNode = null;
var bullets = [];
var bulletSpawnRate = 80;
var bulletSpawnTimer = 0;
var stageText = new Text2('Stage ' + currentStage + '/5', {
size: 80,
fill: '#FFFFFF'
});
stageText.anchor.set(0, 0);
LK.gui.topRight.addChild(stageText);
var livesText = new Text2('Lives: ' + livesRemaining, {
size: 80,
fill: '#FF4444'
});
livesText.anchor.set(1, 0);
LK.gui.topRight.addChild(livesText);
function createStageObstacles(stage) {
obstacles = [];
bulletSpawnRate = 80 - stage * 10;
if (bulletSpawnRate < 40) bulletSpawnRate = 40;
var obs1 = game.addChild(new Obstacle());
obs1.x = 400;
obs1.y = 600;
obstacles.push(obs1);
if (stage >= 2) {
var movObs = game.addChild(new MovingObstacle());
movObs.startX = 600;
movObs.startY = 1000;
movObs.endX = 1400;
movObs.endY = 1000;
movObs.speed = 0.005;
movObs.x = movObs.startX;
movObs.y = movObs.startY;
obstacles.push(movObs);
}
if (stage >= 3) {
var spike1 = game.addChild(new Spike());
spike1.x = 800;
spike1.y = 1500;
obstacles.push(spike1);
var spike2 = game.addChild(new Spike());
spike2.x = 1200;
spike2.y = 1800;
obstacles.push(spike2);
}
if (stage >= 4) {
var obs2 = game.addChild(new Obstacle());
obs2.x = 1600;
obs2.y = 800;
obstacles.push(obs2);
var movObs2 = game.addChild(new MovingObstacle());
movObs2.startX = 300;
movObs2.startY = 2000;
movObs2.endX = 1700;
movObs2.endY = 2000;
movObs2.speed = 0.008;
movObs2.x = movObs2.startX;
movObs2.y = movObs2.startY;
obstacles.push(movObs2);
}
if (stage >= 5) {
var movObs3 = game.addChild(new MovingObstacle());
movObs3.startX = 500;
movObs3.startY = 500;
movObs3.endX = 1500;
movObs3.endY = 500;
movObs3.speed = 0.012;
movObs3.x = movObs3.startX;
movObs3.y = movObs3.startY;
obstacles.push(movObs3);
var spike3 = game.addChild(new Spike());
spike3.x = 1024;
spike3.y = 1366;
obstacles.push(spike3);
}
if (stage >= 3) {
var blackhole1 = game.addChild(new BlackHole());
blackhole1.x = 1024;
blackhole1.y = 800;
obstacles.push(blackhole1);
}
if (stage >= 4) {
var blackhole2 = game.addChild(new BlackHole());
blackhole2.x = 500;
blackhole2.y = 1500;
obstacles.push(blackhole2);
}
if (stage >= 5) {
var blackhole3 = game.addChild(new BlackHole());
blackhole3.x = 1550;
blackhole3.y = 1400;
obstacles.push(blackhole3);
}
}
function addGoalBarriers(stage) {
if (stage === 1) {
var barrier1 = game.addChild(new Obstacle());
barrier1.x = 1024;
barrier1.y = 2200;
obstacles.push(barrier1);
}
if (stage === 2) {
var barrier2a = game.addChild(new Obstacle());
barrier2a.x = 800;
barrier2a.y = 2350;
obstacles.push(barrier2a);
var barrier2b = game.addChild(new Obstacle());
barrier2b.x = 1250;
barrier2b.y = 2350;
obstacles.push(barrier2b);
}
if (stage === 3) {
var barrier3a = game.addChild(new MovingObstacle());
barrier3a.startX = 600;
barrier3a.startY = 2200;
barrier3a.endX = 1400;
barrier3a.endY = 2200;
barrier3a.speed = 0.006;
barrier3a.x = barrier3a.startX;
barrier3a.y = barrier3a.startY;
obstacles.push(barrier3a);
var barrier3b = game.addChild(new Obstacle());
barrier3b.x = 1024;
barrier3b.y = 2100;
obstacles.push(barrier3b);
}
if (stage === 4) {
var barrier4a = game.addChild(new Obstacle());
barrier4a.x = 400;
barrier4a.y = 2250;
obstacles.push(barrier4a);
var barrier4b = game.addChild(new Obstacle());
barrier4b.x = 1650;
barrier4b.y = 2250;
obstacles.push(barrier4b);
var barrier4c = game.addChild(new Obstacle());
barrier4c.x = 1024;
barrier4c.y = 2100;
obstacles.push(barrier4c);
}
if (stage === 5) {
var barrier5a = game.addChild(new MovingObstacle());
barrier5a.startX = 300;
barrier5a.startY = 2300;
barrier5a.endX = 800;
barrier5a.endY = 2300;
barrier5a.speed = 0.008;
barrier5a.x = barrier5a.startX;
barrier5a.y = barrier5a.startY;
obstacles.push(barrier5a);
var barrier5b = game.addChild(new MovingObstacle());
barrier5b.startX = 1250;
barrier5b.startY = 2300;
barrier5b.endX = 1750;
barrier5b.endY = 2300;
barrier5b.speed = 0.008;
barrier5b.x = barrier5b.startX;
barrier5b.y = barrier5b.startY;
obstacles.push(barrier5b);
var spike4 = game.addChild(new Spike());
spike4.x = 1024;
spike4.y = 2500;
obstacles.push(spike4);
}
}
function createGoal(stage) {
if (goal) goal.destroy();
var goalPositions = [{
x: 1024,
y: 2500
}, {
x: 1024,
y: 2400
}, {
x: 1800,
y: 2200
}, {
x: 200,
y: 2300
}, {
x: 1024,
y: 2500
}];
var pos = goalPositions[stage - 1];
goal = game.addChild(new Goal());
goal.x = pos.x;
goal.y = pos.y;
stageComplete = false;
}
var stars = [];
function createStars() {
stars = [];
var starPositions = [{
x: 300,
y: 400
}, {
x: 700,
y: 300
}, {
x: 1300,
y: 500
}, {
x: 1700,
y: 350
}, {
x: 250,
y: 1000
}, {
x: 1800,
y: 1200
}, {
x: 500,
y: 1600
}, {
x: 1400,
y: 1800
}, {
x: 900,
y: 2000
}, {
x: 1600,
y: 2100
}, {
x: 350,
y: 500
}, {
x: 1100,
y: 700
}, {
x: 1900,
y: 1000
}, {
x: 600,
y: 1400
}, {
x: 1200,
y: 2200
}];
for (var s = 0; s < starPositions.length; s++) {
var star = game.addChild(new Star());
star.x = starPositions[s].x;
star.y = starPositions[s].y;
stars.push(star);
}
}
createStars();
createStageObstacles(currentStage);
addGoalBarriers(currentStage);
createGoal(currentStage);
game.move = function (x, y, obj) {
if (gameState === 'playing') {
eyeBall.setTarget(x, y);
}
};
game.down = function (x, y, obj) {
if (gameState === 'playing') {
eyeBall.setTarget(x, y);
}
};
game.up = function (x, y, obj) {};
game.update = function () {
if (gameState !== 'playing') return;
eyeBall.update();
for (var i = 0; i < stars.length; i++) {
if (stars[i].update) {
stars[i].update();
}
}
for (var i = 0; i < obstacles.length; i++) {
if (obstacles[i].update) {
obstacles[i].update();
}
}
if (goal && goal.update) {
goal.update();
}
bulletSpawnTimer++;
if (bulletSpawnTimer >= bulletSpawnRate) {
bulletSpawnTimer = 0;
var newBullet = game.addChild(new Bullet());
newBullet.x = Math.random() * 1800 + 100;
newBullet.y = -50;
newBullet.lastY = newBullet.y;
bullets.push(newBullet);
}
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
bullet.update();
if (bullet.y > 2800) {
bullet.destroy();
bullets.splice(b, 1);
continue;
}
if (eyeBall.intersects(bullet)) {
LK.getSound('loseLifeSound').play();
LK.effects.flashScreen(0xFF0000, 300);
livesRemaining--;
livesText.setText('Lives: ' + livesRemaining);
bullet.destroy();
bullets.splice(b, 1);
if (livesRemaining <= 0) {
gameState = 'gameover';
LK.setTimeout(function () {
currentStage = storage.currentStage || 1;
livesRemaining = 3;
storage.currentStage = 1;
LK.showGameOver();
}, 500);
} else {
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
}
break;
}
}
if (goal && eyeBall.intersects(goal) && !stageComplete) {
stageComplete = true;
LK.getSound('goalSound').play();
LK.effects.flashScreen(0x00FF00, 500);
storage.currentStage = currentStage + 1;
if (currentStage >= 5) {
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
} else {
LK.setTimeout(function () {
currentStage = storage.currentStage;
livesRemaining = 3;
obstacles = [];
bullets = [];
for (var j = obstacles.length - 1; j >= 0; j--) {
if (obstacles[j]) obstacles[j].destroy();
}
for (var jb = bullets.length - 1; jb >= 0; jb--) {
if (bullets[jb]) bullets[jb].destroy();
}
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
for (var st = stars.length - 1; st >= 0; st--) {
if (stars[st]) stars[st].destroy();
}
createStars();
createStageObstacles(currentStage);
addGoalBarriers(currentStage);
createGoal(currentStage);
stageText.setText('Stage ' + currentStage + '/5');
livesText.setText('Lives: ' + livesRemaining);
gameState = 'playing';
}, 1500);
}
gameState = 'stageComplete';
return;
}
for (var st_col = 0; st_col < stars.length; st_col++) {
var star = stars[st_col];
var starIntersecting = eyeBall.intersects(star);
if (star.lastWasIntersecting === undefined) star.lastWasIntersecting = false;
star.lastWasIntersecting = starIntersecting;
}
for (var k = 0; k < obstacles.length; k++) {
var obstacle = obstacles[k];
if (obstacle.type === 'blackhole') {
var pullData = obstacle.getPullDirection(eyeBall.x, eyeBall.y);
if (pullData) {
eyeBall.vx += Math.cos(pullData.angle) * pullData.force;
eyeBall.vy += Math.sin(pullData.angle) * pullData.force;
}
if (eyeBall.x - eyeBall.y >= obstacle.x - obstacle.y - obstacle.damageRadius && eyeBall.x - eyeBall.y <= obstacle.x - obstacle.y + obstacle.damageRadius && Math.sqrt((eyeBall.x - obstacle.x) * (eyeBall.x - obstacle.x) + (eyeBall.y - obstacle.y) * (eyeBall.y - obstacle.y)) < obstacle.damageRadius) {
LK.getSound('loseLifeSound').play();
LK.effects.flashScreen(0xFF0000, 300);
livesRemaining--;
livesText.setText('Lives: ' + livesRemaining);
if (livesRemaining <= 0) {
gameState = 'gameover';
LK.setTimeout(function () {
currentStage = storage.currentStage || 1;
livesRemaining = 3;
storage.currentStage = 1;
LK.showGameOver();
}, 500);
} else {
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
}
break;
}
} else if (eyeBall.intersects(obstacle)) {
LK.getSound('loseLifeSound').play();
LK.effects.flashScreen(0xFF0000, 300);
livesRemaining--;
livesText.setText('Lives: ' + livesRemaining);
if (livesRemaining <= 0) {
gameState = 'gameover';
LK.setTimeout(function () {
currentStage = storage.currentStage || 1;
livesRemaining = 3;
storage.currentStage = 1;
LK.showGameOver();
}, 500);
} else {
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
}
break;
}
}
};
LK.playMusic('bgmusic', {
loop: true
}); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BlackHole = Container.expand(function () {
var self = Container.call(this);
var blackholeGraphics = self.attachAsset('blackhole', {
anchorX: 0.5,
anchorY: 0.5
});
blackholeGraphics.tint = 0x1a1a1a;
self.type = 'blackhole';
self.pullForce = 0.3;
self.pullRadius = 400;
self.damageRadius = 120;
self.rotation = 0;
self.rotationSpeed = 0.02;
self.pulse = 0;
self.update = function () {
self.rotation += self.rotationSpeed;
self.pulse += 0.05;
var pulseScale = 1 + Math.sin(self.pulse) * 0.05;
blackholeGraphics.scaleX = pulseScale;
blackholeGraphics.scaleY = pulseScale;
};
self.getPullDirection = function (targetX, targetY) {
var dx = self.x - targetX;
var dy = self.y - targetY;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.pullRadius && distance > 0) {
return {
angle: Math.atan2(dy, dx),
distance: distance,
force: (1 - distance / self.pullRadius) * self.pullForce
};
}
return null;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0x654321;
self.type = 'bullet';
self.speed = 6;
self.lastY = 0;
self.rotation = 0;
self.rotationSpeed = 0.08;
self.update = function () {
self.y += self.speed;
self.lastY = self.y;
self.rotation += self.rotationSpeed;
};
return self;
});
var Eye = Container.expand(function () {
var self = Container.call(this);
var eyeWhite = self.attachAsset('eye', {
anchorX: 0.5,
anchorY: 0.5
});
var pupil = self.attachAsset('pupil', {
anchorX: 0.5,
anchorY: 0.5
});
pupil.x = 5;
pupil.y = 5;
self.setPupilPosition = function (targetX, targetY) {
var maxDistance = 8;
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var angle = Math.atan2(dy, dx);
pupil.x = Math.cos(angle) * maxDistance;
pupil.y = Math.sin(angle) * maxDistance;
}
};
return self;
});
var EyeBall = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
var leftEye = self.addChild(new Eye());
leftEye.x = -30;
leftEye.y = -20;
var rightEye = self.addChild(new Eye());
rightEye.x = 30;
rightEye.y = -20;
var mouth = self.attachAsset('mouth', {
anchorX: 0.5,
anchorY: 0.5
});
mouth.y = 35;
mouth.scaleX = 0.8;
mouth.scaleY = 0.6;
self.speed = 0;
self.maxSpeed = 8;
self.acceleration = 0.5;
self.friction = 0.92;
self.vx = 0;
self.vy = 0;
self.setTarget = function (targetX, targetY) {
leftEye.setPupilPosition(targetX, targetY);
rightEye.setPupilPosition(targetX, targetY);
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 50) {
var angle = Math.atan2(dy, dx);
self.vx += Math.cos(angle) * self.acceleration;
self.vy += Math.sin(angle) * self.acceleration;
}
};
self.update = function () {
self.vx *= self.friction;
self.vy *= self.friction;
var currentSpeed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
if (currentSpeed > self.maxSpeed) {
var scale = self.maxSpeed / currentSpeed;
self.vx *= scale;
self.vy *= scale;
}
self.x += self.vx;
self.y += self.vy;
if (self.x < 60) self.x = 60;
if (self.x > 2048 - 60) self.x = 2048 - 60;
if (self.y < 60) self.y = 60;
if (self.y > 2732 - 60) self.y = 2732 - 60;
};
return self;
});
var Goal = Container.expand(function () {
var self = Container.call(this);
var doorBody = self.attachAsset('goal', {
anchorX: 0.5,
anchorY: 0.5
});
doorBody.tint = 0x654321;
var doorHandle = self.attachAsset('doorHandle', {
anchorX: 0.5,
anchorY: 0.5
});
doorHandle.x = 25;
doorHandle.y = 0;
self.pulse = 0;
self.update = function () {
self.pulse += 0.05;
var scale = 1 + Math.sin(self.pulse) * 0.05;
doorBody.scaleX = scale;
doorBody.scaleY = scale;
doorHandle.scaleX = scale;
doorHandle.scaleY = scale;
};
return self;
});
var MovingObstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
obstacleGraphics.tint = 0xFF6666;
self.type = 'moving';
self.startX = 0;
self.startY = 0;
self.endX = 0;
self.endY = 0;
self.progress = 0;
self.speed = 0.01;
self.update = function () {
self.progress += self.speed;
if (self.progress > 1) self.progress = 0;
self.x = self.startX + (self.endX - self.startX) * self.progress;
self.y = self.startY + (self.endY - self.startY) * self.progress;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
obstacleGraphics.tint = 0xFF6600;
var flameFlicker = 0;
self.type = 'static';
self.update = function () {
flameFlicker += 0.15;
var flameScale = 1 + Math.sin(flameFlicker) * 0.1;
obstacleGraphics.scaleX = flameScale;
obstacleGraphics.scaleY = flameScale;
};
return self;
});
var Spike = Container.expand(function () {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
spikeGraphics.tint = 0xFF8800;
spikeGraphics.rotation = Math.PI / 4;
self.type = 'hazard';
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
starGraphics.tint = 0xFFFF00;
self.twinkle = 0;
self.lastWasIntersecting = false;
self.update = function () {
self.twinkle += 0.08;
var twinkleScale = 0.6 + Math.sin(self.twinkle) * 0.4;
starGraphics.scaleX = twinkleScale;
starGraphics.scaleY = twinkleScale;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1A1A2E
});
/****
* Game Code
****/
var eyeBall = game.addChild(new EyeBall());
eyeBall.x = 1024;
eyeBall.y = 1366;
var currentStage = storage.currentStage || 1;
var livesRemaining = 3;
var obstacles = [];
var goal = null;
var stageComplete = false;
var gameState = 'playing';
var dragNode = null;
var bullets = [];
var bulletSpawnRate = 80;
var bulletSpawnTimer = 0;
var stageText = new Text2('Stage ' + currentStage + '/5', {
size: 80,
fill: '#FFFFFF'
});
stageText.anchor.set(0, 0);
LK.gui.topRight.addChild(stageText);
var livesText = new Text2('Lives: ' + livesRemaining, {
size: 80,
fill: '#FF4444'
});
livesText.anchor.set(1, 0);
LK.gui.topRight.addChild(livesText);
function createStageObstacles(stage) {
obstacles = [];
bulletSpawnRate = 80 - stage * 10;
if (bulletSpawnRate < 40) bulletSpawnRate = 40;
var obs1 = game.addChild(new Obstacle());
obs1.x = 400;
obs1.y = 600;
obstacles.push(obs1);
if (stage >= 2) {
var movObs = game.addChild(new MovingObstacle());
movObs.startX = 600;
movObs.startY = 1000;
movObs.endX = 1400;
movObs.endY = 1000;
movObs.speed = 0.005;
movObs.x = movObs.startX;
movObs.y = movObs.startY;
obstacles.push(movObs);
}
if (stage >= 3) {
var spike1 = game.addChild(new Spike());
spike1.x = 800;
spike1.y = 1500;
obstacles.push(spike1);
var spike2 = game.addChild(new Spike());
spike2.x = 1200;
spike2.y = 1800;
obstacles.push(spike2);
}
if (stage >= 4) {
var obs2 = game.addChild(new Obstacle());
obs2.x = 1600;
obs2.y = 800;
obstacles.push(obs2);
var movObs2 = game.addChild(new MovingObstacle());
movObs2.startX = 300;
movObs2.startY = 2000;
movObs2.endX = 1700;
movObs2.endY = 2000;
movObs2.speed = 0.008;
movObs2.x = movObs2.startX;
movObs2.y = movObs2.startY;
obstacles.push(movObs2);
}
if (stage >= 5) {
var movObs3 = game.addChild(new MovingObstacle());
movObs3.startX = 500;
movObs3.startY = 500;
movObs3.endX = 1500;
movObs3.endY = 500;
movObs3.speed = 0.012;
movObs3.x = movObs3.startX;
movObs3.y = movObs3.startY;
obstacles.push(movObs3);
var spike3 = game.addChild(new Spike());
spike3.x = 1024;
spike3.y = 1366;
obstacles.push(spike3);
}
if (stage >= 3) {
var blackhole1 = game.addChild(new BlackHole());
blackhole1.x = 1024;
blackhole1.y = 800;
obstacles.push(blackhole1);
}
if (stage >= 4) {
var blackhole2 = game.addChild(new BlackHole());
blackhole2.x = 500;
blackhole2.y = 1500;
obstacles.push(blackhole2);
}
if (stage >= 5) {
var blackhole3 = game.addChild(new BlackHole());
blackhole3.x = 1550;
blackhole3.y = 1400;
obstacles.push(blackhole3);
}
}
function addGoalBarriers(stage) {
if (stage === 1) {
var barrier1 = game.addChild(new Obstacle());
barrier1.x = 1024;
barrier1.y = 2200;
obstacles.push(barrier1);
}
if (stage === 2) {
var barrier2a = game.addChild(new Obstacle());
barrier2a.x = 800;
barrier2a.y = 2350;
obstacles.push(barrier2a);
var barrier2b = game.addChild(new Obstacle());
barrier2b.x = 1250;
barrier2b.y = 2350;
obstacles.push(barrier2b);
}
if (stage === 3) {
var barrier3a = game.addChild(new MovingObstacle());
barrier3a.startX = 600;
barrier3a.startY = 2200;
barrier3a.endX = 1400;
barrier3a.endY = 2200;
barrier3a.speed = 0.006;
barrier3a.x = barrier3a.startX;
barrier3a.y = barrier3a.startY;
obstacles.push(barrier3a);
var barrier3b = game.addChild(new Obstacle());
barrier3b.x = 1024;
barrier3b.y = 2100;
obstacles.push(barrier3b);
}
if (stage === 4) {
var barrier4a = game.addChild(new Obstacle());
barrier4a.x = 400;
barrier4a.y = 2250;
obstacles.push(barrier4a);
var barrier4b = game.addChild(new Obstacle());
barrier4b.x = 1650;
barrier4b.y = 2250;
obstacles.push(barrier4b);
var barrier4c = game.addChild(new Obstacle());
barrier4c.x = 1024;
barrier4c.y = 2100;
obstacles.push(barrier4c);
}
if (stage === 5) {
var barrier5a = game.addChild(new MovingObstacle());
barrier5a.startX = 300;
barrier5a.startY = 2300;
barrier5a.endX = 800;
barrier5a.endY = 2300;
barrier5a.speed = 0.008;
barrier5a.x = barrier5a.startX;
barrier5a.y = barrier5a.startY;
obstacles.push(barrier5a);
var barrier5b = game.addChild(new MovingObstacle());
barrier5b.startX = 1250;
barrier5b.startY = 2300;
barrier5b.endX = 1750;
barrier5b.endY = 2300;
barrier5b.speed = 0.008;
barrier5b.x = barrier5b.startX;
barrier5b.y = barrier5b.startY;
obstacles.push(barrier5b);
var spike4 = game.addChild(new Spike());
spike4.x = 1024;
spike4.y = 2500;
obstacles.push(spike4);
}
}
function createGoal(stage) {
if (goal) goal.destroy();
var goalPositions = [{
x: 1024,
y: 2500
}, {
x: 1024,
y: 2400
}, {
x: 1800,
y: 2200
}, {
x: 200,
y: 2300
}, {
x: 1024,
y: 2500
}];
var pos = goalPositions[stage - 1];
goal = game.addChild(new Goal());
goal.x = pos.x;
goal.y = pos.y;
stageComplete = false;
}
var stars = [];
function createStars() {
stars = [];
var starPositions = [{
x: 300,
y: 400
}, {
x: 700,
y: 300
}, {
x: 1300,
y: 500
}, {
x: 1700,
y: 350
}, {
x: 250,
y: 1000
}, {
x: 1800,
y: 1200
}, {
x: 500,
y: 1600
}, {
x: 1400,
y: 1800
}, {
x: 900,
y: 2000
}, {
x: 1600,
y: 2100
}, {
x: 350,
y: 500
}, {
x: 1100,
y: 700
}, {
x: 1900,
y: 1000
}, {
x: 600,
y: 1400
}, {
x: 1200,
y: 2200
}];
for (var s = 0; s < starPositions.length; s++) {
var star = game.addChild(new Star());
star.x = starPositions[s].x;
star.y = starPositions[s].y;
stars.push(star);
}
}
createStars();
createStageObstacles(currentStage);
addGoalBarriers(currentStage);
createGoal(currentStage);
game.move = function (x, y, obj) {
if (gameState === 'playing') {
eyeBall.setTarget(x, y);
}
};
game.down = function (x, y, obj) {
if (gameState === 'playing') {
eyeBall.setTarget(x, y);
}
};
game.up = function (x, y, obj) {};
game.update = function () {
if (gameState !== 'playing') return;
eyeBall.update();
for (var i = 0; i < stars.length; i++) {
if (stars[i].update) {
stars[i].update();
}
}
for (var i = 0; i < obstacles.length; i++) {
if (obstacles[i].update) {
obstacles[i].update();
}
}
if (goal && goal.update) {
goal.update();
}
bulletSpawnTimer++;
if (bulletSpawnTimer >= bulletSpawnRate) {
bulletSpawnTimer = 0;
var newBullet = game.addChild(new Bullet());
newBullet.x = Math.random() * 1800 + 100;
newBullet.y = -50;
newBullet.lastY = newBullet.y;
bullets.push(newBullet);
}
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
bullet.update();
if (bullet.y > 2800) {
bullet.destroy();
bullets.splice(b, 1);
continue;
}
if (eyeBall.intersects(bullet)) {
LK.getSound('loseLifeSound').play();
LK.effects.flashScreen(0xFF0000, 300);
livesRemaining--;
livesText.setText('Lives: ' + livesRemaining);
bullet.destroy();
bullets.splice(b, 1);
if (livesRemaining <= 0) {
gameState = 'gameover';
LK.setTimeout(function () {
currentStage = storage.currentStage || 1;
livesRemaining = 3;
storage.currentStage = 1;
LK.showGameOver();
}, 500);
} else {
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
}
break;
}
}
if (goal && eyeBall.intersects(goal) && !stageComplete) {
stageComplete = true;
LK.getSound('goalSound').play();
LK.effects.flashScreen(0x00FF00, 500);
storage.currentStage = currentStage + 1;
if (currentStage >= 5) {
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
} else {
LK.setTimeout(function () {
currentStage = storage.currentStage;
livesRemaining = 3;
obstacles = [];
bullets = [];
for (var j = obstacles.length - 1; j >= 0; j--) {
if (obstacles[j]) obstacles[j].destroy();
}
for (var jb = bullets.length - 1; jb >= 0; jb--) {
if (bullets[jb]) bullets[jb].destroy();
}
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
for (var st = stars.length - 1; st >= 0; st--) {
if (stars[st]) stars[st].destroy();
}
createStars();
createStageObstacles(currentStage);
addGoalBarriers(currentStage);
createGoal(currentStage);
stageText.setText('Stage ' + currentStage + '/5');
livesText.setText('Lives: ' + livesRemaining);
gameState = 'playing';
}, 1500);
}
gameState = 'stageComplete';
return;
}
for (var st_col = 0; st_col < stars.length; st_col++) {
var star = stars[st_col];
var starIntersecting = eyeBall.intersects(star);
if (star.lastWasIntersecting === undefined) star.lastWasIntersecting = false;
star.lastWasIntersecting = starIntersecting;
}
for (var k = 0; k < obstacles.length; k++) {
var obstacle = obstacles[k];
if (obstacle.type === 'blackhole') {
var pullData = obstacle.getPullDirection(eyeBall.x, eyeBall.y);
if (pullData) {
eyeBall.vx += Math.cos(pullData.angle) * pullData.force;
eyeBall.vy += Math.sin(pullData.angle) * pullData.force;
}
if (eyeBall.x - eyeBall.y >= obstacle.x - obstacle.y - obstacle.damageRadius && eyeBall.x - eyeBall.y <= obstacle.x - obstacle.y + obstacle.damageRadius && Math.sqrt((eyeBall.x - obstacle.x) * (eyeBall.x - obstacle.x) + (eyeBall.y - obstacle.y) * (eyeBall.y - obstacle.y)) < obstacle.damageRadius) {
LK.getSound('loseLifeSound').play();
LK.effects.flashScreen(0xFF0000, 300);
livesRemaining--;
livesText.setText('Lives: ' + livesRemaining);
if (livesRemaining <= 0) {
gameState = 'gameover';
LK.setTimeout(function () {
currentStage = storage.currentStage || 1;
livesRemaining = 3;
storage.currentStage = 1;
LK.showGameOver();
}, 500);
} else {
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
}
break;
}
} else if (eyeBall.intersects(obstacle)) {
LK.getSound('loseLifeSound').play();
LK.effects.flashScreen(0xFF0000, 300);
livesRemaining--;
livesText.setText('Lives: ' + livesRemaining);
if (livesRemaining <= 0) {
gameState = 'gameover';
LK.setTimeout(function () {
currentStage = storage.currentStage || 1;
livesRemaining = 3;
storage.currentStage = 1;
LK.showGameOver();
}, 500);
} else {
eyeBall.x = 1024;
eyeBall.y = 1366;
eyeBall.vx = 0;
eyeBall.vy = 0;
}
break;
}
}
};
LK.playMusic('bgmusic', {
loop: true
});