User prompt
Quisiera poder cambiarlo por una imagen el fodno azul
User prompt
Pon otra imagen del fondo azul
User prompt
Pero quiero que el bonus tambien sume en donde dice Arrows:
User prompt
Que las plataformas no salgan de la pantalla
User prompt
Haber, que la estrella bono sea otra imagen aparte de la estrella que aparece cuando pasamos el nivel
User prompt
Que sea otra imagen el bono estrella
User prompt
Que el bono estrella aparezca mas seguido
User prompt
Que el bono de la estrella sea aleatorio de aparecer y que sea dificil de darle
User prompt
Que la imagen de bono claro sea para la habilidad de que si le damos a la estrella, se complete el nivel
User prompt
Elimina ese bonoclaro verde
User prompt
QUe el bono de que se vyan todas las frutas, la imagen sea de bonoclaro
User prompt
El bono de flechas no me esta dando mas flechas
User prompt
Que el sonido del nivel completo sea para la estrella que aparece cuando pasas el nivel y el sonido de bonificacion de estrella sea para bonoclaro
User prompt
Hablo del bono de estrella de que si ledamos, pasemos el nivel
User prompt
Que el sonido del bonus de la extrella y mas flechas sean otros
User prompt
Pon sonido cuando pasemos un nivel
User prompt
Agrega musica para el fondo
User prompt
Elimina los arbustos
User prompt
POn arbustos mas abajo, varios
User prompt
Pero no dezaparezcas el fondo
User prompt
Mas arbustos, que desaparezca el fondo
User prompt
Quita los arboles y agrega mas arbustos en varias zoans pero en la misma posicion de abajo
User prompt
Posiciona mejor los arbustos y arboles
User prompt
hazlos mas grandes y que las nube se mantengan arriba
User prompt
Y abajo de todo arbustos, arboles, etc
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Archer = Container.expand(function () {
var self = Container.call(this);
var archerGraphics = self.attachAsset('archer', {
anchorX: 0.5,
anchorY: 1.0
});
var bowGraphics = self.attachAsset('bow', {
anchorX: 0.2,
anchorY: 0.5
});
bowGraphics.x = 40;
bowGraphics.y = -120;
self.bow = bowGraphics;
self.aimAngle = 0;
self.aimAt = function (targetX, targetY) {
var dx = targetX - (self.x + self.bow.x);
var dy = targetY - (self.y + self.bow.y);
self.aimAngle = Math.atan2(dy, dx);
self.bow.rotation = self.aimAngle;
};
self.shoot = function () {
if (arrows.length >= maxArrows) return;
var arrow = new Arrow();
var bowWorldX = self.x + self.bow.x + Math.cos(self.aimAngle) * 40;
var bowWorldY = self.y + self.bow.y + Math.sin(self.aimAngle) * 40;
arrow.x = bowWorldX;
arrow.y = bowWorldY;
arrow.rotation = self.aimAngle;
var power = currentPower; // Use dynamic power based on mouse distance
arrow.velocityX = Math.cos(self.aimAngle) * power;
arrow.velocityY = Math.sin(self.aimAngle) * power;
arrows.push(arrow);
game.addChild(arrow);
LK.getSound('shoot').play();
};
return self;
});
var Arrow = Container.expand(function () {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.3;
self.active = true;
self.update = function () {
if (!self.active) return;
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
// Update arrow rotation to follow movement direction
if (self.velocityX !== 0 || self.velocityY !== 0) {
self.rotation = Math.atan2(self.velocityY, self.velocityX);
}
// Check platform collisions with smaller collision area
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Calculate distance between arrow and platform center
var dx = self.x - platform.x;
var dy = self.y - platform.y;
// Reduce vertical collision sensitivity by using separate X and Y checks
var horizontalDistance = Math.abs(dx);
var verticalDistance = Math.abs(dy);
// Use smaller vertical collision radius (60 pixels) and normal horizontal (100 pixels)
if (horizontalDistance < 100 && verticalDistance < 60) {
self.active = false;
self.velocityX = 0;
self.velocityY = 0;
break;
}
}
// Remove arrow if it goes off screen
// Remove arrow if it goes off screen
if (self.x > 2100 || self.y > 2800 || self.x < -50 || self.y < -50) {
// Give bonus points if arrow didn't hit any platform
if (self.active) {
LK.setScore(LK.getScore() + 5);
scoreTxt.setText(LK.getScore());
}
self.destroy();
for (var i = arrows.length - 1; i >= 0; i--) {
if (arrows[i] === self) {
arrows.splice(i, 1);
break;
}
}
}
};
return self;
});
var ArrowBonus = Container.expand(function () {
var self = Container.call(this);
var bonusGraphics = self.attachAsset('arrowBonus', {
anchorX: 0.5,
anchorY: 0.5
});
self.hit = false;
self.getHit = function () {
if (self.hit) return;
self.hit = true;
// Add random amount of arrows (2-4) directly to available arrows
var bonusArrows = Math.floor(Math.random() * 3) + 2;
maxArrows = Math.min(5, maxArrows + bonusArrows);
// Flash effect
LK.effects.flashObject(self, 0x00ff00, 300);
// Remove from arrowBonuses array
for (var i = arrowBonuses.length - 1; i >= 0; i--) {
if (arrowBonuses[i] === self) {
arrowBonuses.splice(i, 1);
break;
}
}
// Animate bonus disappearing
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
LK.getSound('arrowBonus').play();
// Update arrows display
var remainingArrows = Math.max(0, Math.min(5, maxArrows || 5) - arrows.length);
arrowsTxt.setText('Arrows: ' + remainingArrows);
};
return self;
});
var Bomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('bomb', {
anchorX: 0.5,
anchorY: 0.5
});
self.hit = false;
self.getHit = function () {
if (self.hit) return;
self.hit = true;
// Flash effect
LK.effects.flashObject(self, 0xff0000, 300);
// Remove from bombs array
for (var i = bombs.length - 1; i >= 0; i--) {
if (bombs[i] === self) {
bombs.splice(i, 1);
break;
}
}
// Flash screen red and show game over
LK.effects.flashScreen(0xff0000, 1000);
LK.getSound('explosion').play();
// Animate bomb explosion
tween(self, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
// Show game over after explosion animation
LK.setTimeout(function () {
LK.showGameOver();
}, 200);
}
});
};
return self;
});
var Fruit = Container.expand(function (type) {
var self = Container.call(this);
var fruitType = type || 'apple';
var fruitGraphics = self.attachAsset(fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
self.fruitType = fruitType;
self.points = fruitType === 'apple' ? 10 : fruitType === 'orange' ? 15 : 20;
self.hit = false;
// Start idle floating animation
self.startIdleAnimation = function () {
var animationDuration = 1500 + Math.random() * 1000; // 1.5-2.5 seconds
var moveRange = 8 + Math.random() * 12; // 8-20 pixels movement
if (self.initialY === undefined) {
self.initialY = self.y; // Store the original position only once
}
// Find the platform this fruit is on
var platformY = self.initialY + 60; // Platform is 60 pixels below fruit
// Limit upward movement to not go above initial position too much
var upwardY = self.initialY - moveRange;
// Limit downward movement to not go below platform level
var downwardY = Math.min(self.initialY + moveRange, platformY - 50);
tween(self, {
y: upwardY
}, {
duration: animationDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.hit) {
tween(self, {
y: downwardY
}, {
duration: animationDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!self.hit) {
self.startIdleAnimation();
}
}
});
}
}
});
};
self.getHit = function () {
if (self.hit) return;
self.hit = true;
LK.setScore(LK.getScore() + self.points);
scoreTxt.setText(LK.getScore());
// Flash effect
LK.effects.flashObject(self, 0xFFFFFF, 300);
// Remove from fruits array
for (var i = fruits.length - 1; i >= 0; i--) {
if (fruits[i] === self) {
fruits.splice(i, 1);
break;
}
}
// Only remove arrows when level is completed (no fruits remain)
// The arrows will be cleared when spawnFruits() is called for next level
// Create explosion/disintegration effect
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
rotation: Math.PI * 2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Second phase: shrink and fade out
tween(self, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
}
});
LK.getSound('hit').play();
// Check win condition
if (fruits.length === 0) {
// Show level complete animation immediately
showLevelCompleteAnimation();
}
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('starBonus', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0,
tint: 0xFFD700 // Golden color
});
self.hit = false;
self.getHit = function () {
if (self.hit) return;
self.hit = true;
// Clear all fruits to complete level immediately
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
LK.setScore(LK.getScore() + fruit.points);
fruit.destroy();
fruits.splice(i, 1);
}
scoreTxt.setText(LK.getScore());
// Flash effect
LK.effects.flashObject(self, 0xFFD700, 300);
// Remove from stars array
for (var i = stars.length - 1; i >= 0; i--) {
if (stars[i] === self) {
stars.splice(i, 1);
break;
}
}
// Animate star disappearing
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
LK.getSound('starBonus').play();
// Show level complete animation immediately
showLevelCompleteAnimation();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Sky blue background
});
/****
* Game Code
****/
var archer = new Archer();
var arrows = [];
var fruits = [];
var platforms = [];
var bombs = [];
var arrowBonuses = [];
var stars = [];
var clouds = [];
var groundVegetation = [];
var maxArrows = 5;
var targetScore = 200;
// Create ground vegetation (no bushes)
function createGroundVegetation() {
// No ground vegetation to create
}
// Create background clouds
function createClouds() {
for (var i = 0; i < 8; i++) {
var cloud = LK.getAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7,
scaleX: 0.8 + Math.random() * 0.6,
scaleY: 0.6 + Math.random() * 0.4
});
cloud.x = Math.random() * 2200; // Spread across screen width plus some overflow
cloud.y = 150 + Math.random() * 300; // Keep clouds higher up
cloud.speed = 0.3 + Math.random() * 0.7; // Random slow speed
clouds.push(cloud);
game.addChildAt(cloud, 0); // Add to back layer
// Start floating animation
animateCloud(cloud);
}
}
function animateCloud(cloud) {
var floatRange = 30 + Math.random() * 40;
var originalY = cloud.y;
tween(cloud, {
y: originalY - floatRange
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(cloud, {
y: originalY + floatRange
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
animateCloud(cloud);
}
});
}
});
}
// Position archer in the middle-left area
archer.x = 300;
archer.y = 1366; // Middle of screen vertically (2732/2)
game.addChild(archer);
// Create score display
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create target score display
var targetTxt = new Text2('Target: ' + targetScore, {
size: 60,
fill: 0xFFFF00
});
targetTxt.anchor.set(1, 0);
targetTxt.y = 120;
LK.gui.topRight.addChild(targetTxt);
// Create arrows remaining display
var arrowsTxt = new Text2('Arrows: ' + maxArrows, {
size: 60,
fill: 0xFFFFFF
});
arrowsTxt.anchor.set(0, 0);
arrowsTxt.y = 120;
LK.gui.topLeft.addChild(arrowsTxt);
function showLevelCompleteAnimation() {
// Play level complete sound for level completion
LK.getSound('levelComplete').play();
// Create a large golden star in the center of the screen
var star = LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0,
scaleY: 0,
alpha: 0,
tint: 0xFFD700 // Golden color
});
star.x = 1024; // Center of screen horizontally (2048/2)
star.y = 1366; // Center of screen vertically (2732/2)
game.addChild(star);
// Simple growing animation
tween(star, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 1
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Fade out after growing
tween(star, {
alpha: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
star.destroy();
// After star animation completes, proceed to next level
LK.setTimeout(function () {
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
var nextTargetScore = currentLevel * 200;
if (LK.getScore() >= targetScore) {
targetScore = nextTargetScore + 200;
targetTxt.setText('Target: ' + targetScore);
spawnFruits();
} else {
spawnFruits();
}
}, 100);
}
});
}
});
}
function spawnFruits() {
// Clear existing fruits
for (var i = 0; i < fruits.length; i++) {
fruits[i].destroy();
}
fruits = [];
// Clear existing bombs
for (var i = 0; i < bombs.length; i++) {
bombs[i].destroy();
}
bombs = [];
// Clear existing arrow bonuses
for (var i = 0; i < arrowBonuses.length; i++) {
arrowBonuses[i].destroy();
}
arrowBonuses = [];
// Clear existing stars
for (var i = 0; i < stars.length; i++) {
stars[i].destroy();
}
stars = [];
// Clear all arrows (including those stuck on platforms)
for (var i = 0; i < arrows.length; i++) {
arrows[i].destroy();
}
arrows = [];
// Ensure enough arrows for the number of fruits (minimum 3, but at least equal to fruits)
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
var baseArrows = Math.max(3, 6 - Math.floor(currentLevel / 2));
var calculatedArrows = Math.max(baseArrows, numFruits + 1);
maxArrows = Math.min(5, calculatedArrows); // Always have at least 1 more arrow than fruits, but max 5
// Clear existing platforms
for (var i = 0; i < platforms.length; i++) {
platforms[i].destroy();
}
platforms = [];
var fruitTypes = ['apple', 'orange', 'banana'];
// Calculate level based on score progression
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
// Increase number of fruits with each level (start with 2, add 1 every 2 levels, max 6)
var numFruits = Math.min(6, 2 + Math.floor(currentLevel / 2));
for (var i = 0; i < numFruits; i++) {
// Create platform with collision detection
var platform = new Platform();
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
// Make platforms more spread out and harder to reach in higher levels
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
var spreadFactor = Math.min(2, 1 + currentLevel * 0.2);
// Ensure platforms stay within screen boundaries (150px margin from edges)
var maxX = 2048 - 150; // Right boundary
var maxY = 2732 - 150; // Bottom boundary
var minX = 150; // Left boundary
var minY = 150; // Top boundary
platform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * (800 * spreadFactor)));
platform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * (1400 * spreadFactor)));
validPosition = true;
// Check distance from character to ensure platforms spawn far away
var distanceFromCharacter = Math.sqrt((platform.x - archer.x) * (platform.x - archer.x) + (platform.y - archer.y) * (platform.y - archer.y));
if (distanceFromCharacter < 500) {
validPosition = false;
}
// Check collision with existing platforms
for (var j = 0; j < platforms.length; j++) {
var existingPlatform = platforms[j];
var dx = platform.x - existingPlatform.x;
var dy = platform.y - existingPlatform.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 400) {
// Minimum distance between platforms
validPosition = false;
break;
}
}
attempts++;
}
platforms.push(platform);
game.addChild(platform);
// Create fruit on platform
var fruitType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)];
var fruit = new Fruit(fruitType);
fruit.x = platform.x;
fruit.y = platform.y - 80; // Position above platform
fruits.push(fruit);
game.addChild(fruit);
// Start idle animation immediately for all fruits
fruit.startIdleAnimation();
}
// Create separate platforms for bombs
// Calculate level based on score progression (every 200 points is roughly a level)
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
// Increase bomb count with each level, starting with 1 every 2 levels, maximum 3
var numBombs = Math.min(3, Math.floor(currentLevel / 2));
for (var i = 0; i < numBombs; i++) {
// Create bomb platform with collision detection
var bombPlatform = new Platform();
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
// Make bomb platforms more spread out and harder to avoid in higher levels
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
var spreadFactor = Math.min(2, 1 + currentLevel * 0.2);
// Ensure bomb platforms stay within screen boundaries (150px margin from edges)
var maxX = 2048 - 150; // Right boundary
var maxY = 2732 - 150; // Bottom boundary
var minX = 150; // Left boundary
var minY = 150; // Top boundary
bombPlatform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * (800 * spreadFactor)));
bombPlatform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * (1400 * spreadFactor)));
validPosition = true;
// Check distance from character to ensure bomb platforms spawn far away
var distanceFromCharacter = Math.sqrt((bombPlatform.x - archer.x) * (bombPlatform.x - archer.x) + (bombPlatform.y - archer.y) * (bombPlatform.y - archer.y));
if (distanceFromCharacter < 500) {
validPosition = false;
}
// Check collision with existing platforms (both fruit and bomb platforms)
for (var j = 0; j < platforms.length; j++) {
var existingPlatform = platforms[j];
var dx = bombPlatform.x - existingPlatform.x;
var dy = bombPlatform.y - existingPlatform.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 400) {
// Minimum distance between platforms
validPosition = false;
break;
}
}
attempts++;
}
platforms.push(bombPlatform);
game.addChild(bombPlatform);
// Create bomb on its own platform
var bomb = new Bomb();
bomb.x = bombPlatform.x;
bomb.y = bombPlatform.y - 75; // Position above platform
bombs.push(bomb);
game.addChild(bomb);
}
// Create arrow bonuses (only sometimes, based on level)
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
// 60% chance to spawn arrow bonus, but only every 2-3 levels
var shouldSpawnBonus = Math.random() < 0.6 && currentLevel > 1 && (currentLevel % 2 === 0 || currentLevel % 3 === 0);
if (shouldSpawnBonus) {
// Create arrow bonus platform with collision detection
var bonusPlatform = new Platform();
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
// Ensure bonus platforms stay within screen boundaries (150px margin from edges)
var maxX = 2048 - 150; // Right boundary
var maxY = 2732 - 150; // Bottom boundary
var minX = 150; // Left boundary
var minY = 150; // Top boundary
bonusPlatform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * 800));
bonusPlatform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * 1400));
validPosition = true;
// Check distance from character to ensure bonus platforms spawn far away
var distanceFromCharacter = Math.sqrt((bonusPlatform.x - archer.x) * (bonusPlatform.x - archer.x) + (bonusPlatform.y - archer.y) * (bonusPlatform.y - archer.y));
if (distanceFromCharacter < 500) {
validPosition = false;
}
// Check collision with existing platforms
for (var j = 0; j < platforms.length; j++) {
var existingPlatform = platforms[j];
var dx = bonusPlatform.x - existingPlatform.x;
var dy = bonusPlatform.y - existingPlatform.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 400) {
validPosition = false;
break;
}
}
attempts++;
}
platforms.push(bonusPlatform);
game.addChild(bonusPlatform);
// Create arrow bonus on platform
var arrowBonus = new ArrowBonus();
arrowBonus.x = bonusPlatform.x;
arrowBonus.y = bonusPlatform.y - 75; // Position above platform
arrowBonuses.push(arrowBonus);
game.addChild(arrowBonus);
}
// Create star bonuses (more frequent random appearance)
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
// 30% chance to spawn, completely random regardless of level
var shouldSpawnStar = Math.random() < 0.30 && currentLevel > 1;
if (shouldSpawnStar) {
// Create star platform in a very difficult to reach position
var starPlatform = new Platform();
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
// Place in very hard to reach areas - corners and edges of map
var cornerChoice = Math.floor(Math.random() * 4);
// Define screen boundaries (150px margin from edges)
var maxX = 2048 - 150; // Right boundary
var maxY = 2732 - 150; // Bottom boundary
var minX = 150; // Left boundary
var minY = 150; // Top boundary
if (cornerChoice === 0) {
// Top right corner
starPlatform.x = Math.max(minX, Math.min(maxX, 1400 + Math.random() * 500));
starPlatform.y = Math.max(minY, Math.min(maxY, 600 + Math.random() * 400));
} else if (cornerChoice === 1) {
// Bottom right corner
starPlatform.x = Math.max(minX, Math.min(maxX, 1300 + Math.random() * 600));
starPlatform.y = Math.max(minY, Math.min(maxY, 1800 + Math.random() * 600));
} else if (cornerChoice === 2) {
// Top center (high up)
starPlatform.x = Math.max(minX, Math.min(maxX, 800 + Math.random() * 800));
starPlatform.y = Math.max(minY, Math.min(maxY, 500 + Math.random() * 300));
} else {
// Far right edge
starPlatform.x = Math.max(minX, Math.min(maxX, 1600 + Math.random() * 300));
starPlatform.y = Math.max(minY, Math.min(maxY, 1000 + Math.random() * 800));
}
validPosition = true;
// Ensure star platforms spawn very far from character (harder to reach)
var distanceFromCharacter = Math.sqrt((starPlatform.x - archer.x) * (starPlatform.x - archer.x) + (starPlatform.y - archer.y) * (starPlatform.y - archer.y));
if (distanceFromCharacter < 700) {
validPosition = false;
}
// Check collision with existing platforms
for (var j = 0; j < platforms.length; j++) {
var existingPlatform = platforms[j];
var dx = starPlatform.x - existingPlatform.x;
var dy = starPlatform.y - existingPlatform.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 350) {
validPosition = false;
break;
}
}
attempts++;
}
platforms.push(starPlatform);
game.addChild(starPlatform);
// Create star on platform - make it smaller and harder to hit
var star = new Star();
star.x = starPlatform.x;
star.y = starPlatform.y - 75; // Position above platform
// Make star smaller and harder to hit
star.scaleX = 0.8;
star.scaleY = 0.8;
stars.push(star);
game.addChild(star);
}
}
// Initialize clouds background
createClouds();
// Initialize ground vegetation
createGroundVegetation();
// Play background music
LK.playMusic('Fondo');
// Initialize first level
spawnFruits();
// Mouse controls
var mouseX = 0;
var mouseY = 0;
var currentPower = 12; // Default power
game.move = function (x, y, obj) {
mouseX = x;
mouseY = y;
archer.aimAt(x, y);
// Calculate power based on distance from archer
var dx = x - archer.x;
var dy = y - archer.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Scale power based on distance (minimum 12, maximum 28)
currentPower = Math.min(28, Math.max(12, distance / 25));
};
game.down = function (x, y, obj) {
mouseX = x;
mouseY = y;
archer.aimAt(x, y);
// Calculate power based on distance from archer
var dx = x - archer.x;
var dy = y - archer.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Scale power based on distance from archer (minimum 12, maximum 28)
currentPower = Math.min(28, Math.max(12, distance / 25));
archer.shoot();
// Update arrows remaining display
arrowsTxt.setText('Arrows: ' + (maxArrows - arrows.length));
};
game.update = function () {
// Check arrow-fruit collisions
for (var i = arrows.length - 1; i >= 0; i--) {
var arrow = arrows[i];
if (!arrow.active) continue;
// Check bomb collisions first
for (var j = 0; j < bombs.length; j++) {
var bomb = bombs[j];
if (!bomb.hit && arrow.intersects(bomb)) {
arrow.active = false;
bomb.getHit();
arrow.destroy();
arrows.splice(i, 1);
return; // Exit immediately as game will be over
}
}
// Check arrow bonus collisions
for (var j = 0; j < arrowBonuses.length; j++) {
var arrowBonus = arrowBonuses[j];
if (!arrowBonus.hit && arrow.intersects(arrowBonus)) {
arrow.active = false;
arrowBonus.getHit();
arrow.destroy();
arrows.splice(i, 1);
break;
}
}
// Check star collisions with smaller hit area (harder to hit)
for (var j = 0; j < stars.length; j++) {
var star = stars[j];
if (!star.hit) {
// Use distance-based collision with smaller radius for stars (harder to hit)
var dx = arrow.x - star.x;
var dy = arrow.y - star.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Much smaller collision radius for stars (40 pixels instead of default)
if (distance < 40) {
arrow.active = false;
star.getHit();
arrow.destroy();
arrows.splice(i, 1);
break;
}
}
}
for (var j = 0; j < fruits.length; j++) {
var fruit = fruits[j];
if (!fruit.hit) {
// Calculate distance between arrow and fruit center for larger collision
var dx = arrow.x - fruit.x;
var dy = arrow.y - fruit.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Use slightly larger collision radius (80 pixels instead of default intersects)
if (distance < 80) {
arrow.active = false;
fruit.getHit();
arrow.destroy();
arrows.splice(i, 1);
break;
}
}
}
}
// Give bonus arrows if player is struggling (every 10 seconds when out of arrows)
if (arrows.length >= maxArrows && fruits.length > 0) {
if (!game.lastBonusTime) game.lastBonusTime = 0;
if (LK.ticks - game.lastBonusTime > 600) {
// 10 seconds at 60fps
maxArrows = Math.min(5, maxArrows + 2); // Give 2 bonus arrows but respect maximum
game.lastBonusTime = LK.ticks;
arrowsTxt.setText('Arrows: ' + Math.max(0, maxArrows - arrows.length));
}
}
// Check if out of arrows and no fruits hit recently
if (arrows.length >= maxArrows && fruits.length > 0) {
var allArrowsStopped = true;
for (var i = 0; i < arrows.length; i++) {
if (arrows[i].active && (Math.abs(arrows[i].velocityX) > 0.5 || Math.abs(arrows[i].velocityY) > 0.5)) {
allArrowsStopped = false;
break;
}
}
if (allArrowsStopped) {
// Clear all arrows
for (var i = 0; i < arrows.length; i++) {
arrows[i].destroy();
}
arrows = [];
arrowsTxt.setText('Arrows: ' + maxArrows);
// Check if we have enough score to win
if (LK.getScore() >= targetScore) {
LK.showYouWin();
} else if (fruits.length > 0) {
// Game over if no arrows left and fruits still remain
LK.showGameOver();
}
}
}
// Update clouds movement
for (var i = 0; i < clouds.length; i++) {
var cloud = clouds[i];
cloud.x += cloud.speed;
// Reset cloud position when it goes off screen
if (cloud.x > 2200) {
cloud.x = -200;
cloud.y = 150 + Math.random() * 300;
}
}
// Update arrows remaining display
var remainingArrows = Math.max(0, Math.min(5, maxArrows || 5) - arrows.length);
arrowsTxt.setText('Arrows: ' + remainingArrows);
// Check for game over only when all arrows have been shot AND all arrows have settled
if (remainingArrows <= 0 && fruits.length > 0) {
// Only trigger game over if all arrows have stopped moving (settled on platforms)
var allArrowsStopped = true;
for (var i = 0; i < arrows.length; i++) {
if (arrows[i].active && (Math.abs(arrows[i].velocityX) > 0.5 || Math.abs(arrows[i].velocityY) > 0.5)) {
allArrowsStopped = false;
break;
}
}
if (allArrowsStopped) {
// Game over if no arrows left, all arrows settled, and fruits still remain
LK.showGameOver();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -517,10 +517,15 @@
while (!validPosition && attempts < 50) {
// Make platforms more spread out and harder to reach in higher levels
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
var spreadFactor = Math.min(2, 1 + currentLevel * 0.2);
- platform.x = 600 + Math.random() * (800 * spreadFactor);
- platform.y = 800 + Math.random() * (1400 * spreadFactor);
+ // Ensure platforms stay within screen boundaries (150px margin from edges)
+ var maxX = 2048 - 150; // Right boundary
+ var maxY = 2732 - 150; // Bottom boundary
+ var minX = 150; // Left boundary
+ var minY = 150; // Top boundary
+ platform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * (800 * spreadFactor)));
+ platform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * (1400 * spreadFactor)));
validPosition = true;
// Check distance from character to ensure platforms spawn far away
var distanceFromCharacter = Math.sqrt((platform.x - archer.x) * (platform.x - archer.x) + (platform.y - archer.y) * (platform.y - archer.y));
if (distanceFromCharacter < 500) {
@@ -565,10 +570,15 @@
while (!validPosition && attempts < 50) {
// Make bomb platforms more spread out and harder to avoid in higher levels
var currentLevel = Math.floor(LK.getScore() / 200) + 1;
var spreadFactor = Math.min(2, 1 + currentLevel * 0.2);
- bombPlatform.x = 600 + Math.random() * (800 * spreadFactor);
- bombPlatform.y = 800 + Math.random() * (1400 * spreadFactor);
+ // Ensure bomb platforms stay within screen boundaries (150px margin from edges)
+ var maxX = 2048 - 150; // Right boundary
+ var maxY = 2732 - 150; // Bottom boundary
+ var minX = 150; // Left boundary
+ var minY = 150; // Top boundary
+ bombPlatform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * (800 * spreadFactor)));
+ bombPlatform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * (1400 * spreadFactor)));
validPosition = true;
// Check distance from character to ensure bomb platforms spawn far away
var distanceFromCharacter = Math.sqrt((bombPlatform.x - archer.x) * (bombPlatform.x - archer.x) + (bombPlatform.y - archer.y) * (bombPlatform.y - archer.y));
if (distanceFromCharacter < 500) {
@@ -606,10 +616,15 @@
var bonusPlatform = new Platform();
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
- bonusPlatform.x = 600 + Math.random() * 800;
- bonusPlatform.y = 800 + Math.random() * 1400;
+ // Ensure bonus platforms stay within screen boundaries (150px margin from edges)
+ var maxX = 2048 - 150; // Right boundary
+ var maxY = 2732 - 150; // Bottom boundary
+ var minX = 150; // Left boundary
+ var minY = 150; // Top boundary
+ bonusPlatform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * 800));
+ bonusPlatform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * 1400));
validPosition = true;
// Check distance from character to ensure bonus platforms spawn far away
var distanceFromCharacter = Math.sqrt((bonusPlatform.x - archer.x) * (bonusPlatform.x - archer.x) + (bonusPlatform.y - archer.y) * (bonusPlatform.y - archer.y));
if (distanceFromCharacter < 500) {
@@ -648,24 +663,29 @@
var attempts = 0;
while (!validPosition && attempts < 50) {
// Place in very hard to reach areas - corners and edges of map
var cornerChoice = Math.floor(Math.random() * 4);
+ // Define screen boundaries (150px margin from edges)
+ var maxX = 2048 - 150; // Right boundary
+ var maxY = 2732 - 150; // Bottom boundary
+ var minX = 150; // Left boundary
+ var minY = 150; // Top boundary
if (cornerChoice === 0) {
// Top right corner
- starPlatform.x = 1400 + Math.random() * 500;
- starPlatform.y = 600 + Math.random() * 400;
+ starPlatform.x = Math.max(minX, Math.min(maxX, 1400 + Math.random() * 500));
+ starPlatform.y = Math.max(minY, Math.min(maxY, 600 + Math.random() * 400));
} else if (cornerChoice === 1) {
// Bottom right corner
- starPlatform.x = 1300 + Math.random() * 600;
- starPlatform.y = 1800 + Math.random() * 600;
+ starPlatform.x = Math.max(minX, Math.min(maxX, 1300 + Math.random() * 600));
+ starPlatform.y = Math.max(minY, Math.min(maxY, 1800 + Math.random() * 600));
} else if (cornerChoice === 2) {
// Top center (high up)
- starPlatform.x = 800 + Math.random() * 800;
- starPlatform.y = 500 + Math.random() * 300;
+ starPlatform.x = Math.max(minX, Math.min(maxX, 800 + Math.random() * 800));
+ starPlatform.y = Math.max(minY, Math.min(maxY, 500 + Math.random() * 300));
} else {
// Far right edge
- starPlatform.x = 1600 + Math.random() * 300;
- starPlatform.y = 1000 + Math.random() * 800;
+ starPlatform.x = Math.max(minX, Math.min(maxX, 1600 + Math.random() * 300));
+ starPlatform.y = Math.max(minY, Math.min(maxY, 1000 + Math.random() * 800));
}
validPosition = true;
// Ensure star platforms spawn very far from character (harder to reach)
var distanceFromCharacter = Math.sqrt((starPlatform.x - archer.x) * (starPlatform.x - archer.x) + (starPlatform.y - archer.y) * (starPlatform.y - archer.y));
Estrella animada. In-Game asset. 2d. High contrast. No shadows
Estrella. In-Game asset. 2d. High contrast. No shadows
Nube. In-Game asset. 2d. High contrast. No shadows
Bush. In-Game asset. 2d. High contrast. No shadows
tree. In-Game asset. 2d. High contrast. No shadows
Quita los arboles y las nubes
Boton de start. In-Game asset. 2d. High contrast. No shadows
Fondo para un juego de fruit archer. In-Game asset. 2d. High contrast. No shadows
Fruit Archer titulo. In-Game asset. 2d. High contrast. No shadows