/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Character class (player or AI)
var Character = Container.expand(function () {
var self = Container.call(this);
// Use a food asset as character icon for now
var charAsset = self.attachAsset('food1', {
anchorX: 0.5,
anchorY: 0.5
});
self.isAI = false;
self.targetFood = null;
self.speed = 12; // AI speed
self.playerSpeed = 16; // Player walking speed
self.walkingToFood = false;
self.walkTarget = null;
self.update = function () {
// AI walking logic (unchanged)
if (self.isAI && self.targetFood && !self.targetFood.isDragging) {
var dx = self.targetFood.x - self.x;
var dy = self.targetFood.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.x += dx / dist * Math.min(self.speed, dist);
self.y += dy / dist * Math.min(self.speed, dist);
} else {
// "Pick up" the food if close enough
if (!self.targetFood.isDragging && !draggedFood) {
self.targetFood.isDragging = true;
draggedFood = self.targetFood;
self.targetFood.dragOffsetX = 0;
self.targetFood.dragOffsetY = 0;
self.targetFood.aiOwner = self;
}
}
}
// Player walking logic
if (!self.isAI && self.walkingToFood && self.walkTarget && !self.walkTarget.isDragging) {
var dx = self.walkTarget.x - self.x;
var dy = self.walkTarget.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.x += dx / dist * Math.min(self.playerSpeed, dist);
self.y += dy / dist * Math.min(self.playerSpeed, dist);
} else {
// Arrived at food, start dragging
if (!self.walkTarget.isDragging && !draggedFood) {
self.walkTarget.isDragging = true;
draggedFood = self.walkTarget;
self.walkTarget.dragOffsetX = 0;
self.walkTarget.dragOffsetY = 0;
self.walkTarget.aiOwner = null;
}
self.walkingToFood = false;
self.walkTarget = null;
}
}
};
return self;
});
// Food class
var Food = Container.expand(function () {
var self = Container.call(this);
// Randomly pick a food type (expanded for more variety)
var foodTypes = ['food1', 'food2', 'food3', 'food1', 'food2', 'food3', 'food1', 'food2', 'food3', 'food1', 'food2', 'food3'];
var typeIndex = Math.floor(Math.random() * foodTypes.length);
var foodAsset = self.attachAsset(foodTypes[typeIndex], {
anchorX: 0.5,
anchorY: 0.5
});
// Used for drag logic
self.isDragging = false;
self.dragOffsetX = 0;
self.dragOffsetY = 0;
// Used for collision detection
self.update = function () {
// No movement unless being dragged
};
// Down event for starting drag
self.down = function (x, y, obj) {
if (draggedFood) return; // Only one drag at a time
self.isDragging = true;
draggedFood = self;
// Offset for smooth dragging
self.dragOffsetX = self.x - x;
self.dragOffsetY = self.y - y;
};
// Up event for releasing drag
self.up = function (x, y, obj) {
if (!self.isDragging) return;
self.isDragging = false;
draggedFood = null;
// On release, check if inside basket
if (self.intersects(basket)) {
// Success!
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
foodsDeliveredThisLevel++;
// Animate food into basket and remove, with feedback
// Add a fun bounce before disappearing
tween(self, {
x: basket.x,
y: basket.y - 80,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: basket.y,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.1
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.effects.flashObject(basket, 0x00ff00, 300);
self.destroy();
foods.splice(foods.indexOf(self), 1);
// Only spawn new food if not at max for this level
if (foods.length < foodsPerLevel) {
spawnFood();
}
}
});
}
});
} else {
// If not in basket, animate back to shelf
tween(self, {
x: self.startX,
y: self.startY
}, {
duration: 250,
easing: tween.easeOut
});
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf5f5dc // Light beige, market-like
});
/****
* Game Code
****/
// --- Game variables ---
// Market shelf (raf) - horizontal box
// Food items (3 types for variety)
// Basket (sepet)
var shelfY = 500; // Y position of shelf
var basketY = 2400; // Y position of basket
var foods = [];
var draggedFood = null;
var basket = null;
var shelf = null;
// Characters
var playerChar = null;
var aiChar = null;
// --- Level system ---
var level = 1;
var maxLevel = 10;
var foodsPerLevel = 3;
var foodsDeliveredThisLevel = 0;
var aiBaseSpeed = 12;
var playerBaseSpeed = 16;
var aiSpeedIncrease = 2;
var playerSpeedIncrease = 1.5;
var levelTxt = null;
// --- GUI: Score ---
var scoreTxt = new Text2('0', {
size: 120,
fill: "#222"
});
scoreTxt.anchor.set(0.5, 0);
// --- Add score text to GUI
LK.gui.top.addChild(scoreTxt);
// --- GUI: Level ---
levelTxt = new Text2('Seviye: 1', {
size: 80,
fill: "#444"
});
levelTxt.anchor.set(0.5, 0);
levelTxt.y = 130;
LK.gui.top.addChild(levelTxt);
// --- Add shelf ---
shelf = LK.getAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: shelfY
});
game.addChild(shelf);
// --- Add basket ---
basket = LK.getAsset('basket', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: basketY
});
game.addChild(basket);
// --- Add player character ---
playerChar = new Character();
playerChar.x = 2048 / 2 - 300;
playerChar.y = basketY + 120;
playerChar.isAI = false;
playerChar.playerSpeed = playerBaseSpeed;
game.addChild(playerChar);
// --- Add AI character ---
aiChar = new Character();
aiChar.x = 2048 / 2 + 300;
aiChar.y = basketY + 120;
aiChar.isAI = true;
aiChar.speed = aiBaseSpeed;
game.addChild(aiChar);
// --- Spawn food ---
for (var i = 0; i < foodsPerLevel; i++) {
spawnFood();
}
game.inputEnabled = true;
// --- Main Menu Overlay ---
var mainMenuOverlay = new Container();
mainMenuOverlay.zIndex = 1000; // Ensure on top
// Semi-transparent background
var menuBg = LK.getAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 1800,
height: 1200,
color: 0xffffff
});
menuBg.alpha = 0.92;
mainMenuOverlay.addChild(menuBg);
// Title
var titleTxt = new Text2('MARKET OYUNU', {
size: 180,
fill: 0xB84C00
});
titleTxt.anchor.set(0.5, 0);
titleTxt.x = 2048 / 2;
titleTxt.y = 2732 / 2 - 420;
mainMenuOverlay.addChild(titleTxt);
// Dentist mode info on menu if active
if (game && game.dentistModeActive) {
var dentistMenuTxt = new Text2('DİŞÇİ MODU AKTİF!', {
size: 100,
fill: 0x00BFFF
});
dentistMenuTxt.anchor.set(0.5, 0);
dentistMenuTxt.x = 2048 / 2;
dentistMenuTxt.y = titleTxt.y + 200;
mainMenuOverlay.addChild(dentistMenuTxt);
}
// Start Button
var startBtn = LK.getAsset('food1', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 80,
scaleX: 1.2,
scaleY: 1.2
});
mainMenuOverlay.addChild(startBtn);
var startBtnTxt = new Text2('BAŞLA', {
size: 110,
fill: "#fff"
});
startBtnTxt.anchor.set(0.5, 0.5);
startBtnTxt.x = startBtn.x;
startBtnTxt.y = startBtn.y;
mainMenuOverlay.addChild(startBtnTxt);
// Food Gallery Button
var galleryBtn = LK.getAsset('food2', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 180,
scaleX: 1.1,
scaleY: 1.1
});
mainMenuOverlay.addChild(galleryBtn);
var galleryBtnTxt = new Text2('YİYECEKLER', {
size: 90,
fill: "#fff"
});
galleryBtnTxt.anchor.set(0.5, 0.5);
galleryBtnTxt.x = galleryBtn.x;
galleryBtnTxt.y = galleryBtn.y;
mainMenuOverlay.addChild(galleryBtnTxt);
// Food Gallery Overlay (hidden by default)
var foodGalleryOverlay = new Container();
foodGalleryOverlay.zIndex = 1100;
foodGalleryOverlay.visible = false;
var galleryBg = LK.getAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 1600,
height: 1000,
color: 0xffffff
});
galleryBg.alpha = 0.97;
foodGalleryOverlay.addChild(galleryBg);
var galleryTitle = new Text2('YİYECEKLER', {
size: 120,
fill: 0xB84C00
});
galleryTitle.anchor.set(0.5, 0);
galleryTitle.x = 2048 / 2;
galleryTitle.y = 2732 / 2 - 420;
foodGalleryOverlay.addChild(galleryTitle);
// Show all food types in a row (expanded)
var galleryFoodTypes = game && game.dentistModeActive ? ['food2', 'food2', 'food2', 'food2', 'food2', 'food2'] : ['food1', 'food2', 'food3', 'food1', 'food2', 'food3'];
for (var i = 0; i < galleryFoodTypes.length; i++) {
var fx = 2048 / 2 - 750 + i * 300;
var fy = 2732 / 2 - 100;
var foodIcon = LK.getAsset(galleryFoodTypes[i], {
anchorX: 0.5,
anchorY: 0.5,
x: fx,
y: fy,
scaleX: 1.3,
scaleY: 1.3
});
foodGalleryOverlay.addChild(foodIcon);
}
// Close Gallery Button
var closeGalleryBtn = LK.getAsset('food3', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 320,
scaleX: 1,
scaleY: 1
});
foodGalleryOverlay.addChild(closeGalleryBtn);
var closeGalleryTxt = new Text2('KAPAT', {
size: 80,
fill: "#fff"
});
closeGalleryTxt.anchor.set(0.5, 0.5);
closeGalleryTxt.x = closeGalleryBtn.x;
closeGalleryTxt.y = closeGalleryBtn.y;
foodGalleryOverlay.addChild(closeGalleryTxt);
// Add overlays to game
game.addChild(mainMenuOverlay);
game.addChild(foodGalleryOverlay);
// Block input until start
game.inputEnabled = false;
// Start button logic
startBtn.down = function (x, y, obj) {
mainMenuOverlay.visible = false;
foodGalleryOverlay.visible = false;
game.inputEnabled = true;
};
// Gallery button logic
galleryBtn.down = function (x, y, obj) {
foodGalleryOverlay.visible = true;
mainMenuOverlay.visible = false;
};
// Close gallery logic
closeGalleryBtn.down = function (x, y, obj) {
foodGalleryOverlay.visible = false;
mainMenuOverlay.visible = true;
};
// --- Add shelf, basket, characters, and foods only after game start! ---
// --- Spawn food ---
function spawnFood() {
// Place food randomly along the shelf, but not overlapping with other foods
var maxTries = 10;
var placed = false;
var food = null;
while (!placed && maxTries-- > 0) {
if (game.dentistModeActive) {
// Only spawn 'food2' in dentist mode
food = new Food();
// Replace asset with 'food2'
if (food.children && food.children[0]) {
var oldAsset = food.children[0];
food.removeChild(oldAsset);
var newAsset = food.attachAsset('food2', {
anchorX: 0.5,
anchorY: 0.5
});
}
} else {
food = new Food();
}
// Random X within shelf width, with margin
var margin = 120;
var minX = shelf.x - shelf.width / 2 + margin;
var maxX = shelf.x + shelf.width / 2 - margin;
food.x = Math.floor(minX + Math.random() * (maxX - minX));
food.y = shelf.y - 100; // Just above shelf
food.startX = food.x;
food.startY = food.y;
// Check overlap with other foods
var overlap = false;
for (var i = 0; i < foods.length; i++) {
if (food.intersects(foods[i])) {
overlap = true;
break;
}
}
if (!overlap) {
placed = true;
}
}
if (food) {
foods.push(food);
game.addChild(food);
}
}
// --- Drag logic ---
game.move = function (x, y, obj) {
if (!game.inputEnabled) return;
if (draggedFood && draggedFood.isDragging) {
// Move food with finger, but clamp inside game area
var nx = x + draggedFood.dragOffsetX;
var ny = y + draggedFood.dragOffsetY;
// Clamp to game area
nx = Math.max(draggedFood.width / 2, Math.min(2048 - draggedFood.width / 2, nx));
ny = Math.max(draggedFood.height / 2, Math.min(2732 - draggedFood.height / 2, ny));
draggedFood.x = nx;
draggedFood.y = ny;
// Check collision with other foods (not self) or shelf
for (var i = 0; i < foods.length; i++) {
var f = foods[i];
if (f !== draggedFood && draggedFood.intersects(f)) {
// Fail: touched another food
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// Check collision with shelf (if not above shelf)
if (draggedFood.y > shelf.y - shelf.height / 2 - draggedFood.height / 2 && draggedFood.y < shelf.y + shelf.height / 2 + draggedFood.height / 2 && Math.abs(draggedFood.x - shelf.x) < shelf.width / 2 + draggedFood.width / 2) {
// Fail: touched shelf
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
};
// Down: start drag if on a food
game.down = function (x, y, obj) {
if (!game.inputEnabled) return;
// Find topmost food under pointer
for (var i = foods.length - 1; i >= 0; i--) {
var f = foods[i];
// Simple hit test
var dx = x - f.x;
var dy = y - f.y;
var r = Math.max(f.width, f.height) / 2;
if (dx * dx + dy * dy < r * r) {
// Instead of direct drag, walk to food first
if (!draggedFood && !f.isDragging) {
playerChar.walkingToFood = true;
playerChar.walkTarget = f;
}
break;
}
}
};
// Up: release drag
game.up = function (x, y, obj) {
if (!game.inputEnabled) return;
if (draggedFood) {
draggedFood.up(x, y, obj);
}
};
// --- Game update (not used for movement, but could be for future) ---
game.update = function () {
if (!game.inputEnabled) return;
// Update characters
if (playerChar) playerChar.update();
if (aiChar) aiChar.update();
// AI logic: if not dragging, pick a food to deliver
if (aiChar && !draggedFood) {
// Find a food not being dragged
for (var i = 0; i < foods.length; i++) {
if (!foods[i].isDragging) {
aiChar.targetFood = foods[i];
break;
}
}
}
// If AI is dragging a food, move it toward the basket
if (draggedFood && draggedFood.aiOwner === aiChar) {
// Move food toward basket
var dx = basket.x - draggedFood.x;
var dy = basket.y - draggedFood.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// AI speed increases with level
var aiSpeed = aiBaseSpeed + (level - 1) * aiSpeedIncrease;
if (dist > 20) {
draggedFood.x += dx / dist * Math.min(aiSpeed, dist);
draggedFood.y += dy / dist * Math.min(aiSpeed, dist);
} else {
// Drop food in basket
draggedFood.isDragging = false;
draggedFood.aiOwner = null;
// Score for AI (or just increment score for now)
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
foodsDeliveredThisLevel++;
// Add a fun bounce before disappearing for AI too
if (draggedFood) {
tween(draggedFood, {
x: basket.x,
y: basket.y - 80,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
if (draggedFood) {
tween(draggedFood, {
y: basket.y,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.1
}, {
duration: 120,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.effects.flashObject(basket, 0x00ff00, 300);
if (foods.indexOf(draggedFood) !== -1) {
draggedFood.destroy();
foods.splice(foods.indexOf(draggedFood), 1);
// Only spawn new food if not at max for this level
if (foods.length < foodsPerLevel) {
spawnFood();
}
}
}
});
}
}
});
}
draggedFood = null;
aiChar.targetFood = null;
}
}
// --- Dentist Mode: Activate on level 3 until level 4 ---
if (level === 3 && !game.dentistModeActive) {
game.dentistModeActive = true;
// Dentist mode ON: change visuals and gameplay
// Change background color to white (dental clinic feel)
game.setBackgroundColor(0xffffff);
// Change basket to look like a tooth (if you have a tooth asset, otherwise tint)
if (basket) basket.tint = 0xeeeeee;
// Change foods to only allow 'food2' (simulate "tooth" or "dental" food)
for (var i = 0; i < foods.length; i++) {
foods[i].children[0].tint = 0xeeeeee;
}
// Show dentist mode text
if (!game.dentistModeTxt) {
game.dentistModeTxt = new Text2('DİŞÇİ MODU!', {
size: 120,
fill: 0x00BFFF
});
game.dentistModeTxt.anchor.set(0.5, 0);
game.dentistModeTxt.x = 2048 / 2;
game.dentistModeTxt.y = 400;
LK.gui.top.addChild(game.dentistModeTxt);
}
}
if (level === 4 && game.dentistModeActive) {
game.dentistModeActive = false;
// Revert visuals
game.setBackgroundColor(0xf5f5dc);
if (basket) basket.tint = 0xffffff;
for (var i = 0; i < foods.length; i++) {
foods[i].children[0].tint = 0xffffff;
}
// Remove dentist mode text
if (game.dentistModeTxt) {
LK.gui.top.removeChild(game.dentistModeTxt);
game.dentistModeTxt = null;
}
}
// --- Level up logic ---
if (foodsDeliveredThisLevel >= foodsPerLevel && level < maxLevel) {
// Level up!
level++;
foodsDeliveredThisLevel = 0;
foodsPerLevel = Math.min(foodsPerLevel + 1, 7); // Increase food count per level, cap at 7
// Increase speeds
playerChar.playerSpeed = playerBaseSpeed + (level - 1) * playerSpeedIncrease;
aiChar.speed = aiBaseSpeed + (level - 1) * aiSpeedIncrease;
// Update level text
if (levelTxt) {
levelTxt.setText('Seviye: ' + level);
}
// Remove all foods and respawn for new level
for (var i = foods.length - 1; i >= 0; i--) {
foods[i].destroy();
foods.splice(i, 1);
}
for (var i = 0; i < foodsPerLevel; i++) {
spawnFood();
}
// Optionally, flash screen or give feedback
LK.effects.flashScreen(0x00ff00, 600);
// --- FUN EVENTS! ---
// Pick a random fun event for this level
var funEvent = Math.floor(Math.random() * 20); // 0-2: normal, 3: rare giant food
if (funEvent === 0) {
// Disco mode: flash background and basket colors
var discoColors = [0xff00ff, 0x00ffff, 0xffff00, 0xff8800, 0x00ff00, 0x0080ff];
var discoStep = 0;
var discoTimer = LK.setInterval(function () {
var color = discoColors[discoStep % discoColors.length];
game.setBackgroundColor(color);
basket.tint = color;
discoStep++;
if (discoStep > 12) {
game.setBackgroundColor(0xf5f5dc);
basket.tint = 0xffffff;
LK.clearInterval(discoTimer);
}
}, 90);
} else if (funEvent === 1) {
// Food rain: drop 5 extra foods from the top for fun
for (var r = 0; r < 5; r++) {
var rainFood = new Food();
rainFood.x = Math.floor(300 + Math.random() * (2048 - 600));
rainFood.y = -100 - Math.random() * 200;
rainFood.startX = rainFood.x;
rainFood.startY = rainFood.y;
foods.push(rainFood);
game.addChild(rainFood);
// Animate falling
(function (rainFood) {
var targetY = shelf.y - 100 + Math.random() * 80;
tween(rainFood, {
y: targetY
}, {
duration: 900 + Math.random() * 400,
easing: tween.easeIn,
onFinish: function onFinish() {
rainFood.startY = rainFood.y;
}
});
})(rainFood);
}
} else if (funEvent === 2) {
// Basket shrink: basket shrinks for a short time, then returns to normal
var origScaleX = basket.scaleX || 1;
var origScaleY = basket.scaleY || 1;
tween(basket, {
scaleX: origScaleX * 0.6,
scaleY: origScaleY * 0.6
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(basket, {
scaleX: origScaleX,
scaleY: origScaleY
}, {
duration: 400,
easing: tween.easeOut
});
}, 1200);
}
});
} else if (funEvent === 3) {
// Rare silly event: giant food bounces in!
var giantFood = new Food();
giantFood.x = 2048 / 2;
giantFood.y = -300;
giantFood.scaleX = 3.5;
giantFood.scaleY = 3.5;
game.addChild(giantFood);
tween(giantFood, {
y: shelf.y - 200
}, {
duration: 900,
easing: tween.easeOut,
onFinish: function onFinish() {
// Bounce up and down a few times
var bounces = 0;
var _bounce = function bounce() {
if (bounces < 3) {
tween(giantFood, {
y: giantFood.y + 120
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(giantFood, {
y: giantFood.y - 120
}, {
duration: 180,
easing: tween.easeOut,
onFinish: function onFinish() {
bounces++;
_bounce();
}
});
}
});
} else {
// Fade out and remove
tween(giantFood, {
alpha: 0.0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
giantFood.destroy();
}
});
}
};
_bounce();
}
});
}
}
};
// --- Win condition: 20 items delivered ---
if (LK.getScore() >= 20) {
LK.effects.flashScreen(0x00ff00, 1000);
LK.showYouWin();
}
// --- Prevent elements in top left 100x100 (handled by not placing anything there) --- /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Character class (player or AI)
var Character = Container.expand(function () {
var self = Container.call(this);
// Use a food asset as character icon for now
var charAsset = self.attachAsset('food1', {
anchorX: 0.5,
anchorY: 0.5
});
self.isAI = false;
self.targetFood = null;
self.speed = 12; // AI speed
self.playerSpeed = 16; // Player walking speed
self.walkingToFood = false;
self.walkTarget = null;
self.update = function () {
// AI walking logic (unchanged)
if (self.isAI && self.targetFood && !self.targetFood.isDragging) {
var dx = self.targetFood.x - self.x;
var dy = self.targetFood.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.x += dx / dist * Math.min(self.speed, dist);
self.y += dy / dist * Math.min(self.speed, dist);
} else {
// "Pick up" the food if close enough
if (!self.targetFood.isDragging && !draggedFood) {
self.targetFood.isDragging = true;
draggedFood = self.targetFood;
self.targetFood.dragOffsetX = 0;
self.targetFood.dragOffsetY = 0;
self.targetFood.aiOwner = self;
}
}
}
// Player walking logic
if (!self.isAI && self.walkingToFood && self.walkTarget && !self.walkTarget.isDragging) {
var dx = self.walkTarget.x - self.x;
var dy = self.walkTarget.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
self.x += dx / dist * Math.min(self.playerSpeed, dist);
self.y += dy / dist * Math.min(self.playerSpeed, dist);
} else {
// Arrived at food, start dragging
if (!self.walkTarget.isDragging && !draggedFood) {
self.walkTarget.isDragging = true;
draggedFood = self.walkTarget;
self.walkTarget.dragOffsetX = 0;
self.walkTarget.dragOffsetY = 0;
self.walkTarget.aiOwner = null;
}
self.walkingToFood = false;
self.walkTarget = null;
}
}
};
return self;
});
// Food class
var Food = Container.expand(function () {
var self = Container.call(this);
// Randomly pick a food type (expanded for more variety)
var foodTypes = ['food1', 'food2', 'food3', 'food1', 'food2', 'food3', 'food1', 'food2', 'food3', 'food1', 'food2', 'food3'];
var typeIndex = Math.floor(Math.random() * foodTypes.length);
var foodAsset = self.attachAsset(foodTypes[typeIndex], {
anchorX: 0.5,
anchorY: 0.5
});
// Used for drag logic
self.isDragging = false;
self.dragOffsetX = 0;
self.dragOffsetY = 0;
// Used for collision detection
self.update = function () {
// No movement unless being dragged
};
// Down event for starting drag
self.down = function (x, y, obj) {
if (draggedFood) return; // Only one drag at a time
self.isDragging = true;
draggedFood = self;
// Offset for smooth dragging
self.dragOffsetX = self.x - x;
self.dragOffsetY = self.y - y;
};
// Up event for releasing drag
self.up = function (x, y, obj) {
if (!self.isDragging) return;
self.isDragging = false;
draggedFood = null;
// On release, check if inside basket
if (self.intersects(basket)) {
// Success!
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
foodsDeliveredThisLevel++;
// Animate food into basket and remove, with feedback
// Add a fun bounce before disappearing
tween(self, {
x: basket.x,
y: basket.y - 80,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 120,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: basket.y,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.1
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.effects.flashObject(basket, 0x00ff00, 300);
self.destroy();
foods.splice(foods.indexOf(self), 1);
// Only spawn new food if not at max for this level
if (foods.length < foodsPerLevel) {
spawnFood();
}
}
});
}
});
} else {
// If not in basket, animate back to shelf
tween(self, {
x: self.startX,
y: self.startY
}, {
duration: 250,
easing: tween.easeOut
});
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf5f5dc // Light beige, market-like
});
/****
* Game Code
****/
// --- Game variables ---
// Market shelf (raf) - horizontal box
// Food items (3 types for variety)
// Basket (sepet)
var shelfY = 500; // Y position of shelf
var basketY = 2400; // Y position of basket
var foods = [];
var draggedFood = null;
var basket = null;
var shelf = null;
// Characters
var playerChar = null;
var aiChar = null;
// --- Level system ---
var level = 1;
var maxLevel = 10;
var foodsPerLevel = 3;
var foodsDeliveredThisLevel = 0;
var aiBaseSpeed = 12;
var playerBaseSpeed = 16;
var aiSpeedIncrease = 2;
var playerSpeedIncrease = 1.5;
var levelTxt = null;
// --- GUI: Score ---
var scoreTxt = new Text2('0', {
size: 120,
fill: "#222"
});
scoreTxt.anchor.set(0.5, 0);
// --- Add score text to GUI
LK.gui.top.addChild(scoreTxt);
// --- GUI: Level ---
levelTxt = new Text2('Seviye: 1', {
size: 80,
fill: "#444"
});
levelTxt.anchor.set(0.5, 0);
levelTxt.y = 130;
LK.gui.top.addChild(levelTxt);
// --- Add shelf ---
shelf = LK.getAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: shelfY
});
game.addChild(shelf);
// --- Add basket ---
basket = LK.getAsset('basket', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: basketY
});
game.addChild(basket);
// --- Add player character ---
playerChar = new Character();
playerChar.x = 2048 / 2 - 300;
playerChar.y = basketY + 120;
playerChar.isAI = false;
playerChar.playerSpeed = playerBaseSpeed;
game.addChild(playerChar);
// --- Add AI character ---
aiChar = new Character();
aiChar.x = 2048 / 2 + 300;
aiChar.y = basketY + 120;
aiChar.isAI = true;
aiChar.speed = aiBaseSpeed;
game.addChild(aiChar);
// --- Spawn food ---
for (var i = 0; i < foodsPerLevel; i++) {
spawnFood();
}
game.inputEnabled = true;
// --- Main Menu Overlay ---
var mainMenuOverlay = new Container();
mainMenuOverlay.zIndex = 1000; // Ensure on top
// Semi-transparent background
var menuBg = LK.getAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 1800,
height: 1200,
color: 0xffffff
});
menuBg.alpha = 0.92;
mainMenuOverlay.addChild(menuBg);
// Title
var titleTxt = new Text2('MARKET OYUNU', {
size: 180,
fill: 0xB84C00
});
titleTxt.anchor.set(0.5, 0);
titleTxt.x = 2048 / 2;
titleTxt.y = 2732 / 2 - 420;
mainMenuOverlay.addChild(titleTxt);
// Dentist mode info on menu if active
if (game && game.dentistModeActive) {
var dentistMenuTxt = new Text2('DİŞÇİ MODU AKTİF!', {
size: 100,
fill: 0x00BFFF
});
dentistMenuTxt.anchor.set(0.5, 0);
dentistMenuTxt.x = 2048 / 2;
dentistMenuTxt.y = titleTxt.y + 200;
mainMenuOverlay.addChild(dentistMenuTxt);
}
// Start Button
var startBtn = LK.getAsset('food1', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 80,
scaleX: 1.2,
scaleY: 1.2
});
mainMenuOverlay.addChild(startBtn);
var startBtnTxt = new Text2('BAŞLA', {
size: 110,
fill: "#fff"
});
startBtnTxt.anchor.set(0.5, 0.5);
startBtnTxt.x = startBtn.x;
startBtnTxt.y = startBtn.y;
mainMenuOverlay.addChild(startBtnTxt);
// Food Gallery Button
var galleryBtn = LK.getAsset('food2', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 180,
scaleX: 1.1,
scaleY: 1.1
});
mainMenuOverlay.addChild(galleryBtn);
var galleryBtnTxt = new Text2('YİYECEKLER', {
size: 90,
fill: "#fff"
});
galleryBtnTxt.anchor.set(0.5, 0.5);
galleryBtnTxt.x = galleryBtn.x;
galleryBtnTxt.y = galleryBtn.y;
mainMenuOverlay.addChild(galleryBtnTxt);
// Food Gallery Overlay (hidden by default)
var foodGalleryOverlay = new Container();
foodGalleryOverlay.zIndex = 1100;
foodGalleryOverlay.visible = false;
var galleryBg = LK.getAsset('shelf', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 1600,
height: 1000,
color: 0xffffff
});
galleryBg.alpha = 0.97;
foodGalleryOverlay.addChild(galleryBg);
var galleryTitle = new Text2('YİYECEKLER', {
size: 120,
fill: 0xB84C00
});
galleryTitle.anchor.set(0.5, 0);
galleryTitle.x = 2048 / 2;
galleryTitle.y = 2732 / 2 - 420;
foodGalleryOverlay.addChild(galleryTitle);
// Show all food types in a row (expanded)
var galleryFoodTypes = game && game.dentistModeActive ? ['food2', 'food2', 'food2', 'food2', 'food2', 'food2'] : ['food1', 'food2', 'food3', 'food1', 'food2', 'food3'];
for (var i = 0; i < galleryFoodTypes.length; i++) {
var fx = 2048 / 2 - 750 + i * 300;
var fy = 2732 / 2 - 100;
var foodIcon = LK.getAsset(galleryFoodTypes[i], {
anchorX: 0.5,
anchorY: 0.5,
x: fx,
y: fy,
scaleX: 1.3,
scaleY: 1.3
});
foodGalleryOverlay.addChild(foodIcon);
}
// Close Gallery Button
var closeGalleryBtn = LK.getAsset('food3', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 320,
scaleX: 1,
scaleY: 1
});
foodGalleryOverlay.addChild(closeGalleryBtn);
var closeGalleryTxt = new Text2('KAPAT', {
size: 80,
fill: "#fff"
});
closeGalleryTxt.anchor.set(0.5, 0.5);
closeGalleryTxt.x = closeGalleryBtn.x;
closeGalleryTxt.y = closeGalleryBtn.y;
foodGalleryOverlay.addChild(closeGalleryTxt);
// Add overlays to game
game.addChild(mainMenuOverlay);
game.addChild(foodGalleryOverlay);
// Block input until start
game.inputEnabled = false;
// Start button logic
startBtn.down = function (x, y, obj) {
mainMenuOverlay.visible = false;
foodGalleryOverlay.visible = false;
game.inputEnabled = true;
};
// Gallery button logic
galleryBtn.down = function (x, y, obj) {
foodGalleryOverlay.visible = true;
mainMenuOverlay.visible = false;
};
// Close gallery logic
closeGalleryBtn.down = function (x, y, obj) {
foodGalleryOverlay.visible = false;
mainMenuOverlay.visible = true;
};
// --- Add shelf, basket, characters, and foods only after game start! ---
// --- Spawn food ---
function spawnFood() {
// Place food randomly along the shelf, but not overlapping with other foods
var maxTries = 10;
var placed = false;
var food = null;
while (!placed && maxTries-- > 0) {
if (game.dentistModeActive) {
// Only spawn 'food2' in dentist mode
food = new Food();
// Replace asset with 'food2'
if (food.children && food.children[0]) {
var oldAsset = food.children[0];
food.removeChild(oldAsset);
var newAsset = food.attachAsset('food2', {
anchorX: 0.5,
anchorY: 0.5
});
}
} else {
food = new Food();
}
// Random X within shelf width, with margin
var margin = 120;
var minX = shelf.x - shelf.width / 2 + margin;
var maxX = shelf.x + shelf.width / 2 - margin;
food.x = Math.floor(minX + Math.random() * (maxX - minX));
food.y = shelf.y - 100; // Just above shelf
food.startX = food.x;
food.startY = food.y;
// Check overlap with other foods
var overlap = false;
for (var i = 0; i < foods.length; i++) {
if (food.intersects(foods[i])) {
overlap = true;
break;
}
}
if (!overlap) {
placed = true;
}
}
if (food) {
foods.push(food);
game.addChild(food);
}
}
// --- Drag logic ---
game.move = function (x, y, obj) {
if (!game.inputEnabled) return;
if (draggedFood && draggedFood.isDragging) {
// Move food with finger, but clamp inside game area
var nx = x + draggedFood.dragOffsetX;
var ny = y + draggedFood.dragOffsetY;
// Clamp to game area
nx = Math.max(draggedFood.width / 2, Math.min(2048 - draggedFood.width / 2, nx));
ny = Math.max(draggedFood.height / 2, Math.min(2732 - draggedFood.height / 2, ny));
draggedFood.x = nx;
draggedFood.y = ny;
// Check collision with other foods (not self) or shelf
for (var i = 0; i < foods.length; i++) {
var f = foods[i];
if (f !== draggedFood && draggedFood.intersects(f)) {
// Fail: touched another food
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
// Check collision with shelf (if not above shelf)
if (draggedFood.y > shelf.y - shelf.height / 2 - draggedFood.height / 2 && draggedFood.y < shelf.y + shelf.height / 2 + draggedFood.height / 2 && Math.abs(draggedFood.x - shelf.x) < shelf.width / 2 + draggedFood.width / 2) {
// Fail: touched shelf
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
}
};
// Down: start drag if on a food
game.down = function (x, y, obj) {
if (!game.inputEnabled) return;
// Find topmost food under pointer
for (var i = foods.length - 1; i >= 0; i--) {
var f = foods[i];
// Simple hit test
var dx = x - f.x;
var dy = y - f.y;
var r = Math.max(f.width, f.height) / 2;
if (dx * dx + dy * dy < r * r) {
// Instead of direct drag, walk to food first
if (!draggedFood && !f.isDragging) {
playerChar.walkingToFood = true;
playerChar.walkTarget = f;
}
break;
}
}
};
// Up: release drag
game.up = function (x, y, obj) {
if (!game.inputEnabled) return;
if (draggedFood) {
draggedFood.up(x, y, obj);
}
};
// --- Game update (not used for movement, but could be for future) ---
game.update = function () {
if (!game.inputEnabled) return;
// Update characters
if (playerChar) playerChar.update();
if (aiChar) aiChar.update();
// AI logic: if not dragging, pick a food to deliver
if (aiChar && !draggedFood) {
// Find a food not being dragged
for (var i = 0; i < foods.length; i++) {
if (!foods[i].isDragging) {
aiChar.targetFood = foods[i];
break;
}
}
}
// If AI is dragging a food, move it toward the basket
if (draggedFood && draggedFood.aiOwner === aiChar) {
// Move food toward basket
var dx = basket.x - draggedFood.x;
var dy = basket.y - draggedFood.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// AI speed increases with level
var aiSpeed = aiBaseSpeed + (level - 1) * aiSpeedIncrease;
if (dist > 20) {
draggedFood.x += dx / dist * Math.min(aiSpeed, dist);
draggedFood.y += dy / dist * Math.min(aiSpeed, dist);
} else {
// Drop food in basket
draggedFood.isDragging = false;
draggedFood.aiOwner = null;
// Score for AI (or just increment score for now)
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
foodsDeliveredThisLevel++;
// Add a fun bounce before disappearing for AI too
if (draggedFood) {
tween(draggedFood, {
x: basket.x,
y: basket.y - 80,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
if (draggedFood) {
tween(draggedFood, {
y: basket.y,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.1
}, {
duration: 120,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.effects.flashObject(basket, 0x00ff00, 300);
if (foods.indexOf(draggedFood) !== -1) {
draggedFood.destroy();
foods.splice(foods.indexOf(draggedFood), 1);
// Only spawn new food if not at max for this level
if (foods.length < foodsPerLevel) {
spawnFood();
}
}
}
});
}
}
});
}
draggedFood = null;
aiChar.targetFood = null;
}
}
// --- Dentist Mode: Activate on level 3 until level 4 ---
if (level === 3 && !game.dentistModeActive) {
game.dentistModeActive = true;
// Dentist mode ON: change visuals and gameplay
// Change background color to white (dental clinic feel)
game.setBackgroundColor(0xffffff);
// Change basket to look like a tooth (if you have a tooth asset, otherwise tint)
if (basket) basket.tint = 0xeeeeee;
// Change foods to only allow 'food2' (simulate "tooth" or "dental" food)
for (var i = 0; i < foods.length; i++) {
foods[i].children[0].tint = 0xeeeeee;
}
// Show dentist mode text
if (!game.dentistModeTxt) {
game.dentistModeTxt = new Text2('DİŞÇİ MODU!', {
size: 120,
fill: 0x00BFFF
});
game.dentistModeTxt.anchor.set(0.5, 0);
game.dentistModeTxt.x = 2048 / 2;
game.dentistModeTxt.y = 400;
LK.gui.top.addChild(game.dentistModeTxt);
}
}
if (level === 4 && game.dentistModeActive) {
game.dentistModeActive = false;
// Revert visuals
game.setBackgroundColor(0xf5f5dc);
if (basket) basket.tint = 0xffffff;
for (var i = 0; i < foods.length; i++) {
foods[i].children[0].tint = 0xffffff;
}
// Remove dentist mode text
if (game.dentistModeTxt) {
LK.gui.top.removeChild(game.dentistModeTxt);
game.dentistModeTxt = null;
}
}
// --- Level up logic ---
if (foodsDeliveredThisLevel >= foodsPerLevel && level < maxLevel) {
// Level up!
level++;
foodsDeliveredThisLevel = 0;
foodsPerLevel = Math.min(foodsPerLevel + 1, 7); // Increase food count per level, cap at 7
// Increase speeds
playerChar.playerSpeed = playerBaseSpeed + (level - 1) * playerSpeedIncrease;
aiChar.speed = aiBaseSpeed + (level - 1) * aiSpeedIncrease;
// Update level text
if (levelTxt) {
levelTxt.setText('Seviye: ' + level);
}
// Remove all foods and respawn for new level
for (var i = foods.length - 1; i >= 0; i--) {
foods[i].destroy();
foods.splice(i, 1);
}
for (var i = 0; i < foodsPerLevel; i++) {
spawnFood();
}
// Optionally, flash screen or give feedback
LK.effects.flashScreen(0x00ff00, 600);
// --- FUN EVENTS! ---
// Pick a random fun event for this level
var funEvent = Math.floor(Math.random() * 20); // 0-2: normal, 3: rare giant food
if (funEvent === 0) {
// Disco mode: flash background and basket colors
var discoColors = [0xff00ff, 0x00ffff, 0xffff00, 0xff8800, 0x00ff00, 0x0080ff];
var discoStep = 0;
var discoTimer = LK.setInterval(function () {
var color = discoColors[discoStep % discoColors.length];
game.setBackgroundColor(color);
basket.tint = color;
discoStep++;
if (discoStep > 12) {
game.setBackgroundColor(0xf5f5dc);
basket.tint = 0xffffff;
LK.clearInterval(discoTimer);
}
}, 90);
} else if (funEvent === 1) {
// Food rain: drop 5 extra foods from the top for fun
for (var r = 0; r < 5; r++) {
var rainFood = new Food();
rainFood.x = Math.floor(300 + Math.random() * (2048 - 600));
rainFood.y = -100 - Math.random() * 200;
rainFood.startX = rainFood.x;
rainFood.startY = rainFood.y;
foods.push(rainFood);
game.addChild(rainFood);
// Animate falling
(function (rainFood) {
var targetY = shelf.y - 100 + Math.random() * 80;
tween(rainFood, {
y: targetY
}, {
duration: 900 + Math.random() * 400,
easing: tween.easeIn,
onFinish: function onFinish() {
rainFood.startY = rainFood.y;
}
});
})(rainFood);
}
} else if (funEvent === 2) {
// Basket shrink: basket shrinks for a short time, then returns to normal
var origScaleX = basket.scaleX || 1;
var origScaleY = basket.scaleY || 1;
tween(basket, {
scaleX: origScaleX * 0.6,
scaleY: origScaleY * 0.6
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(basket, {
scaleX: origScaleX,
scaleY: origScaleY
}, {
duration: 400,
easing: tween.easeOut
});
}, 1200);
}
});
} else if (funEvent === 3) {
// Rare silly event: giant food bounces in!
var giantFood = new Food();
giantFood.x = 2048 / 2;
giantFood.y = -300;
giantFood.scaleX = 3.5;
giantFood.scaleY = 3.5;
game.addChild(giantFood);
tween(giantFood, {
y: shelf.y - 200
}, {
duration: 900,
easing: tween.easeOut,
onFinish: function onFinish() {
// Bounce up and down a few times
var bounces = 0;
var _bounce = function bounce() {
if (bounces < 3) {
tween(giantFood, {
y: giantFood.y + 120
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
tween(giantFood, {
y: giantFood.y - 120
}, {
duration: 180,
easing: tween.easeOut,
onFinish: function onFinish() {
bounces++;
_bounce();
}
});
}
});
} else {
// Fade out and remove
tween(giantFood, {
alpha: 0.0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
giantFood.destroy();
}
});
}
};
_bounce();
}
});
}
}
};
// --- Win condition: 20 items delivered ---
if (LK.getScore() >= 20) {
LK.effects.flashScreen(0x00ff00, 1000);
LK.showYouWin();
}
// --- Prevent elements in top left 100x100 (handled by not placing anything there) ---