/****
* Classes
****/
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleAsset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
// Set initial size and color for obstacle asset
obstacleAsset.width = 100;
obstacleAsset.height = 100;
// Defensive: track last position for event logic
self.lastX = 0;
self.lastY = 0;
// Speed and direction will be set on spawn
self.vx = 0;
self.vy = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.vx;
self.y += self.vy;
};
return self;
});
// Player character class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerAsset = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Set initial size and color for player asset
playerAsset.width = 120;
playerAsset.height = 120;
// Attach gun asset to player's hand
// Use a new gun asset (box shape, dark gray)
var gunAsset = self.attachAsset('gun', {
anchorX: 0.1,
// grip of gun at player's hand
anchorY: 0.7
});
gunAsset.width = 80;
gunAsset.height = 28;
gunAsset.x = 50; // offset to right of player center
gunAsset.y = 30; // offset slightly down from center
// No tint needed, color is set in asset
self.gunAsset = gunAsset; // Store reference for rotation
// Defensive: track last position for event logic
self.lastX = 0;
self.lastY = 0;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
;
// --- Shoot-everywhere button logic ---
var shootEverywhereButton = null;
var shootEverywhereCooldown = 0; // ticks left for cooldown (10s = 600 ticks)
var shootEverywhereCooldownMax = 600; // 10 seconds at 60fps
// Add button image (use obstacle asset as placeholder, bottom left, not in top left 100x100)
shootEverywhereButton = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
x: 160,
// 160px from left (avoid top left menu)
y: 2732 - 160,
// 160px from bottom
width: 180,
height: 180
});
shootEverywhereButton.alpha = 0.92;
game.addChild(shootEverywhereButton);
// Add cooldown overlay (semi-transparent)
var shootEverywhereOverlay = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
x: 160,
y: 2732 - 160,
width: 180,
height: 180
});
shootEverywhereOverlay.tint = 0x000000;
shootEverywhereOverlay.alpha = 0.45;
game.addChild(shootEverywhereOverlay);
shootEverywhereOverlay.visible = false;
// Button press handler
shootEverywhereButton.down = function (x, y, obj) {
if (shootEverywhereCooldown === 0) {
// Shoot in all directions
for (var i = 0; i < bulletDirections.length; i++) {
var dir = bulletDirections[i];
var bullet = new Container();
var bulletAsset = bullet.attachAsset('bullet2', {
anchorX: 0.5,
anchorY: 0.5
});
// Position bullet at gun tip (relative to player)
var gunOffset = 80;
var gunOffsetX = gunOffset * Math.cos(dir.angle);
var gunOffsetY = gunOffset * Math.sin(dir.angle);
bullet.x = player.x + gunOffsetX;
bullet.y = player.y + gunOffsetY;
bullet.vx = dir.vx;
bullet.vy = dir.vy;
bullet.update = function () {
this.x += this.vx;
this.y += this.vy;
};
game.addChild(bullet);
bullets.push(bullet);
// Play 'piu' sound for each bullet
LK.getSound('piu').play();
}
shootEverywhereCooldown = shootEverywhereCooldownMax;
shootEverywhereOverlay.visible = true;
}
};
// Defensive: block drag on button
shootEverywhereButton.move = function (x, y, obj) {};
shootEverywhereButton.up = function (x, y, obj) {};
// --- End shoot-everywhere button logic ---
// --- Drag & Dodge core game logic ---
// Global variables
var player = null;
var obstacles = [];
var score = 0;
var scoreText = null;
var dragNode = null;
var lastGameOver = false;
var obstacleSpawnInterval = 90; // ticks between spawns, will decrease for difficulty
var minObstacleInterval = 30;
var ticksSinceLastObstacle = 0;
// Add player to center of screen
player = new Player();
player.x = 2048 / 2;
player.y = 2732 / 2;
player.shootAngle = 0; // Default: look right
game.addChild(player);
// Bullets array
var bullets = [];
// Auto-shooting logic
var bulletDirections = [{
vx: 32,
vy: 0,
angle: 0
},
// right
{
vx: -32,
vy: 0,
angle: Math.PI
},
// left
{
vx: 0,
vy: 32,
angle: Math.PI / 2
},
// down
{
vx: 0,
vy: -32,
angle: -Math.PI / 2
},
// up
{
vx: 22.6,
vy: 22.6,
angle: Math.PI / 4
},
// down-right
{
vx: -22.6,
vy: 22.6,
angle: 3 * Math.PI / 4
},
// down-left
{
vx: 22.6,
vy: -22.6,
angle: -Math.PI / 4
},
// up-right
{
vx: -22.6,
vy: -22.6,
angle: -3 * Math.PI / 4
} // up-left
];
var autoShootInterval = 18; // ticks between auto-shots
var ticksSinceLastShot = 0;
// Score display
scoreText = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Drag logic
game.down = function (x, y, obj) {
// Start dragging player if touch/click is near player
var dx = x - player.x;
var dy = y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 150) {
dragNode = player;
}
// Always update gun direction to look at click
// Store the angle to shoot at
player.shootAngle = Math.atan2(dy, dx);
// Rotate gun asset to look at click
if (player.gunAsset) {
player.gunAsset.rotation = player.shootAngle;
}
};
game.move = function (x, y, obj) {
if (dragNode === player) {
// Clamp player inside game area
var halfW = player.width / 2;
var halfH = player.height / 2;
player.x = Math.max(halfW, Math.min(2048 - halfW, x));
player.y = Math.max(halfH, Math.min(2732 - halfH, y));
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Obstacle spawn logic
function spawnObstacle() {
var edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
var obs = new Obstacle();
var speed = 8 + Math.random() * 6 + Math.min(10, score / 10); // increase speed with score
var px = 0,
py = 0,
vx = 0,
vy = 0;
if (edge === 0) {
// top
px = Math.random() * 2048;
py = -60;
vx = (player.x - px) / 60;
vy = speed;
} else if (edge === 1) {
// right
px = 2048 + 60;
py = Math.random() * 2732;
vx = -speed;
vy = (player.y - py) / 60;
} else if (edge === 2) {
// bottom
px = Math.random() * 2048;
py = 2732 + 60;
vx = (player.x - px) / 60;
vy = -speed;
} else {
// left
px = -60;
py = Math.random() * 2732;
vx = speed;
vy = (player.y - py) / 60;
}
obs.x = px;
obs.y = py;
obs.vx = vx;
obs.vy = vy;
obs.lastWasIntersecting = false;
game.addChild(obs);
obstacles.push(obs);
}
// Game update loop
game.update = function () {
// Spawn obstacles
ticksSinceLastObstacle++;
var interval = Math.max(minObstacleInterval, obstacleSpawnInterval - Math.floor(score / 10));
if (ticksSinceLastObstacle >= interval) {
spawnObstacle();
ticksSinceLastObstacle = 0;
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
// Remove if off screen
if (obs.x < -200 || obs.x > 2248 || obs.y < -200 || obs.y > 2932) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision detection (only on the frame it happens)
if (!obs.lastWasIntersecting && obs.intersects(player)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
lastGameOver = true;
return;
}
obs.lastWasIntersecting = obs.intersects(player);
}
// --- Auto-shoot bullets in the direction the player is looking (towards last click) ---
ticksSinceLastShot++;
if (ticksSinceLastShot >= autoShootInterval) {
// Default shoot angle is right
var shootAngle = typeof player.shootAngle === "number" ? player.shootAngle : 0;
var bulletSpeed = 32;
var vx = bulletSpeed * Math.cos(shootAngle);
var vy = bulletSpeed * Math.sin(shootAngle);
var bullet = new Container();
var bulletAsset = bullet.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
// Position bullet at gun tip (relative to player)
var gunOffset = 80;
var gunOffsetX = gunOffset * Math.cos(shootAngle);
var gunOffsetY = gunOffset * Math.sin(shootAngle);
bullet.x = player.x + gunOffsetX;
bullet.y = player.y + gunOffsetY;
bullet.vx = vx;
bullet.vy = vy;
bullet.update = function () {
this.x += this.vx;
this.y += this.vy;
};
game.addChild(bullet);
bullets.push(bullet);
// Play 'piu' sound when firing
LK.getSound('piu').play();
ticksSinceLastShot = 0;
}
// --- Update bullets ---
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
if (typeof bullet.update === "function") bullet.update();
// Remove if off screen
if (bullet.x < -100 || bullet.x > 2148 || bullet.y < -100 || bullet.y > 2832) {
bullet.destroy();
bullets.splice(b, 1);
continue;
}
// Check collision with obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
if (bullet.intersects(obs)) {
// Destroy both bullet and obstacle
bullet.destroy();
obs.destroy();
bullets.splice(b, 1);
obstacles.splice(i, 1);
break; // Bullet is gone, stop checking this bullet
}
}
}
// Score increases with time survived
if (!lastGameOver && LK.ticks % 6 === 0) {
score++;
scoreText.setText(score);
}
// --- Shoot-everywhere cooldown logic ---
if (typeof shootEverywhereCooldown !== "undefined" && shootEverywhereCooldown > 0) {
shootEverywhereCooldown--;
if (shootEverywhereCooldown === 0) {
shootEverywhereOverlay.visible = false;
} else {
shootEverywhereOverlay.visible = true;
// Optionally, you could animate overlay alpha or add a visual indicator here
}
} else if (typeof shootEverywhereOverlay !== "undefined") {
shootEverywhereOverlay.visible = false;
}
}; /****
* Classes
****/
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleAsset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
// Set initial size and color for obstacle asset
obstacleAsset.width = 100;
obstacleAsset.height = 100;
// Defensive: track last position for event logic
self.lastX = 0;
self.lastY = 0;
// Speed and direction will be set on spawn
self.vx = 0;
self.vy = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.vx;
self.y += self.vy;
};
return self;
});
// Player character class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerAsset = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Set initial size and color for player asset
playerAsset.width = 120;
playerAsset.height = 120;
// Attach gun asset to player's hand
// Use a new gun asset (box shape, dark gray)
var gunAsset = self.attachAsset('gun', {
anchorX: 0.1,
// grip of gun at player's hand
anchorY: 0.7
});
gunAsset.width = 80;
gunAsset.height = 28;
gunAsset.x = 50; // offset to right of player center
gunAsset.y = 30; // offset slightly down from center
// No tint needed, color is set in asset
self.gunAsset = gunAsset; // Store reference for rotation
// Defensive: track last position for event logic
self.lastX = 0;
self.lastY = 0;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
;
// --- Shoot-everywhere button logic ---
var shootEverywhereButton = null;
var shootEverywhereCooldown = 0; // ticks left for cooldown (10s = 600 ticks)
var shootEverywhereCooldownMax = 600; // 10 seconds at 60fps
// Add button image (use obstacle asset as placeholder, bottom left, not in top left 100x100)
shootEverywhereButton = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
x: 160,
// 160px from left (avoid top left menu)
y: 2732 - 160,
// 160px from bottom
width: 180,
height: 180
});
shootEverywhereButton.alpha = 0.92;
game.addChild(shootEverywhereButton);
// Add cooldown overlay (semi-transparent)
var shootEverywhereOverlay = LK.getAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5,
x: 160,
y: 2732 - 160,
width: 180,
height: 180
});
shootEverywhereOverlay.tint = 0x000000;
shootEverywhereOverlay.alpha = 0.45;
game.addChild(shootEverywhereOverlay);
shootEverywhereOverlay.visible = false;
// Button press handler
shootEverywhereButton.down = function (x, y, obj) {
if (shootEverywhereCooldown === 0) {
// Shoot in all directions
for (var i = 0; i < bulletDirections.length; i++) {
var dir = bulletDirections[i];
var bullet = new Container();
var bulletAsset = bullet.attachAsset('bullet2', {
anchorX: 0.5,
anchorY: 0.5
});
// Position bullet at gun tip (relative to player)
var gunOffset = 80;
var gunOffsetX = gunOffset * Math.cos(dir.angle);
var gunOffsetY = gunOffset * Math.sin(dir.angle);
bullet.x = player.x + gunOffsetX;
bullet.y = player.y + gunOffsetY;
bullet.vx = dir.vx;
bullet.vy = dir.vy;
bullet.update = function () {
this.x += this.vx;
this.y += this.vy;
};
game.addChild(bullet);
bullets.push(bullet);
// Play 'piu' sound for each bullet
LK.getSound('piu').play();
}
shootEverywhereCooldown = shootEverywhereCooldownMax;
shootEverywhereOverlay.visible = true;
}
};
// Defensive: block drag on button
shootEverywhereButton.move = function (x, y, obj) {};
shootEverywhereButton.up = function (x, y, obj) {};
// --- End shoot-everywhere button logic ---
// --- Drag & Dodge core game logic ---
// Global variables
var player = null;
var obstacles = [];
var score = 0;
var scoreText = null;
var dragNode = null;
var lastGameOver = false;
var obstacleSpawnInterval = 90; // ticks between spawns, will decrease for difficulty
var minObstacleInterval = 30;
var ticksSinceLastObstacle = 0;
// Add player to center of screen
player = new Player();
player.x = 2048 / 2;
player.y = 2732 / 2;
player.shootAngle = 0; // Default: look right
game.addChild(player);
// Bullets array
var bullets = [];
// Auto-shooting logic
var bulletDirections = [{
vx: 32,
vy: 0,
angle: 0
},
// right
{
vx: -32,
vy: 0,
angle: Math.PI
},
// left
{
vx: 0,
vy: 32,
angle: Math.PI / 2
},
// down
{
vx: 0,
vy: -32,
angle: -Math.PI / 2
},
// up
{
vx: 22.6,
vy: 22.6,
angle: Math.PI / 4
},
// down-right
{
vx: -22.6,
vy: 22.6,
angle: 3 * Math.PI / 4
},
// down-left
{
vx: 22.6,
vy: -22.6,
angle: -Math.PI / 4
},
// up-right
{
vx: -22.6,
vy: -22.6,
angle: -3 * Math.PI / 4
} // up-left
];
var autoShootInterval = 18; // ticks between auto-shots
var ticksSinceLastShot = 0;
// Score display
scoreText = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Drag logic
game.down = function (x, y, obj) {
// Start dragging player if touch/click is near player
var dx = x - player.x;
var dy = y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 150) {
dragNode = player;
}
// Always update gun direction to look at click
// Store the angle to shoot at
player.shootAngle = Math.atan2(dy, dx);
// Rotate gun asset to look at click
if (player.gunAsset) {
player.gunAsset.rotation = player.shootAngle;
}
};
game.move = function (x, y, obj) {
if (dragNode === player) {
// Clamp player inside game area
var halfW = player.width / 2;
var halfH = player.height / 2;
player.x = Math.max(halfW, Math.min(2048 - halfW, x));
player.y = Math.max(halfH, Math.min(2732 - halfH, y));
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Obstacle spawn logic
function spawnObstacle() {
var edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left
var obs = new Obstacle();
var speed = 8 + Math.random() * 6 + Math.min(10, score / 10); // increase speed with score
var px = 0,
py = 0,
vx = 0,
vy = 0;
if (edge === 0) {
// top
px = Math.random() * 2048;
py = -60;
vx = (player.x - px) / 60;
vy = speed;
} else if (edge === 1) {
// right
px = 2048 + 60;
py = Math.random() * 2732;
vx = -speed;
vy = (player.y - py) / 60;
} else if (edge === 2) {
// bottom
px = Math.random() * 2048;
py = 2732 + 60;
vx = (player.x - px) / 60;
vy = -speed;
} else {
// left
px = -60;
py = Math.random() * 2732;
vx = speed;
vy = (player.y - py) / 60;
}
obs.x = px;
obs.y = py;
obs.vx = vx;
obs.vy = vy;
obs.lastWasIntersecting = false;
game.addChild(obs);
obstacles.push(obs);
}
// Game update loop
game.update = function () {
// Spawn obstacles
ticksSinceLastObstacle++;
var interval = Math.max(minObstacleInterval, obstacleSpawnInterval - Math.floor(score / 10));
if (ticksSinceLastObstacle >= interval) {
spawnObstacle();
ticksSinceLastObstacle = 0;
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
// Remove if off screen
if (obs.x < -200 || obs.x > 2248 || obs.y < -200 || obs.y > 2932) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision detection (only on the frame it happens)
if (!obs.lastWasIntersecting && obs.intersects(player)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
lastGameOver = true;
return;
}
obs.lastWasIntersecting = obs.intersects(player);
}
// --- Auto-shoot bullets in the direction the player is looking (towards last click) ---
ticksSinceLastShot++;
if (ticksSinceLastShot >= autoShootInterval) {
// Default shoot angle is right
var shootAngle = typeof player.shootAngle === "number" ? player.shootAngle : 0;
var bulletSpeed = 32;
var vx = bulletSpeed * Math.cos(shootAngle);
var vy = bulletSpeed * Math.sin(shootAngle);
var bullet = new Container();
var bulletAsset = bullet.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
// Position bullet at gun tip (relative to player)
var gunOffset = 80;
var gunOffsetX = gunOffset * Math.cos(shootAngle);
var gunOffsetY = gunOffset * Math.sin(shootAngle);
bullet.x = player.x + gunOffsetX;
bullet.y = player.y + gunOffsetY;
bullet.vx = vx;
bullet.vy = vy;
bullet.update = function () {
this.x += this.vx;
this.y += this.vy;
};
game.addChild(bullet);
bullets.push(bullet);
// Play 'piu' sound when firing
LK.getSound('piu').play();
ticksSinceLastShot = 0;
}
// --- Update bullets ---
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
if (typeof bullet.update === "function") bullet.update();
// Remove if off screen
if (bullet.x < -100 || bullet.x > 2148 || bullet.y < -100 || bullet.y > 2832) {
bullet.destroy();
bullets.splice(b, 1);
continue;
}
// Check collision with obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
if (bullet.intersects(obs)) {
// Destroy both bullet and obstacle
bullet.destroy();
obs.destroy();
bullets.splice(b, 1);
obstacles.splice(i, 1);
break; // Bullet is gone, stop checking this bullet
}
}
}
// Score increases with time survived
if (!lastGameOver && LK.ticks % 6 === 0) {
score++;
scoreText.setText(score);
}
// --- Shoot-everywhere cooldown logic ---
if (typeof shootEverywhereCooldown !== "undefined" && shootEverywhereCooldown > 0) {
shootEverywhereCooldown--;
if (shootEverywhereCooldown === 0) {
shootEverywhereOverlay.visible = false;
} else {
shootEverywhereOverlay.visible = true;
// Optionally, you could animate overlay alpha or add a visual indicator here
}
} else if (typeof shootEverywhereOverlay !== "undefined") {
shootEverywhereOverlay.visible = false;
}
};
someone with a smiling face . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
fireball. In-Game asset. 2d. High contrast. No shadows
create cool blue fire ball. In-Game asset. 2d. High contrast. No shadows
bullet. In-Game asset. 2d. High contrast. No shadows
this gun should look at the better version and to the right side. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat