User prompt
O zaman her 5 puanda bir rouglike seçme ekranı olsun şimdilik bunlar olsun devamını ekleyeceğim
User prompt
Hayır mesela orada tıklamamız gerekecek yani play butonuna arkası simsiyah olabilir
User prompt
Hayır tıklayıp oyuna başlayabileceğimiz bir ana menü
User prompt
Oyuna bir başlangıç ekranı koylalım hani başla tuşudur falan
User prompt
Yılan sağ sola hareket ettirilmiyor
User prompt
Neyse ekrana tıklama olsun baya buglu çalışıyor
User prompt
Bence şöyle olsun kırmızı buton oyunda her zaman ekranın sol köşesinin altında olsun ve tıkladığında yılanın baktığı yöne ateş etsin yani yılan donmasın
User prompt
Kutulu odalarda oyun crash veriyo
User prompt
O zaman şöyle yapalım bi kırmızı tuş ekle ve bu tuşa basıldığında ateş edilsin
User prompt
Şimdi de kutulu elma gelince oyun durdu
User prompt
Kutulu odalar gelince hareket edilmiyor
User prompt
Ama şu an ekrana tıklıyorum ve ateş etmiyor
User prompt
Oyunda iki tuş ekleyelim biri bizim silah ateşleme tuşu olurken digeri kılıç tuşu olsun kılıç da şu işe yarıyor oyunda düşmanlar olacak ve silahla ölmeyecek bizde onları kılıçla devirecez ama hareket için tuşlar ekleme
User prompt
Oyuna bir başlangıç ekranı ekleyelim yazan isimi yerde "snaker" yazsın
User prompt
Elmalar ya da kutular gidebileceğimiz pixel pixel yerlere göre değişsin yani tam da gidebileceğimiz pixellerin üstünde olsun
User prompt
Mermi assetlerinin yönü baktığımız yere göre değişsin
User prompt
Bence daha açık renkli olsun ya da sen arkaya image koy ben yaprım
User prompt
Sen şu oyun alanını birazcık renkli yap canlı olsun
User prompt
Ama kutulu elmalar geldiğinde başka bi elma olmasın yani illaki onu kırıp elmayı yememiz gereksin
User prompt
Yılanın gittiği yöne ateş etsin
User prompt
Artık oyunda bazen %25 ihtimalle kutulu elmalar olacak bu elmalara çarpışınca ölecek yiyebilmek için elimizdeki silahla ona ateş edip sonra yememiz gerekecek
User prompt
Generate the first version of the source code of my game: Snake Classic.
User prompt
Snake Classic
Initial prompt
Bir oyun bu oyun snake e benzer bir oyun olacak ama daha kalitlerisi şimdilik normal snake oyunu yap
/**** * Classes ****/ // BoxFood class (dangerous apple) var BoxFood = Container.expand(function () { var self = Container.call(this); var boxAsset = self.attachAsset('boxFood', { anchorX: 0.5, anchorY: 0.5 }); self.isBox = true; self.destroyedByBullet = false; return self; }); // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletAsset = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); // Default speed values (will be set on fire) self.speedX = 32; self.speedY = 0; self.update = function () { self.lastX = self.x; self.lastY = self.y; self.x += self.speedX; self.y += self.speedY; }; return self; }); // Food class var Food = Container.expand(function () { var self = Container.call(this); var foodAsset = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); self.isBox = false; return self; }); // Snake segment class var Segment = Container.expand(function () { var self = Container.call(this); var segAsset = self.attachAsset('snakeSegment', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Snake class var Snake = Container.expand(function () { var self = Container.call(this); self.segments = []; self.direction = 'right'; self.nextDirection = 'right'; self.moveTimer = 0; self.moveInterval = 16; // Lower is faster, 16 = ~4 moves/sec at 60fps self.alive = true; // Initialize snake with 4 segments for (var i = 0; i < 4; i++) { var seg = new Segment(); seg.x = 1024 - i * 64; seg.y = 1366; self.addChild(seg); self.segments.push(seg); } self.update = function () { if (!self.alive) return; // Snake always moves, even if box food is active self.moveTimer++; if (self.moveTimer < self.moveInterval) return; self.moveTimer = 0; // Update direction self.direction = self.nextDirection; // Calculate new head position var head = self.segments[0]; var newX = head.x; var newY = head.y; if (self.direction === 'right') newX += 64;else if (self.direction === 'left') newX -= 64;else if (self.direction === 'up') newY -= 64;else if (self.direction === 'down') newY += 64; // Move body for (var i = self.segments.length - 1; i > 0; i--) { self.segments[i].x = self.segments[i - 1].x; self.segments[i].y = self.segments[i - 1].y; } head.x = newX; head.y = newY; }; self.grow = function () { var last = self.segments[self.segments.length - 1]; var seg = new Segment(); seg.x = last.x; seg.y = last.y; self.addChild(seg); self.segments.push(seg); }; return self; }); /**** * Initialize Game ****/ // Game variables var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // --- Main menu overlay --- var snake; var food; var scoreTxt; var gameOver = false; var bullets = []; var boxFoods = []; var boxFoodActive = false; var boxFoodObj = null; // --- Main menu overlay --- var menuContainer = new Container(); var menuBg = LK.getAsset('yourBackgroundImageId', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); menuContainer.addChild(menuBg); var menuTitle = new Text2('snaker', { size: 240, fill: 0xFFFFFF }); menuTitle.anchor.set(0.5, 0.5); menuTitle.x = 2048 / 2; menuTitle.y = 900; menuContainer.addChild(menuTitle); var tapText = new Text2('Başlamak için ekrana dokun', { size: 120, fill: 0xffffff }); tapText.anchor.set(0.5, 0.5); tapText.x = 2048 / 2; tapText.y = 1600; menuContainer.addChild(tapText); game.addChild(menuContainer); var menuActive = true; // Only allow tap anywhere to start game game.down = function (x, y, obj) { if (menuActive) { menuActive = false; menuContainer.destroy(); // After menu, allow normal game.down (fire bullet) to work game.down = function (x, y, obj) { if (gameOver) return; lastTouchX = x; lastTouchY = y; if (snake && snake.segments.length > 0) { var head = snake.segments[0]; var bullet = new Bullet(); bullet.x = head.x; bullet.y = head.y; bullet.lastX = bullet.x; // Set bullet speed and direction based on snake direction, and rotate asset accordingly if (snake.direction === 'right') { bullet.speedX = 32; bullet.speedY = 0; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = 0; } else if (snake.direction === 'left') { bullet.speedX = -32; bullet.speedY = 0; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI; } else if (snake.direction === 'up') { bullet.speedX = 0; bullet.speedY = -32; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = -Math.PI / 2; } else if (snake.direction === 'down') { bullet.speedX = 0; bullet.speedY = 32; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI / 2; } bullets.push(bullet); game.addChild(bullet); } }; return; } // If menu is not active, do nothing here (game.down will be replaced) }; // Add a bright background image (replace 'yourBackgroundImageId' with your own image asset id) var bgImage = LK.getAsset('yourBackgroundImageId', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(bgImage); // Create snake snake = new Snake(); game.addChild(snake); // No monster at game start // Create food function spawnFood() { // Remove previous food if (food) food.destroy(); // Remove previous box food if present if (boxFoodObj) { boxFoodObj.destroy(); boxFoodObj = null; boxFoodActive = false; } // Box food spawn chance can be changed by roguelike effects if (typeof roguelike_boxFoodChance === "undefined") roguelike_boxFoodChance = 0.25; if (Math.random() < roguelike_boxFoodChance) { // Build a list of all possible grid positions var possiblePositions = []; for (var gx = 64; gx <= 2048 - 64; gx += 64) { for (var gy = 64; gy <= 2732 - 64; gy += 64) { var occupied = false; for (var i = 0; i < snake.segments.length; i++) { if (Math.abs(snake.segments[i].x - gx) < 1 && Math.abs(snake.segments[i].y - gy) < 1) { occupied = true; break; } } if (!occupied) possiblePositions.push({ x: gx, y: gy }); } } if (possiblePositions.length > 0) { var idx = Math.floor(Math.random() * possiblePositions.length); var newBoxFood = new BoxFood(); newBoxFood.x = possiblePositions[idx].x; newBoxFood.y = possiblePositions[idx].y; game.addChild(newBoxFood); boxFoods.push(newBoxFood); boxFoodObj = newBoxFood; boxFoodActive = true; // Do not spawn normal food when box food is active food = null; } } else { // Only normal food // Build a list of all possible grid positions var possiblePositions = []; for (var gx = 64; gx <= 2048 - 64; gx += 64) { for (var gy = 64; gy <= 2732 - 64; gy += 64) { var occupied = false; for (var i = 0; i < snake.segments.length; i++) { if (Math.abs(snake.segments[i].x - gx) < 1 && Math.abs(snake.segments[i].y - gy) < 1) { occupied = true; break; } } if (!occupied) possiblePositions.push({ x: gx, y: gy }); } } if (possiblePositions.length > 0) { var idx = Math.floor(Math.random() * possiblePositions.length); food = new Food(); food.x = possiblePositions[idx].x; food.y = possiblePositions[idx].y; game.addChild(food); boxFoodActive = false; boxFoodObj = null; } } } spawnFood(); // Score text scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Game update game.update = function () { if (gameOver) return; snake.update(); // Check wall collision var head = snake.segments[0]; if (head.x < 0 || head.x > 2048 || head.y < 0 || head.y > 2732) { gameOver = true; LK.showGameOver(); return; } // Check self collision for (var i = 1; i < snake.segments.length; i++) { if (Math.abs(head.x - snake.segments[i].x) < 1 && Math.abs(head.y - snake.segments[i].y) < 1) { gameOver = true; LK.showGameOver(); return; } } // Handle bullets for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; bullet.update(); // Remove bullet if off screen if (bullet.x > 2048 + 32) { bullet.destroy(); bullets.splice(b, 1); continue; } // Check collision with box food if (boxFoodActive && boxFoodObj && !boxFoodObj._destroyed && !boxFoodObj.destroyedByBullet && bullet.intersects(boxFoodObj)) { boxFoodObj.destroyedByBullet = true; bullet.destroy(); bullets.splice(b, 1); // Remove box, spawn normal food at same position var prevX = boxFoodObj.x; var prevY = boxFoodObj.y; boxFoodObj.destroy(); boxFoodObj = null; boxFoodActive = false; // Spawn normal food at same position if (food) food.destroy(); food = new Food(); food.x = prevX; food.y = prevY; game.addChild(food); } } // Check food collision if (food && head.intersects(food)) { snake.grow(); LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); // Roguelike selection overlay every 5 points if (LK.getScore() > 0 && LK.getScore() % 5 === 0) { // --- Roguelike pool --- // Each option: { name, desc, apply, id } // Pause only snake movement (not all game logic) if (snake) snake.alive = false; // Pause snake movement // --- Monster global variable --- var monster = null; var roguelikePool = [{ id: "grow1", name: "+1 Uzama", desc: "Yılan 1 parça uzar.", apply: function apply() { snake.grow(); } }, { id: "speedup", name: "Hızlan", desc: "Yılan daha hızlı hareket eder.", apply: function apply() { if (snake.moveInterval > 2) snake.moveInterval -= 2; } }, { id: "slow3_box50", name: "-3 Hız, %50 Kutulu Elma", desc: "Yılan 3 birim yavaşlar, kutulu elma çıkma şansı %50 olur.", apply: function apply() { if (snake.moveInterval < 32) snake.moveInterval += 3; roguelike_boxFoodChance = 0.5; } }, { id: "boxFoodAlways", name: "Her zaman kutulu elma", desc: "Her yiyecek kutulu elma olur.", apply: function apply() { roguelike_boxFoodChance = 1.0; } }, { id: "normalFoodAlways", name: "Sadece normal elma", desc: "Kutulu elma çıkmaz.", apply: function apply() { roguelike_boxFoodChance = 0.0; } }, { id: "grow3", name: "+3 Uzama", desc: "Yılan 3 parça uzar.", apply: function apply() { snake.grow(); snake.grow(); snake.grow(); } }, { id: "score5", name: "+5 Puan", desc: "Anında 5 puan kazan.", apply: function apply() { LK.setScore(LK.getScore() + 5); scoreTxt.setText(LK.getScore()); } }, { id: "shorten2", name: "-2 Uzunluk", desc: "Yılan 2 parça kısalır.", apply: function apply() { for (var i = 0; i < 2; i++) { if (snake.segments.length > 1) { var seg = snake.segments.pop(); seg.destroy(); } } } }, { id: "boxFoodDoubleScore", name: "Kutulu Elma 2x Puan", desc: "Kutulu elma yersen 2 kat puan.", apply: function apply() { roguelike_boxFoodDoubleScore = true; } } // Add more options here! ]; // --- Roguelike state variables --- if (typeof roguelike_boxFoodChance === "undefined") roguelike_boxFoodChance = 0.25; if (typeof roguelike_boxFoodDoubleScore === "undefined") roguelike_boxFoodDoubleScore = false; // Pick 2 random, different options var idx1 = Math.floor(Math.random() * roguelikePool.length); var idx2; do { idx2 = Math.floor(Math.random() * roguelikePool.length); } while (idx2 === idx1); var optA = roguelikePool[idx1]; var optB = roguelikePool[idx2]; // Create overlay container var roguelikeOverlay = new Container(); // Dim background var dimBg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, scaleX: 20, scaleY: 20, alpha: 0.7 }); roguelikeOverlay.addChild(dimBg); // Title var rlTitle = new Text2('Roguelike Seçimi!', { size: 160, fill: 0xffffff }); rlTitle.anchor.set(0.5, 0.5); rlTitle.x = 2048 / 2; rlTitle.y = 900; roguelikeOverlay.addChild(rlTitle); // Option 1 var opt1 = new Text2(optA.name, { size: 100, fill: 0x00ff00 }); opt1.anchor.set(0.5, 0.5); opt1.x = 2048 / 2; opt1.y = 1300; roguelikeOverlay.addChild(opt1); var opt1desc = new Text2(optA.desc, { size: 60, fill: 0xffffff }); opt1desc.anchor.set(0.5, 0.5); opt1desc.x = 2048 / 2; opt1desc.y = 1400; roguelikeOverlay.addChild(opt1desc); // Option 2 var opt2 = new Text2(optB.name, { size: 100, fill: 0x00bfff }); opt2.anchor.set(0.5, 0.5); opt2.x = 2048 / 2; opt2.y = 1700; roguelikeOverlay.addChild(opt2); var opt2desc = new Text2(optB.desc, { size: 60, fill: 0xffffff }); opt2desc.anchor.set(0.5, 0.5); opt2desc.x = 2048 / 2; opt2desc.y = 1800; roguelikeOverlay.addChild(opt2desc); // Add overlay to game game.addChild(roguelikeOverlay); // Option selection logic roguelikeOverlay.down = function (x, y, obj) { // Check which option was tapped if (Math.abs(y - opt1.y) < 120) { optA.apply(); } else if (Math.abs(y - opt2.y) < 120) { optB.apply(); } else { // Not on option, ignore return; } // Remove overlay and resume game roguelikeOverlay.destroy(); // (popupMonster logic removed) // --- Teleport snake to center if head is near wall --- if (snake && snake.segments.length > 0) { var head = snake.segments[0]; // Define "near wall" as within 128px of any edge var margin = 128; var centerX = 1024; var centerY = 1366; if (head.x < margin || head.x > 2048 - margin || head.y < margin || head.y > 2732 - margin) { // Calculate offset between all segments and head var dx = centerX - head.x; var dy = centerY - head.y; for (var i = 0; i < snake.segments.length; i++) { snake.segments[i].x += dx; snake.segments[i].y += dy; } } } if (snake) snake.alive = true; // Resume snake movement gameOver = false; // After roguelike selection, spawn food or box food spawnFood(); // Restore swipe and tap controls game.down = function (x, y, obj) { if (gameOver) return; // Store initial touch for swipe direction detection lastTouchX = x; lastTouchY = y; if (snake && snake.segments.length > 0) { var head = snake.segments[0]; var bullet = new Bullet(); bullet.x = head.x; bullet.y = head.y; bullet.lastX = bullet.x; // Set bullet speed and direction based on snake direction, and rotate asset accordingly if (snake.direction === 'right') { bullet.speedX = 32; bullet.speedY = 0; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = 0; } else if (snake.direction === 'left') { bullet.speedX = -32; bullet.speedY = 0; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI; } else if (snake.direction === 'up') { bullet.speedX = 0; bullet.speedY = -32; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = -Math.PI / 2; } else if (snake.direction === 'down') { bullet.speedX = 0; bullet.speedY = 32; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI / 2; } bullets.push(bullet); game.addChild(bullet); } }; }; // Forward tap events to overlay game.down = function (x, y, obj) { if (roguelikeOverlay && roguelikeOverlay.down) roguelikeOverlay.down(x, y, obj); }; // Prevent further game logic until overlay is closed return; } spawnFood(); // Speed up as snake grows (slower acceleration) if (snake.moveInterval > 6) { snake.moveInterval--; } else if (snake.moveInterval > 4 && LK.getScore() % 10 === 0) { // Only speed up every 10 points when very fast snake.moveInterval--; } } // SWORD ATTACK LOGIC if (swordActive) { swordTimer++; // Sword effect follows head if (swordEffect && snake && snake.segments.length > 0) { var head = snake.segments[0]; swordEffect.x = head.x; swordEffect.y = head.y; } // Check for box food collision with sword if (boxFoodActive && boxFoodObj && !boxFoodObj._destroyed && snake && snake.segments.length > 0) { var head = snake.segments[0]; if (head.intersects(boxFoodObj) && !boxFoodObj.destroyedByBullet) { // Defeat box food with sword snake.grow(); LK.setScore(LK.getScore() + 2); scoreTxt.setText(LK.getScore()); boxFoodObj.destroy(); boxFoodObj = null; boxFoodActive = false; spawnFood(); if (snake.moveInterval > 4) snake.moveInterval--; // End sword effect swordActive = false; swordTimer = 0; if (swordEffect) { swordEffect.destroy(); swordEffect = null; } } } // Sword duration end if (swordTimer > swordDuration) { swordActive = false; swordTimer = 0; if (swordEffect) { swordEffect.destroy(); swordEffect = null; } } } // Check box food collision if (boxFoodActive && boxFoodObj && !boxFoodObj._destroyed) { if (head.intersects(boxFoodObj)) { if (boxFoodObj.destroyedByBullet) { // Now edible snake.grow(); var boxScore = 2; if (typeof roguelike_boxFoodDoubleScore !== "undefined" && roguelike_boxFoodDoubleScore) boxScore *= 2; LK.setScore(LK.getScore() + boxScore); scoreTxt.setText(LK.getScore()); boxFoodObj.destroy(); boxFoodObj = null; boxFoodActive = false; spawnFood(); if (snake.moveInterval > 4) snake.moveInterval--; } else if (!swordActive) { // Deadly! gameOver = true; LK.showGameOver(); return; } } } }; // Touch controls var lastTouchX = null; var lastTouchY = null; // Sword attack state var swordActive = false; var swordTimer = 0; var swordDuration = 18; // ~0.3s at 60fps // Sword attack visual (simple overlay on snake head) var swordEffect = null; // Main game tap: always fire bullet in snake's direction game.down = function (x, y, obj) { if (gameOver) return; // Store initial touch for swipe direction detection lastTouchX = x; lastTouchY = y; if (snake && snake.segments.length > 0) { var head = snake.segments[0]; var bullet = new Bullet(); bullet.x = head.x; bullet.y = head.y; bullet.lastX = bullet.x; // Set bullet speed and direction based on snake direction, and rotate asset accordingly if (snake.direction === 'right') { bullet.speedX = 32; bullet.speedY = 0; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = 0; } else if (snake.direction === 'left') { bullet.speedX = -32; bullet.speedY = 0; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI; } else if (snake.direction === 'up') { bullet.speedX = 0; bullet.speedY = -32; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = -Math.PI / 2; } else if (snake.direction === 'down') { bullet.speedX = 0; bullet.speedY = 32; if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI / 2; } bullets.push(bullet); game.addChild(bullet); } }; // --- SWORD LOGIC in update (see below) --- game.up = function (x, y, obj) { if (lastTouchX === null || lastTouchY === null) return; var dx = x - lastTouchX; var dy = y - lastTouchY; if (Math.abs(dx) > Math.abs(dy)) { if (dx > 0 && snake.direction !== 'left') snake.nextDirection = 'right';else if (dx < 0 && snake.direction !== 'right') snake.nextDirection = 'left'; } else { if (dy > 0 && snake.direction !== 'up') snake.nextDirection = 'down';else if (dy < 0 && snake.direction !== 'down') snake.nextDirection = 'up'; } lastTouchX = null; lastTouchY = null; };
/****
* Classes
****/
// BoxFood class (dangerous apple)
var BoxFood = Container.expand(function () {
var self = Container.call(this);
var boxAsset = self.attachAsset('boxFood', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBox = true;
self.destroyedByBullet = false;
return self;
});
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletAsset = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
// Default speed values (will be set on fire)
self.speedX = 32;
self.speedY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.speedX;
self.y += self.speedY;
};
return self;
});
// Food class
var Food = Container.expand(function () {
var self = Container.call(this);
var foodAsset = self.attachAsset('food', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBox = false;
return self;
});
// Snake segment class
var Segment = Container.expand(function () {
var self = Container.call(this);
var segAsset = self.attachAsset('snakeSegment', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Snake class
var Snake = Container.expand(function () {
var self = Container.call(this);
self.segments = [];
self.direction = 'right';
self.nextDirection = 'right';
self.moveTimer = 0;
self.moveInterval = 16; // Lower is faster, 16 = ~4 moves/sec at 60fps
self.alive = true;
// Initialize snake with 4 segments
for (var i = 0; i < 4; i++) {
var seg = new Segment();
seg.x = 1024 - i * 64;
seg.y = 1366;
self.addChild(seg);
self.segments.push(seg);
}
self.update = function () {
if (!self.alive) return;
// Snake always moves, even if box food is active
self.moveTimer++;
if (self.moveTimer < self.moveInterval) return;
self.moveTimer = 0;
// Update direction
self.direction = self.nextDirection;
// Calculate new head position
var head = self.segments[0];
var newX = head.x;
var newY = head.y;
if (self.direction === 'right') newX += 64;else if (self.direction === 'left') newX -= 64;else if (self.direction === 'up') newY -= 64;else if (self.direction === 'down') newY += 64;
// Move body
for (var i = self.segments.length - 1; i > 0; i--) {
self.segments[i].x = self.segments[i - 1].x;
self.segments[i].y = self.segments[i - 1].y;
}
head.x = newX;
head.y = newY;
};
self.grow = function () {
var last = self.segments[self.segments.length - 1];
var seg = new Segment();
seg.x = last.x;
seg.y = last.y;
self.addChild(seg);
self.segments.push(seg);
};
return self;
});
/****
* Initialize Game
****/
// Game variables
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// --- Main menu overlay ---
var snake;
var food;
var scoreTxt;
var gameOver = false;
var bullets = [];
var boxFoods = [];
var boxFoodActive = false;
var boxFoodObj = null;
// --- Main menu overlay ---
var menuContainer = new Container();
var menuBg = LK.getAsset('yourBackgroundImageId', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
menuContainer.addChild(menuBg);
var menuTitle = new Text2('snaker', {
size: 240,
fill: 0xFFFFFF
});
menuTitle.anchor.set(0.5, 0.5);
menuTitle.x = 2048 / 2;
menuTitle.y = 900;
menuContainer.addChild(menuTitle);
var tapText = new Text2('Başlamak için ekrana dokun', {
size: 120,
fill: 0xffffff
});
tapText.anchor.set(0.5, 0.5);
tapText.x = 2048 / 2;
tapText.y = 1600;
menuContainer.addChild(tapText);
game.addChild(menuContainer);
var menuActive = true;
// Only allow tap anywhere to start game
game.down = function (x, y, obj) {
if (menuActive) {
menuActive = false;
menuContainer.destroy();
// After menu, allow normal game.down (fire bullet) to work
game.down = function (x, y, obj) {
if (gameOver) return;
lastTouchX = x;
lastTouchY = y;
if (snake && snake.segments.length > 0) {
var head = snake.segments[0];
var bullet = new Bullet();
bullet.x = head.x;
bullet.y = head.y;
bullet.lastX = bullet.x;
// Set bullet speed and direction based on snake direction, and rotate asset accordingly
if (snake.direction === 'right') {
bullet.speedX = 32;
bullet.speedY = 0;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = 0;
} else if (snake.direction === 'left') {
bullet.speedX = -32;
bullet.speedY = 0;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI;
} else if (snake.direction === 'up') {
bullet.speedX = 0;
bullet.speedY = -32;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = -Math.PI / 2;
} else if (snake.direction === 'down') {
bullet.speedX = 0;
bullet.speedY = 32;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI / 2;
}
bullets.push(bullet);
game.addChild(bullet);
}
};
return;
}
// If menu is not active, do nothing here (game.down will be replaced)
};
// Add a bright background image (replace 'yourBackgroundImageId' with your own image asset id)
var bgImage = LK.getAsset('yourBackgroundImageId', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(bgImage);
// Create snake
snake = new Snake();
game.addChild(snake);
// No monster at game start
// Create food
function spawnFood() {
// Remove previous food
if (food) food.destroy();
// Remove previous box food if present
if (boxFoodObj) {
boxFoodObj.destroy();
boxFoodObj = null;
boxFoodActive = false;
}
// Box food spawn chance can be changed by roguelike effects
if (typeof roguelike_boxFoodChance === "undefined") roguelike_boxFoodChance = 0.25;
if (Math.random() < roguelike_boxFoodChance) {
// Build a list of all possible grid positions
var possiblePositions = [];
for (var gx = 64; gx <= 2048 - 64; gx += 64) {
for (var gy = 64; gy <= 2732 - 64; gy += 64) {
var occupied = false;
for (var i = 0; i < snake.segments.length; i++) {
if (Math.abs(snake.segments[i].x - gx) < 1 && Math.abs(snake.segments[i].y - gy) < 1) {
occupied = true;
break;
}
}
if (!occupied) possiblePositions.push({
x: gx,
y: gy
});
}
}
if (possiblePositions.length > 0) {
var idx = Math.floor(Math.random() * possiblePositions.length);
var newBoxFood = new BoxFood();
newBoxFood.x = possiblePositions[idx].x;
newBoxFood.y = possiblePositions[idx].y;
game.addChild(newBoxFood);
boxFoods.push(newBoxFood);
boxFoodObj = newBoxFood;
boxFoodActive = true;
// Do not spawn normal food when box food is active
food = null;
}
} else {
// Only normal food
// Build a list of all possible grid positions
var possiblePositions = [];
for (var gx = 64; gx <= 2048 - 64; gx += 64) {
for (var gy = 64; gy <= 2732 - 64; gy += 64) {
var occupied = false;
for (var i = 0; i < snake.segments.length; i++) {
if (Math.abs(snake.segments[i].x - gx) < 1 && Math.abs(snake.segments[i].y - gy) < 1) {
occupied = true;
break;
}
}
if (!occupied) possiblePositions.push({
x: gx,
y: gy
});
}
}
if (possiblePositions.length > 0) {
var idx = Math.floor(Math.random() * possiblePositions.length);
food = new Food();
food.x = possiblePositions[idx].x;
food.y = possiblePositions[idx].y;
game.addChild(food);
boxFoodActive = false;
boxFoodObj = null;
}
}
}
spawnFood();
// Score text
scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Game update
game.update = function () {
if (gameOver) return;
snake.update();
// Check wall collision
var head = snake.segments[0];
if (head.x < 0 || head.x > 2048 || head.y < 0 || head.y > 2732) {
gameOver = true;
LK.showGameOver();
return;
}
// Check self collision
for (var i = 1; i < snake.segments.length; i++) {
if (Math.abs(head.x - snake.segments[i].x) < 1 && Math.abs(head.y - snake.segments[i].y) < 1) {
gameOver = true;
LK.showGameOver();
return;
}
}
// Handle bullets
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
bullet.update();
// Remove bullet if off screen
if (bullet.x > 2048 + 32) {
bullet.destroy();
bullets.splice(b, 1);
continue;
}
// Check collision with box food
if (boxFoodActive && boxFoodObj && !boxFoodObj._destroyed && !boxFoodObj.destroyedByBullet && bullet.intersects(boxFoodObj)) {
boxFoodObj.destroyedByBullet = true;
bullet.destroy();
bullets.splice(b, 1);
// Remove box, spawn normal food at same position
var prevX = boxFoodObj.x;
var prevY = boxFoodObj.y;
boxFoodObj.destroy();
boxFoodObj = null;
boxFoodActive = false;
// Spawn normal food at same position
if (food) food.destroy();
food = new Food();
food.x = prevX;
food.y = prevY;
game.addChild(food);
}
}
// Check food collision
if (food && head.intersects(food)) {
snake.grow();
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
// Roguelike selection overlay every 5 points
if (LK.getScore() > 0 && LK.getScore() % 5 === 0) {
// --- Roguelike pool ---
// Each option: { name, desc, apply, id }
// Pause only snake movement (not all game logic)
if (snake) snake.alive = false; // Pause snake movement
// --- Monster global variable ---
var monster = null;
var roguelikePool = [{
id: "grow1",
name: "+1 Uzama",
desc: "Yılan 1 parça uzar.",
apply: function apply() {
snake.grow();
}
}, {
id: "speedup",
name: "Hızlan",
desc: "Yılan daha hızlı hareket eder.",
apply: function apply() {
if (snake.moveInterval > 2) snake.moveInterval -= 2;
}
}, {
id: "slow3_box50",
name: "-3 Hız, %50 Kutulu Elma",
desc: "Yılan 3 birim yavaşlar, kutulu elma çıkma şansı %50 olur.",
apply: function apply() {
if (snake.moveInterval < 32) snake.moveInterval += 3;
roguelike_boxFoodChance = 0.5;
}
}, {
id: "boxFoodAlways",
name: "Her zaman kutulu elma",
desc: "Her yiyecek kutulu elma olur.",
apply: function apply() {
roguelike_boxFoodChance = 1.0;
}
}, {
id: "normalFoodAlways",
name: "Sadece normal elma",
desc: "Kutulu elma çıkmaz.",
apply: function apply() {
roguelike_boxFoodChance = 0.0;
}
}, {
id: "grow3",
name: "+3 Uzama",
desc: "Yılan 3 parça uzar.",
apply: function apply() {
snake.grow();
snake.grow();
snake.grow();
}
}, {
id: "score5",
name: "+5 Puan",
desc: "Anında 5 puan kazan.",
apply: function apply() {
LK.setScore(LK.getScore() + 5);
scoreTxt.setText(LK.getScore());
}
}, {
id: "shorten2",
name: "-2 Uzunluk",
desc: "Yılan 2 parça kısalır.",
apply: function apply() {
for (var i = 0; i < 2; i++) {
if (snake.segments.length > 1) {
var seg = snake.segments.pop();
seg.destroy();
}
}
}
}, {
id: "boxFoodDoubleScore",
name: "Kutulu Elma 2x Puan",
desc: "Kutulu elma yersen 2 kat puan.",
apply: function apply() {
roguelike_boxFoodDoubleScore = true;
}
}
// Add more options here!
];
// --- Roguelike state variables ---
if (typeof roguelike_boxFoodChance === "undefined") roguelike_boxFoodChance = 0.25;
if (typeof roguelike_boxFoodDoubleScore === "undefined") roguelike_boxFoodDoubleScore = false;
// Pick 2 random, different options
var idx1 = Math.floor(Math.random() * roguelikePool.length);
var idx2;
do {
idx2 = Math.floor(Math.random() * roguelikePool.length);
} while (idx2 === idx1);
var optA = roguelikePool[idx1];
var optB = roguelikePool[idx2];
// Create overlay container
var roguelikeOverlay = new Container();
// Dim background
var dimBg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
scaleX: 20,
scaleY: 20,
alpha: 0.7
});
roguelikeOverlay.addChild(dimBg);
// Title
var rlTitle = new Text2('Roguelike Seçimi!', {
size: 160,
fill: 0xffffff
});
rlTitle.anchor.set(0.5, 0.5);
rlTitle.x = 2048 / 2;
rlTitle.y = 900;
roguelikeOverlay.addChild(rlTitle);
// Option 1
var opt1 = new Text2(optA.name, {
size: 100,
fill: 0x00ff00
});
opt1.anchor.set(0.5, 0.5);
opt1.x = 2048 / 2;
opt1.y = 1300;
roguelikeOverlay.addChild(opt1);
var opt1desc = new Text2(optA.desc, {
size: 60,
fill: 0xffffff
});
opt1desc.anchor.set(0.5, 0.5);
opt1desc.x = 2048 / 2;
opt1desc.y = 1400;
roguelikeOverlay.addChild(opt1desc);
// Option 2
var opt2 = new Text2(optB.name, {
size: 100,
fill: 0x00bfff
});
opt2.anchor.set(0.5, 0.5);
opt2.x = 2048 / 2;
opt2.y = 1700;
roguelikeOverlay.addChild(opt2);
var opt2desc = new Text2(optB.desc, {
size: 60,
fill: 0xffffff
});
opt2desc.anchor.set(0.5, 0.5);
opt2desc.x = 2048 / 2;
opt2desc.y = 1800;
roguelikeOverlay.addChild(opt2desc);
// Add overlay to game
game.addChild(roguelikeOverlay);
// Option selection logic
roguelikeOverlay.down = function (x, y, obj) {
// Check which option was tapped
if (Math.abs(y - opt1.y) < 120) {
optA.apply();
} else if (Math.abs(y - opt2.y) < 120) {
optB.apply();
} else {
// Not on option, ignore
return;
}
// Remove overlay and resume game
roguelikeOverlay.destroy();
// (popupMonster logic removed)
// --- Teleport snake to center if head is near wall ---
if (snake && snake.segments.length > 0) {
var head = snake.segments[0];
// Define "near wall" as within 128px of any edge
var margin = 128;
var centerX = 1024;
var centerY = 1366;
if (head.x < margin || head.x > 2048 - margin || head.y < margin || head.y > 2732 - margin) {
// Calculate offset between all segments and head
var dx = centerX - head.x;
var dy = centerY - head.y;
for (var i = 0; i < snake.segments.length; i++) {
snake.segments[i].x += dx;
snake.segments[i].y += dy;
}
}
}
if (snake) snake.alive = true; // Resume snake movement
gameOver = false;
// After roguelike selection, spawn food or box food
spawnFood();
// Restore swipe and tap controls
game.down = function (x, y, obj) {
if (gameOver) return;
// Store initial touch for swipe direction detection
lastTouchX = x;
lastTouchY = y;
if (snake && snake.segments.length > 0) {
var head = snake.segments[0];
var bullet = new Bullet();
bullet.x = head.x;
bullet.y = head.y;
bullet.lastX = bullet.x;
// Set bullet speed and direction based on snake direction, and rotate asset accordingly
if (snake.direction === 'right') {
bullet.speedX = 32;
bullet.speedY = 0;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = 0;
} else if (snake.direction === 'left') {
bullet.speedX = -32;
bullet.speedY = 0;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI;
} else if (snake.direction === 'up') {
bullet.speedX = 0;
bullet.speedY = -32;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = -Math.PI / 2;
} else if (snake.direction === 'down') {
bullet.speedX = 0;
bullet.speedY = 32;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI / 2;
}
bullets.push(bullet);
game.addChild(bullet);
}
};
};
// Forward tap events to overlay
game.down = function (x, y, obj) {
if (roguelikeOverlay && roguelikeOverlay.down) roguelikeOverlay.down(x, y, obj);
};
// Prevent further game logic until overlay is closed
return;
}
spawnFood();
// Speed up as snake grows (slower acceleration)
if (snake.moveInterval > 6) {
snake.moveInterval--;
} else if (snake.moveInterval > 4 && LK.getScore() % 10 === 0) {
// Only speed up every 10 points when very fast
snake.moveInterval--;
}
}
// SWORD ATTACK LOGIC
if (swordActive) {
swordTimer++;
// Sword effect follows head
if (swordEffect && snake && snake.segments.length > 0) {
var head = snake.segments[0];
swordEffect.x = head.x;
swordEffect.y = head.y;
}
// Check for box food collision with sword
if (boxFoodActive && boxFoodObj && !boxFoodObj._destroyed && snake && snake.segments.length > 0) {
var head = snake.segments[0];
if (head.intersects(boxFoodObj) && !boxFoodObj.destroyedByBullet) {
// Defeat box food with sword
snake.grow();
LK.setScore(LK.getScore() + 2);
scoreTxt.setText(LK.getScore());
boxFoodObj.destroy();
boxFoodObj = null;
boxFoodActive = false;
spawnFood();
if (snake.moveInterval > 4) snake.moveInterval--;
// End sword effect
swordActive = false;
swordTimer = 0;
if (swordEffect) {
swordEffect.destroy();
swordEffect = null;
}
}
}
// Sword duration end
if (swordTimer > swordDuration) {
swordActive = false;
swordTimer = 0;
if (swordEffect) {
swordEffect.destroy();
swordEffect = null;
}
}
}
// Check box food collision
if (boxFoodActive && boxFoodObj && !boxFoodObj._destroyed) {
if (head.intersects(boxFoodObj)) {
if (boxFoodObj.destroyedByBullet) {
// Now edible
snake.grow();
var boxScore = 2;
if (typeof roguelike_boxFoodDoubleScore !== "undefined" && roguelike_boxFoodDoubleScore) boxScore *= 2;
LK.setScore(LK.getScore() + boxScore);
scoreTxt.setText(LK.getScore());
boxFoodObj.destroy();
boxFoodObj = null;
boxFoodActive = false;
spawnFood();
if (snake.moveInterval > 4) snake.moveInterval--;
} else if (!swordActive) {
// Deadly!
gameOver = true;
LK.showGameOver();
return;
}
}
}
};
// Touch controls
var lastTouchX = null;
var lastTouchY = null;
// Sword attack state
var swordActive = false;
var swordTimer = 0;
var swordDuration = 18; // ~0.3s at 60fps
// Sword attack visual (simple overlay on snake head)
var swordEffect = null;
// Main game tap: always fire bullet in snake's direction
game.down = function (x, y, obj) {
if (gameOver) return;
// Store initial touch for swipe direction detection
lastTouchX = x;
lastTouchY = y;
if (snake && snake.segments.length > 0) {
var head = snake.segments[0];
var bullet = new Bullet();
bullet.x = head.x;
bullet.y = head.y;
bullet.lastX = bullet.x;
// Set bullet speed and direction based on snake direction, and rotate asset accordingly
if (snake.direction === 'right') {
bullet.speedX = 32;
bullet.speedY = 0;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = 0;
} else if (snake.direction === 'left') {
bullet.speedX = -32;
bullet.speedY = 0;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI;
} else if (snake.direction === 'up') {
bullet.speedX = 0;
bullet.speedY = -32;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = -Math.PI / 2;
} else if (snake.direction === 'down') {
bullet.speedX = 0;
bullet.speedY = 32;
if (bullet.children && bullet.children.length > 0) bullet.children[0].rotation = Math.PI / 2;
}
bullets.push(bullet);
game.addChild(bullet);
}
};
// --- SWORD LOGIC in update (see below) ---
game.up = function (x, y, obj) {
if (lastTouchX === null || lastTouchY === null) return;
var dx = x - lastTouchX;
var dy = y - lastTouchY;
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0 && snake.direction !== 'left') snake.nextDirection = 'right';else if (dx < 0 && snake.direction !== 'right') snake.nextDirection = 'left';
} else {
if (dy > 0 && snake.direction !== 'up') snake.nextDirection = 'down';else if (dy < 0 && snake.direction !== 'down') snake.nextDirection = 'up';
}
lastTouchX = null;
lastTouchY = null;
};
Bir top pixel art yeşil renkli. In-Game asset. 2d. High contrast. No shadows
Pixel art bullet. In-Game asset. 2d. High contrast. No shadows
Pixel art apple. In-Game asset. 2d. High contrast. No shadows
Çimen ama bütün elranı kaplıyor . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Kırmızı bir pixel art oyun tuşu. In-Game asset. 2d. High contrast. No shadows
2D pixel art para kasası. In-Game asset. High contrast. No shadows
A red MONSTER . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat