/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Fly = Container.expand(function () {
var self = Container.call(this);
// Use the updated fly asset (already set in Assets section)
// If the new fly image has a different anchor or size, adjust here:
var flyGraphics = self.attachAsset('fly', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.directionX = (Math.random() - 0.5) * 2;
self.directionY = (Math.random() - 0.5) * 2;
// For more accurate hitbox, store width/height for later use if needed
self.flyWidth = flyGraphics.width;
self.flyHeight = flyGraphics.height;
self.update = function () {
self.x += self.speed * self.directionX;
self.y += self.speed * self.directionY;
// Bounce off edges, using new fly size for boundaries
if (self.x < self.flyWidth / 2 + 10 || self.x > 2048 - self.flyWidth / 2 - 10) self.directionX *= -1;
// Prevent flies from going below the vertical center (1366)
var flyTopLimit = self.flyHeight / 2 + 10;
var flyBottomLimit = 1366 - self.flyHeight / 2 - 10;
if (self.y < flyTopLimit) {
self.y = flyTopLimit;
self.directionY *= -1;
}
if (self.y > flyBottomLimit) {
self.y = flyBottomLimit;
self.directionY *= -1;
}
// Flip fly image based on directionX
if (self.directionX < 0) {
flyGraphics.scaleX = 1; // Face left
} else {
flyGraphics.scaleX = -1; // Face right
}
};
return self;
});
var Frog = Container.expand(function () {
var self = Container.call(this);
var frogGraphics = self.attachAsset('frog', {
anchorX: 0.5,
anchorY: 0.5
});
self.canShoot = true;
self.tongue = null;
self.shootTongue = function (targetX, targetY) {
if (!self.canShoot) return;
self.canShoot = false;
self.tongue = self.addChild(LK.getAsset('tongue', {
anchorX: 0.5,
anchorY: 1.0
}));
// Position tongue at the mouth
// Position tongue at the mouth (visually, frog's mouth is a bit below the center of the image)
// Let's assume mouth is about 20% down from the top of the frog image
self.tongue.x = 0;
self.tongue.y = -frogGraphics.height * 0.18;
// Calculate distance and angle
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var angle = Math.atan2(dy, dx) + Math.PI / 2; // Add PI/2 because tongue asset is vertical
self.tongue.rotation = angle;
self.tongue.height = 0; // Start tongue retracted
// Track if a fly was hit during this tongue extension
self.tongue.flyWasHit = false;
// Extend tongue
tween(self.tongue, {
height: distance
}, {
duration: 300,
onFinish: function onFinish() {
// If tongue did not hit any fly, end the game
var missed = true;
if (self.tongue && self.tongue.flyWasHit === true) {
missed = false;
}
if (missed) {
// Play miss sound and show game over
if (typeof missSound !== "undefined") missSound.play();
LK.showGameOver();
return;
}
// Retract tongue
tween(self.tongue, {
height: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.removeChild(self.tongue);
self.tongue = null;
self.canShoot = true;
}
});
}
});
};
return self;
});
//Library for using the camera (the background becomes the user's camera video feed) and the microphone. It can access face coordinates for interactive play, as well detect microphone volume / voice interactions
// var facekit = LK.import('@upit/facekit.v1');
//Classes can only be defined here. You cannot create inline classes in the games code.
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Add arkaplan image as background, scaled to fill the game area
var bg = LK.getAsset('arkaplan', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(bg);
//Note game dimensions are 2048x2732
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.setText(LK.getScore());
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Highscore text for top right
var highscore = storage.highscore || 0;
var highscoreTxt = new Text2('Highscore: ' + highscore, {
size: 80,
fill: 0xFFFF00
});
highscoreTxt.anchor.set(1, 0); // right aligned, top
LK.gui.topRight.addChild(highscoreTxt);
var platform = game.addChild(new Platform());
platform.x = 2048 / 2;
// Only show the green part of the platform at the bottom.
// The green part is assumed to be the top 200px of the platform image.
// Position the platform so that only the top 200px is visible at the bottom of the screen.
platform.y = 2732 - 100; // Move platform so only green part is visible
var frog = game.addChild(new Frog());
// Kurbağayı platformun yeşil kısmının tam ortasına konumlandır, daha da aşağı indir
frog.x = platform.x;
// Platformun üst kenarı (görünür yeşil kısmın başladığı yer)
var greenTopY = platform.y - platform.height / 2;
// Yeşil kısmın yüksekliği 100px, ortası: greenTopY + 50
// Daha da aşağı indirmek için y değerini daha fazla artırıyoruz (ör: 30 yerine 60 yapıyoruz)
frog.y = greenTopY + 60;
var flies = [];
var flySpawnTimer;
var catchSound = LK.getSound('catchFly');
var missSound = LK.getSound('miss');
// Timer to increase all flies' speed every 5 seconds
var flySpeedIncreaseTimer = LK.setInterval(function () {
for (var i = 0; i < flies.length; i++) {
if (flies[i] && typeof flies[i].speed === "number") {
flies[i].speed += 0.5;
}
}
}, 5000);
function spawnFly() {
var newFly = new Fly();
// Spawn X as before
newFly.x = Math.random() * (2048 - 100) + 50;
// Spawn Y only in the upper half (above center)
var flySpawnTop = 50;
var flySpawnBottom = 1366 - 100; // 1366 is half of 2732, minus some margin
newFly.y = Math.random() * (flySpawnBottom - flySpawnTop) + flySpawnTop;
newFly.lastIntersecting = false;
flies.push(newFly);
game.addChild(newFly);
}
// Start spawning flies
LK.clearInterval(flySpawnTimer); // Stop the initial fly spawn timer
spawnFly(); // Spawn the first fly immediately
game.down = function (x, y, obj) {
// Shoot tongue towards touch location
frog.shootTongue(x, y);
};
game.update = function () {
// Update and check for collisions between tongue and flies
if (frog.tongue) {
for (var i = flies.length - 1; i >= 0; i--) {
var fly = flies[i];
// Check if fly is in the game area and not pending destruction
if (fly.parent === game) {
// Use bounding box intersection for more accurate hitbox
var tongueBounds = frog.tongue.getBounds();
var flyBounds = fly.getBounds();
// Optionally, shrink fly hitbox for new asset if needed (e.g. if new image has transparent border)
// Example: shrink by 10% on each side
var shrinkX = flyBounds.width * 0.1;
var shrinkY = flyBounds.height * 0.1;
var flyHitbox = {
x: flyBounds.x + shrinkX,
y: flyBounds.y + shrinkY,
width: flyBounds.width - 2 * shrinkX,
height: flyBounds.height - 2 * shrinkY
};
var currentIntersecting = tongueBounds.x < flyHitbox.x + flyHitbox.width && tongueBounds.x + tongueBounds.width > flyHitbox.x && tongueBounds.y < flyHitbox.y + flyHitbox.height && tongueBounds.y + tongueBounds.height > flyHitbox.y;
if (!fly.lastIntersecting && currentIntersecting) {
// Fly caught!
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
// Update highscore if needed
if (LK.getScore() > highscore) {
highscore = LK.getScore();
storage.highscore = highscore;
highscoreTxt.setText('Highscore: ' + highscore);
}
LK.stopMusic();
catchSound.play();
LK.setTimeout(function () {
LK.playMusic('bgMusic');
}, 500);
// Mark that the tongue hit a fly, so game over does not trigger
if (frog.tongue) {
frog.tongue.flyWasHit = true;
}
// Remove fly
fly.destroy();
flies.splice(i, 1);
// Spawn a new fly after a successful catch with a 0.5-second delay
LK.setTimeout(spawnFly, 500);
// Increase speed slightly for challenge
Fly.prototype.speed += 0.3;
continue; // Skip further checks for this fly
}
fly.lastIntersecting = currentIntersecting;
}
}
}
// Update all flies
for (var i = flies.length - 1; i >= 0; i--) {
var fly = flies[i];
if (fly.update) {
fly.update();
}
}
};
// Play background music
LK.playMusic('bgMusic'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Fly = Container.expand(function () {
var self = Container.call(this);
// Use the updated fly asset (already set in Assets section)
// If the new fly image has a different anchor or size, adjust here:
var flyGraphics = self.attachAsset('fly', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.directionX = (Math.random() - 0.5) * 2;
self.directionY = (Math.random() - 0.5) * 2;
// For more accurate hitbox, store width/height for later use if needed
self.flyWidth = flyGraphics.width;
self.flyHeight = flyGraphics.height;
self.update = function () {
self.x += self.speed * self.directionX;
self.y += self.speed * self.directionY;
// Bounce off edges, using new fly size for boundaries
if (self.x < self.flyWidth / 2 + 10 || self.x > 2048 - self.flyWidth / 2 - 10) self.directionX *= -1;
// Prevent flies from going below the vertical center (1366)
var flyTopLimit = self.flyHeight / 2 + 10;
var flyBottomLimit = 1366 - self.flyHeight / 2 - 10;
if (self.y < flyTopLimit) {
self.y = flyTopLimit;
self.directionY *= -1;
}
if (self.y > flyBottomLimit) {
self.y = flyBottomLimit;
self.directionY *= -1;
}
// Flip fly image based on directionX
if (self.directionX < 0) {
flyGraphics.scaleX = 1; // Face left
} else {
flyGraphics.scaleX = -1; // Face right
}
};
return self;
});
var Frog = Container.expand(function () {
var self = Container.call(this);
var frogGraphics = self.attachAsset('frog', {
anchorX: 0.5,
anchorY: 0.5
});
self.canShoot = true;
self.tongue = null;
self.shootTongue = function (targetX, targetY) {
if (!self.canShoot) return;
self.canShoot = false;
self.tongue = self.addChild(LK.getAsset('tongue', {
anchorX: 0.5,
anchorY: 1.0
}));
// Position tongue at the mouth
// Position tongue at the mouth (visually, frog's mouth is a bit below the center of the image)
// Let's assume mouth is about 20% down from the top of the frog image
self.tongue.x = 0;
self.tongue.y = -frogGraphics.height * 0.18;
// Calculate distance and angle
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var angle = Math.atan2(dy, dx) + Math.PI / 2; // Add PI/2 because tongue asset is vertical
self.tongue.rotation = angle;
self.tongue.height = 0; // Start tongue retracted
// Track if a fly was hit during this tongue extension
self.tongue.flyWasHit = false;
// Extend tongue
tween(self.tongue, {
height: distance
}, {
duration: 300,
onFinish: function onFinish() {
// If tongue did not hit any fly, end the game
var missed = true;
if (self.tongue && self.tongue.flyWasHit === true) {
missed = false;
}
if (missed) {
// Play miss sound and show game over
if (typeof missSound !== "undefined") missSound.play();
LK.showGameOver();
return;
}
// Retract tongue
tween(self.tongue, {
height: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.removeChild(self.tongue);
self.tongue = null;
self.canShoot = true;
}
});
}
});
};
return self;
});
//Library for using the camera (the background becomes the user's camera video feed) and the microphone. It can access face coordinates for interactive play, as well detect microphone volume / voice interactions
// var facekit = LK.import('@upit/facekit.v1');
//Classes can only be defined here. You cannot create inline classes in the games code.
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Add arkaplan image as background, scaled to fill the game area
var bg = LK.getAsset('arkaplan', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(bg);
//Note game dimensions are 2048x2732
var scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
scoreTxt.setText(LK.getScore());
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Highscore text for top right
var highscore = storage.highscore || 0;
var highscoreTxt = new Text2('Highscore: ' + highscore, {
size: 80,
fill: 0xFFFF00
});
highscoreTxt.anchor.set(1, 0); // right aligned, top
LK.gui.topRight.addChild(highscoreTxt);
var platform = game.addChild(new Platform());
platform.x = 2048 / 2;
// Only show the green part of the platform at the bottom.
// The green part is assumed to be the top 200px of the platform image.
// Position the platform so that only the top 200px is visible at the bottom of the screen.
platform.y = 2732 - 100; // Move platform so only green part is visible
var frog = game.addChild(new Frog());
// Kurbağayı platformun yeşil kısmının tam ortasına konumlandır, daha da aşağı indir
frog.x = platform.x;
// Platformun üst kenarı (görünür yeşil kısmın başladığı yer)
var greenTopY = platform.y - platform.height / 2;
// Yeşil kısmın yüksekliği 100px, ortası: greenTopY + 50
// Daha da aşağı indirmek için y değerini daha fazla artırıyoruz (ör: 30 yerine 60 yapıyoruz)
frog.y = greenTopY + 60;
var flies = [];
var flySpawnTimer;
var catchSound = LK.getSound('catchFly');
var missSound = LK.getSound('miss');
// Timer to increase all flies' speed every 5 seconds
var flySpeedIncreaseTimer = LK.setInterval(function () {
for (var i = 0; i < flies.length; i++) {
if (flies[i] && typeof flies[i].speed === "number") {
flies[i].speed += 0.5;
}
}
}, 5000);
function spawnFly() {
var newFly = new Fly();
// Spawn X as before
newFly.x = Math.random() * (2048 - 100) + 50;
// Spawn Y only in the upper half (above center)
var flySpawnTop = 50;
var flySpawnBottom = 1366 - 100; // 1366 is half of 2732, minus some margin
newFly.y = Math.random() * (flySpawnBottom - flySpawnTop) + flySpawnTop;
newFly.lastIntersecting = false;
flies.push(newFly);
game.addChild(newFly);
}
// Start spawning flies
LK.clearInterval(flySpawnTimer); // Stop the initial fly spawn timer
spawnFly(); // Spawn the first fly immediately
game.down = function (x, y, obj) {
// Shoot tongue towards touch location
frog.shootTongue(x, y);
};
game.update = function () {
// Update and check for collisions between tongue and flies
if (frog.tongue) {
for (var i = flies.length - 1; i >= 0; i--) {
var fly = flies[i];
// Check if fly is in the game area and not pending destruction
if (fly.parent === game) {
// Use bounding box intersection for more accurate hitbox
var tongueBounds = frog.tongue.getBounds();
var flyBounds = fly.getBounds();
// Optionally, shrink fly hitbox for new asset if needed (e.g. if new image has transparent border)
// Example: shrink by 10% on each side
var shrinkX = flyBounds.width * 0.1;
var shrinkY = flyBounds.height * 0.1;
var flyHitbox = {
x: flyBounds.x + shrinkX,
y: flyBounds.y + shrinkY,
width: flyBounds.width - 2 * shrinkX,
height: flyBounds.height - 2 * shrinkY
};
var currentIntersecting = tongueBounds.x < flyHitbox.x + flyHitbox.width && tongueBounds.x + tongueBounds.width > flyHitbox.x && tongueBounds.y < flyHitbox.y + flyHitbox.height && tongueBounds.y + tongueBounds.height > flyHitbox.y;
if (!fly.lastIntersecting && currentIntersecting) {
// Fly caught!
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
// Update highscore if needed
if (LK.getScore() > highscore) {
highscore = LK.getScore();
storage.highscore = highscore;
highscoreTxt.setText('Highscore: ' + highscore);
}
LK.stopMusic();
catchSound.play();
LK.setTimeout(function () {
LK.playMusic('bgMusic');
}, 500);
// Mark that the tongue hit a fly, so game over does not trigger
if (frog.tongue) {
frog.tongue.flyWasHit = true;
}
// Remove fly
fly.destroy();
flies.splice(i, 1);
// Spawn a new fly after a successful catch with a 0.5-second delay
LK.setTimeout(spawnFly, 500);
// Increase speed slightly for challenge
Fly.prototype.speed += 0.3;
continue; // Skip further checks for this fly
}
fly.lastIntersecting = currentIntersecting;
}
}
}
// Update all flies
for (var i = flies.length - 1; i >= 0; i--) {
var fly = flies[i];
if (fly.update) {
fly.update();
}
}
};
// Play background music
LK.playMusic('bgMusic');