User prompt
Que la IA ased caminando1 pueda decidir entre moverse o quedarse quieto o saltar
User prompt
As que la IA ased caminando1 Balla a la misma velocidad del jugador y que si vea un obstáculo enfrente los salte para seguir su camino
User prompt
As que el ased Final1 este en la parte derecha en el centro de la pantalla y que el objetivo de la IA ased caminando1 sea Aser todo lo posible por ir asia ella caminando y saltando
User prompt
As que el ased Final1 este delante del jugador pero que no pueda alcanzarlo ni la IA ased caminando1 no el jugador y que cuando el ased Final1 llegue a la distancia 1000
User prompt
As que la IA ased caminando1 pueda saltar para moverse
User prompt
As que la IA ased caminando1 se mueva sola y que no dependa del jugador para moverse
User prompt
As que la IA ased caminando1 se pueda mover a la izquierda y la derecha
User prompt
La IA ased caminando1 no detecta las colisiones de las plataformas
User prompt
La IA ased caminando1 no se está moviendo
User prompt
La IA no se mueve as que se mueva a la derecha
User prompt
As que la IA sea el ased caminando1
User prompt
As una IA que pueda Aser todo lo que puede Aser el player saltar moverse a la izquierda y derecha y que pueda identificar los obstáculos y que su unico destino sería el ased Final1
User prompt
As que el ased Final1 este arriba de la plataforma
User prompt
As que el ased Final1 este en la distancia 1000
User prompt
El ased Final1 no estaba en la distancia 1500
User prompt
Cambia la posición del ased Final1 a la distancia 1500
User prompt
As que en la distancia 5000 aparezca el ased Final1 y que esa sea la meta y que al jugador tocarla aparezca un mensaje de victoria
User prompt
As que los botones de izquierda y el botón derecha estén un poco separados
User prompt
Separa los botones de derecha y izquierda
User prompt
As que el botón de la derecha sea remplasado por el ased derecha2
User prompt
As que el botón de la izquierda sea remplasado por el ased izquierda1
User prompt
As que el botón de salto sea remplasado por el ased salto1
User prompt
Puedes Aser que al personaje estar quieto tenga una animación y cuando esté en movimiento tenga otra animación ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Puedes Aser que los botones sean un poco más grandes
User prompt
Hay una parte imposible recomiendo Aser algo que verifique el nivel y que lo modifique para que sea posible y si puedes Aser que con cada intento se cambie el nivel
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AI = Container.expand(function () {
var self = Container.call(this);
var aiGraphics = self.attachAsset('Caminando1', {
anchorX: 0.5,
anchorY: 1.0
});
self.target = null;
self.lastX = 0;
self.lastY = 0;
self.stuckCounter = 0;
self.jumpCooldown = 0;
self.scanDistance = 800;
self.pathfindingCooldown = 0;
self.velocityY = 0;
self.velocityX = 0;
self.isGrounded = false;
self.jumpPower = -25;
self.gravity = 1.2;
self.speed = 8; // Match player speed exactly
self.maxFallSpeed = 20;
// AI decision making
self.makeDecision = function () {
if (!aiGoalAsset) return;
// Update cooldowns
if (self.jumpCooldown > 0) self.jumpCooldown--;
if (self.pathfindingCooldown > 0) self.pathfindingCooldown--;
// Check if stuck
var aiMovement = Math.abs(self.x - self.lastX) + Math.abs(self.y - self.lastY);
if (aiMovement < 2) {
self.stuckCounter++;
} else {
self.stuckCounter = 0;
}
self.lastX = self.x;
self.lastY = self.y;
// Decision state system - AI can choose between different actions
var decisionState = self.evaluateSituation();
switch (decisionState) {
case 'JUMP':
if (self.isGrounded && self.jumpCooldown <= 0) {
self.jump();
self.jumpCooldown = 20;
}
break;
case 'MOVE_LEFT':
self.moveLeft();
break;
case 'MOVE_RIGHT':
self.moveRight();
break;
case 'STAY_STILL':
// AI decides to stay still - do nothing
self.velocityX *= 0.5; // Slow down gradually
break;
default:
// Default fallback behavior
self.executeDefaultBehavior();
break;
}
};
// Evaluate current situation and decide what action to take
self.evaluateSituation = function () {
if (!aiGoalAsset) return 'MOVE_RIGHT'; // Default if no goal
var goalDistance = aiGoalAsset.x - self.x;
var goalVerticalDistance = aiGoalAsset.y - self.y;
var obstacleAhead = self.checkForObstaclesAhead();
// Priority 1: If stuck for too long, jump
if (self.stuckCounter > 30 && self.isGrounded && self.jumpCooldown <= 0) {
return 'JUMP';
}
// Priority 2: Jump over obstacles when moving
if (obstacleAhead && self.isGrounded && self.jumpCooldown <= 0 && Math.abs(self.velocityX) > 1) {
return 'JUMP';
}
// Priority 3: Jump if goal is significantly above and we're close horizontally
if (Math.abs(goalDistance) < 200 && goalVerticalDistance < -100 && self.isGrounded && self.jumpCooldown <= 0) {
return 'JUMP';
}
// Priority 4: Stay still if very close to goal (within 100 units)
if (Math.abs(goalDistance) < 100 && Math.abs(goalVerticalDistance) < 50) {
return 'STAY_STILL';
}
// Priority 5: Stay still if on unstable ground or dangerous situation
if (!self.isGrounded && self.velocityY > 10) {
return 'STAY_STILL'; // Don't make sudden moves while falling fast
}
// Priority 6: Move towards goal
if (goalDistance > 50) {
return 'MOVE_RIGHT';
} else if (goalDistance < -50) {
return 'MOVE_LEFT';
}
// Priority 7: Stay still if goal is close horizontally
return 'STAY_STILL';
};
// Execute default behavior when no specific decision is made
self.executeDefaultBehavior = function () {
// Find target platform to move towards goal
if (self.pathfindingCooldown <= 0) {
self.target = self.findBestPlatform();
self.pathfindingCooldown = 10;
}
// Navigate towards target
if (self.target) {
self.navigateToTarget();
} else {
// Move towards goal as fallback
if (aiGoalAsset) {
var goalDistance = aiGoalAsset.x - self.x;
var goalVerticalDistance = aiGoalAsset.y - self.y;
// Check for obstacles ahead when moving towards goal
var obstacleAhead = self.checkForObstaclesAhead();
if (obstacleAhead && self.isGrounded && self.jumpCooldown <= 0) {
self.jump();
self.jumpCooldown = 20;
}
if (goalDistance > 50) {
self.moveRight();
} else if (goalDistance < -50) {
self.moveLeft();
}
} else {
// No goal yet, move right by default
// Check for obstacles when moving right
var obstacleAhead = self.checkForObstaclesAhead();
if (obstacleAhead && self.isGrounded && self.jumpCooldown <= 0) {
self.jump();
self.jumpCooldown = 20;
}
self.moveRight();
}
}
};
self.findBestPlatform = function () {
var bestPlatform = null;
var bestScore = -999999;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Skip platforms too far away or too close
if (Math.abs(platform.x - self.x) > 400 || Math.abs(platform.x - self.x) < 20) continue;
// Calculate score based on progress towards goal and reachability
var distanceToGoal = Math.abs(platform.x - aiGoalAsset.x);
var progressScore = (platform.x - self.x) * 2; // Favor forward movement
var goalProximityScore = -distanceToGoal * 0.5; // Favor platforms closer to goal
var heightPenalty = Math.abs(platform.y - self.y) * 0.1;
var score = progressScore + goalProximityScore - heightPenalty;
// Check if platform is reachable
if (self.isPlatformReachableByAI(platform)) {
score += 1000; // Bonus for reachable platforms
}
// Check for obstacles on platform
if (self.hasObstacleOnPlatform(platform)) {
score -= 500; // Penalty for obstacles
}
if (score > bestScore) {
bestScore = score;
bestPlatform = platform;
}
}
return bestPlatform;
};
self.isPlatformReachableByAI = function (platform) {
var horizontalDistance = Math.abs(platform.x - self.x);
var verticalDistance = platform.y - self.y;
// Simple reachability check
if (horizontalDistance > 350) return false; // Too far horizontally
if (verticalDistance > 400) return false; // Too high
if (verticalDistance < -600) return false; // Too far below
return true;
};
self.hasObstacleOnPlatform = function (platform) {
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
var distToPlatform = Math.abs(obstacle.x - platform.x);
var heightDiff = Math.abs(obstacle.y - platform.y);
if (distToPlatform < platform.width / 2 + 50 && heightDiff < 100) {
return true;
}
}
return false;
};
self.navigateToTarget = function () {
if (!self.target) return;
var horizontalDistance = self.target.x - self.x;
var verticalDistance = self.target.y - self.y;
// Check if we need to jump over obstacles
var needsJump = self.checkForObstaclesAhead();
// Jump if target is above us or if there's an obstacle (be more aggressive)
if ((verticalDistance < -50 || needsJump) && self.isGrounded && self.jumpCooldown <= 0) {
self.jump();
self.jumpCooldown = 20; // Reduced cooldown for more responsive jumping
}
// Also jump if we're close to the target horizontally but need to reach it vertically
if (Math.abs(horizontalDistance) < 100 && verticalDistance < -50 && self.isGrounded && self.jumpCooldown <= 0) {
self.jump();
self.jumpCooldown = 20;
}
// Move horizontally towards target
if (horizontalDistance > 30) {
self.moveRight();
} else if (horizontalDistance < -30) {
self.moveLeft();
}
// Check if we've reached the target platform
if (Math.abs(horizontalDistance) < 50 && Math.abs(verticalDistance) < 100) {
self.target = null; // Find new target
}
};
self.checkForObstaclesAhead = function () {
// Look ahead based on current movement speed and direction
var lookAheadDistance = Math.abs(self.velocityX) * 15 + 100; // Scale with speed
var direction = self.velocityX >= 0 ? 1 : -1; // Moving right or left
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
var obstacleDistance = (obstacle.x - self.x) * direction;
var heightDiff = Math.abs(obstacle.y - self.y);
// Check if obstacle is ahead in movement direction and at similar height
if (obstacleDistance > 0 && obstacleDistance < lookAheadDistance && heightDiff < 120) {
return true;
}
}
return false;
};
self.moveLeft = function () {
self.velocityX = -self.speed;
};
self.moveRight = function () {
self.velocityX = self.speed;
};
self.jump = function () {
if (self.isGrounded) {
self.velocityY = self.jumpPower;
self.isGrounded = false;
}
};
self.update = function () {
// Apply gravity
if (!self.isGrounded) {
self.velocityY += self.gravity;
if (self.velocityY > self.maxFallSpeed) {
self.velocityY = self.maxFallSpeed;
}
}
// Check for obstacles before moving and jump if needed
if (self.isGrounded && self.jumpCooldown <= 0 && Math.abs(self.velocityX) > 2) {
var obstacleAhead = self.checkForObstaclesAhead();
if (obstacleAhead) {
self.jump();
self.jumpCooldown = 25;
}
}
// Apply horizontal movement with friction
self.x += self.velocityX;
self.velocityX *= 0.85;
// Apply vertical movement
self.y += self.velocityY;
// Check if AI needs to jump to avoid falling (gap detection)
if (self.isGrounded && self.jumpCooldown <= 0) {
// Look ahead to see if there's a platform to land on
var foundPlatformAhead = false;
var lookAheadX = self.x + (self.velocityX > 0 ? 150 : -150);
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
var platformLeft = platform.x - platform.width / 2;
var platformRight = platform.x + platform.width / 2;
var heightDiff = Math.abs(platform.y - self.y);
// Check if there's a platform ahead at similar height
if (lookAheadX >= platformLeft && lookAheadX <= platformRight && heightDiff < 200) {
foundPlatformAhead = true;
break;
}
}
// If no platform found ahead and we're moving, jump to try to reach something
if (!foundPlatformAhead && Math.abs(self.velocityX) > 2) {
self.jump();
self.jumpCooldown = 40;
}
}
// Make AI decisions
self.makeDecision();
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1.0
});
self.width = 40;
self.height = 80;
return self;
});
var Platform = Container.expand(function (width) {
var self = Container.call(this);
width = width || 300;
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: width / 300
});
self.width = width;
self.height = 40;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.velocityY = 0;
self.velocityX = 0;
self.isGrounded = false;
self.jumpPower = -25;
self.gravity = 1.2;
self.speed = 8;
self.maxFallSpeed = 20;
self.isMoving = false;
self.idleAnimationTime = 0;
self.movementAnimationTime = 0;
self.moveLeft = function () {
self.velocityX = -self.speed;
};
self.moveRight = function () {
self.velocityX = self.speed;
};
self.jump = function () {
if (self.isGrounded) {
self.velocityY = self.jumpPower;
self.isGrounded = false;
LK.getSound('jump').play();
}
};
self.update = function () {
// Apply gravity
if (!self.isGrounded) {
self.velocityY += self.gravity;
if (self.velocityY > self.maxFallSpeed) {
self.velocityY = self.maxFallSpeed;
}
}
// Apply horizontal movement with friction
self.x += self.velocityX;
self.velocityX *= 0.85;
// Apply vertical movement
self.y += self.velocityY;
// Check if player is moving horizontally
self.isMoving = Math.abs(self.velocityX) > 0.5;
// Update animations
if (self.isMoving) {
// Movement animation - slight bouncing effect
self.movementAnimationTime += 0.3;
var bounceOffset = Math.sin(self.movementAnimationTime) * 3;
playerGraphics.y = bounceOffset;
playerGraphics.scaleX = 1 + Math.sin(self.movementAnimationTime * 2) * 0.05;
playerGraphics.scaleY = 1 + Math.cos(self.movementAnimationTime * 2) * 0.05;
// Reset idle animation
self.idleAnimationTime = 0;
} else {
// Idle animation - gentle floating effect
self.idleAnimationTime += 0.1;
var floatOffset = Math.sin(self.idleAnimationTime) * 2;
playerGraphics.y = floatOffset;
playerGraphics.scaleX = 1 + Math.sin(self.idleAnimationTime * 0.5) * 0.02;
playerGraphics.scaleY = 1 + Math.cos(self.idleAnimationTime * 0.5) * 0.02;
// Reset movement animation
self.movementAnimationTime = 0;
}
// No horizontal boundaries - allow infinite movement for side-scrolling
// Check if fallen off screen
if (self.y > 2800) {
LK.showGameOver();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var player;
var platforms = [];
var obstacles = [];
var cameraOffset = 0;
var distanceScore = 0;
var lastPlatformX = 0;
var leftButtonPressed = false;
var rightButtonPressed = false;
var jumpButtonPressed = false;
var gameAttempts = 0;
var levelSeed = 0;
var goalReached = false;
var goalAsset = null;
var aiPlayer = null;
var aiCameraOffset = 0;
var aiDistanceScore = 0;
var aiGoalAsset = null;
var aiGoalReached = false;
var aiLastPlatformX = 0;
// Create score display
var scoreText = new Text2('Distance: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Create control instruction text
var instructionText = new Text2('Use Buttons to Move and Jump', {
size: 40,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(instructionText);
// Initialize player
player = new Player();
player.x = 300;
player.y = 2000;
game.addChild(player);
// Initialize AI
aiPlayer = new AI();
aiPlayer.x = 200;
aiPlayer.y = 2000;
game.addChild(aiPlayer);
// Initialize AI-specific variables
aiCameraOffset = 0;
aiDistanceScore = 0;
aiLastPlatformX = 2200; // Same as initial lastPlatformX
// Create initial platforms
function createPlatform(x, y, width) {
var platform = new Platform(width);
platform.x = x;
platform.y = y;
platforms.push(platform);
game.addChild(platform);
return platform;
}
function createObstacle(x, y) {
var obstacle = new Obstacle();
obstacle.x = x;
obstacle.y = y;
obstacles.push(obstacle);
game.addChild(obstacle);
return obstacle;
}
// Generate initial level
createPlatform(200, 2100, 400); // Starting platform
createPlatform(600, 2000, 300);
createPlatform(1000, 1900, 250);
createPlatform(1400, 1800, 300);
createObstacle(1400, 1800);
createPlatform(1800, 1700, 200);
createPlatform(2200, 1600, 350);
lastPlatformX = 2200;
function generateLevel() {
// Remove platforms that are too far behind
for (var i = platforms.length - 1; i >= 0; i--) {
var platform = platforms[i];
if (platform.x < cameraOffset - 500) {
platform.destroy();
platforms.splice(i, 1);
}
}
// Remove obstacles that are too far behind
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.x < cameraOffset - 500) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Generate new platforms ahead for player
while (lastPlatformX < cameraOffset + 3000) {
var lastPlatform = findLastPlatform();
var newPlatform = generateVerifiedPlatform(lastPlatform);
lastPlatformX = newPlatform.x;
createPlatform(newPlatform.x, newPlatform.y, newPlatform.width);
// Add obstacles with attempt-based variation
var obstacleChance = 0.2 + gameAttempts * 0.05; // Increase difficulty with attempts
if (obstacleChance > 0.5) obstacleChance = 0.5; // Cap at 50%
if (Math.random() < obstacleChance) {
createObstacle(newPlatform.x, newPlatform.y);
}
}
// Generate new platforms ahead for AI
while (aiLastPlatformX < aiCameraOffset + 3000) {
var aiLastPlatform = findLastPlatform();
var aiNewPlatform = generateVerifiedPlatform(aiLastPlatform);
aiLastPlatformX = aiNewPlatform.x;
createPlatform(aiNewPlatform.x, aiNewPlatform.y, aiNewPlatform.width);
// Add obstacles for AI path
if (Math.random() < 0.3) {
createObstacle(aiNewPlatform.x, aiNewPlatform.y);
}
}
}
function findLastPlatform() {
var lastPlatform = null;
var maxX = -999999;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].x > maxX) {
maxX = platforms[i].x;
lastPlatform = platforms[i];
}
}
return lastPlatform;
}
function generateVerifiedPlatform(lastPlatform) {
var maxJumpDistance = 320; // Maximum horizontal jump distance
var maxJumpHeight = 350; // Maximum jump height (going up)
var maxFallHeight = 600; // Maximum fall height (going down)
// Attempt-based level variation
var difficultyMultiplier = 1 + gameAttempts * 0.1;
if (difficultyMultiplier > 2) difficultyMultiplier = 2; // Cap difficulty
var attemptSeed = gameAttempts * 12345 % 100000;
var pseudoRandom = (attemptSeed + lastPlatformX * 7) % 1000 / 1000;
var gapDistance = 150 + pseudoRandom * 200 * difficultyMultiplier;
var platformWidth = 150 + pseudoRandom * 150;
var heightVariation = -150 + pseudoRandom * 300;
// Ensure gap is not too large
if (gapDistance > maxJumpDistance) {
gapDistance = maxJumpDistance - 20;
}
var newX = lastPlatform.x + gapDistance;
var newY = lastPlatform.y + heightVariation;
// Verify vertical reachability
var heightDifference = newY - lastPlatform.y;
if (heightDifference > maxFallHeight) {
newY = lastPlatform.y + maxFallHeight;
} else if (heightDifference < -maxJumpHeight) {
newY = lastPlatform.y - maxJumpHeight;
}
// Keep platforms within screen bounds
if (newY > 2200) newY = 2200;
if (newY < 1000) newY = 1000;
// Verify horizontal reachability with physics simulation
if (!isPlatformReachable(lastPlatform, {
x: newX,
y: newY,
width: platformWidth
})) {
// Adjust platform to make it reachable
gapDistance = maxJumpDistance - 50;
newX = lastPlatform.x + gapDistance;
// Also adjust height to be more forgiving
if (heightDifference > 0) {
newY = lastPlatform.y + Math.min(heightDifference, 200);
} else {
newY = lastPlatform.y + Math.max(heightDifference, -250);
}
}
return {
x: newX,
y: newY,
width: platformWidth
};
}
function isPlatformReachable(fromPlatform, toPlatform) {
// Simulate a jump from the edge of fromPlatform to toPlatform
var startX = fromPlatform.x + fromPlatform.width / 2;
var startY = fromPlatform.y;
var targetX = toPlatform.x;
var targetY = toPlatform.y;
var targetLeft = targetX - toPlatform.width / 2;
var targetRight = targetX + toPlatform.width / 2;
// Simulate jump physics
var jumpPower = -25;
var gravity = 1.2;
var speed = 8;
var maxSimulationTime = 100; // Prevent infinite loops
var simX = startX;
var simY = startY;
var velocityY = jumpPower;
var velocityX = speed;
for (var t = 0; t < maxSimulationTime; t++) {
simX += velocityX;
simY += velocityY;
velocityY += gravity;
// Check if we've reached the target platform level
if (simY >= targetY && simX >= targetLeft && simX <= targetRight) {
return true;
}
// If we've fallen too far below the target, we can't reach it
if (simY > targetY + 100) {
break;
}
}
return false;
}
function checkCollisions() {
player.isGrounded = false;
// Check platform collisions
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
var playerBounds = {
left: player.x - 30,
right: player.x + 30,
top: player.y - 60,
bottom: player.y
};
var platformBounds = {
left: platform.x - platform.width / 2,
right: platform.x + platform.width / 2,
top: platform.y - 20,
bottom: platform.y + 20
};
// Check if player overlaps with platform
if (playerBounds.right > platformBounds.left && playerBounds.left < platformBounds.right && playerBounds.bottom > platformBounds.top && playerBounds.top < platformBounds.bottom) {
// Landing on top of platform
if (player.velocityY >= 0 && playerBounds.bottom - platformBounds.top < 20) {
player.y = platformBounds.top;
player.velocityY = 0;
player.isGrounded = true;
}
}
}
// Check obstacle collisions
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (player.intersects(obstacle)) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
// Final1 asset is unreachable - no collision detection needed
}
function updateCamera() {
// Camera follows player with some offset
var targetCameraX = player.x - 400;
cameraOffset += (targetCameraX - cameraOffset) * 0.1;
// Move all game objects relative to camera
game.x = -cameraOffset;
// Update distance score
distanceScore = Math.floor(cameraOffset / 10);
scoreText.setText('Distance: ' + distanceScore);
LK.setScore(distanceScore);
// Create Final1 asset that stays ahead of player and is unreachable
if (!goalAsset) {
goalAsset = LK.getAsset('Final1', {
width: 100,
height: 100,
anchorX: 0.5,
anchorY: 1.0
});
game.addChild(goalAsset);
}
// Keep Final1 asset ahead of player - unreachable distance
goalAsset.x = cameraOffset + 1500; // Always 1500 units ahead of camera
goalAsset.y = 800; // High in the sky, unreachable
// Check if Final1 has reached distance 1000 from start
var finalAssetDistance = goalAsset.x - 300; // Subtract initial player position
if (finalAssetDistance >= 1000 && !goalReached) {
goalReached = true;
LK.effects.flashScreen(0xFFD700, 2000); // Flash gold when Final1 reaches distance 1000
// You can add more actions here when Final1 reaches distance 1000
}
}
function updateAICamera() {
// AI camera follows AI player
var aiTargetCameraX = aiPlayer.x - 400;
aiCameraOffset += (aiTargetCameraX - aiCameraOffset) * 0.1;
// Update AI distance score
aiDistanceScore = Math.floor(aiCameraOffset / 10);
// Create Final1 asset at right center of screen as AI goal
if (!aiGoalAsset) {
aiGoalAsset = LK.getAsset('Final1', {
width: 100,
height: 100,
anchorX: 0.5,
anchorY: 0.5
});
// Position at right center of screen (fixed position)
aiGoalAsset.x = 1700; // Right side of screen
aiGoalAsset.y = 1366; // Center vertically (2732/2)
game.addChild(aiGoalAsset);
}
}
// Create control buttons
var leftButton = LK.getAsset('Izquierda1', {
width: 150,
height: 100,
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
leftButton.alpha = 0.7;
var rightButton = LK.getAsset('Derecha2', {
width: 150,
height: 100,
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
rightButton.alpha = 0.7;
var jumpButton = LK.getAsset('Salto1', {
width: 120,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 2.2
});
jumpButton.tint = 0x32cd32;
jumpButton.alpha = 0.8;
// Position buttons in GUI - left and right buttons together in bottom left
LK.gui.bottomLeft.addChild(leftButton);
leftButton.x = 80;
leftButton.y = -100;
LK.gui.bottomLeft.addChild(rightButton);
rightButton.x = 300;
rightButton.y = -100;
LK.gui.bottomRight.addChild(jumpButton);
jumpButton.x = -130;
jumpButton.y = -100;
// Button event handlers
leftButton.down = function () {
leftButton.alpha = 1.0;
leftButtonPressed = true;
};
leftButton.up = function () {
leftButton.alpha = 0.7;
leftButtonPressed = false;
};
rightButton.down = function () {
rightButton.alpha = 1.0;
rightButtonPressed = true;
};
rightButton.up = function () {
rightButton.alpha = 0.7;
rightButtonPressed = false;
};
jumpButton.down = function () {
jumpButton.alpha = 1.0;
jumpButton.scaleX = 1.3;
jumpButton.scaleY = 1.3;
jumpButtonPressed = true;
player.jump();
};
jumpButton.up = function () {
jumpButton.alpha = 0.8;
jumpButton.scaleX = 1.5;
jumpButton.scaleY = 1.5;
jumpButtonPressed = false;
};
// Track when game starts/resets
var originalShowGameOver = LK.showGameOver;
LK.showGameOver = function () {
gameAttempts++;
levelSeed = gameAttempts * 54321; // Change seed each attempt
originalShowGameOver();
};
game.update = function () {
// Handle continuous movement based on button states
if (leftButtonPressed) {
player.moveLeft();
}
if (rightButtonPressed) {
player.moveRight();
}
// Handle continuous jump (allows jump when held down and landing)
if (jumpButtonPressed) {
player.jump();
}
// Update AI if it exists
if (aiPlayer) {
aiPlayer.update();
// Check AI collisions with platforms
aiPlayer.isGrounded = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
var aiBounds = {
left: aiPlayer.x - 50,
right: aiPlayer.x + 50,
top: aiPlayer.y - 100,
bottom: aiPlayer.y
};
var platformBounds = {
left: platform.x - platform.width / 2,
right: platform.x + platform.width / 2,
top: platform.y - 20,
bottom: platform.y + 20
};
// Check if AI overlaps with platform
if (aiBounds.right > platformBounds.left && aiBounds.left < platformBounds.right && aiBounds.bottom > platformBounds.top && aiBounds.top < platformBounds.bottom) {
// Landing on top of platform
if (aiPlayer.velocityY >= 0 && aiBounds.bottom - platformBounds.top < 30) {
aiPlayer.y = platformBounds.top;
aiPlayer.velocityY = 0;
aiPlayer.isGrounded = true;
break; // Exit loop once grounded
}
}
}
// Check AI obstacle collisions
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (aiPlayer.intersects(obstacle)) {
// AI hit obstacle - reset its position or handle differently
aiPlayer.x -= 50; // Move back a bit
aiPlayer.velocityX = 0;
break;
}
}
// Prevent AI from falling off screen
if (aiPlayer.y > 2800) {
aiPlayer.y = 2000;
aiPlayer.x = 200; // Reset to independent starting position
aiPlayer.velocityY = 0;
aiPlayer.velocityX = 0;
}
// AI goal stays fixed at right center of screen - no movement needed
}
checkCollisions();
updateCamera();
updateAICamera();
generateLevel();
}; ===================================================================
--- original.js
+++ change.js
@@ -40,14 +40,70 @@
self.stuckCounter = 0;
}
self.lastX = self.x;
self.lastY = self.y;
- // If stuck, try to jump
- if (self.stuckCounter > 30 && self.jumpCooldown <= 0) {
- self.jump();
- self.jumpCooldown = 20;
- self.stuckCounter = 0;
+ // Decision state system - AI can choose between different actions
+ var decisionState = self.evaluateSituation();
+ switch (decisionState) {
+ case 'JUMP':
+ if (self.isGrounded && self.jumpCooldown <= 0) {
+ self.jump();
+ self.jumpCooldown = 20;
+ }
+ break;
+ case 'MOVE_LEFT':
+ self.moveLeft();
+ break;
+ case 'MOVE_RIGHT':
+ self.moveRight();
+ break;
+ case 'STAY_STILL':
+ // AI decides to stay still - do nothing
+ self.velocityX *= 0.5; // Slow down gradually
+ break;
+ default:
+ // Default fallback behavior
+ self.executeDefaultBehavior();
+ break;
}
+ };
+ // Evaluate current situation and decide what action to take
+ self.evaluateSituation = function () {
+ if (!aiGoalAsset) return 'MOVE_RIGHT'; // Default if no goal
+ var goalDistance = aiGoalAsset.x - self.x;
+ var goalVerticalDistance = aiGoalAsset.y - self.y;
+ var obstacleAhead = self.checkForObstaclesAhead();
+ // Priority 1: If stuck for too long, jump
+ if (self.stuckCounter > 30 && self.isGrounded && self.jumpCooldown <= 0) {
+ return 'JUMP';
+ }
+ // Priority 2: Jump over obstacles when moving
+ if (obstacleAhead && self.isGrounded && self.jumpCooldown <= 0 && Math.abs(self.velocityX) > 1) {
+ return 'JUMP';
+ }
+ // Priority 3: Jump if goal is significantly above and we're close horizontally
+ if (Math.abs(goalDistance) < 200 && goalVerticalDistance < -100 && self.isGrounded && self.jumpCooldown <= 0) {
+ return 'JUMP';
+ }
+ // Priority 4: Stay still if very close to goal (within 100 units)
+ if (Math.abs(goalDistance) < 100 && Math.abs(goalVerticalDistance) < 50) {
+ return 'STAY_STILL';
+ }
+ // Priority 5: Stay still if on unstable ground or dangerous situation
+ if (!self.isGrounded && self.velocityY > 10) {
+ return 'STAY_STILL'; // Don't make sudden moves while falling fast
+ }
+ // Priority 6: Move towards goal
+ if (goalDistance > 50) {
+ return 'MOVE_RIGHT';
+ } else if (goalDistance < -50) {
+ return 'MOVE_LEFT';
+ }
+ // Priority 7: Stay still if goal is close horizontally
+ return 'STAY_STILL';
+ };
+ // Execute default behavior when no specific decision is made
+ self.executeDefaultBehavior = function () {
// Find target platform to move towards goal
if (self.pathfindingCooldown <= 0) {
self.target = self.findBestPlatform();
self.pathfindingCooldown = 10;
@@ -59,13 +115,8 @@
// Move towards goal as fallback
if (aiGoalAsset) {
var goalDistance = aiGoalAsset.x - self.x;
var goalVerticalDistance = aiGoalAsset.y - self.y;
- // Jump if goal is above us and we're close horizontally
- if (Math.abs(goalDistance) < 200 && goalVerticalDistance < -100 && self.isGrounded && self.jumpCooldown <= 0) {
- self.jump();
- self.jumpCooldown = 25;
- }
// Check for obstacles ahead when moving towards goal
var obstacleAhead = self.checkForObstaclesAhead();
if (obstacleAhead && self.isGrounded && self.jumpCooldown <= 0) {
self.jump();
Puedes Aser una persona palito de color negra que este pixelada. In-Game asset
Plataforma flotante con pasto ensima y tierra debajo pixelada. In-Game asset. 2d. High contrast. No shadows
Cuadro gris con bordes negros que dentro tenga una flecha apuntando a la derecha pixelada. In-Game asset. No shadows
Personaje que sea un alpinista pixelado con una gran mochila que este en movimiento caminando In-Game asset. 2d. High contrast. No shadows
Bandera de meta en un gran poste Pixelado. In-Game asset. 2d. High contrast. No shadows
As un corazón pixelado. In-Game asset. High contrast. No shadows
Rectángulo gris con bordes negros que en el sentro tenga la palabra Star pixelada. In-Game asset. High contrast. No shadows
Cielo de fondo pixelado con un sol y nubes. No shadows
As un alpinista caminando que sea una persona real. In-Game asset. 2d. High contrast. No shadows