User prompt
make a movement button
User prompt
make enemies come to me ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
when I hold the mouse it shoots
User prompt
make a more comfrotable movment system ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
then make a better movment mechanic ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make a movment system for the carechter
Code edit (1 edits merged)
Please save this source code
User prompt
Mango Shooters
Initial prompt
Game Title: Mango Shooters mechanics: FPS game, you shoot with your mouse and move with w,a,s,d. Enemies are: Mango and Mustard, Mango has 100 HP and Mustard has 200 HP. You have a AK 47 that deals 2 damage per bullet. You kill them in a destroyed city Objective: kill Mangos and Mustards and get coins, every mango you kill is 1 point, every mustard you kill is 2 coin
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.damage = 2;
self.update = function () {
self.y -= self.speed;
};
return self;
});
var Mango = Container.expand(function () {
var self = Container.call(this);
var mangoGraphics = self.attachAsset('mango', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 100;
self.health = self.maxHealth;
self.speed = 2;
self.coinValue = 1;
self.lastHealth = self.health;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
};
self.update = function () {
// Move towards player position
if (player) {
var deltaX = player.x - self.x;
var deltaY = player.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 10) {
// Normalize direction and apply speed
var dirX = deltaX / distance * self.speed;
var dirY = deltaY / distance * self.speed;
self.x += dirX;
self.y += dirY;
}
} else {
// Fallback to original movement if player not found
self.y += self.speed;
}
// Flash red when taking damage
if (self.lastHealth > self.health) {
LK.effects.flashObject(self, 0xff0000, 300);
}
self.lastHealth = self.health;
};
return self;
});
var Mustard = Container.expand(function () {
var self = Container.call(this);
var mustardGraphics = self.attachAsset('mustard', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 200;
self.health = self.maxHealth;
self.speed = 1.5;
self.coinValue = 2;
self.lastHealth = self.health;
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health < 0) self.health = 0;
};
self.update = function () {
// Move towards player position
if (player) {
var deltaX = player.x - self.x;
var deltaY = player.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 10) {
// Normalize direction and apply speed
var dirX = deltaX / distance * self.speed;
var dirY = deltaY / distance * self.speed;
self.x += dirX;
self.y += dirY;
}
} else {
// Fallback to original movement if player not found
self.y += self.speed;
}
// Flash red when taking damage
if (self.lastHealth > self.health) {
LK.effects.flashObject(self, 0xff0000, 300);
}
self.lastHealth = self.health;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.moveTo = function (targetX, targetY) {
// Stop any existing movement tween
tween.stop(self, {
x: true,
y: true
});
// Calculate distance for duration scaling
var deltaX = targetX - self.x;
var deltaY = targetY - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Only move if distance is significant
if (distance > 5) {
// Much faster movement with shorter duration
var duration = Math.min(distance * 0.8, 300);
// Smooth tween movement with more responsive easing
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Add slight bounce effect when reaching destination
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeIn
});
}
});
}
});
}
};
self.update = function () {
// Keep player within screen bounds
if (self.x < 40) self.x = 40;
if (self.x > 2048 - 40) self.x = 2048 - 40;
if (self.y < 200) self.y = 200;
if (self.y > 2732 - 100) self.y = 2732 - 100;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Game variables
var player;
var bullets = [];
var enemies = [];
var coins = 0;
var playerHealth = 100;
var gameStarted = false;
var enemySpawnTimer = 0;
var enemySpawnRate = 120; // frames between spawns
var difficultyTimer = 0;
// Movement variables
var isDragging = false;
var playerSpeed = 8;
var targetX = 0;
var targetY = 0;
// Shooting variables
var isShooting = false;
var shootTimer = null;
var shootInterval = 8; // frames between shots when holding
var lastShootX = 0;
var lastShootY = 0;
// Create city background
var cityBuildings = [];
for (var i = 0; i < 12; i++) {
var buildingType = Math.floor(Math.random() * 3) + 1;
var building = LK.getAsset('cityBuilding' + buildingType, {
anchorX: 0.5,
anchorY: 1
});
building.x = i * 180 + 100;
building.y = 2732;
building.alpha = 0.3;
game.addChild(building);
cityBuildings.push(building);
}
// Create player
player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2732 - 150;
// UI Elements
var coinText = new Text2('Coins: 0', {
size: 60,
fill: 0xFFFFFF
});
coinText.anchor.set(0, 0);
coinText.x = 150;
coinText.y = 50;
LK.gui.topLeft.addChild(coinText);
var healthText = new Text2('Health: 100', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(1, 0);
LK.gui.topRight.addChild(healthText);
// Movement Button
var moveButton = LK.getAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.7
});
moveButton.x = 0;
moveButton.y = 0;
var moveButtonActive = false;
var moveButtonCenter = {
x: 0,
y: 0
};
LK.gui.bottomLeft.addChild(moveButton);
// Position movement button after GUI setup
moveButton.x = 120;
moveButton.y = -120;
moveButtonCenter.x = moveButton.x;
moveButtonCenter.y = moveButton.y;
// Movement button functions
function activateMoveButton(x, y) {
moveButtonActive = true;
var localPos = LK.gui.bottomLeft.toLocal({
x: x,
y: y
});
var deltaX = localPos.x - moveButtonCenter.x;
var deltaY = localPos.y - moveButtonCenter.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Limit movement within button radius
var maxRadius = 60;
if (distance > maxRadius) {
deltaX = deltaX / distance * maxRadius;
deltaY = deltaY / distance * maxRadius;
}
moveButton.x = moveButtonCenter.x + deltaX;
moveButton.y = moveButtonCenter.y + deltaY;
// Move player based on button displacement
var moveStrength = distance / maxRadius;
var playerTargetX = player.x + deltaX * 8 * moveStrength;
var playerTargetY = player.y + deltaY * 8 * moveStrength;
// Keep within bounds
playerTargetX = Math.max(40, Math.min(2048 - 40, playerTargetX));
playerTargetY = Math.max(200, Math.min(2732 - 100, playerTargetY));
player.moveTo(playerTargetX, playerTargetY);
}
function deactivateMoveButton() {
moveButtonActive = false;
// Return button to center with tween
tween(moveButton, {
x: moveButtonCenter.x,
y: moveButtonCenter.y
}, {
duration: 200,
easing: tween.easeOut
});
}
// Game functions
function spawnEnemy() {
var enemy;
var spawnX = Math.random() * (2048 - 100) + 50;
// 70% chance for Mango, 30% chance for Mustard
if (Math.random() < 0.7) {
enemy = new Mango();
} else {
enemy = new Mustard();
}
enemy.x = spawnX;
enemy.y = -50;
enemy.lastY = enemy.y;
enemies.push(enemy);
game.addChild(enemy);
}
function fireBullet(targetX, targetY) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 40;
bullet.lastY = bullet.y;
// Calculate angle to target
var deltaX = targetX - bullet.x;
var deltaY = targetY - bullet.y;
var angle = Math.atan2(deltaY, deltaX);
// Set bullet direction
bullet.velocityX = Math.cos(angle) * bullet.speed;
bullet.velocityY = Math.sin(angle) * bullet.speed;
// Override update to use calculated velocity
bullet.update = function () {
bullet.x += bullet.velocityX;
bullet.y += bullet.velocityY;
};
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
}
// Event handlers
game.down = function (x, y, obj) {
if (gameStarted) {
// Convert coordinates to check if touching movement button
var guiPos = LK.gui.bottomLeft.toLocal({
x: x,
y: y
});
var buttonDistance = Math.sqrt((guiPos.x - moveButtonCenter.x) * (guiPos.x - moveButtonCenter.x) + (guiPos.y - moveButtonCenter.y) * (guiPos.y - moveButtonCenter.y));
if (buttonDistance < 80) {
// Touching movement button
activateMoveButton(x, y);
} else if (y < 2732 / 2) {
// Top half - start continuous shooting
isShooting = true;
lastShootX = x;
lastShootY = y;
// Fire first bullet immediately
fireBullet(x, y);
} else {
// Bottom half - fallback movement (keep existing behavior)
isDragging = true;
targetX = x;
targetY = y;
// Add immediate visual feedback on touch
tween(player, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(player, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
player.moveTo(x, y);
}
} else {
gameStarted = true;
}
};
game.move = function (x, y, obj) {
if (gameStarted) {
if (moveButtonActive) {
// Update movement button position and player movement
activateMoveButton(x, y);
} else if (isShooting && y < 2732 / 2) {
// Update shooting target position
lastShootX = x;
lastShootY = y;
} else if (isDragging && y >= 2732 / 2) {
// More responsive movement with lower threshold
var deltaX = x - targetX;
var deltaY = y - targetY;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 15) {
// More responsive movement threshold
targetX = x;
targetY = y;
player.moveTo(x, y);
// Add visual feedback for movement
tween(player, {
tint: 0xffffff
}, {
duration: 50,
onFinish: function onFinish() {
tween(player, {
tint: 0x4a90e2
}, {
duration: 100
});
}
});
}
}
}
};
game.up = function (x, y, obj) {
if (moveButtonActive) {
deactivateMoveButton();
}
isDragging = false;
isShooting = false;
};
// Main game loop
game.update = function () {
if (!gameStarted) {
return;
}
// Handle continuous shooting
if (isShooting) {
if (shootTimer === null) {
shootTimer = 0;
}
shootTimer++;
if (shootTimer >= shootInterval) {
fireBullet(lastShootX, lastShootY);
shootTimer = 0;
}
} else {
shootTimer = null;
}
// Player movement is now handled by tween system
// Spawn enemies
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
spawnEnemy();
enemySpawnTimer = 0;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer >= 1800) {
// Every 30 seconds
if (enemySpawnRate > 30) {
enemySpawnRate -= 5;
}
difficultyTimer = 0;
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that go off screen
if (bullet.lastY <= 2732 && (bullet.y > 2732 || bullet.y < -50 || bullet.x < -50 || bullet.x > 2098)) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
bullet.lastY = bullet.y;
}
// Update enemies and check collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
// Check if enemy collides with player
if (enemy.intersects(player)) {
playerHealth -= 20;
healthText.setText('Health: ' + playerHealth);
LK.effects.flashScreen(0xff0000, 500);
if (playerHealth <= 0) {
LK.setScore(coins);
LK.showGameOver();
return;
}
enemy.destroy();
enemies.splice(j, 1);
continue;
}
// Remove enemies that go too far off screen
if (enemy.y > 2732 + 100 || enemy.x < -100 || enemy.x > 2148) {
enemy.destroy();
enemies.splice(j, 1);
continue;
}
// Check bullet collisions
for (var k = bullets.length - 1; k >= 0; k--) {
var bullet = bullets[k];
if (bullet.intersects(enemy)) {
enemy.takeDamage(bullet.damage);
LK.getSound('enemyHit').play();
// Remove bullet
bullet.destroy();
bullets.splice(k, 1);
// Check if enemy is dead
if (enemy.health <= 0) {
coins += enemy.coinValue;
coinText.setText('Coins: ' + coins);
LK.getSound('enemyDeath').play();
enemy.destroy();
enemies.splice(j, 1);
}
break;
}
}
enemy.lastY = enemy.y;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -223,8 +223,67 @@
fill: 0xFF0000
});
healthText.anchor.set(1, 0);
LK.gui.topRight.addChild(healthText);
+// Movement Button
+var moveButton = LK.getAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 0.8,
+ alpha: 0.7
+});
+moveButton.x = 0;
+moveButton.y = 0;
+var moveButtonActive = false;
+var moveButtonCenter = {
+ x: 0,
+ y: 0
+};
+LK.gui.bottomLeft.addChild(moveButton);
+// Position movement button after GUI setup
+moveButton.x = 120;
+moveButton.y = -120;
+moveButtonCenter.x = moveButton.x;
+moveButtonCenter.y = moveButton.y;
+// Movement button functions
+function activateMoveButton(x, y) {
+ moveButtonActive = true;
+ var localPos = LK.gui.bottomLeft.toLocal({
+ x: x,
+ y: y
+ });
+ var deltaX = localPos.x - moveButtonCenter.x;
+ var deltaY = localPos.y - moveButtonCenter.y;
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ // Limit movement within button radius
+ var maxRadius = 60;
+ if (distance > maxRadius) {
+ deltaX = deltaX / distance * maxRadius;
+ deltaY = deltaY / distance * maxRadius;
+ }
+ moveButton.x = moveButtonCenter.x + deltaX;
+ moveButton.y = moveButtonCenter.y + deltaY;
+ // Move player based on button displacement
+ var moveStrength = distance / maxRadius;
+ var playerTargetX = player.x + deltaX * 8 * moveStrength;
+ var playerTargetY = player.y + deltaY * 8 * moveStrength;
+ // Keep within bounds
+ playerTargetX = Math.max(40, Math.min(2048 - 40, playerTargetX));
+ playerTargetY = Math.max(200, Math.min(2732 - 100, playerTargetY));
+ player.moveTo(playerTargetX, playerTargetY);
+}
+function deactivateMoveButton() {
+ moveButtonActive = false;
+ // Return button to center with tween
+ tween(moveButton, {
+ x: moveButtonCenter.x,
+ y: moveButtonCenter.y
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+}
// Game functions
function spawnEnemy() {
var enemy;
var spawnX = Math.random() * (2048 - 100) + 50;
@@ -263,18 +322,26 @@
}
// Event handlers
game.down = function (x, y, obj) {
if (gameStarted) {
- // Check if touch is in top half (shooting) or bottom half (movement)
- if (y < 2732 / 2) {
+ // Convert coordinates to check if touching movement button
+ var guiPos = LK.gui.bottomLeft.toLocal({
+ x: x,
+ y: y
+ });
+ var buttonDistance = Math.sqrt((guiPos.x - moveButtonCenter.x) * (guiPos.x - moveButtonCenter.x) + (guiPos.y - moveButtonCenter.y) * (guiPos.y - moveButtonCenter.y));
+ if (buttonDistance < 80) {
+ // Touching movement button
+ activateMoveButton(x, y);
+ } else if (y < 2732 / 2) {
// Top half - start continuous shooting
isShooting = true;
lastShootX = x;
lastShootY = y;
// Fire first bullet immediately
fireBullet(x, y);
} else {
- // Bottom half - start movement
+ // Bottom half - fallback movement (keep existing behavior)
isDragging = true;
targetX = x;
targetY = y;
// Add immediate visual feedback on touch
@@ -300,9 +367,12 @@
}
};
game.move = function (x, y, obj) {
if (gameStarted) {
- if (isShooting && y < 2732 / 2) {
+ if (moveButtonActive) {
+ // Update movement button position and player movement
+ activateMoveButton(x, y);
+ } else if (isShooting && y < 2732 / 2) {
// Update shooting target position
lastShootX = x;
lastShootY = y;
} else if (isDragging && y >= 2732 / 2) {
@@ -332,8 +402,11 @@
}
}
};
game.up = function (x, y, obj) {
+ if (moveButtonActive) {
+ deactivateMoveButton();
+ }
isDragging = false;
isShooting = false;
};
// Main game loop