User prompt
Slow down sparkle speed and reduce amount by 25%
User prompt
Stop the rightward motion of the sparkles, keep the dancing and fading.
User prompt
Make the sparkles dance around the coin like fireflies
User prompt
Have the sparkles swirl around the coin instead of trailing back.
User prompt
Randomize the location of the sparkles on the coin.
User prompt
Make a class for GoldSparkle and use it to generate particle effects on Coins to simulate sparkling.
User prompt
Make the coin counter text bigger
User prompt
Add a coin asset beside the coin counter to the left and pin it there.
User prompt
Add collision detection with the coin to the coot. Destroy coin and add it to global coin count variable that has been defined and set to 0 at the beginning of the game. Add coin counter in the top right corner of the screen with a coin asset beside it.
User prompt
Slow down more
User prompt
Slow down more
User prompt
Reduce a little bit more
User prompt
Slow down more
User prompt
The coin is spinning too fast
User prompt
Remove rotation from the coin, but not the spin
User prompt
Code like this: var spinSpeed = 0.2; // Speed for spinning animation newDomino.update = function () { if (newDomino.x < targetX) { newDomino.x += 15; // Move towards the target slot faster newDomino.scale.x = Math.sin(newDomino.x * spinSpeed); // Spin effect over Y axis }
User prompt
Coins should spin instead of rotate
User prompt
I want to have Coins randomly generated and moving from right to left. Coins should start off screen to the right and have a Y range of 30% from the top of the screen and 15% from the bottom.
User prompt
Make a Coin class using Coin asset
User prompt
At the bottom of the swoop make sure the Eagle stops tracking the Coot if the Coot is returning, is diving or has a return delay counter that’s greater than 0.
User prompt
The eagle should not track the Coot if the return delay is greater than 0
User prompt
The Eagle should NOT track the coot if the coot is Diving or Returning
User prompt
Add a check to the Eagle that it can’t track the Coot if it’s state is set to diving or returning.
User prompt
Add a check to Eagle to not track the Coot if it’s diving or returning.
User prompt
Make the eagle track the Coot if it tries to jump over it
/**** * Classes ****/ var CollisionBlock = Container.expand(function () { var self = Container.call(this); var collisionBlockGraphics = self.attachAsset('Collisionblock', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); }); // Assets will be automatically created and loaded by the LK engine based on their usage in the code. // Example assets: 'coot', 'obstacle', 'background' // Class for the main character, the American coot var Coot = Container.expand(function () { var self = Container.call(this); var cootGraphics = self.attachAsset('coot', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6.5; self.jumpVelocity = 40; // Increased initial upward velocity for jump self.gravity = 1.0; // Gravity to apply during jump self.jumpHeight = 105; self.isJumping = false; self.isReturning = false; // New state to handle returning to top after diving self.update = function () { if (self.isJumping) { self.x += self.speed * 0.1 * gameSpeed; self.y -= self.jumpVelocity; // Move upwards with initial velocity self.jumpVelocity -= self.gravity; // Apply gravity to slow down ascent if (self.jumpVelocity <= 0) { self.isJumping = false; // Stop jumping when upward velocity is zero self.isFalling = true; // Start falling } } else if (self.isFalling) { self.y += self.gravity * 7; // Apply even more increased gravity to fall down faster if (self.y >= self.originalY) { self.y = self.originalY; // Ensure Coot doesn't go below original position self.isFalling = false; // Stop falling self.x = self.originalX; // Reset X position when jump completes self.jumpVelocity = 40; // Reset jump velocity for next jump self.isJumping = false; // Ensure jumping state is reset // Removed unnecessary isReturning reset in the falling state } // Remove wobble and water particles during falling cootGraphics.rotation = 0; // Reset rotation to remove wobble } else if (self.isDiving) { self.y += self.speed * 1.5; cootGraphics.alpha = Math.max(0.5, cootGraphics.alpha - 0.05); // Gradually decrease opacity cootGraphics.tint = 0x0000ff; // Change tint to blue if (self.y >= 2732 * 0.90) { self.y = 2732 * 0.90; // Ensure Coot doesn't go below this point self.isDiving = false; // Stop diving self.returnDelay = Date.now() + 1000; // 1 second delay using time } } else if (self.returnDelay > 0) { if (Date.now() >= self.returnDelay) { self.returnDelay = 0; // Reset returnDelay after it is used if (self.y >= 2732 * 0.90) { self.isReturning = true; // Start returning after delay } } } else if (self.isReturning) { self.y -= self.speed * 1.5; // Match surfacing speed with descent speed var transitionFactor = 1 - (self.y - self.originalY) / (2732 * 0.90 - self.originalY); cootGraphics.alpha = 0.5 + 0.5 * transitionFactor; // Smoothly increase opacity // Convert tint colors to RGB and interpolate var startTint = self.underwaterTint; var endTint = 0xffffff; var r = (startTint >> 16 & 0xff) + ((endTint >> 16 & 0xff) - (startTint >> 16 & 0xff)) * transitionFactor; var g = (startTint >> 8 & 0xff) + ((endTint >> 8 & 0xff) - (startTint >> 8 & 0xff)) * transitionFactor; var b = (startTint & 0xff) + ((endTint & 0xff) - (startTint & 0xff)) * transitionFactor; cootGraphics.tint = (r << 16) + (g << 8) + b; // Apply interpolated tint if (self.y <= self.originalY) { self.y = self.originalY; self.isReturning = false; // Reset returning state cootGraphics.alpha = 1.0; // Ensure opacity is fully reset cootGraphics.tint = 0xffffff; // Reset tint to normal color when fully surfaced } // Removed redundant isReturning block to ensure visual effects are not reset prematurely if (self.isReturning) { self.x += (self.originalX - self.x) * 0.1; // Gradually slide back to original X position } } // Add wobble effect to the coot while running if (!self.isJumping && !self.isDiving && !self.isReturning && !self.isFalling) { cootGraphics.rotation = Math.sin(LK.ticks / 5) * 0.1; // Increase wobble speed by reducing the divisor // Generate 1-2 water splash particles every 60 ticks (1 second) only when not jumping, diving, or falling if (!self.isJumping && !self.isDiving && !self.isFalling && LK.ticks % 60 == 0) { var numParticles = Math.floor(Math.random() * 2) + 1; for (var i = 0; i < numParticles; i++) { var splashLeft = new Splash(); splashLeft.x = self.x - cootGraphics.width / 2; splashLeft.y = self.y + cootGraphics.height / 2; game.addChildAt(splashLeft, game.getChildIndex(foreground1) - 1); var splashRight = new Splash(); splashRight.x = self.x + cootGraphics.width / 2; splashRight.y = self.y + cootGraphics.height / 2; game.addChildAt(splashRight, game.getChildIndex(foreground1) - 1); } } } // Handle dash state if (self.isDashing) { if (self.dashTimer < self.dashDelay) { // Dash forward if (self.x < 2048 * 0.75) { // Stop at 3/4 of screen width self.x += self.dashSpeed; } self.dashTimer++; } else { // Return to original position if (self.x > self.originalX) { self.x -= self.dashSpeed / 2; // Return at half speed } else { self.x = self.originalX; self.isDashing = false; self.dashTimer = 0; } } } }; self.isDiving = false; self.isDashing = false; self.dashSpeed = 15; self.dashDelay = 60; // frames before return (1 second at 60fps) self.dashTimer = 0; self.originalX = self.x; // Store original position self.jump = function () { if (!self.isJumping && !self.isDiving && !self.isReturning && !self.isDashing) { self.isJumping = true; self.originalX = self.x; // Removed X position update from jump function self.isReturning = false; // Ensure returning state is reset when jumping self.originalY = self.y; } }; self.dive = function () { if (!self.isJumping && !self.isDiving && !self.isDashing) { self.isDiving = true; self.returnDelay = Date.now() + 5000; // Set return delay to 5 seconds using time self.isReturning = false; // Ensure returning state is reset when diving self.underwaterTint = 0x4444ff; // Set initial underwater tint color // Removed duplicate isReturning = false line self.originalX = self.x; self.originalY = self.y; self.y += self.speed * 2; // Start diving downwards immediately with increased speed // Generate water splash particles var numParticles = Math.floor(Math.random() * 3) + 2; // Generate 2-4 particles for (var i = 0; i < numParticles; i++) { var splash = new Splash(); splash.x = self.x; splash.y = self.y + cootGraphics.height / 2; game.addChildAt(splash, game.getChildIndex(foreground1) - 1); } } }; }); var EagleFeather = Container.expand(function () { var self = Container.call(this); var featherGraphics = self.attachAsset('Eaglefeather', { anchorX: 0.5, anchorY: 0.5 }); // Initialize feather properties self.rotationSpeed = Math.random() * 0.02 - 0.01; // Random rotation speed self.driftX = Math.random() * 2 - 1; // Random sideways drift self.driftY = Math.random() * -1 - 0.5; // Upward drift self.fadeRate = 0.005; // Fade out rate self.update = function () { self.x += self.driftX * gameSpeed; self.y += self.driftY * gameSpeed; featherGraphics.rotation += self.rotationSpeed; featherGraphics.alpha -= self.fadeRate; // Destroy feather when fully faded if (featherGraphics.alpha <= 0) { self.destroy(); } }; }); // Class for the foreground var Foreground = Container.expand(function () { var self = Container.call(this); var foregroundGraphics = self.attachAsset('Foreground', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.isFirst = false; // Will be set during initialization self.update = function () { // Only move the first piece if (self.isFirst) { self.x -= self.speed * gameSpeed; // Apply gameSpeed to movement // Move second piece to maintain fixed distance self.other.x = self.x + self.width; // Reset both pieces when first goes off screen if (self.x < -self.width / 1.5) { // Reset earlier - when piece is mostly off screen self.x += self.width; self.other.x = self.x + self.width; } } }; }); // Class for the midgroundtrees var Midgroundtrees = Container.expand(function () { var self = Container.call(this); var midgroundtreesGraphics = self.attachAsset('Midgroundtrees', { anchorX: 0.5, anchorY: 0.7 }); self.speed = 3; self.update = function () { self.x -= self.speed * gameSpeed; // self.y = coot.y; if (self.x <= -self.width / 2) { self.x += self.width * 2; } }; }); // Class for the Obstacle (Duck, Eagle, and Fish combined) var Obstacle = Container.expand(function (type) { var self = Container.call(this); var graphics; var collisionBlock = self.addChild(new CollisionBlock()); collisionBlock.x = 0; collisionBlock.y = 0; graphics = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); // Add a Ripple instance to the Duck obstacle if (type === 'Duck') { self.lastRippleTime = Date.now(); var ripple = new Ripple(); ripple.x = 0; // Center the ripple on the Duck ripple.y = graphics.height / 2; // Position the ripple at the bottom of the Duck self.addChildAt(ripple, 0); // Add ripple below the Duck but above the water layer } self.speedX = -6; if (type === 'Fish') { self.isJumping = false; self.pauseTime = 0; graphics.tint = 0x4444ff; graphics.alpha = 0.7; } if (type === 'Fish') { self.speedX = -6; // Back to original fast swimming speed self.jumpSpeed = 0.05; // Slow jump speed control self.isJumping = false; self.isPausing = false; self.pauseTime = 0; self.lastSplashTime = Date.now(); // Add splash timer graphics.tint = 0x4444ff; // Set underwater blue tint initially graphics.alpha = 0.7; // Set underwater opacity initially self.isFalling = false; self.jumpVelocity = 0; self.jumpStartY = self.y; // Store original position self.jumpTime = 0; // Initialize jump time counter self.y = 2732 * 0.90; // Set Fish Y position to the bottom of the Coot's dive } if (type === 'Eagle') { self.lastFeatherTime = Date.now(); self.targetY = coot.isDiving || coot.isReturning ? coot.originalY : coot.y; self.speedY = (self.targetY - self.y) / 100; self.speedX = -8; // Add horizontal speed variable for eagle } self.update = function () { self.x += self.speedX * gameSpeed; if (type === 'Fish') { // Move horizontally self.x += self.speedX; // Generate underwater splash effects if (!self.isJumping && Date.now() - self.lastSplashTime >= 200) { // Generate every 200ms var numSplashes = Math.floor(Math.random() * 2) + 1; // 1-2 splashes for (var i = 0; i < numSplashes; i++) { var splash = new Splash(); splash.x = self.x + (Math.random() * graphics.width - graphics.width / 2); // Random position along fish body splash.y = self.y; splash.tint = 0x4444ff; // Match fish's underwater tint game.addChildAt(splash, game.getChildIndex(self) - 1); } self.lastSplashTime = Date.now(); } // Check if crossing under Coot if (self.x <= coot.x && !self.isJumping) { self.speedX = 0; graphics.alpha = 0; self.pauseTime += 0.05; } // Add this check for when to reappear if (self.pauseTime >= 1 && !self.isJumping) { graphics.alpha = 1; graphics.rotation = Math.PI / 2; // Changed from -Math.PI/2 to rotate the other way self.isJumping = true; self.jumpStartY = self.y; self.jumpTime = 0; } // Handle jumping motion if (self.isJumping) { self.jumpTime += self.jumpSpeed; // Use slower jumpSpeed var jumpHeight = -Math.sin(self.jumpTime) * 600; // Changed from 300 to 600 self.y = self.jumpStartY + jumpHeight; // Generate bigger splash burst when jumping out if (self.jumpTime < 0.1) { // Only on first frame of jump var burstSplashes = Math.floor(Math.random() * 4) + 6; // 6-9 splashes (increased from 4-6) for (var i = 0; i < burstSplashes; i++) { var splash = new Splash(); splash.x = self.x + (Math.random() * graphics.width - graphics.width / 2); splash.y = self.jumpStartY - Math.random() * 200; // Make splashes go higher game.addChildAt(splash, game.getChildIndex(self) - 1); } } // Change tint based on height above water if (self.y < self.jumpStartY - 50) { graphics.tint = 0xffffff; // Normal color above water graphics.alpha = 1.0; } else { graphics.tint = 0x4444ff; // Blue tint in water graphics.alpha = 0.7; } if (self.jumpTime > Math.PI) { Obstacle.lastDestroyTime = Date.now(); console.log("Fish destroyed after jump at " + Date.now()); currentObstacle = null; // Add this line self.destroy(); } } // Normal destroy check if (self.x <= -self.width / 2) { self.destroy(); Obstacle.lastDestroyTime = Date.now(); } } else if (type === 'Eagle') { self.y += self.speedY; if (Date.now() - self.lastFeatherTime >= 900) { // Feather spawn every 900ms var numFeathers = Math.floor(Math.random() * 2) + 2; // Spawn 2-3 feathers for (var i = 0; i < numFeathers; i++) { var feather = new EagleFeather(); feather.x = self.x + (Math.random() * 20 - 10); // Slight horizontal variation feather.y = self.y + graphics.height / 2; game.addChildAt(feather, game.getChildIndex(self) - 1); } self.lastFeatherTime = Date.now(); } if (self.x <= -self.width / 2) { console.log("Checking for destruction: Eagle at " + self.x); self.destroy(); // Destroy the obstacle when it moves off-screen Obstacle.lastDestroyTime = Date.now(); // Set lastDestroyTime when destroyed console.log("Obstacle destroyed at " + Obstacle.lastDestroyTime); } if (type === 'Eagle') { self.targetY = coot.isJumping ? coot.y : coot.isDiving || coot.isReturning ? coot.originalY : coot.y; self.speedY = (self.targetY - self.y) / 50; } } else if (type === 'Duck') { // Add wobble effect to Duck graphics.rotation = Math.sin(LK.ticks / 20) * 0.05; // Ripple spawn logic if (Date.now() - self.lastRippleTime >= 500) { var ripple = new Ripple(); ripple.x = self.x; ripple.y = self.y + graphics.height / 2; game.addChildAt(ripple, game.getChildIndex(self) - 1); self.lastRippleTime = Date.now(); } // Existing destroy logic if (self.x <= -self.width / 2) { console.log("Checking for destruction: Duck at " + self.x); self.destroy(); Obstacle.lastDestroyTime = Date.now(); console.log("Obstacle destroyed at " + Obstacle.lastDestroyTime); } } collisionBlock.x = 0; collisionBlock.y = 0; }; }); var Ripple = Container.expand(function () { var self = Container.call(this); var rippleGraphics = self.attachAsset('Ripple', { anchorX: 0.5, anchorY: 0.5 }); self.initialScale = 0.05; self.growthRate = 0.02; self.fadeRate = 0.01; self.maxScale = 2.0; rippleGraphics.scaleX = self.initialScale; rippleGraphics.scaleY = self.initialScale; self.update = function () { console.log("Ripple update called"); rippleGraphics.scaleX += self.growthRate; rippleGraphics.scaleY += self.growthRate; rippleGraphics.alpha -= self.fadeRate; console.log("Ripple scale:", rippleGraphics.scaleX, "Ripple alpha:", rippleGraphics.alpha); if (rippleGraphics.scaleX >= self.maxScale || rippleGraphics.alpha <= 0) { console.log("Ripple destroyed"); self.destroy(); } }; }); // Static respawn delay property // Class for the water splash particles var Splash = Container.expand(function () { var self = Container.call(this); var scale = Math.random() * 0.75 + 0.25; var splashGraphics = self.attachAsset('Watersplash', { anchorX: 0.5, anchorY: 0.5, scaleX: scale, scaleY: scale }); self.speedX = Math.random() * 2 - 1; // Random speed in X direction self.speedY = -Math.random() * 5; // Random upward speed in Y direction self.gravity = 0.1; // Gravity to pull the particle down self.update = function () { self.x += self.speedX * gameSpeed; self.y += self.speedY * gameSpeed; self.speedY += self.gravity; // Apply gravity // Add rotation based on the speed of the particle self.rotation += self.speedX / 10; if (self.y > 2732) { // If the particle is below the screen self.destroy(); // Destroy the particle } }; }); // Class for the water var Water = Container.expand(function () { var self = Container.call(this); var waterGraphics = self.attachAsset('Water', { anchorX: 0.5, anchorY: 0.7 }); self.speed = 2; self.update = function () { self.x -= self.speed * gameSpeed; // self.y = midgroundtrees1.y + midgroundtrees1.height / 2; if (self.x <= -self.width / 2) { self.x += self.width * 2; } }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ Obstacle.getRandomDelay = function (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }; Obstacle.spawnDelay = 2500; // Default fallback Obstacle.respawnDelay = { Eagle: Obstacle.getRandomDelay(2000, 3000), Duck: Obstacle.getRandomDelay(2000, 3000), Fish: Obstacle.getRandomDelay(2000, 3000) // Add Fish delay }; Obstacle.lastDestroyTime = Date.now() - 5000; // Initialize to ensure first spawn check passes console.log("Initial lastDestroyTime: " + Obstacle.lastDestroyTime); var background = game.addChild(LK.getAsset('Background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 2048 / 2500, scaleY: 2732 / 2500 })); // Initialize the midgroundtrees var midgroundtrees1 = game.addChild(new Midgroundtrees()); midgroundtrees1.x = 2048 / 2; midgroundtrees1.y = 2732 * 0.7; var midgroundtrees2 = game.addChild(new Midgroundtrees()); midgroundtrees2.x = 2048 / 2 + midgroundtrees2.width; midgroundtrees2.y = 2732 * 0.7; // Initialize the water var water1 = game.addChild(new Water()); water1.x = 2048 / 2; water1.y = midgroundtrees1.y + midgroundtrees1.height / 2; var water2 = game.addChild(new Water()); water2.x = 2048 / 2 + water2.width; water2.y = midgroundtrees2.y + midgroundtrees2.height / 2; // Initialize game variables var coot = game.addChild(new Coot()); coot.x = 2048 * 0.20; coot.y = 2732 * 0.75; coot.originalY = coot.y; // Initialize originalY position var gameSpeed = 1.5; // Global variable for game speed var score = 0; var currentObstacle = null; // Initialize the foreground var foreground1 = new Foreground(); var foreground2 = new Foreground(); game.addChild(foreground1); game.addChild(foreground2); foreground1.x = 2048 / 2; foreground1.y = 2732 * 0.9; foreground2.x = foreground1.x + foreground1.width; foreground2.y = 2732 * 0.9; foreground1.isFirst = true; foreground1.other = foreground2; foreground2.other = foreground1; // Validate positioning if (Math.abs(foreground2.x - (foreground1.x + foreground1.width)) > 1) { console.error("Foreground pieces are not correctly positioned!"); } foreground1.other = foreground2; foreground2.other = foreground1; game.addChild(foreground1); game.addChild(foreground2); var scoreTxt = new Text2('0', { size: 100, fill: "#ffffff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Handle game updates game.update = function () { coot.update(); if (LK.ticks % 60 == 0) { score++; scoreTxt.setText(score); } // Check for collision between the Coot and the Collision Block of the current obstacle if (currentObstacle && coot.intersects(currentObstacle.children[0])) { LK.showGameOver(); } // Update the midgroundtrees midgroundtrees1.update(); midgroundtrees2.update(); // Update the water water1.update(); water2.update(); // Update the current obstacle // Check if the current obstacle needs destruction if (currentObstacle && currentObstacle.x < -currentObstacle.width / 2) { currentObstacle.destroy(); Obstacle.lastDestroyTime = Date.now(); console.log("Obstacle destroyed at " + Obstacle.lastDestroyTime); currentObstacle = null; } // Check if it's time to spawn a new obstacle if (!currentObstacle && Date.now() - Obstacle.lastDestroyTime >= Obstacle.spawnDelay) { var obstacleTypes = ['Duck', 'Eagle', 'Fish']; // Ensure equal chance for all types var randomIndex = Math.floor(Math.random() * obstacleTypes.length); var obstacleType = obstacleTypes[randomIndex]; console.log("Selected obstacle type: ", obstacleType); currentObstacle = game.addChild(new Obstacle(obstacleType)); currentObstacle.x = 2048 + currentObstacle.width / 2; // Ensure it starts off-screen currentObstacle.y = obstacleType === 'Duck' ? 2732 * 0.75 : obstacleType === 'Eagle' ? 2732 * 0.25 : 2732 * 0.85; // Changed from 0.90 to 0.85 for Fish console.log("Spawned " + obstacleType + " at " + Date.now()); } if (currentObstacle) { currentObstacle.update(); } // Update the foreground foreground1.update(); foreground2.update(); }; // Handle touch events for jumping and diving game.down = function (x, y, obj) { dragStartY = y; // Record the initial y position when touch starts dragStartX = x; // Record the initial x position when touch starts }; game.move = function (x, y, obj) { if (dragStartY !== null && dragStartX !== null) { if (x - dragStartX > 50 && !coot.isDashing && coot.x === coot.originalX && !coot.isDiving && !coot.isReturning) { // Check if the drag is rightward and significant coot.isDashing = true; dragStartX = null; // Reset dragStartX to prevent repeated dashes } if (y - dragStartY > 50 && coot.y === coot.originalY) { // Check if the drag is downward and significant coot.dive(); dragStartY = null; // Reset dragStartY to prevent repeated dives } else if (dragStartY - y > 50 && coot.y === coot.originalY) { // Check if the drag is upward and significant coot.jump(); dragStartY = null; // Reset dragStartY to prevent repeated jumps } } }; game.up = function (x, y, obj) { dragStartY = null; // Reset dragStartY when touch ends dragStartX = null; // Reset dragStartX when touch ends };
/****
* Classes
****/
var CollisionBlock = Container.expand(function () {
var self = Container.call(this);
var collisionBlockGraphics = self.attachAsset('Collisionblock', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
});
// Assets will be automatically created and loaded by the LK engine based on their usage in the code.
// Example assets: 'coot', 'obstacle', 'background'
// Class for the main character, the American coot
var Coot = Container.expand(function () {
var self = Container.call(this);
var cootGraphics = self.attachAsset('coot', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6.5;
self.jumpVelocity = 40; // Increased initial upward velocity for jump
self.gravity = 1.0; // Gravity to apply during jump
self.jumpHeight = 105;
self.isJumping = false;
self.isReturning = false; // New state to handle returning to top after diving
self.update = function () {
if (self.isJumping) {
self.x += self.speed * 0.1 * gameSpeed;
self.y -= self.jumpVelocity; // Move upwards with initial velocity
self.jumpVelocity -= self.gravity; // Apply gravity to slow down ascent
if (self.jumpVelocity <= 0) {
self.isJumping = false; // Stop jumping when upward velocity is zero
self.isFalling = true; // Start falling
}
} else if (self.isFalling) {
self.y += self.gravity * 7; // Apply even more increased gravity to fall down faster
if (self.y >= self.originalY) {
self.y = self.originalY; // Ensure Coot doesn't go below original position
self.isFalling = false; // Stop falling
self.x = self.originalX; // Reset X position when jump completes
self.jumpVelocity = 40; // Reset jump velocity for next jump
self.isJumping = false; // Ensure jumping state is reset
// Removed unnecessary isReturning reset in the falling state
}
// Remove wobble and water particles during falling
cootGraphics.rotation = 0; // Reset rotation to remove wobble
} else if (self.isDiving) {
self.y += self.speed * 1.5;
cootGraphics.alpha = Math.max(0.5, cootGraphics.alpha - 0.05); // Gradually decrease opacity
cootGraphics.tint = 0x0000ff; // Change tint to blue
if (self.y >= 2732 * 0.90) {
self.y = 2732 * 0.90; // Ensure Coot doesn't go below this point
self.isDiving = false; // Stop diving
self.returnDelay = Date.now() + 1000; // 1 second delay using time
}
} else if (self.returnDelay > 0) {
if (Date.now() >= self.returnDelay) {
self.returnDelay = 0; // Reset returnDelay after it is used
if (self.y >= 2732 * 0.90) {
self.isReturning = true; // Start returning after delay
}
}
} else if (self.isReturning) {
self.y -= self.speed * 1.5; // Match surfacing speed with descent speed
var transitionFactor = 1 - (self.y - self.originalY) / (2732 * 0.90 - self.originalY);
cootGraphics.alpha = 0.5 + 0.5 * transitionFactor; // Smoothly increase opacity
// Convert tint colors to RGB and interpolate
var startTint = self.underwaterTint;
var endTint = 0xffffff;
var r = (startTint >> 16 & 0xff) + ((endTint >> 16 & 0xff) - (startTint >> 16 & 0xff)) * transitionFactor;
var g = (startTint >> 8 & 0xff) + ((endTint >> 8 & 0xff) - (startTint >> 8 & 0xff)) * transitionFactor;
var b = (startTint & 0xff) + ((endTint & 0xff) - (startTint & 0xff)) * transitionFactor;
cootGraphics.tint = (r << 16) + (g << 8) + b; // Apply interpolated tint
if (self.y <= self.originalY) {
self.y = self.originalY;
self.isReturning = false; // Reset returning state
cootGraphics.alpha = 1.0; // Ensure opacity is fully reset
cootGraphics.tint = 0xffffff; // Reset tint to normal color when fully surfaced
}
// Removed redundant isReturning block to ensure visual effects are not reset prematurely
if (self.isReturning) {
self.x += (self.originalX - self.x) * 0.1; // Gradually slide back to original X position
}
}
// Add wobble effect to the coot while running
if (!self.isJumping && !self.isDiving && !self.isReturning && !self.isFalling) {
cootGraphics.rotation = Math.sin(LK.ticks / 5) * 0.1; // Increase wobble speed by reducing the divisor
// Generate 1-2 water splash particles every 60 ticks (1 second) only when not jumping, diving, or falling
if (!self.isJumping && !self.isDiving && !self.isFalling && LK.ticks % 60 == 0) {
var numParticles = Math.floor(Math.random() * 2) + 1;
for (var i = 0; i < numParticles; i++) {
var splashLeft = new Splash();
splashLeft.x = self.x - cootGraphics.width / 2;
splashLeft.y = self.y + cootGraphics.height / 2;
game.addChildAt(splashLeft, game.getChildIndex(foreground1) - 1);
var splashRight = new Splash();
splashRight.x = self.x + cootGraphics.width / 2;
splashRight.y = self.y + cootGraphics.height / 2;
game.addChildAt(splashRight, game.getChildIndex(foreground1) - 1);
}
}
}
// Handle dash state
if (self.isDashing) {
if (self.dashTimer < self.dashDelay) {
// Dash forward
if (self.x < 2048 * 0.75) {
// Stop at 3/4 of screen width
self.x += self.dashSpeed;
}
self.dashTimer++;
} else {
// Return to original position
if (self.x > self.originalX) {
self.x -= self.dashSpeed / 2; // Return at half speed
} else {
self.x = self.originalX;
self.isDashing = false;
self.dashTimer = 0;
}
}
}
};
self.isDiving = false;
self.isDashing = false;
self.dashSpeed = 15;
self.dashDelay = 60; // frames before return (1 second at 60fps)
self.dashTimer = 0;
self.originalX = self.x; // Store original position
self.jump = function () {
if (!self.isJumping && !self.isDiving && !self.isReturning && !self.isDashing) {
self.isJumping = true;
self.originalX = self.x;
// Removed X position update from jump function
self.isReturning = false; // Ensure returning state is reset when jumping
self.originalY = self.y;
}
};
self.dive = function () {
if (!self.isJumping && !self.isDiving && !self.isDashing) {
self.isDiving = true;
self.returnDelay = Date.now() + 5000; // Set return delay to 5 seconds using time
self.isReturning = false; // Ensure returning state is reset when diving
self.underwaterTint = 0x4444ff; // Set initial underwater tint color
// Removed duplicate isReturning = false line
self.originalX = self.x;
self.originalY = self.y;
self.y += self.speed * 2; // Start diving downwards immediately with increased speed
// Generate water splash particles
var numParticles = Math.floor(Math.random() * 3) + 2; // Generate 2-4 particles
for (var i = 0; i < numParticles; i++) {
var splash = new Splash();
splash.x = self.x;
splash.y = self.y + cootGraphics.height / 2;
game.addChildAt(splash, game.getChildIndex(foreground1) - 1);
}
}
};
});
var EagleFeather = Container.expand(function () {
var self = Container.call(this);
var featherGraphics = self.attachAsset('Eaglefeather', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize feather properties
self.rotationSpeed = Math.random() * 0.02 - 0.01; // Random rotation speed
self.driftX = Math.random() * 2 - 1; // Random sideways drift
self.driftY = Math.random() * -1 - 0.5; // Upward drift
self.fadeRate = 0.005; // Fade out rate
self.update = function () {
self.x += self.driftX * gameSpeed;
self.y += self.driftY * gameSpeed;
featherGraphics.rotation += self.rotationSpeed;
featherGraphics.alpha -= self.fadeRate;
// Destroy feather when fully faded
if (featherGraphics.alpha <= 0) {
self.destroy();
}
};
});
// Class for the foreground
var Foreground = Container.expand(function () {
var self = Container.call(this);
var foregroundGraphics = self.attachAsset('Foreground', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.isFirst = false; // Will be set during initialization
self.update = function () {
// Only move the first piece
if (self.isFirst) {
self.x -= self.speed * gameSpeed; // Apply gameSpeed to movement
// Move second piece to maintain fixed distance
self.other.x = self.x + self.width;
// Reset both pieces when first goes off screen
if (self.x < -self.width / 1.5) {
// Reset earlier - when piece is mostly off screen
self.x += self.width;
self.other.x = self.x + self.width;
}
}
};
});
// Class for the midgroundtrees
var Midgroundtrees = Container.expand(function () {
var self = Container.call(this);
var midgroundtreesGraphics = self.attachAsset('Midgroundtrees', {
anchorX: 0.5,
anchorY: 0.7
});
self.speed = 3;
self.update = function () {
self.x -= self.speed * gameSpeed;
// self.y = coot.y;
if (self.x <= -self.width / 2) {
self.x += self.width * 2;
}
};
});
// Class for the Obstacle (Duck, Eagle, and Fish combined)
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
var graphics;
var collisionBlock = self.addChild(new CollisionBlock());
collisionBlock.x = 0;
collisionBlock.y = 0;
graphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
// Add a Ripple instance to the Duck obstacle
if (type === 'Duck') {
self.lastRippleTime = Date.now();
var ripple = new Ripple();
ripple.x = 0; // Center the ripple on the Duck
ripple.y = graphics.height / 2; // Position the ripple at the bottom of the Duck
self.addChildAt(ripple, 0); // Add ripple below the Duck but above the water layer
}
self.speedX = -6;
if (type === 'Fish') {
self.isJumping = false;
self.pauseTime = 0;
graphics.tint = 0x4444ff;
graphics.alpha = 0.7;
}
if (type === 'Fish') {
self.speedX = -6; // Back to original fast swimming speed
self.jumpSpeed = 0.05; // Slow jump speed control
self.isJumping = false;
self.isPausing = false;
self.pauseTime = 0;
self.lastSplashTime = Date.now(); // Add splash timer
graphics.tint = 0x4444ff; // Set underwater blue tint initially
graphics.alpha = 0.7; // Set underwater opacity initially
self.isFalling = false;
self.jumpVelocity = 0;
self.jumpStartY = self.y; // Store original position
self.jumpTime = 0; // Initialize jump time counter
self.y = 2732 * 0.90; // Set Fish Y position to the bottom of the Coot's dive
}
if (type === 'Eagle') {
self.lastFeatherTime = Date.now();
self.targetY = coot.isDiving || coot.isReturning ? coot.originalY : coot.y;
self.speedY = (self.targetY - self.y) / 100;
self.speedX = -8; // Add horizontal speed variable for eagle
}
self.update = function () {
self.x += self.speedX * gameSpeed;
if (type === 'Fish') {
// Move horizontally
self.x += self.speedX;
// Generate underwater splash effects
if (!self.isJumping && Date.now() - self.lastSplashTime >= 200) {
// Generate every 200ms
var numSplashes = Math.floor(Math.random() * 2) + 1; // 1-2 splashes
for (var i = 0; i < numSplashes; i++) {
var splash = new Splash();
splash.x = self.x + (Math.random() * graphics.width - graphics.width / 2); // Random position along fish body
splash.y = self.y;
splash.tint = 0x4444ff; // Match fish's underwater tint
game.addChildAt(splash, game.getChildIndex(self) - 1);
}
self.lastSplashTime = Date.now();
}
// Check if crossing under Coot
if (self.x <= coot.x && !self.isJumping) {
self.speedX = 0;
graphics.alpha = 0;
self.pauseTime += 0.05;
}
// Add this check for when to reappear
if (self.pauseTime >= 1 && !self.isJumping) {
graphics.alpha = 1;
graphics.rotation = Math.PI / 2; // Changed from -Math.PI/2 to rotate the other way
self.isJumping = true;
self.jumpStartY = self.y;
self.jumpTime = 0;
}
// Handle jumping motion
if (self.isJumping) {
self.jumpTime += self.jumpSpeed; // Use slower jumpSpeed
var jumpHeight = -Math.sin(self.jumpTime) * 600; // Changed from 300 to 600
self.y = self.jumpStartY + jumpHeight;
// Generate bigger splash burst when jumping out
if (self.jumpTime < 0.1) {
// Only on first frame of jump
var burstSplashes = Math.floor(Math.random() * 4) + 6; // 6-9 splashes (increased from 4-6)
for (var i = 0; i < burstSplashes; i++) {
var splash = new Splash();
splash.x = self.x + (Math.random() * graphics.width - graphics.width / 2);
splash.y = self.jumpStartY - Math.random() * 200; // Make splashes go higher
game.addChildAt(splash, game.getChildIndex(self) - 1);
}
}
// Change tint based on height above water
if (self.y < self.jumpStartY - 50) {
graphics.tint = 0xffffff; // Normal color above water
graphics.alpha = 1.0;
} else {
graphics.tint = 0x4444ff; // Blue tint in water
graphics.alpha = 0.7;
}
if (self.jumpTime > Math.PI) {
Obstacle.lastDestroyTime = Date.now();
console.log("Fish destroyed after jump at " + Date.now());
currentObstacle = null; // Add this line
self.destroy();
}
}
// Normal destroy check
if (self.x <= -self.width / 2) {
self.destroy();
Obstacle.lastDestroyTime = Date.now();
}
} else if (type === 'Eagle') {
self.y += self.speedY;
if (Date.now() - self.lastFeatherTime >= 900) {
// Feather spawn every 900ms
var numFeathers = Math.floor(Math.random() * 2) + 2; // Spawn 2-3 feathers
for (var i = 0; i < numFeathers; i++) {
var feather = new EagleFeather();
feather.x = self.x + (Math.random() * 20 - 10); // Slight horizontal variation
feather.y = self.y + graphics.height / 2;
game.addChildAt(feather, game.getChildIndex(self) - 1);
}
self.lastFeatherTime = Date.now();
}
if (self.x <= -self.width / 2) {
console.log("Checking for destruction: Eagle at " + self.x);
self.destroy(); // Destroy the obstacle when it moves off-screen
Obstacle.lastDestroyTime = Date.now(); // Set lastDestroyTime when destroyed
console.log("Obstacle destroyed at " + Obstacle.lastDestroyTime);
}
if (type === 'Eagle') {
self.targetY = coot.isJumping ? coot.y : coot.isDiving || coot.isReturning ? coot.originalY : coot.y;
self.speedY = (self.targetY - self.y) / 50;
}
} else if (type === 'Duck') {
// Add wobble effect to Duck
graphics.rotation = Math.sin(LK.ticks / 20) * 0.05;
// Ripple spawn logic
if (Date.now() - self.lastRippleTime >= 500) {
var ripple = new Ripple();
ripple.x = self.x;
ripple.y = self.y + graphics.height / 2;
game.addChildAt(ripple, game.getChildIndex(self) - 1);
self.lastRippleTime = Date.now();
}
// Existing destroy logic
if (self.x <= -self.width / 2) {
console.log("Checking for destruction: Duck at " + self.x);
self.destroy();
Obstacle.lastDestroyTime = Date.now();
console.log("Obstacle destroyed at " + Obstacle.lastDestroyTime);
}
}
collisionBlock.x = 0;
collisionBlock.y = 0;
};
});
var Ripple = Container.expand(function () {
var self = Container.call(this);
var rippleGraphics = self.attachAsset('Ripple', {
anchorX: 0.5,
anchorY: 0.5
});
self.initialScale = 0.05;
self.growthRate = 0.02;
self.fadeRate = 0.01;
self.maxScale = 2.0;
rippleGraphics.scaleX = self.initialScale;
rippleGraphics.scaleY = self.initialScale;
self.update = function () {
console.log("Ripple update called");
rippleGraphics.scaleX += self.growthRate;
rippleGraphics.scaleY += self.growthRate;
rippleGraphics.alpha -= self.fadeRate;
console.log("Ripple scale:", rippleGraphics.scaleX, "Ripple alpha:", rippleGraphics.alpha);
if (rippleGraphics.scaleX >= self.maxScale || rippleGraphics.alpha <= 0) {
console.log("Ripple destroyed");
self.destroy();
}
};
});
// Static respawn delay property
// Class for the water splash particles
var Splash = Container.expand(function () {
var self = Container.call(this);
var scale = Math.random() * 0.75 + 0.25;
var splashGraphics = self.attachAsset('Watersplash', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scale,
scaleY: scale
});
self.speedX = Math.random() * 2 - 1; // Random speed in X direction
self.speedY = -Math.random() * 5; // Random upward speed in Y direction
self.gravity = 0.1; // Gravity to pull the particle down
self.update = function () {
self.x += self.speedX * gameSpeed;
self.y += self.speedY * gameSpeed;
self.speedY += self.gravity; // Apply gravity
// Add rotation based on the speed of the particle
self.rotation += self.speedX / 10;
if (self.y > 2732) {
// If the particle is below the screen
self.destroy(); // Destroy the particle
}
};
});
// Class for the water
var Water = Container.expand(function () {
var self = Container.call(this);
var waterGraphics = self.attachAsset('Water', {
anchorX: 0.5,
anchorY: 0.7
});
self.speed = 2;
self.update = function () {
self.x -= self.speed * gameSpeed;
// self.y = midgroundtrees1.y + midgroundtrees1.height / 2;
if (self.x <= -self.width / 2) {
self.x += self.width * 2;
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
Obstacle.getRandomDelay = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
Obstacle.spawnDelay = 2500; // Default fallback
Obstacle.respawnDelay = {
Eagle: Obstacle.getRandomDelay(2000, 3000),
Duck: Obstacle.getRandomDelay(2000, 3000),
Fish: Obstacle.getRandomDelay(2000, 3000) // Add Fish delay
};
Obstacle.lastDestroyTime = Date.now() - 5000; // Initialize to ensure first spawn check passes
console.log("Initial lastDestroyTime: " + Obstacle.lastDestroyTime);
var background = game.addChild(LK.getAsset('Background', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 2048 / 2500,
scaleY: 2732 / 2500
}));
// Initialize the midgroundtrees
var midgroundtrees1 = game.addChild(new Midgroundtrees());
midgroundtrees1.x = 2048 / 2;
midgroundtrees1.y = 2732 * 0.7;
var midgroundtrees2 = game.addChild(new Midgroundtrees());
midgroundtrees2.x = 2048 / 2 + midgroundtrees2.width;
midgroundtrees2.y = 2732 * 0.7;
// Initialize the water
var water1 = game.addChild(new Water());
water1.x = 2048 / 2;
water1.y = midgroundtrees1.y + midgroundtrees1.height / 2;
var water2 = game.addChild(new Water());
water2.x = 2048 / 2 + water2.width;
water2.y = midgroundtrees2.y + midgroundtrees2.height / 2;
// Initialize game variables
var coot = game.addChild(new Coot());
coot.x = 2048 * 0.20;
coot.y = 2732 * 0.75;
coot.originalY = coot.y; // Initialize originalY position
var gameSpeed = 1.5; // Global variable for game speed
var score = 0;
var currentObstacle = null;
// Initialize the foreground
var foreground1 = new Foreground();
var foreground2 = new Foreground();
game.addChild(foreground1);
game.addChild(foreground2);
foreground1.x = 2048 / 2;
foreground1.y = 2732 * 0.9;
foreground2.x = foreground1.x + foreground1.width;
foreground2.y = 2732 * 0.9;
foreground1.isFirst = true;
foreground1.other = foreground2;
foreground2.other = foreground1;
// Validate positioning
if (Math.abs(foreground2.x - (foreground1.x + foreground1.width)) > 1) {
console.error("Foreground pieces are not correctly positioned!");
}
foreground1.other = foreground2;
foreground2.other = foreground1;
game.addChild(foreground1);
game.addChild(foreground2);
var scoreTxt = new Text2('0', {
size: 100,
fill: "#ffffff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Handle game updates
game.update = function () {
coot.update();
if (LK.ticks % 60 == 0) {
score++;
scoreTxt.setText(score);
}
// Check for collision between the Coot and the Collision Block of the current obstacle
if (currentObstacle && coot.intersects(currentObstacle.children[0])) {
LK.showGameOver();
}
// Update the midgroundtrees
midgroundtrees1.update();
midgroundtrees2.update();
// Update the water
water1.update();
water2.update();
// Update the current obstacle
// Check if the current obstacle needs destruction
if (currentObstacle && currentObstacle.x < -currentObstacle.width / 2) {
currentObstacle.destroy();
Obstacle.lastDestroyTime = Date.now();
console.log("Obstacle destroyed at " + Obstacle.lastDestroyTime);
currentObstacle = null;
}
// Check if it's time to spawn a new obstacle
if (!currentObstacle && Date.now() - Obstacle.lastDestroyTime >= Obstacle.spawnDelay) {
var obstacleTypes = ['Duck', 'Eagle', 'Fish']; // Ensure equal chance for all types
var randomIndex = Math.floor(Math.random() * obstacleTypes.length);
var obstacleType = obstacleTypes[randomIndex];
console.log("Selected obstacle type: ", obstacleType);
currentObstacle = game.addChild(new Obstacle(obstacleType));
currentObstacle.x = 2048 + currentObstacle.width / 2; // Ensure it starts off-screen
currentObstacle.y = obstacleType === 'Duck' ? 2732 * 0.75 : obstacleType === 'Eagle' ? 2732 * 0.25 : 2732 * 0.85; // Changed from 0.90 to 0.85 for Fish
console.log("Spawned " + obstacleType + " at " + Date.now());
}
if (currentObstacle) {
currentObstacle.update();
}
// Update the foreground
foreground1.update();
foreground2.update();
};
// Handle touch events for jumping and diving
game.down = function (x, y, obj) {
dragStartY = y; // Record the initial y position when touch starts
dragStartX = x; // Record the initial x position when touch starts
};
game.move = function (x, y, obj) {
if (dragStartY !== null && dragStartX !== null) {
if (x - dragStartX > 50 && !coot.isDashing && coot.x === coot.originalX && !coot.isDiving && !coot.isReturning) {
// Check if the drag is rightward and significant
coot.isDashing = true;
dragStartX = null; // Reset dragStartX to prevent repeated dashes
}
if (y - dragStartY > 50 && coot.y === coot.originalY) {
// Check if the drag is downward and significant
coot.dive();
dragStartY = null; // Reset dragStartY to prevent repeated dives
} else if (dragStartY - y > 50 && coot.y === coot.originalY) {
// Check if the drag is upward and significant
coot.jump();
dragStartY = null; // Reset dragStartY to prevent repeated jumps
}
}
};
game.up = function (x, y, obj) {
dragStartY = null; // Reset dragStartY when touch ends
dragStartX = null; // Reset dragStartX when touch ends
};
American Coot sprite sheet. Running with wings up.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A beautiful blue sky background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Grass and reeds foreground layer for endless runner. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
White water bubble. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A mallard floating on the water. Looking left. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A swimming salmon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A single golden coin with the head of an American Coot on it.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
The sun. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Game icon for a video game called “Coot Run”. Show an American Coot with its wings up and its foot big in the foreground. Show the name of the game big in the center with the coots foot underneath.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A moon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A starry sky background image. High resolution. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A fiery Phoenix with wings outspread.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A dark blue rectangle background with rounded edges to place text on top of for a menu.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
An owl with talons extended downwards and wings up. Looking down. Color Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A captain’s hat. Side profile. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A rainbow hat with a propeller on the top. Side profile. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A striped beanie. Side profile. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A white SVG with big bold letters, that says “Start”. A couple black feathers flying off the edge of the word. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A white SVG with big bold letters, that says “How to play”. A couple black feathers flying off the edge of the word. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A sombrero. Side profile. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A knights helmet. Side view. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A horned Viking cap. Side profile. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An astronauts helmet. Side profile. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A cowboy hat. Full side profile. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
duck
Sound effect
eagle
Sound effect
fishsplash
Sound effect
jumpsound
Sound effect
dashsound
Sound effect
backgroundmusic
Music
coin
Sound effect
powerup
Sound effect
coothurt
Sound effect
owl
Sound effect
phoenix
Sound effect
alert
Sound effect
cootdive
Sound effect
whistle
Sound effect