/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Cloud = Container.expand(function () {
var self = Container.call(this);
// Properties
self.speed = 1;
// Create cloud graphics
var cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
// Update method
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Dino = Container.expand(function () {
var self = Container.call(this);
// Properties
self.isJumping = false;
self.isDucking = false;
self.jumpVelocity = 0;
self.gravity = 0.8;
self.groundY = 0; // Will be set when positioning
self.walkFrame = 0; // Current animation frame
self.walkFrameCount = 2; // Total number of walking frames
self.frameChangeInterval = 10; // Ticks between frame changes
self.frameCounter = 0; // Counter for animation timing
// Legs animation
self.leftLeg = null;
self.rightLeg = null;
// Create dino graphics
var dinoGraphics = self.attachAsset('dino', {
anchorX: 0.5,
anchorY: 1.0,
interactive: true
});
// Create legs
self.leftLeg = LK.getAsset('ground', {
width: 20,
height: 40,
anchorX: 0.5,
anchorY: 0,
color: 0x333333
});
self.rightLeg = LK.getAsset('ground', {
width: 20,
height: 40,
anchorX: 0.5,
anchorY: 0,
color: 0x333333
});
self.addChild(self.leftLeg);
self.addChild(self.rightLeg);
// Position legs
self.leftLeg.x = -20;
self.leftLeg.y = -10;
self.rightLeg.x = 20;
self.rightLeg.y = -10;
// Handle click/tap directly on the dinosaur
self.down = function (x, y, obj) {
self.jump();
};
// Jump method
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpVelocity = -30; // Increased from -25 to -30 for even higher jumps
LK.getSound('jump').play();
}
};
// Duck method
self.duck = function () {
if (!self.isDucking && !self.isJumping) {
self.isDucking = true;
dinoGraphics.height = 50; // Half height when ducking
}
};
// Stop ducking
self.stopDucking = function () {
if (self.isDucking) {
self.isDucking = false;
dinoGraphics.height = 100; // Normal height
}
};
// Reset dino state
self.reset = function () {
self.isJumping = false;
self.isDucking = false;
self.jumpVelocity = 0;
self.y = self.groundY;
dinoGraphics.height = 100;
self.walkFrame = 0;
self.frameCounter = 0;
dinoGraphics.scaleY = 1.0;
dinoGraphics.y = 0;
// Reset leg positions
self.leftLeg.y = -10;
self.leftLeg.height = 40;
self.rightLeg.y = -10;
self.rightLeg.height = 40;
};
// Update method
self.update = function () {
if (self.isJumping) {
self.y += self.jumpVelocity;
self.jumpVelocity += self.gravity;
// Check if landed
if (self.y >= self.groundY) {
self.y = self.groundY;
self.isJumping = false;
self.jumpVelocity = 0;
}
} else if (!self.isDucking) {
// Walking animation when not jumping or ducking
self.frameCounter++;
if (self.frameCounter >= self.frameChangeInterval) {
self.frameCounter = 0;
self.walkFrame = (self.walkFrame + 1) % self.walkFrameCount;
// Animate the legs by slightly changing the height and moving legs
if (self.walkFrame === 0) {
dinoGraphics.scaleY = 1.0;
dinoGraphics.y = 0;
// Leg animation - one leg forward, one back
self.leftLeg.y = -10;
self.leftLeg.height = 40;
self.rightLeg.y = 0;
self.rightLeg.height = 30;
} else {
dinoGraphics.scaleY = 0.95;
dinoGraphics.y = 5; // Slight y offset to make it look like the dino is taking a step
// Leg animation - switch positions
self.leftLeg.y = 0;
self.leftLeg.height = 30;
self.rightLeg.y = -10;
self.rightLeg.height = 40;
}
}
}
};
// Hit box for collision detection
self.getHitBox = function () {
return {
x: self.x - dinoGraphics.width / 2,
y: self.y - dinoGraphics.height,
width: dinoGraphics.width,
height: dinoGraphics.height
};
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
// Properties
self.type = type || 'cactus'; // 'cactus' or 'pterodactyl'
self.speed = 8;
// Create obstacle graphics
var graphics;
if (self.type === 'cactus') {
graphics = self.attachAsset('cactus', {
anchorX: 0.5,
anchorY: 1.0
});
} else {
graphics = self.attachAsset('pterodactyl', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Update method
self.update = function () {
self.x -= self.speed;
};
// Increase speed method
self.setSpeed = function (newSpeed) {
self.speed = newSpeed;
};
// Hit box for collision detection
self.getHitBox = function () {
if (self.type === 'cactus') {
return {
x: self.x - graphics.width / 2,
y: self.y - graphics.height,
width: graphics.width,
height: graphics.height
};
} else {
return {
x: self.x - graphics.width / 2,
y: self.y - graphics.height / 2,
width: graphics.width,
height: graphics.height
};
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xFFFFFF
});
/****
* Game Code
****/
// Game state
var gameRunning = false;
var gameSpeed = 8;
var score = 0;
var highScore = storage.highScore || 0;
var lastObstacleTime = 0;
var nightMode = false;
var nextSpeedIncrease = 500;
var nextCloudTime = 0;
// Game objects
var dino;
var ground;
var obstacles = [];
var clouds = [];
// UI elements
var scoreTxt;
var highScoreTxt;
var tapToStartTxt;
// Ground
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
});
ground.y = 2732 - 200; // Position ground near the bottom
game.addChild(ground);
// Score text
scoreTxt = new Text2('0', {
size: 60,
fill: 0x000000
});
scoreTxt.anchor.set(1.0, 0);
scoreTxt.x = 2048 - 30;
scoreTxt.y = 30;
game.addChild(scoreTxt);
// High score text
highScoreTxt = new Text2('HI: ' + highScore, {
size: 60,
fill: 0x888888
});
highScoreTxt.anchor.set(1.0, 0);
highScoreTxt.x = 2048 - 30;
highScoreTxt.y = 100;
game.addChild(highScoreTxt);
// Tap to start text
tapToStartTxt = new Text2('TAP TO START', {
size: 80,
fill: 0x000000
});
tapToStartTxt.anchor.set(0.5, 0.5);
tapToStartTxt.x = 2048 / 2;
tapToStartTxt.y = 2732 / 2;
game.addChild(tapToStartTxt);
// Initialize dino
dino = new Dino();
dino.x = 300;
dino.groundY = ground.y;
dino.y = dino.groundY;
game.addChild(dino);
// Start the game
function startGame() {
if (!gameRunning) {
gameRunning = true;
gameSpeed = 8;
score = 0;
nextSpeedIncrease = 500;
// Reset dino
dino.reset();
// Clear obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
}
obstacles = [];
// Clear clouds
for (var i = clouds.length - 1; i >= 0; i--) {
clouds[i].destroy();
}
clouds = [];
// Update UI
tapToStartTxt.visible = false;
scoreTxt.setText('0');
// Set background to day mode
game.setBackgroundColor(0xFFFFFF);
nightMode = false;
}
}
// Collision detection
function checkCollision(dinoHitBox, obstacleHitBox) {
return !(dinoHitBox.x + dinoHitBox.width < obstacleHitBox.x || dinoHitBox.x > obstacleHitBox.x + obstacleHitBox.width || dinoHitBox.y + dinoHitBox.height < obstacleHitBox.y || dinoHitBox.y > obstacleHitBox.y + obstacleHitBox.height);
}
// Spawn a new obstacle
function spawnObstacle() {
var type = Math.random() > 0.3 ? 'cactus' : 'pterodactyl';
var obstacle = new Obstacle(type);
// Position it
obstacle.x = 2048 + 100;
if (type === 'cactus') {
obstacle.y = ground.y;
} else {
// Pterodactyls can be at different heights
var height = Math.random() > 0.5 ? 200 : 300;
obstacle.y = ground.y - height;
}
obstacle.setSpeed(gameSpeed);
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn a new cloud
function spawnCloud() {
var cloud = new Cloud();
cloud.x = 2048 + 100;
cloud.y = ground.y - 300 - Math.random() * 200;
clouds.push(cloud);
game.addChild(cloud);
}
// Game over
function gameOver() {
gameRunning = false;
LK.getSound('collision').play();
// Update high score
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('HI: ' + highScore);
}
tapToStartTxt.setText('GAME OVER - TAP TO RESTART');
tapToStartTxt.visible = true;
// Show game over screen
LK.showGameOver();
}
// Game input handlers
game.down = function (x, y, obj) {
if (!gameRunning) {
startGame();
} else {
// Jump when clicking anywhere on screen
dino.jump();
}
};
game.up = function (x, y, obj) {
// Stop ducking when released
if (gameRunning) {
dino.stopDucking();
}
};
// Game update loop
game.update = function () {
if (!gameRunning) {
return;
}
// Update score
score++;
if (score % 10 === 0) {
scoreTxt.setText(Math.floor(score / 10));
}
// Day/night transition every 1000 points
if (score % 1000 === 0 && score > 0) {
nightMode = !nightMode;
game.setBackgroundColor(nightMode ? 0x333333 : 0xFFFFFF);
scoreTxt.setFill(nightMode ? "#FFFFFF" : "#000000");
// Play milestone sound
LK.getSound('milestone').play();
}
// Increase speed every 500 points
if (score >= nextSpeedIncrease) {
gameSpeed += 0.5;
nextSpeedIncrease += 500;
// Update speed of existing obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].setSpeed(gameSpeed);
}
}
// Spawn obstacles
if (LK.ticks - lastObstacleTime > 60 + Math.random() * 60) {
spawnObstacle();
lastObstacleTime = LK.ticks;
}
// Spawn clouds
if (LK.ticks - nextCloudTime > 180) {
spawnCloud();
nextCloudTime = LK.ticks + Math.random() * 180;
}
// Update dino
dino.update();
// Collision detection and update for obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].update();
// Check collision with dino
var dinoHitBox = dino.getHitBox();
var obstacleHitBox = obstacles[i].getHitBox();
if (checkCollision(dinoHitBox, obstacleHitBox)) {
gameOver();
return;
}
// Remove obstacles that are off-screen
if (obstacles[i].x < -100) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Update clouds
for (var i = clouds.length - 1; i >= 0; i--) {
clouds[i].update();
// Remove clouds that are off-screen
if (clouds[i].x < -150) {
clouds[i].destroy();
clouds.splice(i, 1);
}
}
};
// Play background music
LK.playMusic('bgMusic', {
volume: 0.3
}); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Cloud = Container.expand(function () {
var self = Container.call(this);
// Properties
self.speed = 1;
// Create cloud graphics
var cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
// Update method
self.update = function () {
self.x -= self.speed;
};
return self;
});
var Dino = Container.expand(function () {
var self = Container.call(this);
// Properties
self.isJumping = false;
self.isDucking = false;
self.jumpVelocity = 0;
self.gravity = 0.8;
self.groundY = 0; // Will be set when positioning
self.walkFrame = 0; // Current animation frame
self.walkFrameCount = 2; // Total number of walking frames
self.frameChangeInterval = 10; // Ticks between frame changes
self.frameCounter = 0; // Counter for animation timing
// Legs animation
self.leftLeg = null;
self.rightLeg = null;
// Create dino graphics
var dinoGraphics = self.attachAsset('dino', {
anchorX: 0.5,
anchorY: 1.0,
interactive: true
});
// Create legs
self.leftLeg = LK.getAsset('ground', {
width: 20,
height: 40,
anchorX: 0.5,
anchorY: 0,
color: 0x333333
});
self.rightLeg = LK.getAsset('ground', {
width: 20,
height: 40,
anchorX: 0.5,
anchorY: 0,
color: 0x333333
});
self.addChild(self.leftLeg);
self.addChild(self.rightLeg);
// Position legs
self.leftLeg.x = -20;
self.leftLeg.y = -10;
self.rightLeg.x = 20;
self.rightLeg.y = -10;
// Handle click/tap directly on the dinosaur
self.down = function (x, y, obj) {
self.jump();
};
// Jump method
self.jump = function () {
if (!self.isJumping) {
self.isJumping = true;
self.jumpVelocity = -30; // Increased from -25 to -30 for even higher jumps
LK.getSound('jump').play();
}
};
// Duck method
self.duck = function () {
if (!self.isDucking && !self.isJumping) {
self.isDucking = true;
dinoGraphics.height = 50; // Half height when ducking
}
};
// Stop ducking
self.stopDucking = function () {
if (self.isDucking) {
self.isDucking = false;
dinoGraphics.height = 100; // Normal height
}
};
// Reset dino state
self.reset = function () {
self.isJumping = false;
self.isDucking = false;
self.jumpVelocity = 0;
self.y = self.groundY;
dinoGraphics.height = 100;
self.walkFrame = 0;
self.frameCounter = 0;
dinoGraphics.scaleY = 1.0;
dinoGraphics.y = 0;
// Reset leg positions
self.leftLeg.y = -10;
self.leftLeg.height = 40;
self.rightLeg.y = -10;
self.rightLeg.height = 40;
};
// Update method
self.update = function () {
if (self.isJumping) {
self.y += self.jumpVelocity;
self.jumpVelocity += self.gravity;
// Check if landed
if (self.y >= self.groundY) {
self.y = self.groundY;
self.isJumping = false;
self.jumpVelocity = 0;
}
} else if (!self.isDucking) {
// Walking animation when not jumping or ducking
self.frameCounter++;
if (self.frameCounter >= self.frameChangeInterval) {
self.frameCounter = 0;
self.walkFrame = (self.walkFrame + 1) % self.walkFrameCount;
// Animate the legs by slightly changing the height and moving legs
if (self.walkFrame === 0) {
dinoGraphics.scaleY = 1.0;
dinoGraphics.y = 0;
// Leg animation - one leg forward, one back
self.leftLeg.y = -10;
self.leftLeg.height = 40;
self.rightLeg.y = 0;
self.rightLeg.height = 30;
} else {
dinoGraphics.scaleY = 0.95;
dinoGraphics.y = 5; // Slight y offset to make it look like the dino is taking a step
// Leg animation - switch positions
self.leftLeg.y = 0;
self.leftLeg.height = 30;
self.rightLeg.y = -10;
self.rightLeg.height = 40;
}
}
}
};
// Hit box for collision detection
self.getHitBox = function () {
return {
x: self.x - dinoGraphics.width / 2,
y: self.y - dinoGraphics.height,
width: dinoGraphics.width,
height: dinoGraphics.height
};
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
// Properties
self.type = type || 'cactus'; // 'cactus' or 'pterodactyl'
self.speed = 8;
// Create obstacle graphics
var graphics;
if (self.type === 'cactus') {
graphics = self.attachAsset('cactus', {
anchorX: 0.5,
anchorY: 1.0
});
} else {
graphics = self.attachAsset('pterodactyl', {
anchorX: 0.5,
anchorY: 0.5
});
}
// Update method
self.update = function () {
self.x -= self.speed;
};
// Increase speed method
self.setSpeed = function (newSpeed) {
self.speed = newSpeed;
};
// Hit box for collision detection
self.getHitBox = function () {
if (self.type === 'cactus') {
return {
x: self.x - graphics.width / 2,
y: self.y - graphics.height,
width: graphics.width,
height: graphics.height
};
} else {
return {
x: self.x - graphics.width / 2,
y: self.y - graphics.height / 2,
width: graphics.width,
height: graphics.height
};
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xFFFFFF
});
/****
* Game Code
****/
// Game state
var gameRunning = false;
var gameSpeed = 8;
var score = 0;
var highScore = storage.highScore || 0;
var lastObstacleTime = 0;
var nightMode = false;
var nextSpeedIncrease = 500;
var nextCloudTime = 0;
// Game objects
var dino;
var ground;
var obstacles = [];
var clouds = [];
// UI elements
var scoreTxt;
var highScoreTxt;
var tapToStartTxt;
// Ground
ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0
});
ground.y = 2732 - 200; // Position ground near the bottom
game.addChild(ground);
// Score text
scoreTxt = new Text2('0', {
size: 60,
fill: 0x000000
});
scoreTxt.anchor.set(1.0, 0);
scoreTxt.x = 2048 - 30;
scoreTxt.y = 30;
game.addChild(scoreTxt);
// High score text
highScoreTxt = new Text2('HI: ' + highScore, {
size: 60,
fill: 0x888888
});
highScoreTxt.anchor.set(1.0, 0);
highScoreTxt.x = 2048 - 30;
highScoreTxt.y = 100;
game.addChild(highScoreTxt);
// Tap to start text
tapToStartTxt = new Text2('TAP TO START', {
size: 80,
fill: 0x000000
});
tapToStartTxt.anchor.set(0.5, 0.5);
tapToStartTxt.x = 2048 / 2;
tapToStartTxt.y = 2732 / 2;
game.addChild(tapToStartTxt);
// Initialize dino
dino = new Dino();
dino.x = 300;
dino.groundY = ground.y;
dino.y = dino.groundY;
game.addChild(dino);
// Start the game
function startGame() {
if (!gameRunning) {
gameRunning = true;
gameSpeed = 8;
score = 0;
nextSpeedIncrease = 500;
// Reset dino
dino.reset();
// Clear obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
}
obstacles = [];
// Clear clouds
for (var i = clouds.length - 1; i >= 0; i--) {
clouds[i].destroy();
}
clouds = [];
// Update UI
tapToStartTxt.visible = false;
scoreTxt.setText('0');
// Set background to day mode
game.setBackgroundColor(0xFFFFFF);
nightMode = false;
}
}
// Collision detection
function checkCollision(dinoHitBox, obstacleHitBox) {
return !(dinoHitBox.x + dinoHitBox.width < obstacleHitBox.x || dinoHitBox.x > obstacleHitBox.x + obstacleHitBox.width || dinoHitBox.y + dinoHitBox.height < obstacleHitBox.y || dinoHitBox.y > obstacleHitBox.y + obstacleHitBox.height);
}
// Spawn a new obstacle
function spawnObstacle() {
var type = Math.random() > 0.3 ? 'cactus' : 'pterodactyl';
var obstacle = new Obstacle(type);
// Position it
obstacle.x = 2048 + 100;
if (type === 'cactus') {
obstacle.y = ground.y;
} else {
// Pterodactyls can be at different heights
var height = Math.random() > 0.5 ? 200 : 300;
obstacle.y = ground.y - height;
}
obstacle.setSpeed(gameSpeed);
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn a new cloud
function spawnCloud() {
var cloud = new Cloud();
cloud.x = 2048 + 100;
cloud.y = ground.y - 300 - Math.random() * 200;
clouds.push(cloud);
game.addChild(cloud);
}
// Game over
function gameOver() {
gameRunning = false;
LK.getSound('collision').play();
// Update high score
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('HI: ' + highScore);
}
tapToStartTxt.setText('GAME OVER - TAP TO RESTART');
tapToStartTxt.visible = true;
// Show game over screen
LK.showGameOver();
}
// Game input handlers
game.down = function (x, y, obj) {
if (!gameRunning) {
startGame();
} else {
// Jump when clicking anywhere on screen
dino.jump();
}
};
game.up = function (x, y, obj) {
// Stop ducking when released
if (gameRunning) {
dino.stopDucking();
}
};
// Game update loop
game.update = function () {
if (!gameRunning) {
return;
}
// Update score
score++;
if (score % 10 === 0) {
scoreTxt.setText(Math.floor(score / 10));
}
// Day/night transition every 1000 points
if (score % 1000 === 0 && score > 0) {
nightMode = !nightMode;
game.setBackgroundColor(nightMode ? 0x333333 : 0xFFFFFF);
scoreTxt.setFill(nightMode ? "#FFFFFF" : "#000000");
// Play milestone sound
LK.getSound('milestone').play();
}
// Increase speed every 500 points
if (score >= nextSpeedIncrease) {
gameSpeed += 0.5;
nextSpeedIncrease += 500;
// Update speed of existing obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].setSpeed(gameSpeed);
}
}
// Spawn obstacles
if (LK.ticks - lastObstacleTime > 60 + Math.random() * 60) {
spawnObstacle();
lastObstacleTime = LK.ticks;
}
// Spawn clouds
if (LK.ticks - nextCloudTime > 180) {
spawnCloud();
nextCloudTime = LK.ticks + Math.random() * 180;
}
// Update dino
dino.update();
// Collision detection and update for obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].update();
// Check collision with dino
var dinoHitBox = dino.getHitBox();
var obstacleHitBox = obstacles[i].getHitBox();
if (checkCollision(dinoHitBox, obstacleHitBox)) {
gameOver();
return;
}
// Remove obstacles that are off-screen
if (obstacles[i].x < -100) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
// Update clouds
for (var i = clouds.length - 1; i >= 0; i--) {
clouds[i].update();
// Remove clouds that are off-screen
if (clouds[i].x < -150) {
clouds[i].destroy();
clouds.splice(i, 1);
}
}
};
// Play background music
LK.playMusic('bgMusic', {
volume: 0.3
});