/****
* Classes
****/
// HeroBullet class representing the hero's projectiles
var HeroBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.createAsset('heroBullet', 'Hero Bullet', 0.5, 0.5);
self.speed = -10;
self.move = function () {
if (!hero.isTimestopped || self.timestopActive) {
self.y += self.speed;
if (self.y < -self.height) {
self.destroy();
}
}
};
self.timestopActive = false;
self.activateTimestop = function () {
self.timestopActive = true;
LK.setTimeout(function () {
self.timestopActive = false;
}, 100);
};
self.isOffScreen = function () {
return self.y < -self.height;
};
});
// EnemyBullet class representing the enemy's projectiles
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.createAsset('enemyBullet', 'Enemy Bullet', 0.5, 0.5);
self.speed = 5;
self.move = function () {
if (!hero.isTimestopped) {
self.y += self.speed;
if (self.y > game.height + self.height) {
self.destroy();
}
}
};
self.isOffScreen = function () {
return self.y > game.height + self.height;
};
});
// Hero class representing the main character
var Hero = Container.expand(function () {
var self = Container.call(this);
self.shoot = function () {
var bullets = [];
for (var i = -1; i <= 1; i++) {
var bullet = new HeroBullet();
bullet.x = self.x + i * 20;
bullet.y = self.y - self.height / 2;
game.addChild(bullet);
bullets.push(bullet);
}
return bullets;
};
var heroGraphics = self.createAsset('jojoHero', 'Main Hero', 0.5, 0.5);
self.speed = 5;
self.isTimestopped = false;
self.timestopDuration = 3000; // Initial timestop duration
self.timestopCooldown = 5000; // Cooldown duration in milliseconds
self.timestopAvailable = true; // Flag to check if timestop is available
self.move = function (direction) {
if (self.isTimestopped) {
return;
}
if (direction === 'left') {
self.x -= self.speed;
}
if (direction === 'right') {
self.x += self.speed;
}
if (direction === 'up') {
self.y -= self.speed;
}
if (direction === 'down') {
self.y += self.speed;
}
};
self.timestop = function () {
if (self.timestopAvailable) {
self.isTimestopped = true;
self.timestopAvailable = false;
heroBullets.forEach(function (bullet) {
bullet.activateTimestop();
});
self.timestopDuration += 100; // Increase duration by 0.1 seconds
timestopDurationTxt.setText(self.timestopDuration.toString()); // Update the timestop duration display
LK.setTimeout(function () {
self.isTimestopped = false;
}, self.timestopDuration);
LK.setTimeout(function () {
self.timestopAvailable = true;
}, self.timestopCooldown);
}
};
});
// ShopButton class representing the button to open the shop
// Enemy class representing the adversaries
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.createAsset('jojoEnemy', 'Enemy Character', 0.5, 0.5);
self.speed = 2;
self.move = function () {
if (hero.isTimestopped) {
return;
}
self.y += self.speed;
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000,
// Init game with black background
paused: false,
enemySpawnRate: 120 // Initial spawn rate is now every 2 seconds (120 frames)
});
/****
* Game Code
****/
// Instantiate shop button and add it to the GUI
// Initialize hero
var hero = game.addChild(new Hero());
hero.x = game.width / 2;
hero.y = game.height - 100;
// Initialize enemies array
var enemies = [];
// Initialize hero bullets array
var heroBullets = [];
// Initialize score and currency
var score = 0;
var currency = 0; // New currency variable
var scoreTxt = new Text2(score.toString(), {
size: 150,
fill: "#ffffff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Add a new Text2 object to display the current timestop duration
var timestopDurationTxt = new Text2(hero.timestopDuration.toString(), {
size: 150,
fill: "#ffffff"
});
timestopDurationTxt.anchor.set(0.5, 0);
timestopDurationTxt.y = scoreTxt.height; // Position below the score
LK.gui.top.addChild(timestopDurationTxt);
// Add a new Text2 object to display the current currency
var currencyTxt = new Text2(currency.toString(), {
size: 150,
fill: "#ffffff"
});
currencyTxt.anchor.set(0.5, 0);
currencyTxt.y = timestopDurationTxt.y + timestopDurationTxt.height; // Position below the timestop duration
LK.gui.top.addChild(currencyTxt);
// Function to update score
function updateScore(value) {
score += value;
scoreTxt.setText(score.toString());
}
// Function to spawn enemies
function spawnEnemy() {
var enemy = new Enemy();
enemy.x = Math.random() * (game.width - enemy.width) + enemy.width / 2;
enemy.y = -enemy.height;
enemies.push(enemy);
game.addChild(enemy);
}
// Event listener for 'down' events on the game area to allow the hero to shoot on left click
game.on('down', function (obj) {
if (obj.event.button === 0 && !obj.event.ctrlKey && !obj.event.altKey && !game.paused && !hero.isTimestopped) {
// Check if the left mouse button was clicked without any modifier keys and the game is not paused and hero is not timestopped
var bullets = hero.shoot();
heroBullets = heroBullets.concat(bullets);
}
});
// Event listener for right-click events on the game area to trigger timestop
game.on('rightdown', function (obj) {
hero.timestop();
});
// Event listener for the space key to toggle game pause
game.on('keydown', function (obj) {
if (obj.event.key === ' ') {
game.paused = !game.paused;
}
});
// Event listener for touch move events on the game area
game.on('move', function (obj) {
var pos = obj.event.getLocalPosition(game);
hero.x = pos.x;
hero.y = pos.y;
});
// Event listener for touch 'down' events to allow the hero to shoot
game.on('down', function (obj) {
if (!game.paused && !hero.isTimestopped) {
var bullets = hero.shoot();
heroBullets = heroBullets.concat(bullets);
}
});
// Main game loop
LK.on('tick', function () {
if (game.paused) {
return;
}
// Move hero based on touch input (handled by event listeners)
// Move enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].move();
// Check for collision with hero
if (enemies[i].intersects(hero)) {
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
return;
}
// Remove enemies that are off-screen
if (enemies[i].y > game.height + enemies[i].height) {
enemies[i].destroy();
enemies.splice(i, 1);
updateScore(-1);
}
}
// Move hero bullets
for (var b = heroBullets.length - 1; b >= 0; b--) {
heroBullets[b].move();
// Check for collision with enemies
for (var e = enemies.length - 1; e >= 0; e--) {
if (heroBullets[b].intersects(enemies[e])) {
enemies[e].destroy();
enemies.splice(e, 1);
updateScore(1);
}
}
// Remove bullets that are off-screen
if (heroBullets[b].isOffScreen()) {
heroBullets[b].destroy();
heroBullets.splice(b, 1);
}
}
// Spawn enemies at regular intervals
if (LK.ticks % (60 * 2) === 0) {
spawnEnemy();
}
}); /****
* Classes
****/
// HeroBullet class representing the hero's projectiles
var HeroBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.createAsset('heroBullet', 'Hero Bullet', 0.5, 0.5);
self.speed = -10;
self.move = function () {
if (!hero.isTimestopped || self.timestopActive) {
self.y += self.speed;
if (self.y < -self.height) {
self.destroy();
}
}
};
self.timestopActive = false;
self.activateTimestop = function () {
self.timestopActive = true;
LK.setTimeout(function () {
self.timestopActive = false;
}, 100);
};
self.isOffScreen = function () {
return self.y < -self.height;
};
});
// EnemyBullet class representing the enemy's projectiles
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.createAsset('enemyBullet', 'Enemy Bullet', 0.5, 0.5);
self.speed = 5;
self.move = function () {
if (!hero.isTimestopped) {
self.y += self.speed;
if (self.y > game.height + self.height) {
self.destroy();
}
}
};
self.isOffScreen = function () {
return self.y > game.height + self.height;
};
});
// Hero class representing the main character
var Hero = Container.expand(function () {
var self = Container.call(this);
self.shoot = function () {
var bullets = [];
for (var i = -1; i <= 1; i++) {
var bullet = new HeroBullet();
bullet.x = self.x + i * 20;
bullet.y = self.y - self.height / 2;
game.addChild(bullet);
bullets.push(bullet);
}
return bullets;
};
var heroGraphics = self.createAsset('jojoHero', 'Main Hero', 0.5, 0.5);
self.speed = 5;
self.isTimestopped = false;
self.timestopDuration = 3000; // Initial timestop duration
self.timestopCooldown = 5000; // Cooldown duration in milliseconds
self.timestopAvailable = true; // Flag to check if timestop is available
self.move = function (direction) {
if (self.isTimestopped) {
return;
}
if (direction === 'left') {
self.x -= self.speed;
}
if (direction === 'right') {
self.x += self.speed;
}
if (direction === 'up') {
self.y -= self.speed;
}
if (direction === 'down') {
self.y += self.speed;
}
};
self.timestop = function () {
if (self.timestopAvailable) {
self.isTimestopped = true;
self.timestopAvailable = false;
heroBullets.forEach(function (bullet) {
bullet.activateTimestop();
});
self.timestopDuration += 100; // Increase duration by 0.1 seconds
timestopDurationTxt.setText(self.timestopDuration.toString()); // Update the timestop duration display
LK.setTimeout(function () {
self.isTimestopped = false;
}, self.timestopDuration);
LK.setTimeout(function () {
self.timestopAvailable = true;
}, self.timestopCooldown);
}
};
});
// ShopButton class representing the button to open the shop
// Enemy class representing the adversaries
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.createAsset('jojoEnemy', 'Enemy Character', 0.5, 0.5);
self.speed = 2;
self.move = function () {
if (hero.isTimestopped) {
return;
}
self.y += self.speed;
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000,
// Init game with black background
paused: false,
enemySpawnRate: 120 // Initial spawn rate is now every 2 seconds (120 frames)
});
/****
* Game Code
****/
// Instantiate shop button and add it to the GUI
// Initialize hero
var hero = game.addChild(new Hero());
hero.x = game.width / 2;
hero.y = game.height - 100;
// Initialize enemies array
var enemies = [];
// Initialize hero bullets array
var heroBullets = [];
// Initialize score and currency
var score = 0;
var currency = 0; // New currency variable
var scoreTxt = new Text2(score.toString(), {
size: 150,
fill: "#ffffff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Add a new Text2 object to display the current timestop duration
var timestopDurationTxt = new Text2(hero.timestopDuration.toString(), {
size: 150,
fill: "#ffffff"
});
timestopDurationTxt.anchor.set(0.5, 0);
timestopDurationTxt.y = scoreTxt.height; // Position below the score
LK.gui.top.addChild(timestopDurationTxt);
// Add a new Text2 object to display the current currency
var currencyTxt = new Text2(currency.toString(), {
size: 150,
fill: "#ffffff"
});
currencyTxt.anchor.set(0.5, 0);
currencyTxt.y = timestopDurationTxt.y + timestopDurationTxt.height; // Position below the timestop duration
LK.gui.top.addChild(currencyTxt);
// Function to update score
function updateScore(value) {
score += value;
scoreTxt.setText(score.toString());
}
// Function to spawn enemies
function spawnEnemy() {
var enemy = new Enemy();
enemy.x = Math.random() * (game.width - enemy.width) + enemy.width / 2;
enemy.y = -enemy.height;
enemies.push(enemy);
game.addChild(enemy);
}
// Event listener for 'down' events on the game area to allow the hero to shoot on left click
game.on('down', function (obj) {
if (obj.event.button === 0 && !obj.event.ctrlKey && !obj.event.altKey && !game.paused && !hero.isTimestopped) {
// Check if the left mouse button was clicked without any modifier keys and the game is not paused and hero is not timestopped
var bullets = hero.shoot();
heroBullets = heroBullets.concat(bullets);
}
});
// Event listener for right-click events on the game area to trigger timestop
game.on('rightdown', function (obj) {
hero.timestop();
});
// Event listener for the space key to toggle game pause
game.on('keydown', function (obj) {
if (obj.event.key === ' ') {
game.paused = !game.paused;
}
});
// Event listener for touch move events on the game area
game.on('move', function (obj) {
var pos = obj.event.getLocalPosition(game);
hero.x = pos.x;
hero.y = pos.y;
});
// Event listener for touch 'down' events to allow the hero to shoot
game.on('down', function (obj) {
if (!game.paused && !hero.isTimestopped) {
var bullets = hero.shoot();
heroBullets = heroBullets.concat(bullets);
}
});
// Main game loop
LK.on('tick', function () {
if (game.paused) {
return;
}
// Move hero based on touch input (handled by event listeners)
// Move enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].move();
// Check for collision with hero
if (enemies[i].intersects(hero)) {
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
return;
}
// Remove enemies that are off-screen
if (enemies[i].y > game.height + enemies[i].height) {
enemies[i].destroy();
enemies.splice(i, 1);
updateScore(-1);
}
}
// Move hero bullets
for (var b = heroBullets.length - 1; b >= 0; b--) {
heroBullets[b].move();
// Check for collision with enemies
for (var e = enemies.length - 1; e >= 0; e--) {
if (heroBullets[b].intersects(enemies[e])) {
enemies[e].destroy();
enemies.splice(e, 1);
updateScore(1);
}
}
// Remove bullets that are off-screen
if (heroBullets[b].isOffScreen()) {
heroBullets[b].destroy();
heroBullets.splice(b, 1);
}
}
// Spawn enemies at regular intervals
if (LK.ticks % (60 * 2) === 0) {
spawnEnemy();
}
});