User prompt
Te dije q le agas una animación al caminar al saltar y q cuando presione el botón de atacar ataque con la espada q tiene y al aserlo tenga una animación ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Y quiero q en ves de q ataque disparando ataque con la espada q tiene y que tenga una animación de caminar y de cuando ataca ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Quiero q le quites el fondo blanco a la imagen q puse para el hombre palo
User prompt
Mira quiero q cambias a los enemigos por un stickman rojo los stickmans son muñecos de palo osea una bolita la cabeza y el torso un palo largo y la manitas y los pies un palo más pequeño y aparte agregale animaciones y q ataquen al jugador con una espada ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Puedes hacer q los controles sean un poco más grandes y q dentro tenga un icono como un stickman saltando en el botón de salto y haci en el de derecha y izquierda
User prompt
Puedes hacer que la barra sea más visible
User prompt
Esta perfecto pero da saltos ilimitados quiero q arriba del personaje aya una barra q como la estamina pero q la barra este blanca cuando pueda dar un doble salto y q se ponga gris cuando ya haya dado el doble salto y para cargar el doble salto tenga q tocar el piso
User prompt
Sigue sin funcionar
User prompt
El botón de jump cuando lo presionó no hace la acción
User prompt
Quiero q me des un control diseñado para móviles
User prompt
Sigue sin aparecer nada
User prompt
No aparece nada cuando le doy a play
User prompt
Puedes seguir asiendo el código del juego ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Stickman Vs. Digital Warrior
Initial prompt
Quiero crear un videojuego plataformero en estilo pixel art, con estética retro pero moderna. El protagonista es un Stickman guerrero, ágil y con movimientos fluidos. El juego se centra en batallas rápidas, acción intensa y exploración de niveles llenos de enemigos, trampas y secretos. Se llama Stickman Vs., y ocurre en un universo digital futurista donde distintas dimensiones pixeladas están colapsando y los Stickman luchan por sobrevivir. Quiero que tenga: Niveles con plataformas, obstáculos y mecánicas únicas (como gravedad invertida, plataformas que desaparecen, etc.). Combate cuerpo a cuerpo y a distancia (puñetazos, espadas, rayos láser). Jefes épicos con ataques especiales. Estilo visual pixelado pero detallado, como si fuera un juego del futuro hecho en 16 bits. Puede ser para un jugador o con modo VS local.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Platform = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Projectile = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.lifetime = 180; // 3 seconds at 60fps
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifetime--;
// Remove if lifetime expired or off screen
if (self.lifetime <= 0 || self.x < -50 || self.x > 2098 || self.y > 2800) {
self.destroy();
}
};
return self;
});
var Stickman = Container.expand(function () {
var self = Container.call(this);
// Create stickman body parts similar to enemy
var head = self.attachAsset('enemy_head', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -65,
tint: 0x0066FF
});
var body = self.attachAsset('enemy_body', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: -50,
tint: 0x0066FF
});
var leftArm = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: -10,
y: -40,
tint: 0x0066FF
});
var rightArm = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: 10,
y: -40,
tint: 0x0066FF
});
var leftLeg = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: -5,
y: -20,
tint: 0x0066FF
});
var rightLeg = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: 5,
y: -20,
tint: 0x0066FF
});
var sword = self.attachAsset('enemy_sword', {
anchorX: 0.5,
anchorY: 1,
x: 15,
y: -30,
tint: 0xFFFFFF
});
// Movement properties
self.velocityX = 0;
self.velocityY = 0;
self.onGround = false;
self.speed = 8;
self.jumpPower = -18;
self.health = 100;
self.maxHealth = 100;
self.facingRight = true;
// Combat properties
self.canAttack = true;
self.attackCooldown = 0;
self.lastAttackTime = 0;
// Animation properties
self.animationTick = 0;
self.isAttacking = false;
self.isJumping = false;
self.wasOnGround = true;
self.update = function () {
// Apply gravity
if (!self.onGround) {
self.velocityY += 0.8;
}
// Apply velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= 0.85;
// Reset ground detection
self.onGround = false;
// Reset double jump when touching ground later in collision detection
// Update attack cooldown
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
// Animation updates
self.animationTick++;
// Check if jumping state changed
if (!self.onGround && self.wasOnGround) {
self.isJumping = true;
}
if (self.onGround && !self.wasOnGround) {
self.isJumping = false;
}
self.wasOnGround = self.onGround;
// Handle animations
if (self.isAttacking) {
// Attack animation is handled in attack method
} else if (self.isJumping || !self.onGround) {
// Jump animation - spread arms and legs
leftArm.rotation = -0.5;
rightArm.rotation = 0.5;
leftLeg.rotation = -0.3;
rightLeg.rotation = 0.3;
// No body bob during jump
body.y = -50;
head.y = -65;
} else if (Math.abs(self.velocityX) > 0.1) {
// Walking animation
var walkSpeed = 0.25;
var walkCycle = Math.sin(self.animationTick * walkSpeed);
var walkCycleOffset = Math.sin(self.animationTick * walkSpeed + Math.PI);
// Leg animation - alternate walking
leftLeg.rotation = walkCycle * 0.4;
rightLeg.rotation = walkCycleOffset * 0.4;
// Arm animation - opposite to legs
leftArm.rotation = walkCycleOffset * 0.3;
rightArm.rotation = walkCycle * 0.3;
// Body bob animation
body.y = -50 + Math.abs(Math.sin(self.animationTick * walkSpeed * 2)) * 2;
head.y = -65 + Math.abs(Math.sin(self.animationTick * walkSpeed * 2)) * 2;
} else {
// Idle animation - return to normal positions
leftArm.rotation = 0;
rightArm.rotation = 0;
leftLeg.rotation = 0;
rightLeg.rotation = 0;
body.y = -50;
head.y = -65;
}
// Face direction
if (self.facingRight) {
head.scaleX = 1;
body.scaleX = 1;
leftArm.scaleX = 1;
rightArm.scaleX = 1;
leftLeg.scaleX = 1;
rightLeg.scaleX = 1;
sword.x = 15;
} else {
head.scaleX = -1;
body.scaleX = -1;
leftArm.scaleX = -1;
rightArm.scaleX = -1;
leftLeg.scaleX = -1;
rightLeg.scaleX = -1;
sword.x = -15;
}
// Keep player in bounds
if (self.x < 30) self.x = 30;
if (self.x > 2018) self.x = 2018;
};
self.moveLeft = function () {
self.velocityX = -self.speed;
self.facingRight = false;
};
self.moveRight = function () {
self.velocityX = self.speed;
self.facingRight = true;
};
self.jump = function () {
console.log("Jump called! onGround:", self.onGround, "velocityY:", self.velocityY);
if (self.onGround || Math.abs(self.velocityY) < 2) {
// First jump
self.velocityY = self.jumpPower;
self.onGround = false;
LK.getSound('jump').play();
console.log("Jump executed! New velocityY:", self.velocityY);
} else if (self.canDoubleJump && !self.hasUsedDoubleJump) {
// Double jump
self.velocityY = self.jumpPower * 0.8;
self.hasUsedDoubleJump = true;
self.canDoubleJump = false;
LK.getSound('jump').play();
console.log("Double jump executed!");
} else {
console.log("Cannot jump - not on ground and no double jump available");
}
};
self.attack = function () {
if (self.attackCooldown <= 0) {
self.attackCooldown = 30;
self.isAttacking = true;
LK.getSound('attack').play();
// Sword attack animation - swing from back to front
tween(sword, {
rotation: -1.8
}, {
duration: 150,
onFinish: function onFinish() {
// Swing forward
tween(sword, {
rotation: 0.8
}, {
duration: 200,
onFinish: function onFinish() {
// Return to normal position
tween(sword, {
rotation: 0
}, {
duration: 250,
onFinish: function onFinish() {
self.isAttacking = false;
}
});
}
});
// Check for enemy hits during forward swing
LK.setTimeout(function () {
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var distanceToEnemy = Math.abs(self.x - enemy.x);
var verticalDistance = Math.abs(self.y - enemy.y);
if (distanceToEnemy < 80 && verticalDistance < 60) {
if (enemy.takeDamage(50)) {
// Enemy destroyed
enemies.splice(i, 1);
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
}
// Knockback effect
var knockbackDirection = enemy.x > self.x ? 1 : -1;
enemy.velocityX += knockbackDirection * 8;
}
}
}, 150);
}
});
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.getSound('hit').play();
// Damage flash effect on all body parts
tween(head, {
tint: 0xFF0066
}, {
duration: 150,
onFinish: function onFinish() {
tween(head, {
tint: 0x0066FF
}, {
duration: 150
});
}
});
tween(body, {
tint: 0xFF0066
}, {
duration: 150,
onFinish: function onFinish() {
tween(body, {
tint: 0x0066FF
}, {
duration: 150
});
}
});
if (self.health <= 0) {
LK.showGameOver();
}
};
return self;
});
var StickmanEnemy = Container.expand(function () {
var self = Container.call(this);
// Create stickman body parts
var head = self.attachAsset('enemy_head', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -65
});
var body = self.attachAsset('enemy_body', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: -50
});
var leftArm = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: -10,
y: -40
});
var rightArm = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: 10,
y: -40
});
var leftLeg = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: -5,
y: -20
});
var rightLeg = self.attachAsset('enemy_limb', {
anchorX: 0.5,
anchorY: 0,
x: 5,
y: -20
});
var sword = self.attachAsset('enemy_sword', {
anchorX: 0.5,
anchorY: 1,
x: 15,
y: -30
});
self.velocityX = 0;
self.velocityY = 0;
self.health = 50;
self.speed = 1.5;
self.direction = 1;
self.onGround = false;
self.attackRange = 80;
self.attackCooldown = 0;
self.animationTick = 0;
self.isAttacking = false;
self.lastPlayerDistance = 999;
self.update = function () {
// Apply gravity
if (!self.onGround) {
self.velocityY += 0.8;
}
// AI behavior - chase player if close enough
var distanceToPlayer = Math.abs(self.x - player.x);
var verticalDistance = Math.abs(self.y - player.y);
if (distanceToPlayer < 200 && verticalDistance < 100) {
// Chase player
if (player.x > self.x) {
self.direction = 1;
self.velocityX = self.speed;
} else {
self.direction = -1;
self.velocityX = -self.speed;
}
// Attack if in range
if (distanceToPlayer < self.attackRange && self.attackCooldown <= 0) {
self.attackPlayer();
}
} else {
// Simple patrol movement
self.velocityX = self.speed * self.direction;
}
// Apply velocity
self.x += self.velocityX;
self.y += self.velocityY;
// Reset ground detection
self.onGround = false;
// Reverse direction at edges
if (self.x < 50 || self.x > 1998) {
self.direction *= -1;
}
// Update attack cooldown
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
// Animation
self.animationTick++;
if (!self.isAttacking) {
// Walking animation with more realistic movement
var walkSpeed = Math.abs(self.velocityX) > 0.1 ? 0.25 : 0.1;
var walkCycle = Math.sin(self.animationTick * walkSpeed);
var walkCycleOffset = Math.sin(self.animationTick * walkSpeed + Math.PI);
// Leg animation - alternate walking
leftLeg.rotation = walkCycle * 0.4;
rightLeg.rotation = walkCycleOffset * 0.4;
// Arm animation - opposite to legs (natural walking)
leftArm.rotation = walkCycleOffset * 0.3;
rightArm.rotation = walkCycle * 0.3;
// Body bob animation when walking
if (Math.abs(self.velocityX) > 0.1) {
body.y = -50 + Math.abs(Math.sin(self.animationTick * walkSpeed * 2)) * 2;
head.y = -65 + Math.abs(Math.sin(self.animationTick * walkSpeed * 2)) * 2;
} else {
// Return to normal position when not walking
body.y = -50;
head.y = -65;
}
}
// Face direction
if (self.direction > 0) {
head.scaleX = 1;
body.scaleX = 1;
sword.x = 15;
} else {
head.scaleX = -1;
body.scaleX = -1;
sword.x = -15;
}
self.lastPlayerDistance = distanceToPlayer;
};
self.attackPlayer = function () {
if (self.attackCooldown <= 0) {
self.attackCooldown = 120; // 2 seconds at 60fps
self.isAttacking = true;
// Sword attack animation - swing from back to front
tween(sword, {
rotation: -1.8
}, {
duration: 150,
onFinish: function onFinish() {
// Swing forward
tween(sword, {
rotation: 0.8
}, {
duration: 200,
onFinish: function onFinish() {
// Return to normal position
tween(sword, {
rotation: 0
}, {
duration: 250,
onFinish: function onFinish() {
self.isAttacking = false;
}
});
}
});
// Check if player is hit during forward swing (after 150ms delay)
LK.setTimeout(function () {
var distanceToPlayer = Math.abs(self.x - player.x);
if (distanceToPlayer < self.attackRange) {
player.takeDamage(10);
// Knockback effect
var knockbackDirection = player.x > self.x ? 1 : -1;
player.velocityX += knockbackDirection * 8;
}
}, 150);
}
});
}
};
self.takeDamage = function (damage) {
self.health -= damage;
// Damage flash effect
tween(head, {
tint: 0xFFFFFF
}, {
duration: 100,
onFinish: function onFinish() {
tween(head, {
tint: 0xFF0000
}, {
duration: 100
});
}
});
tween(body, {
tint: 0xFFFFFF
}, {
duration: 100,
onFinish: function onFinish() {
tween(body, {
tint: 0xFF0000
}, {
duration: 100
});
}
});
if (self.health <= 0) {
self.destroy();
return true;
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001122 // Dark digital blue background
});
/****
* Game Code
****/
// Initialize assets for Stickman Vs. Digital Warrior
// Game arrays
var platforms = [];
var enemies = [];
var projectiles = [];
// Create ground
var ground = game.addChild(LK.getAsset('ground', {
anchorX: 0.5,
anchorY: 1.0,
x: 1024,
y: 2732
}));
// Create platforms
var platformData = [{
x: 300,
y: 2500
}, {
x: 600,
y: 2300
}, {
x: 1000,
y: 2400
}, {
x: 1400,
y: 2200
}, {
x: 1700,
y: 2500
}];
for (var i = 0; i < platformData.length; i++) {
var platform = new Platform();
platform.x = platformData[i].x;
platform.y = platformData[i].y;
platforms.push(platform);
game.addChild(platform);
}
// Create player
var player = new Stickman();
player.x = 1024;
player.y = 2600;
player.canDoubleJump = true;
player.hasUsedDoubleJump = false;
game.addChild(player);
// Create double jump stamina bar
var staminaBarBackground = LK.getAsset('platform', {
width: 120,
height: 20,
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000
});
game.addChild(staminaBarBackground);
var staminaBar = LK.getAsset('platform', {
width: 110,
height: 14,
anchorX: 0.5,
anchorY: 0.5,
tint: 0xFFFFFF
});
game.addChild(staminaBar);
// Create enemies
var enemyData = [{
x: 700,
y: 2250
}, {
x: 1200,
y: 2350
}, {
x: 1500,
y: 2150
}];
for (var i = 0; i < enemyData.length; i++) {
var enemy = new StickmanEnemy();
enemy.x = enemyData[i].x;
enemy.y = enemyData[i].y;
enemies.push(enemy);
game.addChild(enemy);
}
// UI Elements
var healthText = new Text2('Health: 100', {
size: 40,
fill: 0x00FF00
});
healthText.anchor.set(0, 0);
LK.gui.left.addChild(healthText);
healthText.y = 200; // Position below top-left menu area
var scoreText = new Text2('Score: 0', {
size: 40,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Mobile Controls UI
var leftButton = LK.getAsset('platform', {
width: 160,
height: 160,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6,
tint: 0x4444FF
});
leftButton.x = 150;
leftButton.y = LK.gui.bottom.y - 200;
leftButton.interactive = true;
leftButton.buttonMode = true;
LK.gui.addChild(leftButton);
// Left arrow icon (stickman moving left)
var leftIcon = LK.getAsset('stickman', {
width: 40,
height: 50,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8,
scaleX: -1
});
leftIcon.x = leftButton.x;
leftIcon.y = leftButton.y;
LK.gui.addChild(leftIcon);
var rightButton = LK.getAsset('platform', {
width: 160,
height: 160,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6,
tint: 0x4444FF
});
rightButton.x = 300;
rightButton.y = LK.gui.bottom.y - 200;
rightButton.interactive = true;
rightButton.buttonMode = true;
LK.gui.addChild(rightButton);
// Right arrow icon (stickman moving right)
var rightIcon = LK.getAsset('stickman', {
width: 40,
height: 50,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
rightIcon.x = rightButton.x;
rightIcon.y = rightButton.y;
LK.gui.addChild(rightIcon);
var jumpButton = LK.getAsset('platform', {
width: 180,
height: 180,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6,
tint: 0x44FF44
});
jumpButton.x = LK.gui.right.x - 200;
jumpButton.y = LK.gui.bottom.y - 180;
jumpButton.interactive = true;
jumpButton.buttonMode = true;
LK.gui.addChild(jumpButton);
// Jump icon (stickman jumping)
var jumpIcon = LK.getAsset('stickman', {
width: 50,
height: 60,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8,
rotation: -0.3
});
jumpIcon.x = jumpButton.x;
jumpIcon.y = jumpButton.y - 10;
LK.gui.addChild(jumpIcon);
var attackButton = LK.getAsset('platform', {
width: 160,
height: 160,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6,
tint: 0xFF4444
});
attackButton.x = LK.gui.right.x - 350;
attackButton.y = LK.gui.bottom.y - 180;
attackButton.interactive = true;
attackButton.buttonMode = true;
LK.gui.addChild(attackButton);
// Attack label (keeping text for attack button)
var attackLabel = new Text2('ATK', {
size: 35,
fill: 0xFFFFFF
});
attackLabel.anchor.set(0.5, 0.5);
attackLabel.x = attackButton.x;
attackLabel.y = attackButton.y;
LK.gui.addChild(attackLabel);
// Input handling
var leftPressed = false;
var rightPressed = false;
var currentTouchId = null;
// Button press detection
leftButton.down = function (x, y, obj) {
leftPressed = true;
currentTouchId = 'left';
tween(leftButton, {
alpha: 0.9
}, {
duration: 100
});
};
leftButton.up = function (x, y, obj) {
leftPressed = false;
if (currentTouchId === 'left') currentTouchId = null;
tween(leftButton, {
alpha: 0.6
}, {
duration: 100
});
};
rightButton.down = function (x, y, obj) {
rightPressed = true;
currentTouchId = 'right';
tween(rightButton, {
alpha: 0.9
}, {
duration: 100
});
};
rightButton.up = function (x, y, obj) {
rightPressed = false;
if (currentTouchId === 'right') currentTouchId = null;
tween(rightButton, {
alpha: 0.6
}, {
duration: 100
});
};
jumpButton.down = function (x, y, obj) {
console.log("Jump button pressed!");
player.jump();
tween(jumpButton, {
alpha: 0.9
}, {
duration: 100
});
};
jumpButton.up = function (x, y, obj) {
tween(jumpButton, {
alpha: 0.6
}, {
duration: 100
});
};
attackButton.down = function (x, y, obj) {
player.attack();
tween(attackButton, {
alpha: 0.9
}, {
duration: 100
});
};
attackButton.up = function (x, y, obj) {
tween(attackButton, {
alpha: 0.6
}, {
duration: 100
});
};
game.down = function (x, y, obj) {
// Fallback touch handling for areas outside buttons
};
game.up = function (x, y, obj) {
// Fallback touch release handling
};
// Collision detection function
function checkCollisions(obj, platforms) {
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
if (obj.intersects(platform)) {
// Landing on top of platform
if (obj.velocityY > 0 && obj.y - 40 < platform.y) {
obj.y = platform.y - 40;
obj.velocityY = 0;
obj.onGround = true;
// Reset double jump when landing
if (obj === player) {
obj.canDoubleJump = true;
obj.hasUsedDoubleJump = false;
}
}
}
}
// Ground collision
if (obj.y > 2632) {
obj.y = 2632;
obj.velocityY = 0;
obj.onGround = true;
// Reset double jump when landing on ground
if (obj === player) {
obj.canDoubleJump = true;
obj.hasUsedDoubleJump = false;
}
}
}
game.update = function () {
// Handle input
if (leftPressed) {
player.moveLeft();
}
if (rightPressed) {
player.moveRight();
}
// Check collisions for player
checkCollisions(player, platforms);
// Check collisions for enemies
for (var i = 0; i < enemies.length; i++) {
checkCollisions(enemies[i], platforms);
}
// Update projectiles and check enemy hits
for (var i = projectiles.length - 1; i >= 0; i--) {
var projectile = projectiles[i];
// Check if projectile hits enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (projectile.intersects(enemy)) {
if (enemy.takeDamage(25)) {
// Enemy destroyed
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
}
// Remove projectile
projectile.destroy();
projectiles.splice(i, 1);
break;
}
}
// Remove destroyed projectiles
if (projectile.parent === null) {
projectiles.splice(i, 1);
}
}
// Check player-enemy collisions
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (player.intersects(enemy)) {
// Simple knockback and damage
var dx = player.x - enemy.x;
player.velocityX += dx > 0 ? 5 : -5;
player.takeDamage(1);
// Update health display
healthText.setText('Health: ' + Math.max(0, player.health));
healthText.tint = player.health < 30 ? 0xFF0000 : 0x00FF00;
}
}
// Win condition - defeat all enemies
if (enemies.length === 0) {
LK.showYouWin();
}
// Update stamina bar position and appearance
staminaBarBackground.x = player.x;
staminaBarBackground.y = player.y - 100;
staminaBar.x = player.x;
staminaBar.y = player.y - 100;
// Update stamina bar color based on double jump availability
if (player.canDoubleJump && !player.hasUsedDoubleJump) {
staminaBar.tint = 0x00FF00; // Bright green when available
} else {
staminaBar.tint = 0x444444; // Dark gray when used
}
// Camera follow player (simple)
var targetY = Math.max(-1366, Math.min(0, -(player.y - 1366)));
game.y += (targetY - game.y) * 0.1;
}; ===================================================================
--- original.js
+++ change.js
@@ -35,12 +35,58 @@
return self;
});
var Stickman = Container.expand(function () {
var self = Container.call(this);
- var graphics = self.attachAsset('stickman', {
+ // Create stickman body parts similar to enemy
+ var head = self.attachAsset('enemy_head', {
anchorX: 0.5,
- anchorY: 1.0
+ anchorY: 0.5,
+ x: 0,
+ y: -65,
+ tint: 0x0066FF
});
+ var body = self.attachAsset('enemy_body', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: 0,
+ y: -50,
+ tint: 0x0066FF
+ });
+ var leftArm = self.attachAsset('enemy_limb', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: -10,
+ y: -40,
+ tint: 0x0066FF
+ });
+ var rightArm = self.attachAsset('enemy_limb', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: 10,
+ y: -40,
+ tint: 0x0066FF
+ });
+ var leftLeg = self.attachAsset('enemy_limb', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: -5,
+ y: -20,
+ tint: 0x0066FF
+ });
+ var rightLeg = self.attachAsset('enemy_limb', {
+ anchorX: 0.5,
+ anchorY: 0,
+ x: 5,
+ y: -20,
+ tint: 0x0066FF
+ });
+ var sword = self.attachAsset('enemy_sword', {
+ anchorX: 0.5,
+ anchorY: 1,
+ x: 15,
+ y: -30,
+ tint: 0xFFFFFF
+ });
// Movement properties
self.velocityX = 0;
self.velocityY = 0;
self.onGround = false;
@@ -52,8 +98,13 @@
// Combat properties
self.canAttack = true;
self.attackCooldown = 0;
self.lastAttackTime = 0;
+ // Animation properties
+ self.animationTick = 0;
+ self.isAttacking = false;
+ self.isJumping = false;
+ self.wasOnGround = true;
self.update = function () {
// Apply gravity
if (!self.onGround) {
self.velocityY += 0.8;
@@ -69,21 +120,82 @@
// Update attack cooldown
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
+ // Animation updates
+ self.animationTick++;
+ // Check if jumping state changed
+ if (!self.onGround && self.wasOnGround) {
+ self.isJumping = true;
+ }
+ if (self.onGround && !self.wasOnGround) {
+ self.isJumping = false;
+ }
+ self.wasOnGround = self.onGround;
+ // Handle animations
+ if (self.isAttacking) {
+ // Attack animation is handled in attack method
+ } else if (self.isJumping || !self.onGround) {
+ // Jump animation - spread arms and legs
+ leftArm.rotation = -0.5;
+ rightArm.rotation = 0.5;
+ leftLeg.rotation = -0.3;
+ rightLeg.rotation = 0.3;
+ // No body bob during jump
+ body.y = -50;
+ head.y = -65;
+ } else if (Math.abs(self.velocityX) > 0.1) {
+ // Walking animation
+ var walkSpeed = 0.25;
+ var walkCycle = Math.sin(self.animationTick * walkSpeed);
+ var walkCycleOffset = Math.sin(self.animationTick * walkSpeed + Math.PI);
+ // Leg animation - alternate walking
+ leftLeg.rotation = walkCycle * 0.4;
+ rightLeg.rotation = walkCycleOffset * 0.4;
+ // Arm animation - opposite to legs
+ leftArm.rotation = walkCycleOffset * 0.3;
+ rightArm.rotation = walkCycle * 0.3;
+ // Body bob animation
+ body.y = -50 + Math.abs(Math.sin(self.animationTick * walkSpeed * 2)) * 2;
+ head.y = -65 + Math.abs(Math.sin(self.animationTick * walkSpeed * 2)) * 2;
+ } else {
+ // Idle animation - return to normal positions
+ leftArm.rotation = 0;
+ rightArm.rotation = 0;
+ leftLeg.rotation = 0;
+ rightLeg.rotation = 0;
+ body.y = -50;
+ head.y = -65;
+ }
+ // Face direction
+ if (self.facingRight) {
+ head.scaleX = 1;
+ body.scaleX = 1;
+ leftArm.scaleX = 1;
+ rightArm.scaleX = 1;
+ leftLeg.scaleX = 1;
+ rightLeg.scaleX = 1;
+ sword.x = 15;
+ } else {
+ head.scaleX = -1;
+ body.scaleX = -1;
+ leftArm.scaleX = -1;
+ rightArm.scaleX = -1;
+ leftLeg.scaleX = -1;
+ rightLeg.scaleX = -1;
+ sword.x = -15;
+ }
// Keep player in bounds
if (self.x < 30) self.x = 30;
if (self.x > 2018) self.x = 2018;
};
self.moveLeft = function () {
self.velocityX = -self.speed;
self.facingRight = false;
- graphics.scaleX = -1;
};
self.moveRight = function () {
self.velocityX = self.speed;
self.facingRight = true;
- graphics.scaleX = 1;
};
self.jump = function () {
console.log("Jump called! onGround:", self.onGround, "velocityY:", self.velocityY);
if (self.onGround || Math.abs(self.velocityY) < 2) {
@@ -105,47 +217,84 @@
};
self.attack = function () {
if (self.attackCooldown <= 0) {
self.attackCooldown = 30;
+ self.isAttacking = true;
LK.getSound('attack').play();
- // Flash attack animation
- tween(graphics, {
- tint: 0xFFFF00
+ // Sword attack animation - swing from back to front
+ tween(sword, {
+ rotation: -1.8
}, {
- duration: 100,
+ duration: 150,
onFinish: function onFinish() {
- tween(graphics, {
- tint: 0xFFFFFF
+ // Swing forward
+ tween(sword, {
+ rotation: 0.8
}, {
- duration: 100
+ duration: 200,
+ onFinish: function onFinish() {
+ // Return to normal position
+ tween(sword, {
+ rotation: 0
+ }, {
+ duration: 250,
+ onFinish: function onFinish() {
+ self.isAttacking = false;
+ }
+ });
+ }
});
+ // Check for enemy hits during forward swing
+ LK.setTimeout(function () {
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ var distanceToEnemy = Math.abs(self.x - enemy.x);
+ var verticalDistance = Math.abs(self.y - enemy.y);
+ if (distanceToEnemy < 80 && verticalDistance < 60) {
+ if (enemy.takeDamage(50)) {
+ // Enemy destroyed
+ enemies.splice(i, 1);
+ LK.setScore(LK.getScore() + 100);
+ scoreText.setText('Score: ' + LK.getScore());
+ }
+ // Knockback effect
+ var knockbackDirection = enemy.x > self.x ? 1 : -1;
+ enemy.velocityX += knockbackDirection * 8;
+ }
+ }
+ }, 150);
}
});
- // Create projectile
- var projectile = new Projectile();
- projectile.x = self.x + (self.facingRight ? 40 : -40);
- projectile.y = self.y - 40;
- projectile.velocityX = self.facingRight ? 12 : -12;
- projectiles.push(projectile);
- game.addChild(projectile);
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.getSound('hit').play();
- // Damage flash effect
- tween(graphics, {
- tint: 0xFF0000
+ // Damage flash effect on all body parts
+ tween(head, {
+ tint: 0xFF0066
}, {
duration: 150,
onFinish: function onFinish() {
- tween(graphics, {
- tint: 0xFFFFFF
+ tween(head, {
+ tint: 0x0066FF
}, {
duration: 150
});
}
});
+ tween(body, {
+ tint: 0xFF0066
+ }, {
+ duration: 150,
+ onFinish: function onFinish() {
+ tween(body, {
+ tint: 0x0066FF
+ }, {
+ duration: 150
+ });
+ }
+ });
if (self.health <= 0) {
LK.showGameOver();
}
};
Crea un personaje estilo pixel art, un guerrero simple y fácil de animar. No debe tener manos ni piernas visibles, solo un cuerpo principal con forma redonda u ovalada. El diseño debe sugerir que es un guerrero usando colores llamativos, ojos brillantes o una armadura pixelada pegada al cuerpo. Puede tener una espada flotando al lado o en la espalda como decoración. Debe verse como un personaje de videojuego, pero sin partes que necesiten animación compleja.. In-Game asset. 2d. High contrast. No shadows
Diseña una espada estilo pixel art, sencilla pero llamativa. Debe ser fácil de animar o colocar junto a un personaje. El mango debe ser corto y simple, y la hoja puede ser recta o con un brillo digital. Usa colores llamativos como azul neón, rojo fuego o plateado con detalles pixelados. El diseño debe parecer futurista o mágico, como si fuera un arma especial de un guerrero digital.. In-Game asset. 2d. High contrast. No shadows