User prompt
Cada salto disminuye 20 puntos el score
User prompt
El juego empieza con 1000 de puntos en el score, cada 2 segundos se disminuyen 50 y cuando llega a 0 se pierde
User prompt
El score no sube con el tiempo, solo puede subirse 300 puntos al obtener un orbe
User prompt
agrega un cronómetro que va incrementando su numero arriba del score
User prompt
No deben atravesar los pixeles de los muros
User prompt
Los orbes no deben atravesar los muros
User prompt
Arriba del score pon un contador que indica el tiempo sobrevivido
User prompt
Los orbes no pueden atravesar los pixeles de los muros
User prompt
La repulsion no es acumulable
User prompt
Los orbes pueden chocar entre si y generan una pequeña repulson entre ellos al chocar
User prompt
De vez en cuando cambia el rumbo de las orbes pero solo puede pasar 1 de cada 10 veces cuando choca una pared
User prompt
Las orbes estan cambiando su opacidad como si se borraran y luego vuelven a su forma, haz que esto no pase en sus bordes
User prompt
El score y el numero de orbes debe verse menos, bajale la opacidad ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El score y el numero de orbes debe mostrarse en el centro de la pantalla
User prompt
Hay veces en las que la animación de rotación del stickman ocurre mientras esta saltando, no puede pasar
User prompt
Cuando presiono click izquierdo o derecho mientras el stickman se desplaza a un muro con el click izquierdo no pasa nada, debe reorientar su dirección y moverse hacia el muro de abajo o de arriba
User prompt
Si se presiona el click izquierdo mientras el stickman esta saltando al muro opuesto has que se diriga al muro de abajo, si presiona el click derecho mientras esta saltando a un muro opuesto haz que se diriga hacia el muro de arriba
User prompt
Los orbes deben tener una ligera rotación, que varie de horario a antihorario de manera al azar ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Siguen viendose 10 orbes, soluciona el error para que luego de llegar a los 10 vayan desapareciendo si vuelves a recoger un orbe
User prompt
Ademas de prevenir la recoleccion del orbe ya no debe aparecer en pantalla
User prompt
Corrige el error, luego de llegar al máximo numero de orbes y seguir recolectando vuelven a aparecer nuevos orbes y no debe ser asi
User prompt
Las orbes recolectadas luego de llegar al máximo número posible van desapareciendo
User prompt
Cuando se llega al número máximo de orbes ya no se pueden aumentar el número total de orbes
User prompt
El número máximo de orbes es 10
User prompt
Cuando se llega al límite máximo de orbes al recolectar van desapareciendo las que se toman
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Orb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('orb', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = (Math.random() - 0.5) * 16;
self.velocityY = (Math.random() - 0.5) * 16;
// Start random rotation animation
self.startRotation = function () {
var rotationDirection = Math.random() < 0.5 ? 1 : -1; // Random clockwise or counterclockwise
var rotationSpeed = (Math.random() * 2 + 1) * rotationDirection; // Random speed between 1-3, with direction
var currentRotation = orbGraphics.rotation;
var targetRotation = currentRotation + Math.PI * 2 * rotationSpeed; // Full rotation in chosen direction
tween(orbGraphics, {
rotation: targetRotation
}, {
duration: 2000 + Math.random() * 3000,
// Random duration between 2-5 seconds
easing: tween.linear,
onFinish: function onFinish() {
self.startRotation(); // Continue rotating with new random parameters
}
});
};
self.update = function () {
// Store previous position
var prevX = self.x;
var prevY = self.y;
self.x += self.velocityX;
self.y += self.velocityY;
// Check collision with terrain blocks
var orbRadius = 48; // Approximate orb radius
var collided = false;
for (var i = 0; i < terrainBlocks.length; i++) {
var block = terrainBlocks[i];
var blockHalfWidth = 92; // terrain block half width
var blockHalfHeight = 30.56; // terrain block half height
// Check if orb intersects with terrain block
var dx = Math.abs(self.x - block.x);
var dy = Math.abs(self.y - block.y);
if (dx < orbRadius + blockHalfWidth && dy < orbRadius + blockHalfHeight) {
// Collision detected - determine which side to bounce off
var overlapX = orbRadius + blockHalfWidth - dx;
var overlapY = orbRadius + blockHalfHeight - dy;
if (overlapX < overlapY) {
// Bounce horizontally
if (Math.random() < 0.1) {
// 10% chance to change direction randomly
self.velocityX = (Math.random() - 0.5) * 16;
} else {
// Normal bounce
self.velocityX *= -1;
}
// Push orb out of collision
if (self.x < block.x) {
self.x = block.x - blockHalfWidth - orbRadius;
} else {
self.x = block.x + blockHalfWidth + orbRadius;
}
} else {
// Bounce vertically
if (Math.random() < 0.1) {
// 10% chance to change direction randomly
self.velocityY = (Math.random() - 0.5) * 16;
} else {
// Normal bounce
self.velocityY *= -1;
}
// Push orb out of collision
if (self.y < block.y) {
self.y = block.y - blockHalfHeight - orbRadius;
} else {
self.y = block.y + blockHalfHeight + orbRadius;
}
}
collided = true;
break; // Only handle one collision per frame
}
}
// Bounce off screen boundaries as fallback (if no terrain collision)
if (!collided) {
if (self.x <= 40 || self.x >= 2008) {
if (Math.random() < 0.1) {
// 10% chance to change direction
self.velocityX *= -1;
} else {
// Always reverse velocity to prevent wall penetration
self.velocityX *= -1;
}
self.x = Math.max(40, Math.min(2008, self.x));
}
if (self.y <= 40 || self.y >= 2692) {
if (Math.random() < 0.1) {
// 10% chance to change direction
self.velocityY *= -1;
} else {
// Always reverse velocity to prevent wall penetration
self.velocityY *= -1;
}
self.y = Math.max(40, Math.min(2692, self.y));
}
}
};
// Start rotation animation when orb is created
self.startRotation();
return self;
});
var Stickman = Container.expand(function () {
var self = Container.call(this);
var stickmanGraphics = self.attachAsset('STICKMAN', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.wall = 'bottom'; // current wall: 'top', 'right', 'bottom', 'left'
self.wallProgress = 0; // progress along current wall (0-1)
self.isJumping = false;
self.jumpStartWall = '';
self.jumpStartProgress = 0;
self.jumpProgress = 0;
self.jumpTargetWall = null; // Target wall for redirected jumps
self.update = function () {
if (self.isJumping) {
self.jumpProgress += 0.04;
var startPos;
if (self.jumpStartWall === 'current') {
// Use current position as start for redirected jumps
startPos = {
x: self.x,
y: self.y
};
} else {
startPos = self.getWallPosition(self.jumpStartWall, self.jumpStartProgress);
}
// Use jumpTargetWall if set, otherwise use opposite wall
var targetWall = self.jumpTargetWall || self.getOppositeWall(self.jumpStartWall);
var endPos = self.getWallPosition(targetWall, 0.5);
self.x = startPos.x + (endPos.x - startPos.x) * self.jumpProgress;
self.y = startPos.y + (endPos.y - startPos.y) * self.jumpProgress;
if (self.jumpProgress >= 1) {
self.isJumping = false;
self.wall = targetWall;
self.wallProgress = 0.5;
self.jumpProgress = 0;
self.jumpTargetWall = null; // Reset target wall
// Create impact effect
createImpactEffect(self.x, self.y);
damageTerrain(self.x, self.y);
LK.getSound('impact').play();
}
} else {
self.wallProgress += self.speed / 1000;
if (self.wallProgress > 1) {
self.wallProgress = 0;
self.wall = self.getNextWall();
}
var pos = self.getWallPosition(self.wall, self.wallProgress);
self.x = pos.x;
self.y = pos.y;
// Damage terrain as stickman runs
if (LK.ticks % 15 === 0) {
damageTerrain(self.x, self.y);
}
}
// Rotate STICKMAN so top points toward center
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var angleToCenter = Math.atan2(centerY - self.y, centerX - self.x);
// Add 90 degrees (Math.PI/2) so top of asset points toward center instead of side
stickmanGraphics.rotation = angleToCenter + Math.PI / 2;
// Randomly rotate sprite in any direction (but not in first third of wall and not while jumping)
if (Math.random() < 0.005 && self.wallProgress > 0.33 && !self.isJumping) {
// 0.5% chance per frame for less frequent but more varied rotations
var currentRotation = stickmanGraphics.rotation;
// Random rotation between -360 to 360 degrees (in radians)
var randomRotation = (Math.random() - 0.5) * 4 * Math.PI;
var targetRotation = currentRotation + randomRotation;
tween(stickmanGraphics, {
rotation: targetRotation
}, {
duration: 1000 + Math.random() * 1000,
// Random duration between 1-2 seconds
easing: tween.easeInOut
});
}
// Randomly flip sprite horizontally
if (Math.random() < 0.003) {
// 0.3% chance per frame for horizontal flipping
var currentScaleX = stickmanGraphics.scaleX;
var targetScaleX = currentScaleX * -1; // Flip horizontally
tween(stickmanGraphics, {
scaleX: targetScaleX
}, {
duration: 800 + Math.random() * 400,
// Random duration between 0.8-1.2 seconds
easing: tween.easeInOut,
onFinish: function onFinish() {
// After 2 seconds, return to normal horizontal orientation
LK.setTimeout(function () {
tween(stickmanGraphics, {
scaleX: 1
}, {
duration: 800,
easing: tween.easeInOut
});
}, 2000);
}
});
}
};
self.getWallPosition = function (wall, progress) {
switch (wall) {
case 'top':
return {
x: progress * 2048,
y: 20 + 70 // Match side wall contact distance
};
case 'right':
return {
x: 2028 - 70,
// On top of terrain blocks (terrain x=2028, stickman width offset + 40px)
y: 60 + progress * (2732 - 120)
};
case 'bottom':
return {
x: (1 - progress) * 2048,
y: 2712 - 70 // Match side wall contact distance
};
case 'left':
return {
x: 20 + 70,
// On top of terrain blocks (terrain x=20, stickman width offset + 40px)
y: 2672 - progress * (2732 - 120)
};
}
};
self.getNextWall = function () {
var walls = ['top', 'right', 'bottom', 'left'];
var currentIndex = walls.indexOf(self.wall);
return walls[(currentIndex - 1 + 4) % 4];
};
self.getOppositeWall = function (wall) {
switch (wall) {
case 'top':
return 'bottom';
case 'bottom':
return 'top';
case 'left':
return 'right';
case 'right':
return 'left';
}
};
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpStartWall = self.wall;
self.jumpStartProgress = self.wallProgress;
self.jumpProgress = 0;
self.jumpTargetWall = null; // Reset target wall for new jump
LK.getSound('jump').play();
}
};
return self;
});
var TerrainBlock = Container.expand(function () {
var self = Container.call(this);
var terrainGraphics = self.attachAsset('terrain', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.damage = function () {
self.health--;
terrainGraphics.alpha = self.health / self.maxHealth;
if (self.health <= 0) {
self.destroy();
return true; // Block destroyed
}
return false;
};
self.repair = function () {
self.health = self.maxHealth;
terrainGraphics.alpha = 1;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var stickman;
var orbs = [];
var terrainBlocks = [];
var orbsCollected = 0;
var gameTime = 0;
var destructionRate = 1;
// Create timer display
var timerTxt = new Text2('Time: 0', {
size: 60,
fill: 0x000000
});
timerTxt.anchor.set(0.5, 0.5);
timerTxt.y = -80; // Position above the score text
timerTxt.alpha = 0.4; // Reduce opacity to make it less prominent
LK.gui.center.addChild(timerTxt);
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0x000000
});
scoreTxt.anchor.set(0.5, 0.5);
scoreTxt.alpha = 0.4; // Reduce opacity to make it less prominent
LK.gui.center.addChild(scoreTxt);
// Create orbs collected display
var orbTxt = new Text2('Orbs: 0', {
size: 60,
fill: 0xFFD700
});
orbTxt.anchor.set(0.5, 0.5);
orbTxt.y = 100; // Position below the score text
orbTxt.alpha = 0.4; // Reduce opacity to make it less prominent
LK.gui.center.addChild(orbTxt);
// Initialize score to 1000 points
LK.setScore(1000);
scoreTxt.setText('Score: ' + LK.getScore());
// Initialize stickman
stickman = game.addChild(new Stickman());
var pos = stickman.getWallPosition('bottom', 0);
stickman.x = pos.x;
stickman.y = pos.y;
// Initialize orb
var firstOrb = game.addChild(new Orb());
firstOrb.x = 1024;
firstOrb.y = 1366;
orbs.push(firstOrb);
// Create initial terrain blocks around perimeter
function createInitialTerrain() {
// Top wall
for (var i = 0; i < 17; i++) {
var block = new TerrainBlock();
block.x = i * 120 + 60;
block.y = 20;
terrainBlocks.push(block);
game.addChild(block);
}
// Bottom wall
for (var i = 0; i < 17; i++) {
var block = new TerrainBlock();
block.x = i * 120 + 60;
block.y = 2712;
terrainBlocks.push(block);
game.addChild(block);
}
// Left wall
for (var i = 1; i < 22; i++) {
var block = new TerrainBlock();
block.x = 20;
block.y = i * 120 + 60;
block.rotation = Math.PI / 2; // Rotate 90 degrees toward center
terrainBlocks.push(block);
game.addChild(block);
}
// Right wall
for (var i = 1; i < 22; i++) {
var block = new TerrainBlock();
block.x = 2028;
block.y = i * 120 + 60;
block.rotation = -Math.PI / 2; // Rotate 90 degrees toward center
terrainBlocks.push(block);
game.addChild(block);
}
}
function createImpactEffect(x, y) {
var effect = LK.getAsset('impactEffect', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
alpha: 0.8
});
game.addChild(effect);
tween(effect, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
effect.destroy();
}
});
}
function damageTerrain(x, y) {
var damageRadius = 150;
for (var i = terrainBlocks.length - 1; i >= 0; i--) {
var block = terrainBlocks[i];
var distance = Math.sqrt((block.x - x) * (block.x - x) + (block.y - y) * (block.y - y));
if (distance < damageRadius) {
if (block.damage()) {
terrainBlocks.splice(i, 1);
}
}
}
}
function repairTerrain() {
for (var i = 0; i < terrainBlocks.length; i++) {
terrainBlocks[i].repair();
}
}
function createNewOrb() {
if (orbs.length >= 10) return null; // Limit maximum orbs
var newOrb = game.addChild(new Orb());
newOrb.x = 200 + Math.random() * 1648;
newOrb.y = 200 + Math.random() * 2332;
newOrb.velocityX = (Math.random() - 0.5) * 16;
newOrb.velocityY = (Math.random() - 0.5) * 16;
orbs.push(newOrb);
return newOrb;
}
function checkCollisions() {
// Check orb-to-orb collisions and repulsion
for (var i = 0; i < orbs.length; i++) {
var orb1 = orbs[i];
// Initialize collision tracking if not exists
if (!orb1.collidingWith) orb1.collidingWith = [];
if (!orb1.lastCollidingWith) orb1.lastCollidingWith = [];
for (var j = i + 1; j < orbs.length; j++) {
var orb2 = orbs[j];
// Initialize collision tracking if not exists
if (!orb2.collidingWith) orb2.collidingWith = [];
if (!orb2.lastCollidingWith) orb2.lastCollidingWith = [];
var dx = orb2.x - orb1.x;
var dy = orb2.y - orb1.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Check if orbs are colliding (assuming orb radius of about 48)
var isColliding = distance < 96;
var wasColliding = orb1.lastCollidingWith.indexOf(j) !== -1;
if (isColliding && !wasColliding) {
// Collision just started - apply repulsion only once
var repulsionForce = 8; // Strength of repulsion
var angle = Math.atan2(dy, dx);
// Apply repulsion to both orbs
var forceX = Math.cos(angle) * repulsionForce;
var forceY = Math.sin(angle) * repulsionForce;
// Push orbs apart
orb1.velocityX -= forceX;
orb1.velocityY -= forceY;
orb2.velocityX += forceX;
orb2.velocityY += forceY;
}
// Update collision tracking
if (isColliding) {
if (orb1.collidingWith.indexOf(j) === -1) orb1.collidingWith.push(j);
if (orb2.collidingWith.indexOf(i) === -1) orb2.collidingWith.push(i);
} else {
var index1 = orb1.collidingWith.indexOf(j);
if (index1 !== -1) orb1.collidingWith.splice(index1, 1);
var index2 = orb2.collidingWith.indexOf(i);
if (index2 !== -1) orb2.collidingWith.splice(index2, 1);
}
}
// Update last frame collision state for all orbs
orb1.lastCollidingWith = orb1.collidingWith.slice(); // Copy current state
}
// Check stickman-orb collisions
for (var i = orbs.length - 1; i >= 0; i--) {
var currentOrb = orbs[i];
var distance = Math.sqrt((stickman.x - currentOrb.x) * (stickman.x - currentOrb.x) + (stickman.y - currentOrb.y) * (stickman.y - currentOrb.y));
if (distance < 70) {
// Only allow collection and rewards if we haven't reached maximum collected orbs
if (orbsCollected < 10) {
orbsCollected++;
LK.setScore(LK.getScore() + 300);
scoreTxt.setText('Score: ' + LK.getScore());
orbTxt.setText('Orbs: ' + orbsCollected);
// Repair terrain
repairTerrain();
// Remove collected orb
currentOrb.destroy();
orbs.splice(i, 1);
// Split into 2 new orbs (if under limit)
createNewOrb();
createNewOrb();
LK.getSound('collect').play();
// Flash effect
LK.effects.flashScreen(0xFFD700, 300);
break; // Only collect one orb per frame
} else {
// At maximum orbs - make orb disappear without rewards
currentOrb.destroy();
orbs.splice(i, 1);
break; // Only process one orb per frame
}
}
}
}
function checkGameOver() {
if (terrainBlocks.length < 10) {
LK.showGameOver();
}
}
// Initialize terrain
createInitialTerrain();
// Game controls
game.down = function (x, y, obj) {
if (obj.event && obj.event.button !== undefined) {
// Handle mouse button clicks during jumping
if (stickman.isJumping) {
if (obj.event.button === 0) {
// Left click - redirect to bottom wall
stickman.jumpTargetWall = 'bottom';
// Update jump start position to current position for smooth redirection
stickman.jumpStartWall = 'current';
stickman.jumpStartProgress = 0;
stickman.jumpProgress = 0;
} else if (obj.event.button === 2) {
// Right click - redirect to top wall
stickman.jumpTargetWall = 'top';
// Update jump start position to current position for smooth redirection
stickman.jumpStartWall = 'current';
stickman.jumpStartProgress = 0;
stickman.jumpProgress = 0;
}
} else {
// Regular jump when not already jumping
stickman.jump();
}
} else {
// Fallback for touch devices - regular jump
stickman.jump();
}
};
// Main game loop
game.update = function () {
gameTime++;
// Increase destruction rate over time
if (gameTime % 1800 === 0) {
// Every 30 seconds
destructionRate += 0.5;
}
// Random terrain destruction
if (Math.random() < 0.001 * destructionRate && terrainBlocks.length > 0) {
var randomIndex = Math.floor(Math.random() * terrainBlocks.length);
var block = terrainBlocks[randomIndex];
if (block.damage()) {
terrainBlocks.splice(randomIndex, 1);
}
}
// Update timer display only (no score increase over time)
if (gameTime % 60 === 0) {
// Every second
var seconds = Math.floor(gameTime / 60);
timerTxt.setText('Time: ' + seconds);
}
// Decrease score by 50 every 2 seconds (120 ticks)
if (gameTime % 120 === 0) {
var currentScore = LK.getScore();
var newScore = Math.max(0, currentScore - 50);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
// Check if score reached 0
if (newScore <= 0) {
LK.showGameOver();
}
}
checkCollisions();
checkGameOver();
}; ===================================================================
--- original.js
+++ change.js
@@ -337,8 +337,11 @@
orbTxt.anchor.set(0.5, 0.5);
orbTxt.y = 100; // Position below the score text
orbTxt.alpha = 0.4; // Reduce opacity to make it less prominent
LK.gui.center.addChild(orbTxt);
+// Initialize score to 1000 points
+LK.setScore(1000);
+scoreTxt.setText('Score: ' + LK.getScore());
// Initialize stickman
stickman = game.addChild(new Stickman());
var pos = stickman.getWallPosition('bottom', 0);
stickman.x = pos.x;
@@ -566,7 +569,18 @@
// Every second
var seconds = Math.floor(gameTime / 60);
timerTxt.setText('Time: ' + seconds);
}
+ // Decrease score by 50 every 2 seconds (120 ticks)
+ if (gameTime % 120 === 0) {
+ var currentScore = LK.getScore();
+ var newScore = Math.max(0, currentScore - 50);
+ LK.setScore(newScore);
+ scoreTxt.setText('Score: ' + LK.getScore());
+ // Check if score reached 0
+ if (newScore <= 0) {
+ LK.showGameOver();
+ }
+ }
checkCollisions();
checkGameOver();
};
\ No newline at end of file
Un stickman con una posición de corredor. In-Game asset. 2d. High contrast. No shadows
Cesped en forma de rectangulo como con el pasto arriba tierra y algunas rocas irregulares. In-Game asset. 2d. High contrast. No shadows
Stickman delgado en posición fetal y que este todo relleno de negro
Quitale el fondo
Bebidas energéticas verdes. In-Game asset. 2d. High contrast. No shadows
1 Lata verde con un rayo, sin fondo. In-Game asset. 2d. High contrast. No shadows
Change the green of the grass to dark green