/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy class: Moves in a pattern, can be destroyed var Enemy = Container.expand(function () { var self = Container.call(this); // Attach enemy asset (green ellipse, 100x100) var enemyGfx = self.attachAsset('enemyEllipse', { anchorX: 0.5, anchorY: 0.5 }); // Set size for collision self.width = enemyGfx.width; self.height = enemyGfx.height; // Enemy type: 0 = straight, 1 = zigzag, 2 = fast self.type = 0; self.speed = 6; self.zigzagDir = 1; self.zigzagStep = 0; // For tracking last position for off-screen detection self.lastY = self.y; // For tracking intersection with hero self.lastIntersecting = false; // For zigzag self.baseX = 0; // Set movement pattern self.setType = function (type) { self.type = type; if (type === 0) { self.speed = 6 + Math.floor((typeof survivalFrames !== "undefined" ? survivalFrames / 60 : 0) / 10); } else if (type === 1) { self.speed = 5 + Math.floor((typeof survivalFrames !== "undefined" ? survivalFrames / 60 : 0) / 10); self.zigzagDir = Math.random() > 0.5 ? 1 : -1; self.zigzagStep = 0; self.baseX = self.x; } else if (type === 2) { self.speed = 10 + Math.floor((typeof survivalFrames !== "undefined" ? survivalFrames / 60 : 0) / 10); } }; // Update movement self.update = function () { // Only follow the hero for a certain distance, then move straight if (typeof hero !== "undefined" && hero !== null) { // Always check for collision with hero and trigger game over if intersecting if (!self.lastIntersecting && self.intersects(hero)) { LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } // Initialize followDistance if not set if (typeof self.followDistance === "undefined") { // Enemies will follow the hero for a random distance between 400 and 900 pixels self.followDistance = 400 + Math.random() * 500; // Store the last direction vector for straight movement self.lastDir = { dx: 0, dy: 1 }; self.hasStoppedFollowing = false; } // Calculate direction vector from enemy to hero var dx = hero.x - self.x; var dy = hero.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // If very close to hero but not colliding, enemy can "miss" and move past var missRadius = hero.width / 2 + self.width / 2 + 30; // 30px buffer for "miss" if (dist < missRadius && !self.intersects(hero)) { // Enemy missed the hero, move enemy off screen and mark for removal self.y = 2732 + 200; // Move enemy far below screen to trigger removal } else if (dist > 0) { // Increase speed as score increases (scales up to 3x at 60+ score) // Additionally, increase speed as enemy moves further down the screen (progresses in Y) var scoreMultiplier = 1 + (typeof LK !== "undefined" ? Math.min(LK.getScore(), 60) / 30 : 0); // up to 3x at 60+ score var progress = Math.max(0, Math.min(1, self.y / 2732)); // 0 at top, 1 at bottom var progressMultiplier = 1 + progress * 1.5; // up to 2.5x at bottom var step = Math.min(self.speed * scoreMultiplier * progressMultiplier, dist); if (!self.hasStoppedFollowing && dist > self.followDistance) { // Still follow the hero self.x += dx / dist * step * 0.18; self.y += dy / dist * step * 0.18; // Store last direction for straight movement self.lastDir.dx = dx / dist; self.lastDir.dy = dy / dist; } else { // Stop following, move straight in last direction self.hasStoppedFollowing = true; self.x += self.lastDir.dx * step * 0.18; self.y += self.lastDir.dy * step * 0.18; } } self.lastIntersecting = self.intersects(hero); } }; return self; }); // Hero class: Player's character, draggable var Hero = Container.expand(function () { var self = Container.call(this); // Attach hero asset (red box, 120x120) var heroGfx = self.attachAsset('heroBox', { anchorX: 0.5, anchorY: 0.5 }); // Set size for collision self.width = heroGfx.width; self.height = heroGfx.height; // For possible future use self.update = function () {}; // Down event for possible feedback self.down = function (x, y, obj) {}; // Up event for possible feedback self.up = function (x, y, obj) {}; return self; }); // Player attack class: short range, destroys enemy on contact var HeroAttack = Container.expand(function () { var self = Container.call(this); // Attach attack asset (yellow box, 80x80) var atkGfx = self.attachAsset('attackBox', { anchorX: 0.5, anchorY: 0.5 }); self.width = atkGfx.width; self.height = atkGfx.height; // For tracking self.lastIntersecting = false; // Attack duration self.lifetime = 18; // ~0.3s at 60fps self.update = function () { self.lifetime--; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c2c }); /**** * Game Code ****/ // --- Asset Initialization --- // Tween plugin for enemy/hero animations // --- Game Variables --- // Undertale music (replace 'undertale_theme' with actual asset id if needed) var hero = null; var enemies = []; var attacks = []; var dragNode = null; var lastHeroIntersecting = false; var spawnInterval = 60; // frames between spawns, will decrease var spawnTick = 0; var scoreTxt = null; var canAttack = true; var attackCooldown = 24; // frames var attackCooldownTick = 0; // Survival time in frames (60 per second) var survivalFrames = 0; var winTime = 20; // seconds to win (was winScore) // Add undertale image as background node, centered in game area var undertaleBg = LK.getAsset('undertale', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 700, // Move higher up scaleX: 18, // Shrink (higher quality, less scaling) scaleY: 18 }); game.addChild(undertaleBg); // --- Vibrating Text Over Undertale Image --- var undertaleText = []; var undertaleTextStr = "yapraklarımın hepsi öldürmez"; var undertaleTextFontSize = 90; var undertaleTextSpacing = 0; var undertaleTextBaseX = 2048 / 2; var undertaleTextBaseY = 700 + undertaleBg.height / 2 + 60; var undertaleTextColor = "#fffbe7"; var undertaleTextJitter = 7; var undertaleTextJitterTime = 120 + Math.random() * 100; var totalTextWidth = 0; for (var i = 0; i < undertaleTextStr.length; i++) { var ch = undertaleTextStr[i]; var t = new Text2(ch, { size: undertaleTextFontSize, fill: undertaleTextColor }); t.anchor.set(0.5, 0.5); undertaleText.push(t); totalTextWidth += t.width + undertaleTextSpacing; } totalTextWidth -= undertaleTextSpacing; // remove last extra spacing // Position each letter centered above undertale image var startX = undertaleTextBaseX - totalTextWidth / 2; var currX = startX; for (var i = 0; i < undertaleText.length; i++) { var t = undertaleText[i]; t.x = currX + t.width / 2; t.y = undertaleTextBaseY; currX += t.width + undertaleTextSpacing; game.addChild(t); } // Animate jitter for each letter using tween function vibrateLetter(letter, baseX, baseY) { function doJitter() { var dx = (Math.random() - 0.5) * undertaleTextJitter; var dy = (Math.random() - 0.5) * undertaleTextJitter; tween(letter, { x: baseX + dx, y: baseY + dy }, { duration: 60 + Math.random() * 60, easing: tween.linear, onFinish: doJitter }); } doJitter(); } for (var i = 0; i < undertaleText.length; i++) { vibrateLetter(undertaleText[i], undertaleText[i].x, undertaleText[i].y); } // Area for enemy spawn: use bottom of screen var undertaleSpawnY = 2732 - 200; var undertaleSpawnYMax = 2732 - 60; // --- Score Display --- scoreTxt = new Text2('0.0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Play Undertale music at game start LK.playMusic('undertale_theme'); // --- Hero Initialization --- hero = new Hero(); hero.x = 2048 / 2; hero.y = 2732 - 350; game.addChild(hero); // --- Touch/Drag Controls --- function handleMove(x, y, obj) { if (dragNode) { // Clamp hero inside game area (with margin) var margin = 80; var nx = Math.max(margin, Math.min(2048 - margin, x)); var ny = Math.max(300, Math.min(2732 - margin, y)); dragNode.x = nx; dragNode.y = ny; } } game.move = handleMove; game.down = function (x, y, obj) { // Only allow drag if touch is on hero var dx = x - hero.x; var dy = y - hero.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < hero.width / 1.2) { dragNode = hero; } }; game.up = function (x, y, obj) { dragNode = null; }; // --- Attack on Tap (anywhere except top 200px) --- game.tap = function (x, y, obj) { if (y > 200 && canAttack) { spawnAttack(); } }; // Since LK does not have tap, simulate with up event if not dragging game.up = function (x, y, obj) { if (!dragNode && y > 200 && canAttack) { spawnAttack(); } dragNode = null; }; // --- Attack Logic --- function spawnAttack() { // Only one attack at a time if (!canAttack) return; canAttack = false; attackCooldownTick = attackCooldown; var atk = new HeroAttack(); atk.x = hero.x; atk.y = hero.y - hero.height / 2 - atk.height / 2; attacks.push(atk); game.addChild(atk); // Animate attack (scale up then fade) atk.scaleX = 0.7; atk.scaleY = 0.7; tween(atk, { scaleX: 1.2, scaleY: 1.2 }, { duration: 120, easing: tween.easeOut }); tween(atk, { alpha: 0 }, { duration: 180, easing: tween.linear, onFinish: function onFinish() {} }); } // --- Enemy Spawning --- function spawnEnemy() { var enemy = new Enemy(); // Random x, avoid edges var margin = 120; enemy.x = margin + Math.random() * (2048 - 2 * margin); // Spawn from bottom of screen enemy.y = 2732 - 60; // Random type, more types as time increases var type = 0; var t = survivalFrames / 60; if (t < 5) { type = 0; } else if (t < 12) { type = Math.random() < 0.7 ? 0 : 1; } else { var r = Math.random(); if (r < 0.5) type = 0;else if (r < 0.8) type = 1;else type = 2; } enemy.setType(type); enemies.push(enemy); game.addChild(enemy); } // --- Main Game Update --- game.update = function () { // --- Attack cooldown --- if (!canAttack) { attackCooldownTick--; if (attackCooldownTick <= 0) { canAttack = true; } } // --- Survival time --- survivalFrames++; var survivalSeconds = survivalFrames / 60; scoreTxt.setText(survivalSeconds.toFixed(1)); // Replace undertale image with flow image after 35 seconds if (typeof undertaleBg !== "undefined" && undertaleBg !== null && survivalSeconds > 35) { // Remove undertaleBg if present undertaleBg.destroy(); undertaleBg = null; // Remove undertale text if present if (typeof undertaleText !== "undefined" && undertaleText && undertaleText.length) { for (var i = 0; i < undertaleText.length; i++) { if (undertaleText[i] && undertaleText[i].destroy) undertaleText[i].destroy(); } undertaleText = []; } // Add flow image in same position/scale undertaleBg = LK.getAsset('flow', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 700, scaleX: 18, scaleY: 18 }); game.addChild(undertaleBg); } // --- Win check by survival time --- // Removed win condition for endless mode // --- Spawn enemies --- spawnTick++; // Decrease interval as time increases (gets harder) var minInterval = 24; spawnInterval = Math.max(minInterval, 60 - Math.floor(survivalSeconds / 2) * 4); if (spawnTick >= spawnInterval) { spawnTick = 0; spawnEnemy(); } // --- Update enemies --- for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.update(); // Off-screen detection if (enemy.lastY < 2732 + 100 && enemy.y >= 2732 + 100) { // Enemy left screen, destroy enemy.destroy(); enemies.splice(i, 1); continue; } enemy.lastY = enemy.y; // Collision with hero var currIntersect = enemy.intersects(hero); if (!enemy.lastIntersecting && currIntersect) { // Hit! Game over LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); return; } enemy.lastIntersecting = currIntersect; } // --- Update attacks --- for (var j = attacks.length - 1; j >= 0; j--) { var atk = attacks[j]; atk.update(); // Remove if expired if (atk.lifetime <= 0) { atk.destroy(); attacks.splice(j, 1); continue; } // Check collision with enemies for (var k = enemies.length - 1; k >= 0; k--) { var enemy = enemies[k]; var currAtkIntersect = atk.intersects(enemy); if (!atk.lastIntersecting && currAtkIntersect) { // Destroy enemy enemy.destroy(); enemies.splice(k, 1); // Flash effect on attack LK.effects.flashObject(atk, 0xffff00, 200); // Remove attack (one hit per attack) atk.destroy(); attacks.splice(j, 1); break; } atk.lastIntersecting = currAtkIntersect; } } }; // --- Prevent elements in top left 100x100 (menu area) --- // --- End of Game Code ---
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Enemy class: Moves in a pattern, can be destroyed
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Attach enemy asset (green ellipse, 100x100)
var enemyGfx = self.attachAsset('enemyEllipse', {
anchorX: 0.5,
anchorY: 0.5
});
// Set size for collision
self.width = enemyGfx.width;
self.height = enemyGfx.height;
// Enemy type: 0 = straight, 1 = zigzag, 2 = fast
self.type = 0;
self.speed = 6;
self.zigzagDir = 1;
self.zigzagStep = 0;
// For tracking last position for off-screen detection
self.lastY = self.y;
// For tracking intersection with hero
self.lastIntersecting = false;
// For zigzag
self.baseX = 0;
// Set movement pattern
self.setType = function (type) {
self.type = type;
if (type === 0) {
self.speed = 6 + Math.floor((typeof survivalFrames !== "undefined" ? survivalFrames / 60 : 0) / 10);
} else if (type === 1) {
self.speed = 5 + Math.floor((typeof survivalFrames !== "undefined" ? survivalFrames / 60 : 0) / 10);
self.zigzagDir = Math.random() > 0.5 ? 1 : -1;
self.zigzagStep = 0;
self.baseX = self.x;
} else if (type === 2) {
self.speed = 10 + Math.floor((typeof survivalFrames !== "undefined" ? survivalFrames / 60 : 0) / 10);
}
};
// Update movement
self.update = function () {
// Only follow the hero for a certain distance, then move straight
if (typeof hero !== "undefined" && hero !== null) {
// Always check for collision with hero and trigger game over if intersecting
if (!self.lastIntersecting && self.intersects(hero)) {
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
// Initialize followDistance if not set
if (typeof self.followDistance === "undefined") {
// Enemies will follow the hero for a random distance between 400 and 900 pixels
self.followDistance = 400 + Math.random() * 500;
// Store the last direction vector for straight movement
self.lastDir = {
dx: 0,
dy: 1
};
self.hasStoppedFollowing = false;
}
// Calculate direction vector from enemy to hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// If very close to hero but not colliding, enemy can "miss" and move past
var missRadius = hero.width / 2 + self.width / 2 + 30; // 30px buffer for "miss"
if (dist < missRadius && !self.intersects(hero)) {
// Enemy missed the hero, move enemy off screen and mark for removal
self.y = 2732 + 200; // Move enemy far below screen to trigger removal
} else if (dist > 0) {
// Increase speed as score increases (scales up to 3x at 60+ score)
// Additionally, increase speed as enemy moves further down the screen (progresses in Y)
var scoreMultiplier = 1 + (typeof LK !== "undefined" ? Math.min(LK.getScore(), 60) / 30 : 0); // up to 3x at 60+ score
var progress = Math.max(0, Math.min(1, self.y / 2732)); // 0 at top, 1 at bottom
var progressMultiplier = 1 + progress * 1.5; // up to 2.5x at bottom
var step = Math.min(self.speed * scoreMultiplier * progressMultiplier, dist);
if (!self.hasStoppedFollowing && dist > self.followDistance) {
// Still follow the hero
self.x += dx / dist * step * 0.18;
self.y += dy / dist * step * 0.18;
// Store last direction for straight movement
self.lastDir.dx = dx / dist;
self.lastDir.dy = dy / dist;
} else {
// Stop following, move straight in last direction
self.hasStoppedFollowing = true;
self.x += self.lastDir.dx * step * 0.18;
self.y += self.lastDir.dy * step * 0.18;
}
}
self.lastIntersecting = self.intersects(hero);
}
};
return self;
});
// Hero class: Player's character, draggable
var Hero = Container.expand(function () {
var self = Container.call(this);
// Attach hero asset (red box, 120x120)
var heroGfx = self.attachAsset('heroBox', {
anchorX: 0.5,
anchorY: 0.5
});
// Set size for collision
self.width = heroGfx.width;
self.height = heroGfx.height;
// For possible future use
self.update = function () {};
// Down event for possible feedback
self.down = function (x, y, obj) {};
// Up event for possible feedback
self.up = function (x, y, obj) {};
return self;
});
// Player attack class: short range, destroys enemy on contact
var HeroAttack = Container.expand(function () {
var self = Container.call(this);
// Attach attack asset (yellow box, 80x80)
var atkGfx = self.attachAsset('attackBox', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = atkGfx.width;
self.height = atkGfx.height;
// For tracking
self.lastIntersecting = false;
// Attack duration
self.lifetime = 18; // ~0.3s at 60fps
self.update = function () {
self.lifetime--;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181c2c
});
/****
* Game Code
****/
// --- Asset Initialization ---
// Tween plugin for enemy/hero animations
// --- Game Variables ---
// Undertale music (replace 'undertale_theme' with actual asset id if needed)
var hero = null;
var enemies = [];
var attacks = [];
var dragNode = null;
var lastHeroIntersecting = false;
var spawnInterval = 60; // frames between spawns, will decrease
var spawnTick = 0;
var scoreTxt = null;
var canAttack = true;
var attackCooldown = 24; // frames
var attackCooldownTick = 0;
// Survival time in frames (60 per second)
var survivalFrames = 0;
var winTime = 20; // seconds to win (was winScore)
// Add undertale image as background node, centered in game area
var undertaleBg = LK.getAsset('undertale', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 700,
// Move higher up
scaleX: 18,
// Shrink (higher quality, less scaling)
scaleY: 18
});
game.addChild(undertaleBg);
// --- Vibrating Text Over Undertale Image ---
var undertaleText = [];
var undertaleTextStr = "yapraklarımın hepsi öldürmez";
var undertaleTextFontSize = 90;
var undertaleTextSpacing = 0;
var undertaleTextBaseX = 2048 / 2;
var undertaleTextBaseY = 700 + undertaleBg.height / 2 + 60;
var undertaleTextColor = "#fffbe7";
var undertaleTextJitter = 7;
var undertaleTextJitterTime = 120 + Math.random() * 100;
var totalTextWidth = 0;
for (var i = 0; i < undertaleTextStr.length; i++) {
var ch = undertaleTextStr[i];
var t = new Text2(ch, {
size: undertaleTextFontSize,
fill: undertaleTextColor
});
t.anchor.set(0.5, 0.5);
undertaleText.push(t);
totalTextWidth += t.width + undertaleTextSpacing;
}
totalTextWidth -= undertaleTextSpacing; // remove last extra spacing
// Position each letter centered above undertale image
var startX = undertaleTextBaseX - totalTextWidth / 2;
var currX = startX;
for (var i = 0; i < undertaleText.length; i++) {
var t = undertaleText[i];
t.x = currX + t.width / 2;
t.y = undertaleTextBaseY;
currX += t.width + undertaleTextSpacing;
game.addChild(t);
}
// Animate jitter for each letter using tween
function vibrateLetter(letter, baseX, baseY) {
function doJitter() {
var dx = (Math.random() - 0.5) * undertaleTextJitter;
var dy = (Math.random() - 0.5) * undertaleTextJitter;
tween(letter, {
x: baseX + dx,
y: baseY + dy
}, {
duration: 60 + Math.random() * 60,
easing: tween.linear,
onFinish: doJitter
});
}
doJitter();
}
for (var i = 0; i < undertaleText.length; i++) {
vibrateLetter(undertaleText[i], undertaleText[i].x, undertaleText[i].y);
}
// Area for enemy spawn: use bottom of screen
var undertaleSpawnY = 2732 - 200;
var undertaleSpawnYMax = 2732 - 60;
// --- Score Display ---
scoreTxt = new Text2('0.0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Play Undertale music at game start
LK.playMusic('undertale_theme');
// --- Hero Initialization ---
hero = new Hero();
hero.x = 2048 / 2;
hero.y = 2732 - 350;
game.addChild(hero);
// --- Touch/Drag Controls ---
function handleMove(x, y, obj) {
if (dragNode) {
// Clamp hero inside game area (with margin)
var margin = 80;
var nx = Math.max(margin, Math.min(2048 - margin, x));
var ny = Math.max(300, Math.min(2732 - margin, y));
dragNode.x = nx;
dragNode.y = ny;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Only allow drag if touch is on hero
var dx = x - hero.x;
var dy = y - hero.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < hero.width / 1.2) {
dragNode = hero;
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// --- Attack on Tap (anywhere except top 200px) ---
game.tap = function (x, y, obj) {
if (y > 200 && canAttack) {
spawnAttack();
}
};
// Since LK does not have tap, simulate with up event if not dragging
game.up = function (x, y, obj) {
if (!dragNode && y > 200 && canAttack) {
spawnAttack();
}
dragNode = null;
};
// --- Attack Logic ---
function spawnAttack() {
// Only one attack at a time
if (!canAttack) return;
canAttack = false;
attackCooldownTick = attackCooldown;
var atk = new HeroAttack();
atk.x = hero.x;
atk.y = hero.y - hero.height / 2 - atk.height / 2;
attacks.push(atk);
game.addChild(atk);
// Animate attack (scale up then fade)
atk.scaleX = 0.7;
atk.scaleY = 0.7;
tween(atk, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 120,
easing: tween.easeOut
});
tween(atk, {
alpha: 0
}, {
duration: 180,
easing: tween.linear,
onFinish: function onFinish() {}
});
}
// --- Enemy Spawning ---
function spawnEnemy() {
var enemy = new Enemy();
// Random x, avoid edges
var margin = 120;
enemy.x = margin + Math.random() * (2048 - 2 * margin);
// Spawn from bottom of screen
enemy.y = 2732 - 60;
// Random type, more types as time increases
var type = 0;
var t = survivalFrames / 60;
if (t < 5) {
type = 0;
} else if (t < 12) {
type = Math.random() < 0.7 ? 0 : 1;
} else {
var r = Math.random();
if (r < 0.5) type = 0;else if (r < 0.8) type = 1;else type = 2;
}
enemy.setType(type);
enemies.push(enemy);
game.addChild(enemy);
}
// --- Main Game Update ---
game.update = function () {
// --- Attack cooldown ---
if (!canAttack) {
attackCooldownTick--;
if (attackCooldownTick <= 0) {
canAttack = true;
}
}
// --- Survival time ---
survivalFrames++;
var survivalSeconds = survivalFrames / 60;
scoreTxt.setText(survivalSeconds.toFixed(1));
// Replace undertale image with flow image after 35 seconds
if (typeof undertaleBg !== "undefined" && undertaleBg !== null && survivalSeconds > 35) {
// Remove undertaleBg if present
undertaleBg.destroy();
undertaleBg = null;
// Remove undertale text if present
if (typeof undertaleText !== "undefined" && undertaleText && undertaleText.length) {
for (var i = 0; i < undertaleText.length; i++) {
if (undertaleText[i] && undertaleText[i].destroy) undertaleText[i].destroy();
}
undertaleText = [];
}
// Add flow image in same position/scale
undertaleBg = LK.getAsset('flow', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 700,
scaleX: 18,
scaleY: 18
});
game.addChild(undertaleBg);
}
// --- Win check by survival time ---
// Removed win condition for endless mode
// --- Spawn enemies ---
spawnTick++;
// Decrease interval as time increases (gets harder)
var minInterval = 24;
spawnInterval = Math.max(minInterval, 60 - Math.floor(survivalSeconds / 2) * 4);
if (spawnTick >= spawnInterval) {
spawnTick = 0;
spawnEnemy();
}
// --- Update enemies ---
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Off-screen detection
if (enemy.lastY < 2732 + 100 && enemy.y >= 2732 + 100) {
// Enemy left screen, destroy
enemy.destroy();
enemies.splice(i, 1);
continue;
}
enemy.lastY = enemy.y;
// Collision with hero
var currIntersect = enemy.intersects(hero);
if (!enemy.lastIntersecting && currIntersect) {
// Hit! Game over
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
enemy.lastIntersecting = currIntersect;
}
// --- Update attacks ---
for (var j = attacks.length - 1; j >= 0; j--) {
var atk = attacks[j];
atk.update();
// Remove if expired
if (atk.lifetime <= 0) {
atk.destroy();
attacks.splice(j, 1);
continue;
}
// Check collision with enemies
for (var k = enemies.length - 1; k >= 0; k--) {
var enemy = enemies[k];
var currAtkIntersect = atk.intersects(enemy);
if (!atk.lastIntersecting && currAtkIntersect) {
// Destroy enemy
enemy.destroy();
enemies.splice(k, 1);
// Flash effect on attack
LK.effects.flashObject(atk, 0xffff00, 200);
// Remove attack (one hit per attack)
atk.destroy();
attacks.splice(j, 1);
break;
}
atk.lastIntersecting = currAtkIntersect;
}
}
};
// --- Prevent elements in top left 100x100 (menu area) ---
// --- End of Game Code ---
kalbi kırmızı yap. In-Game asset. 2d. High contrast. No shadows. bu kalbi kırmızı yap
undertale oyunundaki flowey karakterini yap. In-Game asset. 2d. High contrast. No shadows
bu resmi yaprağa çevir rengi beyaz olsun . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
undertale flowy character angry. In-Game asset. 2d. High contrast. No shadows. undertale game