User prompt
Haz que el multiplicador de monedas valga 50 monedas y que solo dure 3 partidas ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Haz que en la tienda se pueda comprar un potenciador de monedas ×2 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Haz que puedas saltar al agua y perder de esa manera
User prompt
Arregla esto: el sonido splash no suena
User prompt
Arregla esto: la rana "Double jump" no hace doble salto
User prompt
Elimina la rana "high Jumper" de la tienda
User prompt
Ahora haz que las piedras dezaparescan mientras la rana está encima
User prompt
Arregla esto: las otras ranas no pueden saltar
User prompt
Haz que solo la rana con la habilidad "Big jump" pueda saltar lejos y que las otras ranas no puedan saltar lejos
User prompt
Haz que solo te lleve al siguiente nivel cuando solo haya una roca
User prompt
Soluciona este problema: cuando paso por algunas piedras derrepente me lleva al siguiente nivel sin hacer que todas las rocas desaparezcan
User prompt
Añade que cuando ya no hallan rocas pases al siguiente nivel y que cada vez que pases al siguiente nivel aparezcan más peces y los otros tipos de rocas
User prompt
Ahora en el menú añade un botón abajo del de empezar el juego que diga "store" para abrir una tienda en la que puedas comprar ranas con abilidades como doble salto más velocidad etc. Y que puedas comprar esas ranas con las monedas
User prompt
Ahora añade un menú que te salga al iniciar el juego en el que este el título del juego "froggy river rush" y abajo del título este el botón para empezar "play"
User prompt
Y ahora añade este objetivo: Llega lo más lejos posible sin caer al agua. Hay monedas para coleccionar que se pueden usar para desbloquear diferentes ranas con habilidades especiales (más salto, velocidad, doble salto, etc.). ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Froggy River Rush
Initial prompt
Necesito hacer un juego que se trate de esto: Eres una rana que debe cruzar un río saltando sobre piedras flotantes. Cada piedra se hunde unos segundos después de que la pisas, así que debes moverte rápido. Algunas piedras se mueven, otras son resbaladizas, y hay enemigos como peces que saltan y pueden derribarte.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinGraphics = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.collect = function () {
if (self.collected) return;
self.collected = true;
LK.getSound('coinCollect').play();
// Add coin to storage
var currentCoins = storage.coins || 0;
storage.coins = currentCoins + 1;
// Update coin display
coinsTxt.setText('Coins: ' + storage.coins);
self.destroy();
};
return self;
});
var Fish = Container.expand(function () {
var self = Container.call(this);
var fishGraphics = self.attachAsset('fish', {
anchorX: 0.5,
anchorY: 0.5
});
self.jumpSpeed = -8;
self.gravity = 0.4;
self.velocityY = self.jumpSpeed;
self.startY = 0;
self.jump = function () {
self.velocityY = self.jumpSpeed;
LK.getSound('fishJump').play();
};
self.update = function () {
self.velocityY += self.gravity;
self.y += self.velocityY;
if (self.y > self.startY + 100) {
self.destroy();
}
};
return self;
});
var Frog = Container.expand(function (frogType) {
var self = Container.call(this);
self.frogType = frogType || 'normal';
var frogGraphics = self.attachAsset('frog', {
anchorX: 0.5,
anchorY: 0.5
});
self.isJumping = false;
self.currentStone = null;
self.jumpSpeed = 8;
self.targetX = 0;
self.targetY = 0;
self.doubleJumpUsed = false;
// Apply frog abilities based on type
if (self.frogType === 'fast') {
self.jumpSpeed = 12;
frogGraphics.tint = 0xff6b6b;
} else if (self.frogType === 'jumper') {
self.jumpSpeed = 10;
frogGraphics.tint = 0x4ecdc4;
} else if (self.frogType === 'double') {
frogGraphics.tint = 0xffe66d;
}
self.jumpTo = function (stone) {
if (self.isJumping) return;
self.isJumping = true;
self.targetX = stone.x;
self.targetY = stone.y - 50;
if (self.currentStone) {
self.currentStone.startSinking();
}
self.currentStone = stone;
LK.getSound('jump').play();
var jumpDistance = Math.sqrt(Math.pow(self.targetX - self.x, 2) + Math.pow(self.targetY - self.y, 2));
var jumpDuration = jumpDistance / self.jumpSpeed * 16.67; // Convert to ms
tween(self, {
x: self.targetX,
y: self.targetY
}, {
duration: jumpDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isJumping = false;
if (self.frogType === 'double') {
self.doubleJumpUsed = false;
}
if (stone.stoneType === 'slippery') {
var slipAmount = (Math.random() - 0.5) * 40;
self.x += slipAmount;
}
}
});
};
self.doubleJump = function (stone) {
if (self.frogType !== 'double' || self.doubleJumpUsed) return;
self.doubleJumpUsed = true;
self.isJumping = false; // Reset jumping state to allow new jump
self.jumpTo(stone);
};
return self;
});
var Stone = Container.expand(function (stoneType) {
var self = Container.call(this);
self.stoneType = stoneType || 'regular';
self.sinkTimer = 0;
self.maxSinkTime = 180; // 3 seconds at 60fps
self.isOccupied = false;
self.originalY = 0;
self.moveSpeed = 0;
var assetName = 'stone';
if (self.stoneType === 'moving') {
assetName = 'movingStone';
self.moveSpeed = Math.random() * 2 - 1; // -1 to 1
} else if (self.stoneType === 'slippery') {
assetName = 'slipperyStone';
}
var stoneGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.startSinking = function () {
self.isOccupied = true;
self.sinkTimer = 0;
};
self.update = function () {
if (self.isOccupied) {
// Stone disappears immediately when frog is on it
self.destroy();
return;
}
if (self.stoneType === 'moving') {
self.x += self.moveSpeed;
if (self.x < 60 || self.x > 1988) {
self.moveSpeed *= -1;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0077BE
});
/****
* Game Code
****/
var gameStarted = false;
var titleTxt = null;
var playButton = null;
var storeButton = null;
var showingStore = false;
var storeItems = [];
var storeTexts = [];
var waterBackground = game.addChild(LK.getAsset('water', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var stones = [];
var fishes = [];
var coins = [];
var currentFrogType = storage.selectedFrog || 'normal';
var frogPrices = {
'normal': 0,
'fast': 50,
'jumper': 75,
'double': 100
};
var frogNames = {
'normal': 'Normal Frog',
'fast': 'Fast Frog',
'jumper': 'High Jumper',
'double': 'Double Jump'
};
var frog = game.addChild(new Frog(currentFrogType));
var level = 1;
var crossingCount = 0;
var fishSpawnTimer = 0;
var coinSpawnTimer = 0;
var maxDistance = 0;
var startY = 2650;
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 120;
scoreTxt.y = 50;
LK.gui.topLeft.addChild(scoreTxt);
// Level display
var levelTxt = new Text2('Level: 1', {
size: 50,
fill: 0xFFFFFF
});
levelTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(levelTxt);
// Coins display
var coinsTxt = new Text2('Coins: ' + (storage.coins || 0), {
size: 50,
fill: 0xffd700
});
coinsTxt.anchor.set(0, 0);
coinsTxt.x = 120;
coinsTxt.y = 120;
LK.gui.topLeft.addChild(coinsTxt);
// Distance display
var distanceTxt = new Text2('Distance: 0m', {
size: 50,
fill: 0xFFFFFF
});
distanceTxt.anchor.set(1, 0);
distanceTxt.x = -20;
distanceTxt.y = 60;
LK.gui.topRight.addChild(distanceTxt);
function createStoneRow(y, count) {
var stoneSpacing = 2048 / (count + 1);
for (var i = 0; i < count; i++) {
var stoneType = 'regular';
var rand = Math.random();
// Increase probability of special stones with level
var movingChance = Math.min(0.4, 0.1 + level * 0.05);
var slipperyChance = Math.min(0.3, 0.1 + level * 0.04);
if (level > 1 && rand < movingChance) {
stoneType = 'moving';
} else if (level > 2 && rand < movingChance + slipperyChance) {
stoneType = 'slippery';
}
var stone = new Stone(stoneType);
stone.x = stoneSpacing * (i + 1) + (Math.random() - 0.5) * 100;
stone.y = y;
stone.originalY = y;
stones.push(stone);
game.addChild(stone);
// Spawn coin randomly on some stones
if (Math.random() < 0.3) {
var coin = new Coin();
coin.x = stone.x;
coin.y = stone.y - 40;
coins.push(coin);
game.addChild(coin);
}
}
}
function initializeLevel() {
// Clear existing stones
for (var i = stones.length - 1; i >= 0; i--) {
stones[i].destroy();
}
stones = [];
// Create stone rows
var rows = 6 + level;
var rowSpacing = 2200 / rows;
for (var row = 0; row < rows; row++) {
var y = 2600 - row * rowSpacing;
var stoneCount = 3 + Math.floor(Math.random() * 3);
createStoneRow(y, stoneCount);
}
// Position frog at start
frog.x = 1024;
frog.y = 2650;
frog.currentStone = null;
frog.isJumping = false;
}
function spawnFish() {
if (Math.random() < 0.3) {
var fish = new Fish();
fish.x = Math.random() * 1800 + 124;
fish.y = Math.random() * 1800 + 400;
fish.startY = fish.y;
fish.jump();
fishes.push(fish);
game.addChild(fish);
}
}
function checkWinCondition() {
// Count remaining stones (not destroyed or sinking)
var remainingStones = 0;
for (var i = 0; i < stones.length; i++) {
if (!stones[i].destroyed && !stones[i].isOccupied) {
remainingStones++;
}
}
// Check if only one stone remains
if (remainingStones === 1) {
crossingCount++;
LK.setScore(LK.getScore() + 100 + level * 20);
level++;
levelTxt.setText('Level: ' + level);
// Clear existing coins
for (var i = coins.length - 1; i >= 0; i--) {
coins[i].destroy();
}
coins = [];
// Clear existing fish
for (var i = fishes.length - 1; i >= 0; i--) {
fishes[i].destroy();
}
fishes = [];
initializeLevel();
}
}
function checkGameOver() {
// Check if frog fell in water
if (frog.y > 2650 && !frog.isJumping) {
LK.getSound('splash').play();
LK.showGameOver();
return;
}
// Check fish collision
for (var i = fishes.length - 1; i >= 0; i--) {
var fish = fishes[i];
if (frog.intersects(fish)) {
LK.getSound('splash').play();
LK.showGameOver();
return;
}
}
}
function showStartMenu() {
// Create title text
titleTxt = new Text2('FROGGY RIVER RUSH', {
size: 120,
fill: 0xFFFFFF
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 1024;
titleTxt.y = 800;
game.addChild(titleTxt);
// Create play button
playButton = game.addChild(LK.getAsset('stone', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
var playTxt = new Text2('PLAY', {
size: 80,
fill: 0x000000
});
playTxt.anchor.set(0.5, 0.5);
playTxt.x = 1024;
playTxt.y = 1200;
game.addChild(playTxt);
// Create store button
storeButton = game.addChild(LK.getAsset('stone', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400
}));
var storeTxt = new Text2('STORE', {
size: 80,
fill: 0x000000
});
storeTxt.anchor.set(0.5, 0.5);
storeTxt.x = 1024;
storeTxt.y = 1400;
game.addChild(storeTxt);
}
function showStore() {
showingStore = true;
if (titleTxt) titleTxt.destroy();
if (playButton) playButton.destroy();
if (storeButton) storeButton.destroy();
// Remove menu text by destroying all text children except UI
var gameChildren = game.children.slice();
for (var i = 0; i < gameChildren.length; i++) {
if (gameChildren[i] instanceof Text2) {
gameChildren[i].destroy();
}
}
// Create store title
var storeTitleTxt = new Text2('FROG STORE', {
size: 100,
fill: 0xFFFFFF
});
storeTitleTxt.anchor.set(0.5, 0.5);
storeTitleTxt.x = 1024;
storeTitleTxt.y = 400;
game.addChild(storeTitleTxt);
storeTexts.push(storeTitleTxt);
// Show coins
var coinsDisplayTxt = new Text2('Coins: ' + (storage.coins || 0), {
size: 60,
fill: 0xffd700
});
coinsDisplayTxt.anchor.set(0.5, 0.5);
coinsDisplayTxt.x = 1024;
coinsDisplayTxt.y = 500;
game.addChild(coinsDisplayTxt);
storeTexts.push(coinsDisplayTxt);
// Create frog items
var frogTypes = ['normal', 'fast', 'double'];
for (var i = 0; i < frogTypes.length; i++) {
var frogType = frogTypes[i];
var yPos = 700 + i * 200;
// Create frog preview
var frogPreview = game.addChild(LK.getAsset('frog', {
anchorX: 0.5,
anchorY: 0.5,
x: 400,
y: yPos
}));
if (frogType === 'fast') {
frogPreview.tint = 0xff6b6b;
} else if (frogType === 'jumper') {
frogPreview.tint = 0x4ecdc4;
} else if (frogType === 'double') {
frogPreview.tint = 0xffe66d;
}
storeItems.push(frogPreview);
// Create name and price text
var isOwned = storage.ownedFrogs && storage.ownedFrogs[frogType];
var isSelected = currentFrogType === frogType;
var price = frogPrices[frogType];
var statusText = '';
if (isSelected) {
statusText = ' (SELECTED)';
} else if (isOwned || price === 0) {
statusText = ' (OWNED)';
} else {
statusText = ' - ' + price + ' coins';
}
var frogNameTxt = new Text2(frogNames[frogType] + statusText, {
size: 50,
fill: isSelected ? 0x00ff00 : 0xFFFFFF
});
frogNameTxt.anchor.set(0, 0.5);
frogNameTxt.x = 500;
frogNameTxt.y = yPos;
game.addChild(frogNameTxt);
storeTexts.push(frogNameTxt);
// Store frog type for purchase detection
frogPreview.frogType = frogType;
}
// Create back button
var backButton = game.addChild(LK.getAsset('stone', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2200
}));
var backTxt = new Text2('BACK', {
size: 80,
fill: 0x000000
});
backTxt.anchor.set(0.5, 0.5);
backTxt.x = 1024;
backTxt.y = 2200;
game.addChild(backTxt);
storeItems.push(backButton);
storeTexts.push(backTxt);
backButton.isBackButton = true;
}
function startGame() {
gameStarted = true;
showingStore = false;
if (titleTxt) titleTxt.destroy();
if (playButton) playButton.destroy();
if (storeButton) storeButton.destroy();
// Clean up store items
for (var i = 0; i < storeItems.length; i++) {
storeItems[i].destroy();
}
storeItems = [];
// Clean up store texts
for (var i = 0; i < storeTexts.length; i++) {
storeTexts[i].destroy();
}
storeTexts = [];
// Remove play text by destroying all text children except UI
var gameChildren = game.children.slice();
for (var i = 0; i < gameChildren.length; i++) {
if (gameChildren[i] instanceof Text2) {
gameChildren[i].destroy();
}
}
initializeLevel();
}
// Show start menu instead of initializing level
showStartMenu();
game.down = function (x, y, obj) {
if (!gameStarted && !showingStore) {
// Check if play button was clicked
if (playButton) {
var distance = Math.sqrt(Math.pow(x - playButton.x, 2) + Math.pow(y - playButton.y, 2));
if (distance < 100) {
startGame();
return;
}
}
// Check if store button was clicked
if (storeButton) {
var distance = Math.sqrt(Math.pow(x - storeButton.x, 2) + Math.pow(y - storeButton.y, 2));
if (distance < 100) {
showStore();
return;
}
}
return;
}
if (showingStore) {
// Handle store interactions
for (var i = 0; i < storeItems.length; i++) {
var item = storeItems[i];
var distance = Math.sqrt(Math.pow(x - item.x, 2) + Math.pow(y - item.y, 2));
if (distance < 100) {
if (item.isBackButton) {
showingStore = false;
// Clean up store
for (var j = 0; j < storeItems.length; j++) {
storeItems[j].destroy();
}
storeItems = [];
for (var j = 0; j < storeTexts.length; j++) {
storeTexts[j].destroy();
}
storeTexts = [];
showStartMenu();
return;
} else if (item.frogType) {
// Try to buy/select frog
var frogType = item.frogType;
var price = frogPrices[frogType];
var isOwned = storage.ownedFrogs && storage.ownedFrogs[frogType];
var currentCoins = storage.coins || 0;
if (price === 0 || isOwned) {
// Select this frog
storage.selectedFrog = frogType;
currentFrogType = frogType;
// Refresh store display
showingStore = false;
for (var j = 0; j < storeItems.length; j++) {
storeItems[j].destroy();
}
storeItems = [];
for (var j = 0; j < storeTexts.length; j++) {
storeTexts[j].destroy();
}
storeTexts = [];
showStore();
} else if (currentCoins >= price) {
// Buy frog
storage.coins = currentCoins - price;
if (!storage.ownedFrogs) storage.ownedFrogs = {};
storage.ownedFrogs[frogType] = true;
storage.selectedFrog = frogType;
currentFrogType = frogType;
// Update coin display
coinsTxt.setText('Coins: ' + storage.coins);
// Refresh store display
showingStore = false;
for (var j = 0; j < storeItems.length; j++) {
storeItems[j].destroy();
}
storeItems = [];
for (var j = 0; j < storeTexts.length; j++) {
storeTexts[j].destroy();
}
storeTexts = [];
showStore();
}
}
break;
}
}
return;
}
if (frog.isJumping && frog.frogType !== 'double') return;
if (frog.isJumping && frog.frogType === 'double' && frog.doubleJumpUsed) return;
var nearestStone = null;
var nearestDistance = Infinity;
for (var i = 0; i < stones.length; i++) {
var stone = stones[i];
var distance = Math.sqrt(Math.pow(x - stone.x, 2) + Math.pow(y - stone.y, 2));
if (distance < 150 && distance < nearestDistance) {
nearestDistance = distance;
nearestStone = stone;
}
}
if (nearestStone && !nearestStone.isOccupied) {
if (frog.isJumping && frog.frogType === 'double') {
frog.doubleJump(nearestStone);
} else {
frog.jumpTo(nearestStone);
}
LK.setScore(LK.getScore() + 10);
scoreTxt.setText('Score: ' + LK.getScore());
}
};
game.update = function () {
if (!gameStarted) return;
// Clean up destroyed stones
for (var i = stones.length - 1; i >= 0; i--) {
if (stones[i].destroyed) {
stones.splice(i, 1);
}
}
// Clean up destroyed fish
for (var i = fishes.length - 1; i >= 0; i--) {
if (fishes[i].destroyed) {
fishes.splice(i, 1);
}
}
// Clean up destroyed coins
for (var i = coins.length - 1; i >= 0; i--) {
if (coins[i].destroyed) {
coins.splice(i, 1);
}
}
// Check coin collection
for (var i = coins.length - 1; i >= 0; i--) {
var coin = coins[i];
if (frog.intersects(coin) && !coin.collected) {
coin.collect();
coins.splice(i, 1);
}
}
// Update distance traveled
var currentDistance = Math.max(0, Math.floor((startY - frog.y) / 10));
if (currentDistance > maxDistance) {
maxDistance = currentDistance;
storage.maxDistance = maxDistance;
}
distanceTxt.setText('Distance: ' + currentDistance + 'm');
// Spawn fish periodically - more fish at higher levels
fishSpawnTimer++;
var fishSpawnRate = Math.max(30, 120 - level * 8); // Minimum 30 frames between spawns
if (fishSpawnTimer > fishSpawnRate) {
fishSpawnTimer = 0;
// Spawn multiple fish at higher levels
var fishCount = Math.min(3, Math.floor(level / 3) + 1);
for (var f = 0; f < fishCount; f++) {
spawnFish();
}
}
checkWinCondition();
checkGameOver();
}; ===================================================================
--- original.js
+++ change.js
@@ -103,10 +103,11 @@
}
});
};
self.doubleJump = function (stone) {
- if (self.frogType !== 'double' || self.doubleJumpUsed || !self.isJumping) return;
+ if (self.frogType !== 'double' || self.doubleJumpUsed) return;
self.doubleJumpUsed = true;
+ self.isJumping = false; // Reset jumping state to allow new jump
self.jumpTo(stone);
};
return self;
});
@@ -583,8 +584,9 @@
}
return;
}
if (frog.isJumping && frog.frogType !== 'double') return;
+ if (frog.isJumping && frog.frogType === 'double' && frog.doubleJumpUsed) return;
var nearestStone = null;
var nearestDistance = Infinity;
for (var i = 0; i < stones.length; i++) {
var stone = stones[i];