/****
* 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;
}; ===================================================================
--- original.js
+++ change.js
@@ -500,12 +500,9 @@
return;
}
// Remove overlay and resume game
roguelikeOverlay.destroy();
- // Resume popup monster if it was paused
- if (popupMonster && !popupMonster._destroyed) {
- popupMonster.tapped = false;
- }
+ // (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
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