Code edit (4 edits merged)
Please save this source code
User prompt
add a conffeti class
Code edit (6 edits merged)
Please save this source code
User prompt
in setupFinalPhoto hide background2 to 5
Code edit (1 edits merged)
Please save this source code
User prompt
in setupFinalPhoto, restore sandcastle, banner, pickets and to their initial y
User prompt
apply the ratio to the banner and pickets too
User prompt
log the ratio in setupFinalPhoto
User prompt
in setupFinalPhoto dont use scaleX/scaleY, but calculate a ratio from the number of sandblocks (3 sandblocks => ratio 1, 8 sandblocks ratio 0.5, 13 => 0.25, ...) and apply this ratio to widths and heights
Code edit (6 edits merged)
Please save this source code
User prompt
impleme,t setupFinalPhoto
Code edit (1 edits merged)
Please save this source code
Code edit (5 edits merged)
Please save this source code
User prompt
flying objects shouve move with camera
Code edit (6 edits merged)
Please save this source code
User prompt
flying object only pass once per level
User prompt
add a class for flying objects
User prompt
pass an index to cloud constructor
Code edit (1 edits merged)
Please save this source code
User prompt
clouds should also move when camera move
User prompt
when first apearing clouds should be out of the screen
User prompt
no, clouds should be initialized from the begining, but kept invisible until level 4
User prompt
clouds should appear only from level 4
User prompt
Please fix the bug: 'ReferenceError: cloud1 is not defined' in or related to this line: 'cloud1.update();' Line Number: 709
User prompt
add a cloud class
/****
* Classes
****/
var BeachToys = Container.expand(function () {
var self = Container.call(this);
var beachToysShadow = self.attachAsset('beachToysShadow', {
anchorX: 0.5,
anchorY: 0.5,
x: 150,
y: -150,
alpha: 0.3,
scaleX: -1,
scaleY: 1,
tint: 0x000000,
rotation: 2.3
});
var beachToysGraphics = self.attachAsset('beachToys', {
anchorX: 0.5,
anchorY: 1.0
});
});
var Bucket = Container.expand(function () {
var self = Container.call(this);
var bucketGraphics = self.attachAsset('bucket', {
anchorX: 0.5,
anchorY: 0.0
});
self.scoreTxt = new Text2('00', {
size: 200,
fill: "#03a2c3",
weight: 1000
});
self.scoreTxt.anchor.set(0.5, 0);
self.scoreTxt.x = 0;
self.scoreTxt.y = 330;
self.addChild(self.scoreTxt);
});
var Cloud = Container.expand(function (index) {
var self = Container.call(this);
var cloudGraphics = self.attachAsset('cloud' + index, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1; // Speed of the cloud movement
self.update = function () {
if (!self.visible) {
return;
}
self.x += self.speed;
if (self.x > 2048 + cloudGraphics.width / 2) {
self.x = -cloudGraphics.width / 2 - Math.random() * 2048; // Reset position to the left of the screen
self.y = Math.random() * 512;
}
};
});
var FlyingObject = Container.expand(function (index) {
var self = Container.call(this);
var flyingObjectGraphics = self.attachAsset('flyingObject' + index, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3; // Speed of the flying object movement
self.update = function () {
if (!self.visible) {
return;
}
self.x += self.speed;
if (self.x > 2048 + flyingObjectGraphics.width / 2) {
self.x = -flyingObjectGraphics.width / 2 - Math.random() * 1024; // Reset position to the left of the screen
self.y = Math.random() * 512 + backgroundImage.y; // Reset position relative to the camera
}
};
});
var SandBlock = Container.expand(function () {
var self = Container.call(this);
var sandBlockGraphics = self.attachAsset('sandBlock', {
anchorX: 0.5,
anchorY: 0
});
self.height = sandBlockAssetHeight * sandBlockHeightBaseRatio;
self.velocity = 0; // Initial velocity for natural falling speed increase
self.update = function () {
// SandBlock specific update logic
};
});
/***********************************************************************************/
/********************************** SANDCASTLE CLASS ************************************/
/***********************************************************************************/
var Sandcastle = Container.expand(function () {
var self = Container.call(this);
var sandcastleGraphics = self.attachAsset('sandcastle', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Sandcastle specific update logic
};
});
/****
* Initialize Game
****/
// Utility function to draw a polygon using drawLine
var game = new LK.Game({
backgroundColor: 0x000050 // Initialize game with a black background
});
/****
* Game Code
****/
/****************************************************************************************** */
/************************************** GLOBAL VARIABLES ********************************** */
/****************************************************************************************** */
// Enumeration for game states
var isBucketMovingUp = false; // Flag to track if the bucket is moving up
var isBucketMovingDown = false; // Flag to track if the bucket is moving down
var GAME_STATE = {
INIT: 'INIT',
MENU: 'MENU',
NEW_ROUND: 'NEW_ROUND',
PLAYING: 'PLAYING',
SCORE: 'SCORE'
};
var gameState = GAME_STATE.INIT;
var score = 0;
var level = 0;
var scoreTxt;
var isDebug = true;
var debugText;
var debugMarker;
var backgroundImage;
var bucket;
var banner;
var picketLeft;
var picketRight;
var sandBlocks = [];
var lives = 3;
var livesIcons = [];
var cameraMoved = false; // Flag to track if the camera has moved for the current sandblock fall
var sandBlockDropped = false; // Flag to track if a sand block has been dropped
var isCameraMoving = false; // Flag to track if the camera is currently moving
var bucketReady = false; // Flag to track if the bucket has reached y=0
var sandcastle;
var sandcastleBaseY = 2212;
var sandcastleHeight = 1640;
var previousBlockX = 1024;
var sandBlockWidth = 390;
var sandBlockHalfWidth = 195;
var sandBlockAssetHeight = 1618; // height of the asset
var sandBlockHeightBaseRatio = 0.6; // Extend effect start ratio
var sandBlockHeightRatio = sandBlockHeightBaseRatio; // Extend effect current ratio
var sandBlockSize = 460; // height of the visible sand block
var centralPointY = 1380 - sandBlockSize;
var bgHeight = 1152;
var bgHalfHeight = 576;
var gravity = 2; // Gravity effect for sand block falling
var bucketDirection = 1; // 1 for right, -1 for left
var isBucketMovingHorizontally = false; // Flag to track if the bucket is moving horizontally
var bucketMoveStep = 10; // Initial bucket move step size
var currentSandBlock = null; // Global variable to keep track of the current sand block
var startButton = null; // Global variable for the start button
var isPlaying = false; // Global variable to track if the game is currently in the playing state
var sandBlockMoveStep = 2; // Step size for sand block horizontal movement
var bgMusic;
var globalDelta = 0;
var beachToys = null; // Global variable for beach toys
var cloud1 = null; // Global variable for cloud1
var cloud2 = null; // Global variable for cloud2
var moveStep = 0; // Global variable for move step
var flyingObject1 = null; // Global variable for flyingObject1
var flyingObject2 = null; // Global variable for flyingObject2
var fadeOutStartButtonStartTime = 0;
var isCleaningNewRound = false; // Flag to prevent multiple calls to cleanNewRoundState
/****************************************************************************************** */
/*********************************** UTILITY FUNCTIONS ************************************ */
/****************************************************************************************** */
function moveCamera() {
var targetY = backgroundImage.y + sandBlockSize;
moveStep = sandBlockSize / 60; // Move over 1 second (60 frames)
function progressiveMove() {
if (backgroundImage.y < targetY) {
if (flyingObject1) {
flyingObject1.y += moveStep * 0.5;
}
if (flyingObject2) {
flyingObject2.y += moveStep * 0.5;
}
log("Camera is moving. Current y position: " + backgroundImage.y);
backgroundImage.y += moveStep;
background2.y += moveStep;
background3.y += moveStep;
sandcastle.y += moveStep;
background4.y += moveStep;
background5.y += moveStep;
banner.y += moveStep * 1.05;
picketLeft.y += moveStep * 1.05;
picketRight.y += moveStep * 1.05;
for (var j = 0; j < sandBlocks.length; j++) {
sandBlocks[j].y += moveStep;
}
if (cloud1) {
cloud1.y += moveStep * 0.5;
}
if (cloud2) {
cloud2.y += moveStep * 0.5;
}
if (backgroundImage.y < targetY) {
LK.setTimeout(progressiveMove, 1000 / 60); // Call progressiveMove every 1/60th of a second
} else {
isCameraMoving = false; // Set the flag to false when the camera stops moving
var checkBucketUpCompletion = function checkBucketUpCompletion() {
if (bucket.y <= -bucket.height && !isBucketMovingUp) {
isBucketMovingHorizontally = true; // Resume horizontal movement of the bucket
moveBucketDown(); // Progressively move the bucket down when the camera reaches the target
game.addChild(bucket); // Ensure bucket is above sand blocks
} else {
LK.setTimeout(checkBucketUpCompletion, 1000 / 60); // Check again in the next frame
}
};
checkBucketUpCompletion();
}
if (background2.y > 2732 + bgHalfHeight) {
background2.y = background5.y - background5.height;
}
if (background3.y > 2732 + bgHalfHeight) {
background3.y = background2.y - background2.height;
}
if (background4.y > 2732 + bgHalfHeight) {
background4.y = background3.y - background3.height;
}
if (background5.y > 2732 + bgHalfHeight) {
background5.y = background4.y - background4.height;
}
}
}
progressiveMove();
}
function log() {
if (isDebug) {
var _console;
(_console = console).log.apply(_console, arguments);
}
}
/****************************************************************************************** */
/************************************** INPUT HANDLERS ************************************ */
/****************************************************************************************** */
game.on('down', function (x, y, obj) {
handleGameState(x, y, obj);
});
function handleGameState(x, y, obj) {
switch (gameState) {
case GAME_STATE.MENU:
gameMenuDown(x, y, obj);
break;
case GAME_STATE.NEW_ROUND:
gameNewRoundDown(x, y, obj);
break;
case GAME_STATE.PLAYING:
gamePlayingDown(x, y, obj);
break;
case GAME_STATE.SCORE:
gameScoreDown(x, y, obj);
break;
}
}
function gameMenuDown(x, y, obj) {
log("gameMenuDown...");
if (gameState != GAME_STATE.MENU) {
return;
}
cleanMenuState();
initNewRoundState();
}
function gameNewRoundDown(x, y, obj) {
log("gameNewRoundDown...");
if (gameState != GAME_STATE.NEW_ROUND || isCleaningNewRound) {
return;
}
log("gameNewRoundDown Ok clean...");
cleanNewRoundState();
}
function gamePlayingDown(x, y, obj) {
log("gamePlayingDown...", "state=" + (gameState == GAME_STATE.PLAYING), "playing=" + isPlaying, "dropped=" + !sandBlockDropped, "camera=" + !isCameraMoving, "bucket=" + bucketReady);
if (gameState != GAME_STATE.PLAYING || !isPlaying || sandBlockDropped || isCameraMoving || !bucketReady) {
return; // Prevent taps during camera movement
}
sandBlockDropped = true;
log("gamePlayingDown OK");
// Pause horizontal movement of the bucket
isBucketMovingHorizontally = false;
// Move the bucket vertically to hide over the screen top with shake
moveBucketUp();
LK.setTimeout(createNewSandBlock, 512); // Delay creating new sand block until after shake
}
function gameScoreDown(x, y, obj) {
log("gameScoreDown...");
cleanScoreState();
}
/****************************************************************************************** */
/************************************* GAME FUNCTIONS ************************************* */
/****************************************************************************************** */
function moveBucketUp() {
if (isBucketMovingDown) {
return;
} // Prevent concurrent moves
isBucketMovingUp = true; // Set flag to true when bucket starts moving up
var bucketMoveStep = 15; // Adjust the step size as needed
var shakeStep = 40; // Step size for shake movement
var shakeCount = 0; // Counter for shake movement
function shakeBucket() {
if (shakeCount < 5) {
// Shake for 10 frames
bucket.y += shakeCount % 2 === 0 ? -shakeStep : shakeStep;
shakeCount++;
LK.setTimeout(shakeBucket, 100); // Call shakeBucket every 1/60th of a second
} else {
moveBucketUpAfterShake(); // Move bucket up after shaking
}
}
function moveBucketUpAfterShake() {
if (isPlaying && bucket.y > -bucket.height) {
isBucketMovingUp = true; // Ensure flag remains true while moving up
//log("Bucket is moving up. Current y position: " + bucket.y);
bucket.y -= bucketMoveStep;
game.addChild(bucket); // Ensure bucket is above sand blocks
LK.setTimeout(moveBucketUpAfterShake, 5); // Call moveBucketUp every 1/240th of a second
} else {
//log("Bucket end moving up. Current y position: " + bucket.y + "/-" + bucket.height);
isBucketMovingUp = false; // Set flag to false when bucket finishes moving up
}
}
shakeBucket(); // Start shaking the bucket
}
function moveBucketDown() {
if (isBucketMovingUp) {
return;
} // Prevent concurrent moves
isBucketMovingDown = true; // Set flag to true when bucket starts moving down
var bucketMoveStep = 15; // Adjust the step size as needed
if (isPlaying && bucket.y < 0) {
//log("Bucket is moving down. Current y position: " + bucket.y);
bucketReady = false; // Reset the flag when the bucket is moving down
bucket.y += bucketMoveStep;
game.addChild(bucket); // Ensure bucket is above sand blocks
LK.setTimeout(moveBucketDown, 1000 / 60); // Call moveBucketDown every 1/60th of a second
} else {
bucketReady = true; // Set the flag to true when the bucket reaches y=0
isBucketMovingDown = false; // Set flag to false when bucket finishes moving down
}
}
function createNewSandBlock() {
sandBlockHeightRatio = sandBlockHeightBaseRatio;
currentSandBlock = new SandBlock();
var sandBlock = currentSandBlock;
sandBlock.x = bucket.x;
sandBlock.y = 256;
game.addChild(sandBlock);
game.addChild(bucket);
cameraMoved = false; // Reset the flag when a new sandblock is created
sandBlockDropped = true; // Set the flag to true when a new sand block is created
}
function updateSandBlockPosition(sandBlock) {
bucketReady = false;
if (sandBlock.y < 512) {
// Restore sand block height when out of bucket
if (sandBlockHeightRatio < 1) {
sandBlockHeightRatio += 0.05;
sandBlock.height = sandBlockAssetHeight * Math.min(1, sandBlockHeightRatio);
} else {
sandBlockHeightRatio = 1;
sandBlock.height = sandBlockAssetHeight;
}
//log("sandBlockHeightRatio=" + sandBlockHeightRatio);
}
if (sandBlock.y < centralPointY) {
// Start of fall until center
sandBlock.velocity += gravity; // Increase velocity due to gravity
sandBlock.y += sandBlock.velocity; // Update position based on velocity
} else {
// Center : Check if on previous block or out
if (Math.abs(sandBlock.x - previousBlockX) > sandBlockHalfWidth) {
// Out : Continue falling
if (sandBlock.y < 2732 + sandBlockSize) {
// Fall until botom
sandBlock.rotation += 0.07 * Math.sign(sandBlock.x - previousBlockX);
sandBlock.x += 20 * Math.sign(sandBlock.x - previousBlockX);
sandBlock.velocity += gravity; // Increase velocity due to gravity
sandBlock.y += sandBlock.velocity; // Update position based on velocity
} else {
var checkBucketUpCompletion = function checkBucketUpCompletion() {
if (!isBucketMovingUp) {
sandBlockDropped = false;
isBucketMovingHorizontally = true; // Resume horizontal movement of the bucket
moveBucketDown(); // Progressively move the bucket down when the camera reaches the target
game.addChild(bucket); // Ensure bucket is above sand blocks
} else {
LK.setTimeout(checkBucketUpCompletion, 1000 / 60); // Check again in the next frame
}
};
// Reached bottom
checkBlockAlignmentAndUpdate(sandBlock);
sandBlock.fallen = true;
sandBlock.destroy();
currentSandBlock = null;
// Ensure bucket has finished moving up before running the next steps
checkBucketUpCompletion();
}
} else {
// Ok : Stop
sandBlocks.push(currentSandBlock);
globalDelta = Math.max(globalDelta, Math.abs(currentSandBlock.x - 1024));
sandBlockMoveStep = Math.floor(globalDelta / 100);
previousBlockX = currentSandBlock.x;
// Move background, sandcastle, and fallen sandblock vertically by sandBlockSize
if (!cameraMoved) {
cameraMoved = true;
isCameraMoving = true; // Set the flag to true when the camera starts moving
LK.setTimeout(function () {
moveCamera();
// Set the flag to true after moving the camera
//bucket.y = 0; // Reset bucket position when the camera moves
}, 640); // Delay of 1 second before moving the camera
// Check if sand block reached the base
checkBlockAlignmentAndUpdate(sandBlock);
}
currentSandBlock = null;
}
}
}
function moveBucketHorizontally() {
if (!level) {
return;
}
if (bucket.x >= 2048 - bucket.width / 2) {
bucketDirection = -1; // Change direction to left
} else if (bucket.x <= bucket.width / 2) {
bucketDirection = 1; // Change direction to right
}
bucket.x += bucketMoveStep * bucketDirection;
}
function checkBlockAlignmentAndUpdate(sandBlock) {
if (Math.abs(sandBlock.x - previousBlockX) < sandBlockHalfWidth) {
LK.getSound('dropped').play();
// Check for perfect alignment
level += 1;
score += 1; // Bonus points for perfect alignment
LK.setScore(score); // Store the score in LK score
if (level > 0 && level % 3 === 0) {
bucketMoveStep += 4; // Increase bucket speed by 2 units
}
} else {
LK.getSound('missed').play();
lives--;
livesIcons[lives].destroy();
livesIcons.pop();
if (lives <= 0) {
var checkBucketUpCompletionForScore = function checkBucketUpCompletionForScore() {
if (!isBucketMovingUp) {
cleanPlayingState();
initScoreState();
} else {
LK.setTimeout(checkBucketUpCompletionForScore, 1000 / 60); // Check again in the next frame
}
};
checkBucketUpCompletionForScore();
return;
}
}
sandBlockDropped = false; // Reset the flag after handling sand block reaching the base
game.addChild(bucket); // Ensure bucket is above sand blocks
}
function initializeBackgrounds() {
var mainBgY = 1566;
var mainBgHeight = 2732;
//var bgHeight = 1152;
//var bgHalfHeight = 576;
backgroundImage = LK.getAsset('backgroundImage', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: mainBgY
});
game.addChild(backgroundImage);
background2 = LK.getAsset('background2', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2
});
background2.y = backgroundImage.y - mainBgHeight / 2 - bgHalfHeight;
game.addChild(background2);
background3 = LK.getAsset('background3', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2
});
background3.y = background2.y - bgHeight;
background4 = LK.getAsset('background2', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2
});
background4.y = background3.y - bgHeight;
game.addChild(background4);
background5 = LK.getAsset('background3', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2
});
background5.y = background4.y - bgHeight;
;
game.addChild(background5);
game.addChild(background3);
}
function loopBgMusic() {
if (bgMusic && Date.now() - bgMusic.lastPlayTime > 10000) {
bgMusic.lastPlayTime = Date.now();
bgMusic.play();
}
}
/****************************************************************************************** */
/************************************* GAME STATES **************************************** */
/****************************************************************************************** */
function gameInitialize() {
log("Game initialize...");
initializeBackgrounds();
sandcastle = new Sandcastle();
sandcastle.x = 2048 / 2;
sandcastle.y = -sandcastleHeight; // Hide the sandcastle above the screen initially
game.addChild(sandcastle);
picketLeft = LK.getAsset('picket', {
anchorX: 0.5,
anchorY: 1,
x: 30,
y: 2140
});
game.addChild(picketLeft);
picketRight = LK.getAsset('picket', {
anchorX: 0.5,
anchorY: 1,
scaleX: -1,
x: 2018,
y: 2140
});
game.addChild(picketRight);
banner = LK.getAsset('banner', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 400
});
game.addChild(banner);
game.addChild(sandcastle);
level = 0;
score = 0;
LK.setScore(score); // Initialize LK score to zero at game start
bgMusic = LK.getSound('music');
bgMusic.lastPlayTime = 0;
startButton = LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1420 // Center of the screen
});
startButton.visible = false; // Initially hidden
game.addChild(startButton);
beachToys = new BeachToys();
beachToys.x = 2048 / 2;
beachToys.y = 2922;
game.addChild(beachToys);
// Initialize clouds at the beginning but keep them invisible
cloud1 = new Cloud(1);
cloud1.x = -cloud1.width;
cloud1.y = -cloud1.height;
cloud1.visible = false;
game.addChild(cloud1);
cloud2 = new Cloud(2);
cloud2.x = -cloud2.width;
cloud2.y = -cloud2.height;
cloud2.visible = false;
game.addChild(cloud2);
// Initialize flying objects at the beginning but keep them invisible
flyingObject1 = new FlyingObject(1);
flyingObject1.x = -Math.random() * 512;
flyingObject1.y = flyingObject1.height + 256 * Math.random();
flyingObject1.visible = false;
flyingObject1.passed = false;
game.addChild(flyingObject1);
flyingObject2 = new FlyingObject(2);
flyingObject2.x = -Math.random() * 512;
flyingObject2.y = flyingObject2.height + 256 * Math.random();
flyingObject2.visible = false;
flyingObject2.passed = false;
game.addChild(flyingObject2);
initMenuState();
if (isDebug) {
debugMarker = LK.getAsset('debugMarker', {
anchorX: 0.5,
anchorY: 0.5,
x: 1300,
y: 160
});
game.addChild(debugMarker);
debugText = new Text2('Debug Info', {
size: 50,
fill: "#ffffff"
});
debugText.anchor.set(0.5, 1); // Anchor to the bottom-right
LK.gui.bottom.addChild(debugText);
}
}
// GAME MENU
function initMenuState() {
log("initMenuState...");
gameState = GAME_STATE.MENU;
}
function handleMenuLoop() {
// Menu animations here
}
function cleanMenuState() {
log("cleanMenuState...");
}
// NEW ROUND
function initNewRoundState() {
log("initNewRoundState...");
gameState = GAME_STATE.NEW_ROUND;
// Fade in the start button
startButton.visible = true;
startButton.alpha = 0;
var fadeInStep = 0.05;
function fadeInStartButton() {
if (startButton.alpha < 1) {
startButton.alpha += fadeInStep;
LK.setTimeout(fadeInStartButton, 1000 / 60); // Call fadeInStartButton every 1/60th of a second
}
}
fadeInStartButton();
// Reset flying objects passed property
if (flyingObject1) {
flyingObject1.passed = false;
}
if (flyingObject2) {
flyingObject2.passed = false;
}
// Round preparation logic here.
}
function handleNewRoundLoop() {
// New Round animations here
loopBgMusic();
}
function cleanNewRoundState() {
if (isCleaningNewRound) {
return;
} // Prevent multiple calls
isCleaningNewRound = true;
log("cleanNewRoundState...");
// Animate the start button removal
var fadeOutStep = 0.05;
function fadeOutStartButton() {
log("fadeOutStartButton...", startButton.alpha, "step=" + fadeOutStep);
if (startButton.alpha > 0 && Date.now() - fadeOutStartButtonStartTime < 1000) {
startButton.alpha -= fadeOutStep;
LK.setTimeout(fadeOutStartButton, 1000 / 60); // Call fadeOutStartButton every 1/60th of a second
} else {
log("fadeOutStartButton End");
startButton.alpha = 0;
var fadeOutBeachToys = function fadeOutBeachToys() {
log("fadeOutBeachToys...");
if (beachToys.alpha > 0) {
beachToys.alpha -= fadeOutStep;
LK.setTimeout(fadeOutBeachToys, 1000 / 60);
} else {
log("fadeOutBeachToys End");
beachToys.visible = false;
beachToys.alpha = 1; // Reset alpha for future use
var animateSandcastleFall = function animateSandcastleFall() {
log("animateSandcastleFall...");
if (sandcastle.y < sandcastleBaseY) {
sandcastle.velocity += gravity; // Increase velocity due to gravity
sandcastle.y += sandcastle.velocity; // Update position based on velocity
LK.setTimeout(animateSandcastleFall, 1000 / 60); // Call animateSandcastleFall every 1/60th of a second
} else {
log("animateSandcastleFall End");
sandcastle.y = sandcastleBaseY; // Ensure it stops exactly at the base
LK.getSound('dropped').play(); // Play drop sound when it reaches its position
initPlayingState();
isCleaningNewRound = false; // Reset the flag after completion
}
};
startButton.visible = false;
startButton.alpha = 1; // Reset alpha for future use
sandcastle.velocity = 0; // Initial velocity for natural falling speed increase
animateSandcastleFall();
}
};
fadeOutBeachToys();
}
}
fadeOutStartButtonStartTime = Date.now(); // Prevent Bug alpha stucked on tap
fadeOutStartButton();
}
// PLAYING
function initPlayingState() {
log("initPlayingState...");
gameState = GAME_STATE.PLAYING;
isPlaying = true;
for (var i = 0; i < lives; i++) {
var lifeIcon = LK.getAsset('bucketIcon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 100,
y: 1166 + i * 130
});
livesIcons.push(lifeIcon);
game.addChild(lifeIcon);
}
bucket = new Bucket();
bucket.x = 2048 / 2;
bucket.y = -bucket.height;
game.addChild(bucket); // Ensure bucket is above sand blocks
moveBucketDown();
}
function handlePlayingLoop() {
loopBgMusic();
if (isPlaying && currentSandBlock) {
updateSandBlockPosition(currentSandBlock);
//game.addChild(bucket); // Ensure bucket is above sand blocks
}
if (level >= 4) {
for (var i = 0; i < sandBlocks.length; i++) {
var sandBlock = sandBlocks[i];
sandBlock.x += Math.sin(LK.ticks / 20) * sandBlockMoveStep; // Move sand blocks back and forth
}
}
if (bucket && bucket.scoreTxt) {
if (score === 0) {
bucket.scoreTxt.visible = false;
} else {
bucket.scoreTxt.visible = true;
bucket.scoreTxt.setText(score);
}
}
if (isBucketMovingHorizontally) {
moveBucketHorizontally(); // Ensure horizontal movement is restored
}
if (level >= 5 && cloud1 && cloud2 && !cloud1.visible) {
cloud1.visible = true;
cloud2.visible = true;
}
if (level >= 2 && flyingObject1 && !flyingObject1.visible && !flyingObject1.passed) {
flyingObject1.visible = true;
flyingObject1.passed = true;
}
if (level >= 3 && flyingObject2 && !flyingObject2.visible && !flyingObject2.passed) {
flyingObject2.visible = true;
flyingObject2.passed = true;
}
if (isDebug) {
//debugText.setText("X: " + bucket.x + " Y: " + bucket.y);
debugText.setText("Delta: " + globalDelta);
}
}
function cleanPlayingState() {
log("cleanPlayingState...");
isPlaying = false;
// TODO Remove elements
}
// SCORE
function initScoreState() {
log("initScoreState...");
gameState = GAME_STATE.SCORE;
// Prepare final animation
// Add a 1-second white screen flash
LK.effects.flashScreen(0xffffff, 2000);
}
function handleScoreLoop() {
// Score display logic here
}
function cleanScoreState() {
log("cleanScoreState...");
LK.showGameOver();
}
/***********************************************************************************/
/******************************** MAIN GAME LOOP ***********************************/
/***********************************************************************************/
game.update = function () {
switch (gameState) {
case GAME_STATE.MENU:
handleMenuLoop();
break;
case GAME_STATE.NEW_ROUND:
handleNewRoundLoop();
break;
case GAME_STATE.PLAYING:
handlePlayingLoop();
break;
case GAME_STATE.SCORE:
handleScoreLoop();
break;
}
};
gameInitialize(); // Initialize the game
/********************************************************************************/
/**************************** GAME DESCRIPTION *********************************/
/******************************************************************************/
/*
**Game Title**: **Sand Tower**
**Description**: Build towering sandcastles, perfect your alignment, and climb to the top! Sand Tower awaits! 🏖️🏰
**Objective**:
- Players aim to construct the tallest sandcastle tower.
- Perfect alignment of sand blocks is crucial for stability and bonus points.
**Visuals**:
- The game features a sandy beach backdrop.
- A basic sandcastle stands in the center, serving as the base.
- The central tower is the focal point.
**Gameplay Mechanics**:
- **Beach Bucket Mechanism**:
- Players use an upside-down beach bucket.
- When the player taps, the bucket tips over, releasing sand.
- **Sand Block Placement**:
- Sand falls vertically from the bucket onto the base.
- The player must time their taps to stack the sand blocks.
- Perfect alignment grants bonus points.
- **Lives System**:
- The player starts with 3 lives (represented by small bucket icons).
- Each time a sand block isn't centered enough and falls, 1 life is lost.
- **Scoring**:
- Points increase with tower height.
- Bonus points for precise alignment.
- **Game Over**:
- The game ends if the player loses all their lives (buckets).
**Audio**:
- Gentle beach sounds (waves, distant chatter).
- Encouraging music during gameplay.
*/ ===================================================================
--- original.js
+++ change.js
@@ -580,15 +580,15 @@
game.addChild(cloud2);
// Initialize flying objects at the beginning but keep them invisible
flyingObject1 = new FlyingObject(1);
flyingObject1.x = -Math.random() * 512;
- flyingObject1.y = flyingObject1.height + 256 * Math.random() + backgroundImage.y;
+ flyingObject1.y = flyingObject1.height + 256 * Math.random();
flyingObject1.visible = false;
flyingObject1.passed = false;
game.addChild(flyingObject1);
flyingObject2 = new FlyingObject(2);
flyingObject2.x = -Math.random() * 512;
- flyingObject2.y = flyingObject2.height + 256 * Math.random() + backgroundImage.y;
+ flyingObject2.y = flyingObject2.height + 256 * Math.random();
flyingObject2.visible = false;
flyingObject2.passed = false;
game.addChild(flyingObject2);
initMenuState();
Front close view of a calm sea from the beach. nothing on the beach just flat sand. no sun... photorealistic
Start button. Beach themed
face view of a red beach bucket with a blue handle.. photo
beach toys. photorealistic
beach construction toys. red bucket with blue handle.. photorealistic
an horizontal cloud. photorealistic
an air ballon. photorealistic
simple rectangular white ribon.
a soaring gull. lateral view