User prompt
Mientras dura el juego reproducir la musica de Flash
User prompt
Cuando no hay orbes realizar comando "Salto directo" en donde el stickman salta perperndicularmente al muro o asset en el que se encuentra dirigiendose al que esta en el lado opuesto ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En el salto en parabola el puntero indica la altura y desde ahi se debe dirigir hacia el asset o earth que cumpla una parabola simetrica ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En el salto en parabola la parabola no debe tener como punto final la ubicación del puntero, este determina la altura entre el punto inicial y el siguiente en el que se toca un muro o asset de earth ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Al terminar la parabola donde se hace contacto es la nueva posición del stickman para seguir corriendo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
La parabola no se modifica luego de hacer click ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En el salto en parabola luego de alcanzar el mouse se continua la parabola hasta contactar un muro o asset de terrain ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En el salto en parabola luego de alcanzar al mouse se continua con el trayecto hasta hacer contacto con el muro o un asset de terrain ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El salto en parabola se dirige a donde se apunta con el mouse ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El salto en parabola va dirigido a la zona que tenga la mayor cantidad de asseys terrain juntos cerca al puntero del mouse ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
El salto en parabola va dirigido a la zona enfrente que tenga la mayor cantidad de assets terrain juntos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Que el salto en parabola no solo este dirigido a los centros de los muros ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
la disminución por salto que sea de 1 punto
User prompt
la disminución de score cada 2 segundos que sea de 10
User prompt
Convierte el número máximo de orbes a 3
User prompt
El daño por tocar una zona donde no hay asset terrain has que sea de 1
User prompt
Cuando no hay ninguna orbe visible en pantalla el click hace que el persona que haga un salto en parabola ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
No estan cambiando los assets
User prompt
El asset terrain al ser tocado se convierte en el asset EARTH, la siguiente vez que es tocado desaparece y al agarrar un orbe si se regenera aparece el asset terrain en lugar del asset EARTH
User prompt
Las orbes que se encuentran en pantalla después de que se llegue al número máximo deben también tener la capacidad de hacer que se regenere el terreno
User prompt
Al agarrar un orbe regenerar 5 assets de terrain aleatorios en el campo dando preferencia a los centros de los muros
User prompt
En la segunda vez que se genera un orbe por el contador de next orb haz que el fondo cambie a verde ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
En lugar que la pantalla se ponga amarilla cada vez que agarraz un orbe haz que alrededor del stickman brille ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Pon en pantalla un contado llamado "Charges" en donde se indiquen las orbes que ha tocado el stickman
User prompt
Que no se vea el contador de orbes
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Track number of times orbs have been generated
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) {
// Apply acceleration when approaching destination wall
var baseSpeed = 0.04;
var accelerationFactor = 1;
// Apply slow motion in the center of the jump (40%-60%)
if (self.jumpProgress >= 0.4 && self.jumpProgress <= 0.6) {
// Calculate how close we are to the center (0.4 to 0.6 maps to 1.0 to 0.0 to 1.0)
var centerDistance = Math.abs(0.5 - self.jumpProgress) / 0.1; // 0 at center, 1 at edges
var slowMotionFactor = 0.4875 + centerDistance * 0.5125; // 0.4875x speed at center (25% more slow motion), 1.0x at edges
accelerationFactor *= slowMotionFactor;
}
// Start accelerating when past 60% of the jump
if (self.jumpProgress > 0.6) {
// Calculate how close we are to the end (0.6 to 1.0 maps to 0.0 to 1.0)
var accelerationProgress = (self.jumpProgress - 0.6) / 0.4;
// Apply quadratic acceleration (starts slow, gets faster)
accelerationFactor = 1 + accelerationProgress * accelerationProgress * 1;
}
self.jumpProgress += baseSpeed * accelerationFactor;
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);
}
if (self.isParabolicJump) {
// Parabolic jump - elevate relative to current wall
var targetWall = self.jumpTargetWall || self.getOppositeWall(self.jumpStartWall);
var endPos = self.getWallPosition(targetWall, 0.5);
// Calculate base trajectory
var linearX = startPos.x + (endPos.x - startPos.x) * self.jumpProgress;
var linearY = startPos.y + (endPos.y - startPos.y) * self.jumpProgress;
// Add parabolic elevation with tween easing
var parabolaHeight = 400; // Maximum height of parabola
var elevationFactor = tween.easeInOut(self.jumpProgress);
var parabolicOffset = parabolaHeight * (1 - Math.pow(2 * self.jumpProgress - 1, 2));
// Apply elevation perpendicular to the wall direction
var wallDirection = self.getWallDirection(self.jumpStartWall);
self.x = linearX + wallDirection.perpX * parabolicOffset;
self.y = linearY + wallDirection.perpY * parabolicOffset;
} else {
// Regular jump - straight line
// Use jumpTargetWall if set, otherwise use opposite wall
var targetWall = self.jumpTargetWall || self.getOppositeWall(self.jumpStartWall);
// For direct jumps, target the perpendicular position on opposite wall
var targetProgress = self.jumpTargetWall ? self.jumpStartProgress : 0.5;
var endPos = self.getWallPosition(targetWall, targetProgress);
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;
var targetWall = self.jumpTargetWall || self.getOppositeWall(self.jumpStartWall);
self.wall = targetWall;
// For direct jumps, maintain perpendicular position; for others use center
self.wallProgress = self.jumpTargetWall ? self.jumpStartProgress : 0.5;
self.jumpProgress = 0;
self.jumpTargetWall = null; // Reset target wall
self.isParabolicJump = false; // Reset parabolic flag
// 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;
// Check if stickman is on terrain (only when not jumping)
if (!self.isJumping) {
var onTerrain = false;
var stickmanRadius = 70; // Half of stickman width
// Check collision with all terrain blocks
for (var t = 0; t < terrainBlocks.length; t++) {
var block = terrainBlocks[t];
var blockHalfWidth = 92; // terrain block half width
var blockHalfHeight = 30.56; // terrain block half height
// Check if stickman overlaps with terrain block
var dx = Math.abs(self.x - block.x);
var dy = Math.abs(self.y - block.y);
if (dx < stickmanRadius + blockHalfWidth && dy < stickmanRadius + blockHalfHeight) {
onTerrain = true;
break;
}
}
// Track last terrain state
if (self.lastOnTerrain === undefined) self.lastOnTerrain = true;
// If we just stepped off terrain (transition from on terrain to off terrain)
if (self.lastOnTerrain && !onTerrain) {
// Deduct 1 point
var currentScore = LK.getScore();
var newScore = Math.max(0, currentScore - 1);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
// Check if score reached 0
if (newScore <= 0) {
LK.showGameOver();
}
}
// Update last terrain state
self.lastOnTerrain = onTerrain;
}
// 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) {
// Stickman sprite half-width (140/2 = 70)
var stickmanHalfWidth = 70;
// Terrain block height is approximately 61.12, so half is about 30.56
var terrainHalfHeight = 30.56;
switch (wall) {
case 'top':
return {
x: progress * 2048,
y: stickmanHalfWidth + terrainHalfHeight // Position above terrain pixels
};
case 'right':
return {
x: 2048 - stickmanHalfWidth - terrainHalfHeight,
// Position above terrain pixels
y: 60 + progress * (2732 - 120)
};
case 'bottom':
return {
x: (1 - progress) * 2048,
y: 2732 - stickmanHalfWidth - terrainHalfHeight // Position above terrain pixels
};
case 'left':
return {
x: stickmanHalfWidth + terrainHalfHeight,
// Position above terrain pixels
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
self.isParabolicJump = false; // Regular jump
// Decrease score by 1 point for each jump
var currentScore = LK.getScore();
var newScore = Math.max(0, currentScore - 1);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
// Check if score reached 0 after jump
if (newScore <= 0) {
LK.showGameOver();
}
LK.getSound('jump').play();
}
};
self.parabolicJump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpStartWall = self.wall;
self.jumpStartProgress = self.wallProgress;
self.jumpProgress = 0;
self.jumpTargetWall = null;
self.isParabolicJump = true; // Parabolic jump flag
// Decrease score by 1 point for parabolic jump
var currentScore = LK.getScore();
var newScore = Math.max(0, currentScore - 1);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
// Check if score reached 0 after jump
if (newScore <= 0) {
LK.showGameOver();
}
LK.getSound('jump').play();
}
};
self.directJump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpStartWall = self.wall;
self.jumpStartProgress = self.wallProgress;
self.jumpProgress = 0;
// Set target to opposite wall maintaining perpendicular position
self.jumpTargetWall = self.getOppositeWall(self.wall);
self.isParabolicJump = false; // Direct jump flag
// Decrease score by 1 point for direct jump
var currentScore = LK.getScore();
var newScore = Math.max(0, currentScore - 1);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
// Check if score reached 0 after jump
if (newScore <= 0) {
LK.showGameOver();
}
LK.getSound('jump').play();
}
};
self.getWallDirection = function (wall) {
// Returns perpendicular direction vectors for parabolic elevation
switch (wall) {
case 'top':
return {
perpX: 0,
perpY: 1
};
// Elevate downward from top wall
case 'bottom':
return {
perpX: 0,
perpY: -1
};
// Elevate upward from bottom wall
case 'left':
return {
perpX: 1,
perpY: 0
};
// Elevate rightward from left wall
case 'right':
return {
perpX: -1,
perpY: 0
};
// Elevate leftward from right wall
}
};
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 orbGenerationCount = 0;
var stickman;
var orbs = [];
var terrainBlocks = [];
var orbsCollected = 0;
var gameTime = 0;
var destructionRate = 1;
var orbSpawnTimer = 10 * 60; // Start with 10 seconds
var orbSpawnActive = true; // Start active so timer is always running
var orbSpawnTxt = null;
// Create timer display
var timerTxt = new Text2('Time: 0', {
size: 60,
fill: 0xFFFFFF
});
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: 0xFFFFFF
});
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 (hidden)
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; // Hide the orb counter completely
// Note: Not adding to LK.gui.center to keep it hidden
// Create orb spawn countdown display (always visible)
orbSpawnTxt = new Text2('Next Orb: 10', {
size: 70,
fill: 0xFF4500
});
orbSpawnTxt.anchor.set(0.5, 0.5);
orbSpawnTxt.y = 200; // Position below orb count
orbSpawnTxt.alpha = 0.4; // Always visible with reduced opacity
LK.gui.center.addChild(orbSpawnTxt);
// 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 >= 3) 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 createCenterOrb() {
var newOrb = game.addChild(new Orb());
newOrb.x = 1024; // Center X
newOrb.y = 1366; // Center Y
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 < 3) {
orbsCollected++;
LK.setScore(LK.getScore() + 300);
scoreTxt.setText('Score: ' + LK.getScore());
// Repair terrain
repairTerrain();
// Regenerate 5 terrain blocks with wall center preference
regenerateTerrainBlocks(5);
// Remove collected orb
currentOrb.destroy();
orbs.splice(i, 1);
// Split into 2 new orbs (if under limit)
createNewOrb();
createNewOrb();
LK.getSound('collect').play();
// Create glow effect around stickman
tween(stickman, {
tint: 0xFFD700
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(stickman, {
tint: 0xFFFFFF
}, {
duration: 150,
easing: tween.easeIn
});
}
});
break; // Only collect one orb per frame
} else {
// At maximum orbs - make orb disappear and regenerate terrain
currentOrb.destroy();
orbs.splice(i, 1);
// Regenerate 5 terrain blocks with wall center preference
regenerateTerrainBlocks(5);
break; // Only process one orb per frame
}
}
}
}
function regenerateTerrainBlocks(count) {
// Define wall center positions with higher priority
var wallCenters = [{
x: 1024,
y: 20,
rotation: 0
},
// Top wall center
{
x: 1024,
y: 2712,
rotation: 0
},
// Bottom wall center
{
x: 20,
y: 1366,
rotation: Math.PI / 2
},
// Left wall center
{
x: 2028,
y: 1366,
rotation: -Math.PI / 2
} // Right wall center
];
// Define all possible terrain positions
var allPositions = [];
// Top wall positions
for (var i = 0; i < 17; i++) {
allPositions.push({
x: i * 120 + 60,
y: 20,
rotation: 0,
isCenter: i === 8
});
}
// Bottom wall positions
for (var i = 0; i < 17; i++) {
allPositions.push({
x: i * 120 + 60,
y: 2712,
rotation: 0,
isCenter: i === 8
});
}
// Left wall positions
for (var i = 1; i < 22; i++) {
allPositions.push({
x: 20,
y: i * 120 + 60,
rotation: Math.PI / 2,
isCenter: i === 11
});
}
// Right wall positions
for (var i = 1; i < 22; i++) {
allPositions.push({
x: 2028,
y: i * 120 + 60,
rotation: -Math.PI / 2,
isCenter: i === 11
});
}
// Filter out positions that already have terrain blocks
var availablePositions = [];
for (var p = 0; p < allPositions.length; p++) {
var pos = allPositions[p];
var hasBlock = false;
for (var t = 0; t < terrainBlocks.length; t++) {
var block = terrainBlocks[t];
var dx = Math.abs(block.x - pos.x);
var dy = Math.abs(block.y - pos.y);
if (dx < 30 && dy < 30) {
// Close enough to consider same position
hasBlock = true;
break;
}
}
if (!hasBlock) {
availablePositions.push(pos);
}
}
// Create blocks with preference for wall centers
var blocksCreated = 0;
while (blocksCreated < count && availablePositions.length > 0) {
var selectedIndex;
// 70% chance to prefer center positions if available
if (Math.random() < 0.7) {
var centerPositions = [];
for (var a = 0; a < availablePositions.length; a++) {
if (availablePositions[a].isCenter) {
centerPositions.push(a);
}
}
if (centerPositions.length > 0) {
selectedIndex = centerPositions[Math.floor(Math.random() * centerPositions.length)];
} else {
selectedIndex = Math.floor(Math.random() * availablePositions.length);
}
} else {
selectedIndex = Math.floor(Math.random() * availablePositions.length);
}
var selectedPos = availablePositions[selectedIndex];
var newBlock = new TerrainBlock();
newBlock.x = selectedPos.x;
newBlock.y = selectedPos.y;
newBlock.rotation = selectedPos.rotation;
terrainBlocks.push(newBlock);
game.addChild(newBlock);
// Remove used position
availablePositions.splice(selectedIndex, 1);
blocksCreated++;
}
}
function checkGameOver() {
if (terrainBlocks.length < 10) {
LK.showGameOver();
}
}
// Initialize terrain
createInitialTerrain();
// Play Flash music during the game
LK.playMusic('Flash');
// Context menu prevention is handled by LK engine automatically
// Game controls
game.down = function (x, y, obj) {
console.log('Game down event triggered', obj.event ? obj.event.button : 'no button info');
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 {
// Handle mouse button clicks when not jumping
// Check if no orbs are visible on screen
if (orbs.length === 0) {
// No orbs visible - trigger direct jump to opposite wall
console.log('No orbs visible - direct jump');
stickman.directJump();
} else {
// Orbs are visible - handle normal controls
if (obj.event.button === 0) {
// Left click - regular jump to opposite wall
console.log('Left click - regular jump');
stickman.jump();
} else if (obj.event.button === 2) {
// Right click - parabolic jump relative to current wall
console.log('Right click - parabolic jump');
stickman.parabolicJump();
}
}
}
} else {
// Fallback for touch devices
// Check if no orbs are visible on screen
if (orbs.length === 0) {
// No orbs visible - trigger direct jump to opposite wall
console.log('Touch fallback - no orbs visible - direct jump');
stickman.directJump();
} else {
// Orbs are visible - regular jump
console.log('Touch fallback - 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 10 every 2 seconds (120 ticks)
if (gameTime % 120 === 0) {
var currentScore = LK.getScore();
var newScore = Math.max(0, currentScore - 10);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
// Check if score reached 0
if (newScore <= 0) {
LK.showGameOver();
}
}
// Only update orb spawn countdown if no orbs exist
if (orbs.length === 0) {
orbSpawnTimer--;
var secondsLeft = Math.ceil(orbSpawnTimer / 60);
orbSpawnTxt.setText('Next Orb: ' + secondsLeft);
// When timer reaches 0, spawn orb and reset
if (orbSpawnTimer <= 0) {
createCenterOrb();
orbSpawnTimer = 10 * 60; // Reset to 10 seconds
orbGenerationCount++; // Increment generation counter
// Change background to green on second generation
if (orbGenerationCount === 2) {
tween(game, {
backgroundColor: 0x00FF00
}, {
duration: 1000,
easing: tween.easeInOut
});
}
}
} else {
// Reset timer when orbs exist so it starts fresh when they're all gone
orbSpawnTimer = 10 * 60;
orbSpawnTxt.setText('Next Orb: 10');
}
checkCollisions();
checkGameOver();
}; ===================================================================
--- original.js
+++ change.js
@@ -830,8 +830,10 @@
}
}
// Initialize terrain
createInitialTerrain();
+// Play Flash music during the game
+LK.playMusic('Flash');
// Context menu prevention is handled by LK engine automatically
// Game controls
game.down = function (x, y, obj) {
console.log('Game down event triggered', obj.event ? obj.event.button : 'no button info');
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