User prompt
add asset for larvae
User prompt
add a larvae bug that moves downwards. it has a direction assigned at creation, either moves from left end of screen to the right, or from the right end to the left.
User prompt
the animated bug should always use the same asset as the originally clicked bug
User prompt
add a new bug type (ladybird) that moves slowly downwards but zig-zags horizontally
User prompt
refactor so that we can have multiple enemy types (bug types)
User prompt
when snapping a photo, display a white rectangle of size 600x400, centered on the clicked position, fading out quickly as a flash ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (3 edits merged)
Please save this source code
User prompt
play sound when heart is added
User prompt
when adding score, check if multiple of 50 and, if so add a heart (with sound). ensure maximum 3 hearts always.
User prompt
trees only start appearing after 5 photos (score)
User prompt
fix: i'm not seeing the hearts (lives) on the top right of screen
User prompt
replace the Lives placar on the hud by icon hearts at the top right
User prompt
Grant 3 seconds immunity after losing a life, blinking the jeep ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
3 lives
User prompt
add sounds for snapping a picture (when clicking a bug) and car crashing (on car collisions)
User prompt
play music "safariMusc"
User prompt
move car only horizontally
User prompt
Please fix the bug: 'game.swapChildren is not a function' in or related to this line: 'game.swapChildren(stripe, game.getChildAt(0));' Line Number: 205
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
//<Assets used in the game will automatically appear here>
// AnimatedBug class to represent the bug that flies to the top of the screen
var AnimatedBug = Container.expand(function () {
var self = Container.call(this);
var bugGraphics = self.attachAsset('bug', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.update = function () {
// Determine the direction to fly to (left or right)
var direction = Math.random() < 0.5 ? -1 : 1;
// Update the x and y position
self.x += self.speed * direction * 3;
self.y -= self.speed * 3;
// Destroy the bug when it flies off the screen
if (self.y < 0 || self.x < 0 || self.x > 2048) {
self.destroy();
}
};
});
var Bug = Container.expand(function () {
var self = Container.call(this);
var bugGraphics = self.attachAsset('bug', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.update = function () {
self.y += self.speed;
};
self.down = function (x, y, obj) {
// Play photo snap sound
LK.getSound('snapPhoto').play();
// Increment score
LK.setScore(LK.getScore() + 1);
// Update score text
scoreTxt.setText('Photos: ' + LK.getScore());
// Replace bug with AnimatedBug
var animatedBug = game.addChild(new AnimatedBug());
animatedBug.x = self.x;
animatedBug.y = self.y;
isTouching = false; // Prevent car from moving when touching a bug
self.destroy();
};
});
// FastBug class to represent the fast bug that scrolls down the screen
var FastBug = Container.expand(function () {
var self = Container.call(this);
var bugGraphics = self.attachAsset('fastBug', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.update = function () {
self.y += self.speed;
};
self.down = function (x, y, obj) {
// Play photo snap sound
LK.getSound('snapPhoto').play();
// Increment score
LK.setScore(LK.getScore() + 1);
// Update score text
scoreTxt.setText('Photos: ' + LK.getScore());
// Replace bug with AnimatedBug
var animatedBug = game.addChild(new AnimatedBug());
animatedBug.x = self.x;
animatedBug.y = self.y;
isTouching = false; // Prevent car from moving when touching a bug
self.destroy();
};
});
// GrassStripe class for representing the scrolling grass stripes
var GrassStripe = Container.expand(function () {
var self = Container.call(this);
self.isDark = false; // Track if this is a dark stripe
var stripeGraphics = self.attachAsset('grassStripe', {
anchorX: 0.5,
anchorY: 0.5
});
// Set speed of scrolling
self.speed = 5;
// Method to toggle between light and dark stripe
self.setDark = function (isDark) {
self.isDark = isDark;
if (isDark) {
stripeGraphics = self.attachAsset('grassStripeDark', {
anchorX: 0.5,
anchorY: 0.5
});
} else {
stripeGraphics = self.attachAsset('grassStripe', {
anchorX: 0.5,
anchorY: 0.5
});
}
};
self.update = function () {
self.y += self.speed;
// If stripe moves off screen, reset to top
if (self.y > 2732 + self.height / 2) {
self.y = -self.height / 2;
}
};
return self;
});
// Heart class to represent lives
var Heart = Container.expand(function () {
var self = Container.call(this);
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
self.setActive = function (active) {
heartGraphics.alpha = active ? 1 : 0.3;
};
return self;
});
// Jeep class to represent the player's vehicle
var Jeep = Container.expand(function () {
var self = Container.call(this);
var jeepGraphics = self.attachAsset('jeep', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.isImmune = false;
self.immunityTimer = 0;
self.setImmunity = function (immune) {
self.isImmune = immune;
if (immune) {
// Create blinking effect using tweens
var _blink = function blink() {
if (!self.isImmune) return;
tween(jeepGraphics, {
alpha: 0.3
}, {
duration: 150,
onFinish: function onFinish() {
if (!self.isImmune) return;
tween(jeepGraphics, {
alpha: 1
}, {
duration: 150,
onFinish: _blink
});
}
});
};
// Start blinking effect with alternating alpha values
self.immunityTimer = LK.setTimeout(function () {
self.isImmune = false;
// Reset alpha to fully opaque when immunity ends
jeepGraphics.alpha = 1;
// Stop any ongoing blink tweens
tween.stop(jeepGraphics, {
alpha: true
});
}, 3000);
_blink();
} else {
// Clear immunity timer if immunity is turned off early
if (self.immunityTimer) {
LK.clearTimeout(self.immunityTimer);
self.immunityTimer = 0;
}
jeepGraphics.alpha = 1;
}
};
self.update = function () {
var dx = targetPosition.x - self.x;
// Only update x position, ignore vertical movement
self.x += self.speed * (dx > 0 ? 1 : dx < 0 ? -1 : 0);
// Keep y position fixed
self.y = 2732 - 200; // Fixed position at bottom of screen
};
});
var Tree = Container.expand(function () {
var self = Container.call(this);
var treeGraphics = self.attachAsset('tree', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
// Create a trunk hit box for collision detection
self.trunkWidth = 60; // width of trunk collision area
self.trunkHeight = 200; // height of trunk collision area
self.trunkOffsetY = 50; // offset from center of tree
// Check if point is within the trunk area
self.trunkIntersects = function (obj) {
// Calculate trunk boundaries
var trunkLeft = self.x - self.trunkWidth / 2;
var trunkRight = self.x + self.trunkWidth / 2;
var trunkTop = self.y + self.trunkOffsetY - self.trunkHeight / 2;
var trunkBottom = self.y + self.trunkOffsetY + self.trunkHeight / 2;
// Get object boundaries
var objLeft = obj.x - obj.width / 2;
var objRight = obj.x + obj.width / 2;
var objTop = obj.y - obj.height / 2;
var objBottom = obj.y + obj.height / 2;
// Check for intersection
return !(objRight < trunkLeft || objLeft > trunkRight || objBottom < trunkTop || objTop > trunkBottom);
};
self.update = function () {
self.y += self.speed;
};
});
/****
* Initialize Game
****/
// Helper function to swap children in display list
var game = new LK.Game({
backgroundColor: 0x006400 //Init game with darker green background
});
/****
* Game Code
****/
// Initialize game variables
// Helper function to swap children in display list
function swapChildren(parent, child1, child2) {
if (!parent || !child1 || !child2) {
return;
}
// Get the index of both children
var index1 = -1;
var index2 = -1;
for (var i = 0; i < parent.children.length; i++) {
if (parent.children[i] === child1) {
index1 = i;
}
if (parent.children[i] === child2) {
index2 = i;
}
}
// If both children are found, swap them
if (index1 !== -1 && index2 !== -1) {
// Remove both children (higher index first to not affect the lower index)
var temp;
if (index1 > index2) {
temp = parent.removeChildAt(index1);
parent.addChildAt(temp, index2);
} else {
temp = parent.removeChildAt(index2);
parent.addChildAt(temp, index1);
}
}
}
var jeep;
var scoreTxt;
var deathReasonTxt;
var deathReason = "";
var isTouching = false;
var grassStripes = [];
var lives = 3;
var hearts = [];
// Function to create scrolling grass stripes
function createGrassStripes() {
// Clear existing stripes if any
for (var i = 0; i < grassStripes.length; i++) {
if (grassStripes[i]) {
grassStripes[i].destroy();
}
}
grassStripes = [];
// Create new stripes to fill the screen
var stripeHeight = 200;
var numStripes = Math.ceil(2732 / stripeHeight) + 1; // +1 for seamless scrolling
for (var i = 0; i < numStripes; i++) {
var stripe = new GrassStripe();
stripe.x = 2048 / 2;
stripe.y = i * stripeHeight;
stripe.setDark(i % 2 === 0); // Alternate between light and dark
grassStripes.push(stripe);
game.addChild(stripe);
// Make sure stripes are added at the bottom of the display list (background)
swapChildren(game, stripe, game.getChildAt(0));
}
}
// Function to initialize game elements
function initGame() {
// Reset lives to 3
lives = 3;
// Initialize grass stripes
createGrassStripes();
// Create and position the Jeep
jeep = game.addChild(new Jeep());
jeep.x = 2048 / 2;
jeep.y = 2732 - 200;
targetPosition.x = jeep.x;
targetPosition.y = jeep.y;
// Initialize score display
scoreTxt = new Text2('Photos: 0', {
size: 100,
fill: 0xFFFFFF
});
// Initialize death reason display
deathReasonTxt = new Text2('', {
size: 80,
fill: 0xFFFFFF
});
// Initialize lives display with heart icons
hearts = [];
for (var i = 0; i < 3; i++) {
var heart = new Heart();
heart.x = -300 + i * 120; // Position hearts side by side with spacing, offset from right edge
heart.y = 100; // Position at top
heart.setActive(i < lives);
hearts.push(heart);
LK.gui.topRight.addChild(heart);
}
// Initialize bugs, fastBugs and trees arrays
bugs = [];
fastBugs = [];
trees = [];
scoreTxt.anchor.set(0.5, 0);
deathReasonTxt.anchor.set(0.5, 0);
deathReasonTxt.y = 120; // Position below score text
LK.gui.top.addChild(scoreTxt);
LK.gui.top.addChild(deathReasonTxt);
}
var targetPosition = {
x: 0,
y: 0
};
game.down = function (x, y, obj) {
// Check if the touch is on a bug, if so ignore and return
for (var i = 0; i < bugs.length; i++) {
if (x >= bugs[i].x - 100 && x <= bugs[i].x + 100 && y >= bugs[i].y - 100 && y <= bugs[i].y + 100) {
return;
}
}
// Check if the touch is on a fast bug, if so ignore and return
for (var i = 0; i < fastBugs.length; i++) {
if (x >= fastBugs[i].x - 100 && x <= fastBugs[i].x + 100 && y >= fastBugs[i].y - 100 && y <= fastBugs[i].y + 100) {
return;
}
}
// Set target position for the jeep movement (horizontal only)
targetPosition.x = x;
// Keep targetPosition.y fixed to maintain jeep's vertical position
targetPosition.y = 2732 - 200;
};
game.update = function () {
// Update grass stripes
for (var i = 0; i < grassStripes.length; i++) {
grassStripes[i].update();
}
jeep.update();
// Bug and tree spawning logic
if (LK.ticks % 60 == 0) {
var newBug = new Bug();
newBug.x = Math.random() * 2048;
newBug.y = 0;
bugs.push(newBug);
game.addChild(newBug);
}
if (LK.ticks % 180 == 0) {
var newFastBug = new FastBug();
newFastBug.x = Math.random() * 2048;
newFastBug.y = 0;
fastBugs.push(newFastBug);
game.addChild(newFastBug);
}
if (LK.ticks % 180 == 0 && LK.getScore() >= 5) {
var newTree = new Tree();
newTree.x = Math.random() * 2048;
newTree.y = 0;
trees.push(newTree);
game.addChild(newTree);
}
// Bug and tree movement and collision detection logic
for (var i = bugs.length - 1; i >= 0; i--) {
bugs[i].update();
// Only check collision if it's not an AnimatedBug
if (bugs[i].intersects(jeep) && !(bugs[i] instanceof AnimatedBug) && !jeep.isImmune) {
deathReason = "Hit by a bug!";
deathReasonTxt.setText(deathReason);
LK.getSound('carCrash').play();
lives -= 1;
// Update hearts display
for (var h = 0; h < hearts.length; h++) {
hearts[h].setActive(h < lives);
}
if (lives <= 0) {
LK.showGameOver();
} else {
// Give player immunity for 3 seconds
jeep.setImmunity(true);
// Remove the bug after collision
bugs[i].destroy();
bugs.splice(i, 1);
// Flash screen to indicate damage
LK.effects.flashScreen(0xff0000, 500);
continue;
}
}
if (bugs[i].y > 2732) {
bugs[i].destroy();
bugs.splice(i, 1);
}
}
for (var i = fastBugs.length - 1; i >= 0; i--) {
fastBugs[i].update();
// Only check collision if it's not an AnimatedBug
if (fastBugs[i].intersects(jeep) && !(fastBugs[i] instanceof AnimatedBug) && !jeep.isImmune) {
deathReason = "Hit by a fast bug!";
deathReasonTxt.setText(deathReason);
LK.getSound('carCrash').play();
lives -= 1;
// Update hearts display
for (var h = 0; h < hearts.length; h++) {
hearts[h].setActive(h < lives);
}
if (lives <= 0) {
LK.showGameOver();
} else {
// Give player immunity for 3 seconds
jeep.setImmunity(true);
// Remove the fast bug after collision
fastBugs[i].destroy();
fastBugs.splice(i, 1);
// Flash screen to indicate damage
LK.effects.flashScreen(0xff0000, 500);
continue;
}
}
if (fastBugs[i].y > 2732) {
fastBugs[i].destroy();
fastBugs.splice(i, 1);
}
}
for (var i = trees.length - 1; i >= 0; i--) {
trees[i].update();
if (trees[i].trunkIntersects(jeep) && !jeep.isImmune) {
deathReason = "Crashed into a tree!";
deathReasonTxt.setText(deathReason);
LK.getSound('carCrash').play();
lives -= 1;
// Update hearts display
for (var h = 0; h < hearts.length; h++) {
hearts[h].setActive(h < lives);
}
if (lives <= 0) {
LK.showGameOver();
} else {
// Give player immunity for 3 seconds
jeep.setImmunity(true);
// Remove the tree after collision
trees[i].destroy();
trees.splice(i, 1);
// Flash screen to indicate damage
LK.effects.flashScreen(0xff0000, 500);
continue;
}
}
if (trees[i].y > 2732) {
trees[i].destroy();
trees.splice(i, 1);
}
}
};
// Initialize the game
initGame();
// Play safari background music
LK.playMusic('safariMusc');
// Import the tween plugin; ===================================================================
--- original.js
+++ change.js
@@ -224,10 +224,10 @@
/****
* Game Code
****/
-// Helper function to swap children in display list
// Initialize game variables
+// Helper function to swap children in display list
function swapChildren(parent, child1, child2) {
if (!parent || !child1 || !child2) {
return;
}
@@ -370,9 +370,9 @@
newFastBug.y = 0;
fastBugs.push(newFastBug);
game.addChild(newFastBug);
}
- if (LK.ticks % 180 == 0) {
+ if (LK.ticks % 180 == 0 && LK.getScore() >= 5) {
var newTree = new Tree();
newTree.x = Math.random() * 2048;
newTree.y = 0;
trees.push(newTree);
Giant insect, facing down, open wings, cartoony. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Jeep car cartoony, top down view. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoony heart for game hud. In-Game asset. 2d. High contrast. No shadows
ladybug insect. In-Game asset. 2d. High contrast. No shadows
larvae bug. In-Game asset. 2d. High contrast. No shadows