Code edit (1 edits merged)
Please save this source code
User prompt
add shooter mechanichs to the hero. add some obstacles. refuel the bullet time everytime hero kills an enemy
Code edit (1 edits merged)
Please save this source code
User prompt
Bullet Time Hero
Initial prompt
make a game exactly like max payne
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.health = 1;
self.shootTimer = 0;
self.shootInterval = 120; // 2 seconds at 60fps
self.update = function () {
// Move toward player
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var moveX = dx / distance * self.speed * timeScale;
var moveY = dy / distance * self.speed * timeScale;
var newX = self.x + moveX;
var newY = self.y + moveY;
// Check collision with obstacles
var canMove = true;
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (newX + 30 > obstacle.x - 60 && newX - 30 < obstacle.x + 60 && newY + 30 > obstacle.y - 60 && newY - 30 < obstacle.y + 60) {
canMove = false;
break;
}
}
if (canMove) {
self.x = newX;
self.y = newY;
}
}
// Shoot at player
self.shootTimer += timeScale;
if (self.shootTimer >= self.shootInterval) {
self.shoot();
self.shootTimer = 0;
}
};
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y;
enemyBullets.push(bullet);
game.addChild(bullet);
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
LK.effects.flashObject(self, 0xFFFFFF, 200);
LK.getSound('enemyHit').play();
return true; // Enemy destroyed
}
return false;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.damage = 1;
self.update = function () {
self.y += self.speed * timeScale;
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 3;
self.health = self.maxHealth;
self.shootTimer = 0;
self.shootInterval = 15; // Fast shooting
self.update = function () {
// Always shoot when enemies exist
if (enemies.length > 0) {
self.shootTimer += timeScale;
if (self.shootTimer >= self.shootInterval) {
self.shoot();
self.shootTimer = 0;
}
}
};
self.shoot = function () {
var bullet = new HeroBullet();
bullet.x = self.x;
bullet.y = self.y - 40;
heroBullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFF0000, 500);
LK.getSound('playerHit').play();
updateHealthBar();
if (self.health <= 0) {
LK.showGameOver();
}
};
return self;
});
var HeroBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('heroBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.damage = 1;
self.update = function () {
self.y -= self.speed * timeScale;
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.takeDamage = function (damage) {
self.health -= damage;
// Change color based on damage
var healthPercent = self.health / self.maxHealth;
if (healthPercent > 0.66) {
graphics.tint = 0x666666;
} else if (healthPercent > 0.33) {
graphics.tint = 0x444444;
} else {
graphics.tint = 0x222222;
}
if (self.health <= 0) {
return true; // Obstacle destroyed
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game variables
var hero;
var enemies = [];
var heroBullets = [];
var enemyBullets = [];
var obstacles = [];
var timeScale = 1.0;
var isBulletTimeActive = false;
var bulletTimeEnergy = 100;
var maxBulletTimeEnergy = 100;
var bulletTimeDecayRate = 2;
var bulletTimeRechargeRate = 1;
var bulletTimeSlowFactor = 0.2;
var dragNode = null;
var enemySpawnTimer = 0;
var enemySpawnInterval = 180; // 3 seconds
var waveNumber = 1;
var enemiesPerWave = 3;
// UI elements
var scoreTxt = new Text2('0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
var healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0
});
var healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0
});
var bulletTimeBarBg = LK.getAsset('bulletTimeBarBg', {
anchorX: 0,
anchorY: 0
});
var bulletTimeBar = LK.getAsset('bulletTimeBar', {
anchorX: 0,
anchorY: 0
});
LK.gui.topLeft.addChild(healthBarBg);
LK.gui.topLeft.addChild(healthBar);
LK.gui.topLeft.addChild(bulletTimeBarBg);
LK.gui.topLeft.addChild(bulletTimeBar);
healthBarBg.x = 120;
healthBarBg.y = 20;
healthBar.x = 122;
healthBar.y = 22;
bulletTimeBarBg.x = 120;
bulletTimeBarBg.y = 60;
bulletTimeBar.x = 122;
bulletTimeBar.y = 62;
// Initialize hero
hero = game.addChild(new Hero());
hero.x = 1024;
hero.y = 2200;
// Create obstacles
for (var i = 0; i < 6; i++) {
var obstacle = new Obstacle();
obstacle.x = 400 + i % 3 * 600;
obstacle.y = 800 + Math.floor(i / 3) * 600;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Update score display
function updateScore() {
scoreTxt.setText(LK.getScore());
}
// Update health bar
function updateHealthBar() {
var healthPercent = hero.health / hero.maxHealth;
healthBar.width = 400 * healthPercent;
}
// Update bullet time bar
function updateBulletTimeBar() {
var energyPercent = bulletTimeEnergy / maxBulletTimeEnergy;
bulletTimeBar.width = 300 * energyPercent;
}
// Spawn enemy
function spawnEnemy() {
var enemy = new Enemy();
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
// Right
enemy.x = 2098;
enemy.y = Math.random() * 1000 + 100;
break;
case 2:
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 3:
// Left
enemy.x = -50;
enemy.y = Math.random() * 1000 + 100;
break;
}
// Scale enemy stats with wave number
enemy.speed = 2 + waveNumber * 0.3;
enemy.shootInterval = Math.max(60, 120 - waveNumber * 5);
enemies.push(enemy);
game.addChild(enemy);
}
// Handle bullet time activation
function activateBulletTime() {
if (bulletTimeEnergy > 0) {
isBulletTimeActive = true;
timeScale = bulletTimeSlowFactor;
}
}
// Handle bullet time deactivation
function deactivateBulletTime() {
isBulletTimeActive = false;
timeScale = 1.0;
}
// Event handlers
function handleMove(x, y, obj) {
if (dragNode) {
var newX = x;
var newY = y;
// Keep hero within bounds
newX = Math.max(40, Math.min(2008, newX));
newY = Math.max(40, Math.min(2692, newY));
// Check collision with obstacles
var canMove = true;
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
var tempHero = {
x: newX,
y: newY,
width: 80,
height: 80
};
if (newX + 40 > obstacle.x - 60 && newX - 40 < obstacle.x + 60 && newY + 40 > obstacle.y - 60 && newY - 40 < obstacle.y + 60) {
canMove = false;
break;
}
}
if (canMove) {
dragNode.x = newX;
dragNode.y = newY;
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = hero;
activateBulletTime();
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
deactivateBulletTime();
};
// Main game update loop
game.update = function () {
// Update bullet time energy
if (isBulletTimeActive) {
bulletTimeEnergy -= bulletTimeDecayRate;
if (bulletTimeEnergy <= 0) {
bulletTimeEnergy = 0;
deactivateBulletTime();
}
} else {
bulletTimeEnergy += bulletTimeRechargeRate;
if (bulletTimeEnergy > maxBulletTimeEnergy) {
bulletTimeEnergy = maxBulletTimeEnergy;
}
}
updateBulletTimeBar();
// Spawn enemies
enemySpawnTimer += timeScale;
if (enemySpawnTimer >= enemySpawnInterval) {
if (enemies.length < enemiesPerWave) {
spawnEnemy();
}
enemySpawnTimer = 0;
// Start new wave if no enemies left
if (enemies.length === 0) {
waveNumber++;
enemiesPerWave = Math.min(8, 3 + Math.floor(waveNumber / 2));
enemySpawnInterval = Math.max(60, 180 - waveNumber * 10);
}
}
// Update hero bullets
for (var i = heroBullets.length - 1; i >= 0; i--) {
var bullet = heroBullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove bullets that go off screen
if (bullet.lastY >= -20 && bullet.y < -20) {
bullet.destroy();
heroBullets.splice(i, 1);
continue;
}
// Check collision with enemies
var hitEnemy = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
// Enemy destroyed
enemy.destroy();
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 10);
updateScore();
// Refuel bullet time on enemy kill
bulletTimeEnergy += 20;
if (bulletTimeEnergy > maxBulletTimeEnergy) {
bulletTimeEnergy = maxBulletTimeEnergy;
}
}
bullet.destroy();
heroBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
if (!hitEnemy) {
// Check collision with obstacles
for (var j = obstacles.length - 1; j >= 0; j--) {
var obstacle = obstacles[j];
if (bullet.intersects(obstacle)) {
if (obstacle.takeDamage(bullet.damage)) {
// Obstacle destroyed
obstacle.destroy();
obstacles.splice(j, 1);
}
bullet.destroy();
heroBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
}
if (!hitEnemy) {
bullet.lastY = bullet.y;
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove bullets that go off screen
if (bullet.lastY <= 2752 && bullet.y > 2752) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with hero
if (bullet.intersects(hero)) {
hero.takeDamage(bullet.damage);
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with obstacles
var hitObstacle = false;
for (var j = obstacles.length - 1; j >= 0; j--) {
var obstacle = obstacles[j];
if (bullet.intersects(obstacle)) {
if (obstacle.takeDamage(bullet.damage)) {
// Obstacle destroyed
obstacle.destroy();
obstacles.splice(j, 1);
}
bullet.destroy();
enemyBullets.splice(i, 1);
hitObstacle = true;
break;
}
}
if (!hitObstacle) {
bullet.lastY = bullet.y;
}
}
// Check enemy collision with hero
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.intersects(hero)) {
hero.takeDamage(1);
enemy.destroy();
enemies.splice(i, 1);
}
}
};
// Initialize UI
updateScore();
updateHealthBar();
updateBulletTimeBar(); ===================================================================
--- original.js
+++ change.js
@@ -21,10 +21,25 @@
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
- self.x += dx / distance * self.speed * timeScale;
- self.y += dy / distance * self.speed * timeScale;
+ var moveX = dx / distance * self.speed * timeScale;
+ var moveY = dy / distance * self.speed * timeScale;
+ var newX = self.x + moveX;
+ var newY = self.y + moveY;
+ // Check collision with obstacles
+ var canMove = true;
+ for (var i = 0; i < obstacles.length; i++) {
+ var obstacle = obstacles[i];
+ if (newX + 30 > obstacle.x - 60 && newX - 30 < obstacle.x + 60 && newY + 30 > obstacle.y - 60 && newY - 30 < obstacle.y + 60) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ self.x = newX;
+ self.y = newY;
+ }
}
// Shoot at player
self.shootTimer += timeScale;
if (self.shootTimer >= self.shootInterval) {
@@ -73,10 +88,10 @@
self.health = self.maxHealth;
self.shootTimer = 0;
self.shootInterval = 15; // Fast shooting
self.update = function () {
- // Auto-shoot when in bullet time and enemies exist
- if (isBulletTimeActive && enemies.length > 0) {
+ // Always shoot when enemies exist
+ if (enemies.length > 0) {
self.shootTimer += timeScale;
if (self.shootTimer >= self.shootInterval) {
self.shoot();
self.shootTimer = 0;
@@ -114,8 +129,34 @@
self.y -= self.speed * timeScale;
};
return self;
});
+var Obstacle = Container.expand(function () {
+ var self = Container.call(this);
+ var graphics = self.attachAsset('obstacle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 3;
+ self.maxHealth = 3;
+ self.takeDamage = function (damage) {
+ self.health -= damage;
+ // Change color based on damage
+ var healthPercent = self.health / self.maxHealth;
+ if (healthPercent > 0.66) {
+ graphics.tint = 0x666666;
+ } else if (healthPercent > 0.33) {
+ graphics.tint = 0x444444;
+ } else {
+ graphics.tint = 0x222222;
+ }
+ if (self.health <= 0) {
+ return true; // Obstacle destroyed
+ }
+ return false;
+ };
+ return self;
+});
/****
* Initialize Game
****/
@@ -130,8 +171,9 @@
var hero;
var enemies = [];
var heroBullets = [];
var enemyBullets = [];
+var obstacles = [];
var timeScale = 1.0;
var isBulletTimeActive = false;
var bulletTimeEnergy = 100;
var maxBulletTimeEnergy = 100;
@@ -182,8 +224,16 @@
// Initialize hero
hero = game.addChild(new Hero());
hero.x = 1024;
hero.y = 2200;
+// Create obstacles
+for (var i = 0; i < 6; i++) {
+ var obstacle = new Obstacle();
+ obstacle.x = 400 + i % 3 * 600;
+ obstacle.y = 800 + Math.floor(i / 3) * 600;
+ obstacles.push(obstacle);
+ game.addChild(obstacle);
+}
// Update score display
function updateScore() {
scoreTxt.setText(LK.getScore());
}
@@ -243,13 +293,32 @@
}
// Event handlers
function handleMove(x, y, obj) {
if (dragNode) {
- dragNode.x = x;
- dragNode.y = y;
+ var newX = x;
+ var newY = y;
// Keep hero within bounds
- dragNode.x = Math.max(40, Math.min(2008, dragNode.x));
- dragNode.y = Math.max(40, Math.min(2692, dragNode.y));
+ newX = Math.max(40, Math.min(2008, newX));
+ newY = Math.max(40, Math.min(2692, newY));
+ // Check collision with obstacles
+ var canMove = true;
+ for (var i = 0; i < obstacles.length; i++) {
+ var obstacle = obstacles[i];
+ var tempHero = {
+ x: newX,
+ y: newY,
+ width: 80,
+ height: 80
+ };
+ if (newX + 40 > obstacle.x - 60 && newX - 40 < obstacle.x + 60 && newY + 40 > obstacle.y - 60 && newY - 40 < obstacle.y + 60) {
+ canMove = false;
+ break;
+ }
+ }
+ if (canMove) {
+ dragNode.x = newX;
+ dragNode.y = newY;
+ }
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
@@ -311,16 +380,38 @@
enemy.destroy();
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 10);
updateScore();
+ // Refuel bullet time on enemy kill
+ bulletTimeEnergy += 20;
+ if (bulletTimeEnergy > maxBulletTimeEnergy) {
+ bulletTimeEnergy = maxBulletTimeEnergy;
+ }
}
bullet.destroy();
heroBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
if (!hitEnemy) {
+ // Check collision with obstacles
+ for (var j = obstacles.length - 1; j >= 0; j--) {
+ var obstacle = obstacles[j];
+ if (bullet.intersects(obstacle)) {
+ if (obstacle.takeDamage(bullet.damage)) {
+ // Obstacle destroyed
+ obstacle.destroy();
+ obstacles.splice(j, 1);
+ }
+ bullet.destroy();
+ heroBullets.splice(i, 1);
+ hitEnemy = true;
+ break;
+ }
+ }
+ }
+ if (!hitEnemy) {
bullet.lastY = bullet.y;
}
}
// Update enemy bullets
@@ -339,9 +430,27 @@
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
- bullet.lastY = bullet.y;
+ // Check collision with obstacles
+ var hitObstacle = false;
+ for (var j = obstacles.length - 1; j >= 0; j--) {
+ var obstacle = obstacles[j];
+ if (bullet.intersects(obstacle)) {
+ if (obstacle.takeDamage(bullet.damage)) {
+ // Obstacle destroyed
+ obstacle.destroy();
+ obstacles.splice(j, 1);
+ }
+ bullet.destroy();
+ enemyBullets.splice(i, 1);
+ hitObstacle = true;
+ break;
+ }
+ }
+ if (!hitObstacle) {
+ bullet.lastY = bullet.y;
+ }
}
// Check enemy collision with hero
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
draw a man like max payne. In-Game asset. 2d. High contrast. No shadows
draw a mafia guy with gun. In-Game asset. 2d. High contrast. No shadows
draw a city road map. In-Game asset. 2d. High contrast. No shadows
draw a mafia guy like a monster with gun. In-Game asset. 2d. High contrast. No shadows
draw a skyscraper. In-Game asset. 2d. High contrast. No shadows
draw a pistol bullet 50 calibre. In-Game asset. 2d. High contrast. No shadows
draw a heart with pixel art. In-Game asset. 2d. High contrast. No shadows