/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Balloon = Container.expand(function () { var self = Container.call(this); var balloonGraphics = self.attachAsset('balloon', { anchorX: 0.5, anchorY: 0.5 }); self.velocityY = 0; self.velocityX = 0; self.gravity = 0.8; self.jumpForce = -15; self.maxFallSpeed = 12; self.moveSpeed = 8; self.maxMoveSpeed = 12; self.friction = 0.95; self.isPopped = false; self.jump = function () { if (!self.isPopped) { self.velocityY = self.jumpForce; LK.getSound('jump').play(); // Balloon inflation animation on jump tween(balloonGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(balloonGraphics, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeIn }); } }); } }; self.pop = function () { if (!self.isPopped) { self.isPopped = true; LK.getSound('pop').play(); // Pop animation tween(balloonGraphics, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 300, easing: tween.easeIn }); } }; self.moveLeft = function () { if (!self.isPopped) { self.velocityX -= self.moveSpeed; if (self.velocityX < -self.maxMoveSpeed) { self.velocityX = -self.maxMoveSpeed; } } }; self.moveRight = function () { if (!self.isPopped) { self.velocityX += self.moveSpeed; if (self.velocityX > self.maxMoveSpeed) { self.velocityX = self.maxMoveSpeed; } } }; self.update = function () { if (!self.isPopped) { // Apply gravity self.velocityY += self.gravity; // Limit fall speed if (self.velocityY > self.maxFallSpeed) { self.velocityY = self.maxFallSpeed; } // Apply friction to horizontal movement self.velocityX *= self.friction; // Update position self.x += self.velocityX; self.y += self.velocityY; // Keep balloon within screen bounds if (self.x < 60) { self.x = 60; self.velocityX = 0; } else if (self.x > 2048 - 60) { self.x = 2048 - 60; self.velocityX = 0; } // Subtle floating animation when not jumping if (self.velocityY > 0) { var deflationScale = 1.0 - self.velocityY / self.maxFallSpeed * 0.1; balloonGraphics.scaleX = deflationScale; balloonGraphics.scaleY = deflationScale; } } }; return self; }); var Ground = Container.expand(function () { var self = Container.call(this); var groundGraphics = self.attachAsset('ground', { anchorX: 0, anchorY: 0 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb }); /**** * Game Code ****/ // Game variables var balloon; var ground; var gameStarted = false; var survivalTime = 0; var difficultyMultiplier = 1; // UI Elements var scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var instructionTxt = new Text2('TAP TO JUMP!\nDRAG TO MOVE!', { size: 50, fill: 0xFFFFFF }); instructionTxt.anchor.set(0.5, 0.5); instructionTxt.x = 2048 / 2; instructionTxt.y = 1000; game.addChild(instructionTxt); // Create balloon balloon = new Balloon(); balloon.x = 2048 / 2; balloon.y = 1366; // Center vertically game.addChild(balloon); // Create ground ground = new Ground(); ground.x = 0; ground.y = 2732 - 200; // At bottom of screen game.addChild(ground); // Start background music LK.playMusic('atmosphere'); // Track last collision state var lastColliding = false; // Track touch/drag state var isDragging = false; var lastTouchX = 0; // Game input handling game.down = function (x, y, obj) { if (!gameStarted) { gameStarted = true; instructionTxt.alpha = 0; } if (!balloon.isPopped) { balloon.jump(); isDragging = true; lastTouchX = x; } }; game.up = function (x, y, obj) { isDragging = false; }; game.move = function (x, y, obj) { if (isDragging && !balloon.isPopped) { var deltaX = x - lastTouchX; if (deltaX > 10) { balloon.moveRight(); } else if (deltaX < -10) { balloon.moveLeft(); } lastTouchX = x; } }; // Main game update loop game.update = function () { if (gameStarted && !balloon.isPopped) { // Update survival time and score survivalTime += 1; var score = Math.floor(survivalTime / 60); // Score based on seconds survived LK.setScore(score); scoreTxt.setText(score); // Increase difficulty over time if (survivalTime % 1800 === 0) { // Every 30 seconds difficultyMultiplier += 0.1; balloon.gravity = 0.8 * difficultyMultiplier; balloon.maxFallSpeed = 12 * difficultyMultiplier; } // Check collision with ground var currentColliding = balloon.intersects(ground); if (!lastColliding && currentColliding) { // Balloon just hit the ground balloon.pop(); // Flash screen red and show game over after a delay LK.effects.flashScreen(0xff0000, 500); LK.setTimeout(function () { LK.showGameOver(); }, 800); } lastColliding = currentColliding; // Keep balloon on screen (prevent going too high) if (balloon.y < 100) { balloon.y = 100; balloon.velocityY = 0; } } // Fade out instruction text when game starts if (gameStarted && instructionTxt.alpha > 0) { instructionTxt.alpha -= 0.02; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Balloon = Container.expand(function () {
var self = Container.call(this);
var balloonGraphics = self.attachAsset('balloon', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = 0;
self.velocityX = 0;
self.gravity = 0.8;
self.jumpForce = -15;
self.maxFallSpeed = 12;
self.moveSpeed = 8;
self.maxMoveSpeed = 12;
self.friction = 0.95;
self.isPopped = false;
self.jump = function () {
if (!self.isPopped) {
self.velocityY = self.jumpForce;
LK.getSound('jump').play();
// Balloon inflation animation on jump
tween(balloonGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(balloonGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
};
self.pop = function () {
if (!self.isPopped) {
self.isPopped = true;
LK.getSound('pop').play();
// Pop animation
tween(balloonGraphics, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
}
};
self.moveLeft = function () {
if (!self.isPopped) {
self.velocityX -= self.moveSpeed;
if (self.velocityX < -self.maxMoveSpeed) {
self.velocityX = -self.maxMoveSpeed;
}
}
};
self.moveRight = function () {
if (!self.isPopped) {
self.velocityX += self.moveSpeed;
if (self.velocityX > self.maxMoveSpeed) {
self.velocityX = self.maxMoveSpeed;
}
}
};
self.update = function () {
if (!self.isPopped) {
// Apply gravity
self.velocityY += self.gravity;
// Limit fall speed
if (self.velocityY > self.maxFallSpeed) {
self.velocityY = self.maxFallSpeed;
}
// Apply friction to horizontal movement
self.velocityX *= self.friction;
// Update position
self.x += self.velocityX;
self.y += self.velocityY;
// Keep balloon within screen bounds
if (self.x < 60) {
self.x = 60;
self.velocityX = 0;
} else if (self.x > 2048 - 60) {
self.x = 2048 - 60;
self.velocityX = 0;
}
// Subtle floating animation when not jumping
if (self.velocityY > 0) {
var deflationScale = 1.0 - self.velocityY / self.maxFallSpeed * 0.1;
balloonGraphics.scaleX = deflationScale;
balloonGraphics.scaleY = deflationScale;
}
}
};
return self;
});
var Ground = Container.expand(function () {
var self = Container.call(this);
var groundGraphics = self.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var balloon;
var ground;
var gameStarted = false;
var survivalTime = 0;
var difficultyMultiplier = 1;
// UI Elements
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var instructionTxt = new Text2('TAP TO JUMP!\nDRAG TO MOVE!', {
size: 50,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0.5);
instructionTxt.x = 2048 / 2;
instructionTxt.y = 1000;
game.addChild(instructionTxt);
// Create balloon
balloon = new Balloon();
balloon.x = 2048 / 2;
balloon.y = 1366; // Center vertically
game.addChild(balloon);
// Create ground
ground = new Ground();
ground.x = 0;
ground.y = 2732 - 200; // At bottom of screen
game.addChild(ground);
// Start background music
LK.playMusic('atmosphere');
// Track last collision state
var lastColliding = false;
// Track touch/drag state
var isDragging = false;
var lastTouchX = 0;
// Game input handling
game.down = function (x, y, obj) {
if (!gameStarted) {
gameStarted = true;
instructionTxt.alpha = 0;
}
if (!balloon.isPopped) {
balloon.jump();
isDragging = true;
lastTouchX = x;
}
};
game.up = function (x, y, obj) {
isDragging = false;
};
game.move = function (x, y, obj) {
if (isDragging && !balloon.isPopped) {
var deltaX = x - lastTouchX;
if (deltaX > 10) {
balloon.moveRight();
} else if (deltaX < -10) {
balloon.moveLeft();
}
lastTouchX = x;
}
};
// Main game update loop
game.update = function () {
if (gameStarted && !balloon.isPopped) {
// Update survival time and score
survivalTime += 1;
var score = Math.floor(survivalTime / 60); // Score based on seconds survived
LK.setScore(score);
scoreTxt.setText(score);
// Increase difficulty over time
if (survivalTime % 1800 === 0) {
// Every 30 seconds
difficultyMultiplier += 0.1;
balloon.gravity = 0.8 * difficultyMultiplier;
balloon.maxFallSpeed = 12 * difficultyMultiplier;
}
// Check collision with ground
var currentColliding = balloon.intersects(ground);
if (!lastColliding && currentColliding) {
// Balloon just hit the ground
balloon.pop();
// Flash screen red and show game over after a delay
LK.effects.flashScreen(0xff0000, 500);
LK.setTimeout(function () {
LK.showGameOver();
}, 800);
}
lastColliding = currentColliding;
// Keep balloon on screen (prevent going too high)
if (balloon.y < 100) {
balloon.y = 100;
balloon.velocityY = 0;
}
}
// Fade out instruction text when game starts
if (gameStarted && instructionTxt.alpha > 0) {
instructionTxt.alpha -= 0.02;
}
};