User prompt
Gaster blaster varlığı etrafta harket etmek yerine lazerin başında beklesin ve birden fazla olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Eşya butonunu kullanım hakkını 3'e çıkar
User prompt
Lazer saldırısını Gasterblaster adlı varlık yapsın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Karakterin canını 150 yap ve lazer atan varlığı varlıklar bölümüne ekle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyunu geçici olarak 9.wave de başlat ve karakterin canını arttır
User prompt
Oyunu geçici olarak 9.wave'de başlat
User prompt
Sans 10. Wave Dursunbey hiç saldırı yapmasın.Onun yerine bize merhamet teklif etsin ve bize merhamet etsin.Bu sırada bizde sans'a merhamet edersek bizi kandırsın ve bizi öldürsün.Sans'a merhamet etmeyip ona saldırır sak saldırıdan kaçıp bize"eh en azından denedim"desin ve oyun devam etsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Oyunu şimdilik geçici olarak 9. Wave'de başlat
User prompt
Sans 10. Wawe dursun ve bize saldırmak yerine bize mehamet etsin.Eğer sans merhemt ettiğinde bizde ona merhamet edersek sans bizi kandırıp bizi öldürdürsün.Eğer sans merhamet ettiğinde biz ona saldırır sak saldırıdan kaçıp"eh en azından denedim" desin ve oyun devam etsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sihirli mermi yerine mavi ve turuncu mermi ekle,mavi mermi olduğumuz yerde durduğumuz zaman biza birşey yapmasın,turuncu mermide tam tersi hareket ettiğimiz zaman bişey yapmasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sans'ın canını bir'e indir ama bütün saldırılardan kaçabilsin.Ama 15.wave'den sonra yorulsun ve ona saldırıp onu yenelim ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sağlık çubuğu eylem düğmelerinin yanında görümsün düğmelerin
User prompt
Can barımız görünür olsun
User prompt
Lazer saldırısı 4.wave'e kadar deaktif halde kalsın,4.wave'den sonra aktif hale gelsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Lazer saldırısı 4.dalgadan sonra geldin
User prompt
Lazer saldırı dar bir alana uzun bir saldırı yapsın ve sans'ın kontrol ettiği varlık savaş kutusunun etrafında gezsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sans lazeri ağzından atmasın,sans'ın kontrol ettiği varlık ağzından atsın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Lazeri bir sans'ın kontrol ettiği bir varlık ağzından atsın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Lazer saldırısını yapan varlığı varlıklar bölümüne ekle ve saldırı savaş kutusunun iki ucunada ulaşsın,lazer saldırısı çaprazda olabilsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Işın saldırısı yapan bir varlık ekle çok sade duruyo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sans sadece biz ona saldırı yaptığımız zaman kaçabilsin ve yaptığımız saldırıdan hasar almasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Sans boyunu biraz daha büyütve sans arada bizim saldırılarımızdan kaçabilsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Yazıları biraz daha kalın yap, sans'ı arka plana ekleki diyaloğun önüne geçmesin
User prompt
Sans'ın"bugün güzel bir gün,kuşlar cıvıldıyor,çiçekler çiçeklenir,böyle günler sizin gibi çocuklar,CEHENNEMDE YANMALI"diyaloğu diyalog kutusunun dışına çıkıyor, bunu diyalog kutusunun içine sığacak hale getir
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ActionButton = Container.expand(function (label, action) { var self = Container.call(this); var buttonGraphics = self.attachAsset('actionButton', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); var buttonText = new Text2(label, { size: 60, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.action = action; self.down = function (x, y, obj) { if (isActionPhase) { tween(buttonGraphics, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100, onFinish: function onFinish() { tween(buttonGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); self.action(); } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = 0; self.speedY = 0; self.lifetime = 0; self.maxLifetime = 300; // 5 seconds at 60fps self.update = function () { self.x += self.speedX; self.y += self.speedY; self.lifetime++; // Remove if too old or off screen if (self.lifetime > self.maxLifetime || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { self.markForDestroy = true; } }; return self; }); var Heart = Container.expand(function () { var self = Container.call(this); var heartGraphics = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); // Rotate to make it look like a heart heartGraphics.rotation = Math.PI / 4; self.speed = 8; self.isDragging = false; return self; }); var LaserAttack = Container.expand(function () { var self = Container.call(this); // Warning phase graphics var warningGraphics = self.attachAsset('laserWarning', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Actual laser beam graphics var laserGraphics = self.attachAsset('laserBeam', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.phase = 'warning'; // warning, firing, done self.warningDuration = 60; // 1 second warning self.firingDuration = 90; // 1.5 seconds firing self.timer = 0; self.direction = 'horizontal'; // horizontal or vertical self.isActive = false; self.startWarning = function () { self.isActive = true; self.phase = 'warning'; self.timer = 0; // Animate warning appearing tween(warningGraphics, { alpha: 0.6 }, { duration: 300, easing: tween.easeInOut }); // Pulsing warning effect var _pulseWarning = function pulseWarning() { if (self.phase === 'warning') { tween(warningGraphics, { alpha: 0.3 }, { duration: 400, easing: tween.easeInOut, onFinish: function onFinish() { tween(warningGraphics, { alpha: 0.6 }, { duration: 400, easing: tween.easeInOut, onFinish: _pulseWarning }); } }); } }; _pulseWarning(); }; self.startFiring = function () { self.phase = 'firing'; self.timer = 0; // Hide warning, show laser tween(warningGraphics, { alpha: 0 }, { duration: 100 }); tween(laserGraphics, { alpha: 1 }, { duration: 100 }); // Laser intensity effect tween(laserGraphics, { scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(laserGraphics, { scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); }; self.update = function () { if (!self.isActive) return; self.timer++; if (self.phase === 'warning' && self.timer >= self.warningDuration) { self.startFiring(); } else if (self.phase === 'firing' && self.timer >= self.firingDuration) { self.phase = 'done'; tween(laserGraphics, { alpha: 0 }, { duration: 300 }); self.markForDestroy = true; } // Check collision during firing phase if (self.phase === 'firing' && heart) { var collision = false; if (self.direction === 'horizontal') { // Check if heart is within laser beam vertically var beamTop = self.y - laserGraphics.height / 2; var beamBottom = self.y + laserGraphics.height / 2; if (heart.y >= beamTop && heart.y <= beamBottom) { collision = true; } } else if (self.direction === 'vertical') { // Vertical laser var beamLeft = self.x - laserGraphics.width / 2; var beamRight = self.x + laserGraphics.width / 2; if (heart.x >= beamLeft && heart.x <= beamRight) { collision = true; } } else if (self.direction === 'diagonal1') { // Diagonal laser (top-left to bottom-right) var dx = heart.x - self.x; var dy = heart.y - self.y; var distanceFromLine = Math.abs(dx - dy) / Math.sqrt(2); if (distanceFromLine <= laserGraphics.height / 2) { collision = true; } } else if (self.direction === 'diagonal2') { // Diagonal laser (top-right to bottom-left) var dx = heart.x - self.x; var dy = heart.y - self.y; var distanceFromLine = Math.abs(dx + dy) / Math.sqrt(2); if (distanceFromLine <= laserGraphics.height / 2) { collision = true; } } if (collision) { LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); playerHealth -= 20; if (playerHealth <= 0) { playerHealth = 0; updateHealthBars(); LK.showGameOver(); } else { updateHealthBars(); } self.phase = 'done'; tween(laserGraphics, { alpha: 0 }, { duration: 300 }); self.markForDestroy = true; } } }; return self; }); var LaserEntity = Container.expand(function () { var self = Container.call(this); // Reference to Sans for positioning and animation self.sansRef = null; self.fireTimer = 0; self.fireInterval = 180; // Fire every 3 seconds self.isActive = true; self.setSansReference = function (sansDisplayObject) { self.sansRef = sansDisplayObject; }; self.update = function () { if (!self.isActive || !self.sansRef) return; // Fire laser periodically self.fireTimer++; if (self.fireTimer >= self.fireInterval) { self.fireLaser(); self.fireTimer = 0; // Randomize next fire interval slightly self.fireInterval = 150 + Math.random() * 60; } }; self.fireLaser = function () { if (!self.sansRef) return; // Calculate Sans mouth position (slightly below center) var sansX = self.sansRef.x; var sansY = self.sansRef.y + 20; // Mouth position offset // Flash Sans when firing tween(self.sansRef, { tint: 0xffffff }, { duration: 200, onFinish: function onFinish() { tween(self.sansRef, { tint: 0xffffff }, { duration: 300 }); } }); var laser = new LaserAttack(); // Choose random laser direction and position - now includes diagonal var direction = Math.floor(Math.random() * 4); // 0=horizontal, 1=vertical, 2=diagonal1, 3=diagonal2 if (direction === 0) { // Horizontal laser starting from Sans mouth laser.direction = 'horizontal'; laser.x = sansX; laser.y = sansY; laser.rotation = 0; } else if (direction === 1) { // Vertical laser starting from Sans mouth laser.direction = 'vertical'; laser.x = sansX; laser.y = sansY; laser.rotation = Math.PI / 2; } else if (direction === 2) { // Diagonal laser (top-left to bottom-right) from Sans mouth laser.direction = 'diagonal1'; laser.x = sansX; laser.y = sansY; laser.rotation = Math.PI / 4; } else { // Diagonal laser (top-right to bottom-left) from Sans mouth laser.direction = 'diagonal2'; laser.x = sansX; laser.y = sansY; laser.rotation = -Math.PI / 4; } laser.startWarning(); laserAttacks.push(laser); game.addChild(laser); }; return self; }); var MagicBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('magicBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = 0; self.speedY = 0; self.lifetime = 0; self.maxLifetime = 360; self.rotationSpeed = 0.1; self.update = function () { self.x += self.speedX; self.y += self.speedY; self.lifetime++; // Rotate magic bullets bulletGraphics.rotation += self.rotationSpeed; // Slight homing behavior towards center var centerX = 1024; var centerY = 1366; var dx = centerX - self.x; var dy = centerY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 50) { self.speedX += dx / distance * 0.05; self.speedY += dy / distance * 0.05; } // Cap speed var speed = Math.sqrt(self.speedX * self.speedX + self.speedY * self.speedY); if (speed > 6) { self.speedX = self.speedX / speed * 6; self.speedY = self.speedY / speed * 6; } if (self.lifetime > self.maxLifetime || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { self.markForDestroy = true; } }; return self; }); var SpeechBubble = Container.expand(function (message) { var self = Container.call(this); // Create speech bubble background var bubbleWidth = Math.min(1400, message.length * 25 + 200); var bubbleHeight = 300; var bubbleBg = LK.getAsset('actionButton', { anchorX: 0.5, anchorY: 0.5, scaleX: bubbleWidth / 400, scaleY: bubbleHeight / 150, tint: 0xffffff, alpha: 0.9 }); self.addChild(bubbleBg); // Create speech bubble border var bubbleBorder = LK.getAsset('actionButton', { anchorX: 0.5, anchorY: 0.5, scaleX: (bubbleWidth + 20) / 400, scaleY: (bubbleHeight + 20) / 150, tint: 0x000000, alpha: 0.8 }); self.addChild(bubbleBorder); self.addChild(bubbleBg); // Create speech bubble tail (pointing down to Sans) var tailWidth = 40; var tailHeight = 60; var tail = LK.getAsset('actionButton', { anchorX: 0.5, anchorY: 0, scaleX: tailWidth / 400, scaleY: tailHeight / 150, tint: 0xffffff, alpha: 0.9, y: bubbleHeight / 2, rotation: Math.PI / 4 }); self.addChild(tail); // Create message text var messageText = new Text2(message, { size: 35, fill: 0x000000, font: "'GillSans-Bold',Impact,'Arial Black',Tahoma" }); messageText.anchor.set(0.5, 0.5); self.addChild(messageText); return self; }); var SpiralBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.centerX = 1024; self.centerY = 1366; self.angle = 0; self.radius = 50; self.radiusSpeed = 2; self.angleSpeed = 0.1; self.lifetime = 0; self.maxLifetime = 400; self.update = function () { self.lifetime++; self.angle += self.angleSpeed; self.radius += self.radiusSpeed; self.x = self.centerX + Math.cos(self.angle) * self.radius; self.y = self.centerY + Math.sin(self.angle) * self.radius; if (self.lifetime > self.maxLifetime || self.radius > 800) { self.markForDestroy = true; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state variables var heart; var bullets = []; var magicBullets = []; var laserAttacks = []; var spiralBullets = []; var battleBox; var isDragging = false; var dragOffsetX = 0; var dragOffsetY = 0; var waveTimer = 0; var currentWave = 1; var waveSpawnTimer = 0; var gameTime = 0; var isActionPhase = false; var actionTimer = 0; var playerHealth = 100; var maxHealth = 100; var hasItem = true; var enemyHealth = 200; var maxEnemyHealth = 200; var mercyAttempts = 0; var maxMercyAttempts = 3; var isShowingDialogue = false; var dialogueTimer = 0; var currentDialogue = null; // Create UI elements var scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var waveText = new Text2('Wave 1', { size: 60, fill: 0xFFFF00 }); waveText.anchor.set(0, 0); waveText.x = 50; waveText.y = 200; LK.gui.topLeft.addChild(waveText); // Action phase UI var actionPhaseText = new Text2('Wybierz akcję!', { size: 80, fill: 0xFFFF00 }); actionPhaseText.anchor.set(0.5, 0.5); actionPhaseText.x = 1024; actionPhaseText.y = 300; actionPhaseText.alpha = 0; // Health bars var playerHealthBarBg = LK.getAsset('healthBarBg', { anchorX: 0, anchorY: 0.5, x: 100, y: 2600 }); var playerHealthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 100, y: 2600 }); var playerHealthText = new Text2('HP: 100/100', { size: 50, fill: 0xFFFFFF }); playerHealthText.anchor.set(0, 0.5); playerHealthText.x = 520; playerHealthText.y = 2600; var enemyHealthBarBg = LK.getAsset('healthBarBg', { anchorX: 0, anchorY: 0.5, x: 1500, y: 100 }); var enemyHealthBar = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0.5, x: 1500, y: 100, tint: 0xff0000 }); var enemyHealthText = new Text2('Sans HP: 200/200', { size: 50, fill: 0xFFFFFF }); enemyHealthText.anchor.set(1, 0.5); enemyHealthText.x = 1900; enemyHealthText.y = 100; // Enemy display at top - Sans (positioned in background) - larger size var enemyDisplay = LK.getAsset('sans', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 250, scaleX: 1.5, scaleY: 1.5 }); // Sans dodging variables var sansDodgeTimer = 0; var sansDodgeCooldown = 0; var sansOriginalX = 1024; // Add Sans to game background first so dialogue appears on top game.addChild(enemyDisplay); LK.gui.addChild(playerHealthBarBg); LK.gui.addChild(playerHealthBar); LK.gui.addChild(playerHealthText); LK.gui.addChild(enemyHealthBarBg); LK.gui.addChild(enemyHealthBar); LK.gui.addChild(enemyHealthText); // Action buttons var attackButton = new ActionButton('SALDIRI', function () { // Check if Sans should dodge (50% chance if cooldown is ready) var shouldDodge = sansDodgeCooldown === 0 && Math.random() < 0.5; var damage = 0; var damageText; if (shouldDodge) { // Sans dodges - no damage taken // Choose random dodge direction var dodgeDirection = Math.random() < 0.5 ? -1 : 1; var dodgeDistance = 200 + Math.random() * 150; var newX = sansOriginalX + dodgeDirection * dodgeDistance; // Keep Sans within screen bounds newX = Math.max(200, Math.min(1848, newX)); // Dodge animation - quick movement tween(enemyDisplay, { x: newX }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { // Return to original position after a delay LK.setTimeout(function () { tween(enemyDisplay, { x: sansOriginalX }, { duration: 800, easing: tween.easeInOut }); }, 1000); } }); // Set cooldown to prevent constant dodging sansDodgeCooldown = 300; // 5 seconds cooldown // Show dodge message damageText = new Text2('MISS!\nSans kaçtı!', { size: 60, fill: 0xffff00 }); } else { // Normal attack - deal damage damage = Math.floor(Math.random() * 20) + 10; enemyHealth -= damage; if (enemyHealth <= 0) { enemyHealth = 0; LK.showYouWin(); } // Show damage dealt and remaining health damageText = new Text2('-' + damage + ' HP!\nKalan Can: ' + enemyHealth + '/' + maxEnemyHealth, { size: 60, fill: 0xff4444 }); } damageText.anchor.set(0.5, 0.5); damageText.x = 1024; damageText.y = 400; game.addChild(damageText); tween(damageText, { y: damageText.y - 100, alpha: 0 }, { duration: 2000, onFinish: function onFinish() { damageText.destroy(); } }); updateHealthBars(); endActionPhase(); }); var actButton = new ActionButton('EYLEM', function () { // Act action - show enemy stats var statsText = new Text2('Sans İstatistikleri:\nSaldırı: 15\nSavunma: 8\nHP: ' + enemyHealth + '/' + maxEnemyHealth + '\n*Seni yargılıyor...', { size: 50, fill: 0xFFFFFF }); statsText.anchor.set(0.5, 0.5); statsText.x = 1024; statsText.y = 1366; game.addChild(statsText); tween(statsText, { alpha: 0 }, { duration: 3000, onFinish: function onFinish() { statsText.destroy(); } }); endActionPhase(); }); var itemButton = new ActionButton('EŞYA', function () { // Item action - heal player if (hasItem && playerHealth < maxHealth) { playerHealth = Math.min(maxHealth, playerHealth + 30); hasItem = false; var healText = new Text2('+30 HP!', { size: 60, fill: 0x00ff00 }); healText.anchor.set(0.5, 0.5); healText.x = heart.x; healText.y = heart.y - 50; game.addChild(healText); tween(healText, { y: healText.y - 100, alpha: 0 }, { duration: 2000, onFinish: function onFinish() { healText.destroy(); } }); updateHealthBars(); } endActionPhase(); }); var mercyButton = new ActionButton('MERHAMET', function () { mercyAttempts++; var mercyText; if (mercyAttempts < maxMercyAttempts) { // Sans doesn't forgive yet var responses = ['*Sans sana şüpheyle bakıyor.\n*Henüz affetmeye hazır değil.', '*Sans hala kararlı görünüyor.\n*Biraz daha sabır gerekiyor.', '*Sans\'ın gözlerinde değişim var...\n*Ama henüz yeterli değil.']; mercyText = new Text2(responses[mercyAttempts - 1] + '\n\n(' + mercyAttempts + '/' + maxMercyAttempts + ' deneme)', { size: 60, fill: 0xffff00 }); } else { // Sans finally forgives mercyText = new Text2('*Sans derin bir nefes alıyor...\n*"tamam, belki sen farklısın."\n*Sans seni affetti!\nKazandın!', { size: 70, fill: 0x00ff00 }); } mercyText.anchor.set(0.5, 0.5); mercyText.x = 1024; mercyText.y = 1366; game.addChild(mercyText); if (mercyAttempts >= maxMercyAttempts) { LK.setTimeout(function () { LK.showYouWin(); }, 3000); } else { tween(mercyText, { alpha: 0 }, { duration: 3000, onFinish: function onFinish() { mercyText.destroy(); } }); } endActionPhase(); }); attackButton.x = 512; attackButton.y = 2400; actButton.x = 1024; actButton.y = 2400; itemButton.x = 1536; itemButton.y = 2400; mercyButton.x = 1024; mercyButton.y = 2600; game.addChild(actionPhaseText); game.addChild(attackButton); game.addChild(actButton); game.addChild(itemButton); game.addChild(mercyButton); // Initially hide action elements attackButton.alpha = 0; actButton.alpha = 0; itemButton.alpha = 0; mercyButton.alpha = 0; // Sans dialogue messages var sansDialogues = ["bugün güzel bir gün,kuşlar cıvıldıyor, çiçekler açıyor,böyle günlerde senin gibi çocuklar, CEHENNEMDE YANMALI", "*hmm... yaptıklarını hatırlıyorum.", "*kaç tane masumun canını aldın acaba?", "*o gülümseme yüzünden silinmiyor, değil mi?", "*gerçekten pişman olduğunu sanıyor musun?", "*haha... bu çok komik.", "*seni affetmemi mi bekliyorsun?", "*yaptıklarının hesabını vereceksin.", "*her şeyi hatırlıyorum, her şeyi.", "*bu sefer farklı olacağını mı sanıyorsun?", "*sen sadece bir katilsin, başka bir şey değil."]; // Create battle box (play area boundary) battleBox = game.addChild(LK.getAsset('battleBox', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, alpha: 0.1 })); // Create heart heart = game.addChild(new Heart()); heart.x = 1024; heart.y = 1366; // Create laser entity and link it to Sans var laserEntity = new LaserEntity(); laserEntity.setSansReference(enemyDisplay); // Touch/drag handlers game.down = function (x, y, obj) { // Allow dragging from anywhere on screen for mobile isDragging = true; dragOffsetX = x - heart.x; dragOffsetY = y - heart.y; }; game.move = function (x, y, obj) { if (isDragging) { var newX = x - dragOffsetX; var newY = y - dragOffsetY; // Constrain to battle box var boxLeft = battleBox.x - battleBox.width / 2 + 30; var boxRight = battleBox.x + battleBox.width / 2 - 30; var boxTop = battleBox.y - battleBox.height / 2 + 30; var boxBottom = battleBox.y + battleBox.height / 2 - 30; heart.x = Math.max(boxLeft, Math.min(boxRight, newX)); heart.y = Math.max(boxTop, Math.min(boxBottom, newY)); } }; game.up = function (x, y, obj) { isDragging = false; }; // Spawn patterns function spawnStraightBullets() { var numBullets = 4 + Math.floor(currentWave / 2); var side = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left for (var i = 0; i < numBullets; i++) { var bullet = new Bullet(); var speed = 5 + currentWave * 0.8; switch (side) { case 0: // Top bullet.x = 324 + 1400 / numBullets * i; bullet.y = 566; bullet.speedY = speed; break; case 1: // Right bullet.x = 1724; bullet.y = 666 + 1400 / numBullets * i; bullet.speedX = -speed; break; case 2: // Bottom bullet.x = 324 + 1400 / numBullets * i; bullet.y = 2066; bullet.speedY = -speed; break; case 3: // Left bullet.x = 324; bullet.y = 666 + 1400 / numBullets * i; bullet.speedX = speed; break; } bullets.push(bullet); game.addChild(bullet); } } function spawnConvergingBullets() { var numBullets = 8 + currentWave; var centerX = heart.x; var centerY = heart.y; for (var i = 0; i < numBullets; i++) { var angle = Math.PI * 2 * i / numBullets; var distance = 800; var bullet = new Bullet(); bullet.x = centerX + Math.cos(angle) * distance; bullet.y = centerY + Math.sin(angle) * distance; var speed = 4 + currentWave * 0.6; bullet.speedX = -Math.cos(angle) * speed; bullet.speedY = -Math.sin(angle) * speed; bullets.push(bullet); game.addChild(bullet); } } function spawnMagicBullets() { var numBullets = 3 + Math.floor(currentWave / 3); for (var i = 0; i < numBullets; i++) { var bullet = new MagicBullet(); // Spawn from random edge var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: // Top bullet.x = 324 + Math.random() * 1400; bullet.y = 466; break; case 1: // Right bullet.x = 1824; bullet.y = 566 + Math.random() * 1400; break; case 2: // Bottom bullet.x = 324 + Math.random() * 1400; bullet.y = 2166; break; case 3: // Left bullet.x = 224; bullet.y = 566 + Math.random() * 1400; break; } // Initial speed towards center with some randomness var dx = 1024 - bullet.x; var dy = 1366 - bullet.y; var distance = Math.sqrt(dx * dx + dy * dy); var speed = 3 + currentWave * 0.4; bullet.speedX = dx / distance * speed + (Math.random() - 0.5) * 2; bullet.speedY = dy / distance * speed + (Math.random() - 0.5) * 2; magicBullets.push(bullet); game.addChild(bullet); } } function spawnLaserAttack() { var laser = new LaserAttack(); // Random direction including diagonals var direction = Math.floor(Math.random() * 4); // 0=horizontal, 1=vertical, 2=diagonal1, 3=diagonal2 if (direction === 0) { // Horizontal laser spanning full battle box laser.direction = 'horizontal'; laser.x = battleBox.x; laser.y = battleBox.y - battleBox.height / 2 + Math.random() * battleBox.height; // Random Y position within battle box laser.rotation = 0; } else if (direction === 1) { // Vertical laser spanning full battle box laser.direction = 'vertical'; laser.x = battleBox.x - battleBox.width / 2 + Math.random() * battleBox.width; // Random X position within battle box laser.y = battleBox.y; laser.rotation = Math.PI / 2; } else if (direction === 2) { // Diagonal laser (top-left to bottom-right) laser.direction = 'diagonal1'; laser.x = battleBox.x; laser.y = battleBox.y; laser.rotation = Math.PI / 4; } else { // Diagonal laser (top-right to bottom-left) laser.direction = 'diagonal2'; laser.x = battleBox.x; laser.y = battleBox.y; laser.rotation = -Math.PI / 4; } laser.startWarning(); laserAttacks.push(laser); game.addChild(laser); } function spawnSpiralAttack() { var numSpirals = 2 + Math.floor(currentWave / 4); for (var i = 0; i < numSpirals; i++) { var spiral = new SpiralBullet(); spiral.angle = Math.PI * 2 * i / numSpirals; spiral.angleSpeed = 0.08 + Math.random() * 0.04; spiral.radiusSpeed = 1.5 + Math.random() * 1; spiralBullets.push(spiral); game.addChild(spiral); } } function showSansDialogue(message, callback) { isShowingDialogue = true; dialogueTimer = 0; currentDialogue = new SpeechBubble(message); currentDialogue.x = 1024; currentDialogue.y = 450; // Position above Sans currentDialogue.alpha = 0; currentDialogue.scaleX = 0.3; currentDialogue.scaleY = 0.3; game.addChild(currentDialogue); // Fade in dialogue with bounce effect tween(currentDialogue, { alpha: 1, scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.bounceOut, onFinish: function onFinish() { // Keep dialogue visible for 3 seconds LK.setTimeout(function () { // Fade out dialogue tween(currentDialogue, { alpha: 0, scaleX: 0.8, scaleY: 0.8 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { currentDialogue.destroy(); currentDialogue = null; isShowingDialogue = false; if (callback) callback(); } }); }, 3000); } }); } function startActionPhase() { isActionPhase = true; actionTimer = 0; // Stop all enemy attacks for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].destroy(); } bullets = []; for (var j = magicBullets.length - 1; j >= 0; j--) { magicBullets[j].destroy(); } magicBullets = []; for (var l = laserAttacks.length - 1; l >= 0; l--) { laserAttacks[l].destroy(); } laserAttacks = []; for (var s = spiralBullets.length - 1; s >= 0; s--) { spiralBullets[s].destroy(); } spiralBullets = []; // Show action UI tween(actionPhaseText, { alpha: 1 }, { duration: 500 }); tween(attackButton, { alpha: 1 }, { duration: 500 }); tween(actButton, { alpha: 1 }, { duration: 500 }); tween(itemButton, { alpha: hasItem ? 1 : 0.3 }, { duration: 500 }); tween(mercyButton, { alpha: 1 }, { duration: 500 }); } function endActionPhase() { isActionPhase = false; waveSpawnTimer = 0; // Hide action UI tween(actionPhaseText, { alpha: 0 }, { duration: 500 }); tween(attackButton, { alpha: 0 }, { duration: 500 }); tween(actButton, { alpha: 0 }, { duration: 500 }); tween(itemButton, { alpha: 0 }, { duration: 500 }); tween(mercyButton, { alpha: 0 }, { duration: 500 }); } function updateHealthBars() { var playerHealthPercent = playerHealth / maxHealth; var enemyHealthPercent = enemyHealth / maxEnemyHealth; tween(playerHealthBar, { scaleX: playerHealthPercent }, { duration: 300 }); tween(enemyHealthBar, { scaleX: enemyHealthPercent }, { duration: 300 }); playerHealthText.setText('HP: ' + playerHealth + '/' + maxHealth); enemyHealthText.setText('Sans HP: ' + enemyHealth + '/' + maxEnemyHealth); } // Main game update game.update = function () { gameTime++; // Don't update game during dialogue if (isShowingDialogue) { return; } if (isActionPhase) { actionTimer++; // Auto-end action phase after 10 seconds if no action taken if (actionTimer > 600) { endActionPhase(); } return; } waveTimer++; waveSpawnTimer++; // Update score LK.setScore(Math.floor(gameTime / 60)); scoreText.setText('Score: ' + LK.getScore()); // Wave progression and action phase trigger if (waveTimer > 600 && !isShowingDialogue) { // Show Sans dialogue before action phase var dialogueIndex = Math.min(currentWave - 1, sansDialogues.length - 1); var message = sansDialogues[dialogueIndex]; showSansDialogue(message, function () { // 10 seconds per wave, then action phase startActionPhase(); waveTimer = 0; currentWave++; waveText.setText('Wave ' + currentWave); // Flash effect for new wave LK.effects.flashScreen(0x444444, 500); }); return; } // Spawn bullets based on wave and timing if (waveSpawnTimer > 60 - currentWave * 3) { // Faster spawning each wave waveSpawnTimer = 0; var pattern = Math.floor(Math.random() * 5); if (currentWave < 3) pattern = 0; // Only straight bullets early else if (currentWave < 5) pattern = Math.floor(Math.random() * 3); // No lasers/spirals very early switch (pattern) { case 0: spawnStraightBullets(); break; case 1: spawnConvergingBullets(); break; case 2: spawnMagicBullets(); break; case 3: spawnLaserAttack(); break; case 4: spawnSpiralAttack(); break; } } // Sans dodging cooldown management if (sansDodgeCooldown > 0) { sansDodgeCooldown--; } // Update laser entity (Sans-controlled) if (laserEntity && laserEntity.isActive) { laserEntity.update(); } // Update and check bullet collisions for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.markForDestroy) { bullet.destroy(); bullets.splice(i, 1); continue; } // Collision with heart if (bullet.intersects(heart)) { LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); playerHealth -= 10; if (playerHealth <= 0) { playerHealth = 0; updateHealthBars(); LK.showGameOver(); return; } updateHealthBars(); bullet.destroy(); bullets.splice(i, 1); continue; } } // Update and check magic bullet collisions for (var j = magicBullets.length - 1; j >= 0; j--) { var magicBullet = magicBullets[j]; if (magicBullet.markForDestroy) { magicBullet.destroy(); magicBullets.splice(j, 1); continue; } // Collision with heart if (magicBullet.intersects(heart)) { LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); playerHealth -= 15; if (playerHealth <= 0) { playerHealth = 0; updateHealthBars(); LK.showGameOver(); return; } updateHealthBars(); magicBullet.destroy(); magicBullets.splice(j, 1); continue; } } // Update and check laser attacks for (var l = laserAttacks.length - 1; l >= 0; l--) { var laser = laserAttacks[l]; if (laser.markForDestroy) { laser.destroy(); laserAttacks.splice(l, 1); continue; } } // Update and check spiral bullet collisions for (var s = spiralBullets.length - 1; s >= 0; s--) { var spiral = spiralBullets[s]; if (spiral.markForDestroy) { spiral.destroy(); spiralBullets.splice(s, 1); continue; } // Collision with heart if (spiral.intersects(heart)) { LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); playerHealth -= 12; if (playerHealth <= 0) { playerHealth = 0; updateHealthBars(); LK.showGameOver(); return; } updateHealthBars(); spiral.destroy(); spiralBullets.splice(s, 1); continue; } } // Play dodge sound occasionally for close calls if (gameTime % 180 === 0) { var closeCalls = 0; for (var k = 0; k < bullets.length; k++) { var dist = Math.sqrt(Math.pow(bullets[k].x - heart.x, 2) + Math.pow(bullets[k].y - heart.y, 2)); if (dist < 100) closeCalls++; } if (closeCalls > 2) { LK.getSound('dodge').play(); } } }; // Initialize health bars updateHealthBars(); // Start background music LK.playMusic('megalovania'); ;
===================================================================
--- original.js
+++ change.js
@@ -229,29 +229,18 @@
return self;
});
var LaserEntity = Container.expand(function () {
var self = Container.call(this);
- // Visual representation of the laser entity
- var entityGraphics = self.attachAsset('magicBullet', {
- anchorX: 0.5,
- anchorY: 0.5,
- scaleX: 2,
- scaleY: 2,
- tint: 0xff6600
- });
+ // Reference to Sans for positioning and animation
+ self.sansRef = null;
self.fireTimer = 0;
self.fireInterval = 180; // Fire every 3 seconds
self.isActive = true;
- // Floating animation
- var floatDirection = 1;
- var originalY = 0;
+ self.setSansReference = function (sansDisplayObject) {
+ self.sansRef = sansDisplayObject;
+ };
self.update = function () {
- if (!self.isActive) return;
- // Floating animation
- if (originalY === 0) originalY = self.y;
- self.y = originalY + Math.sin(LK.ticks * 0.05) * 20;
- // Rotation animation
- entityGraphics.rotation += 0.02;
+ if (!self.isActive || !self.sansRef) return;
// Fire laser periodically
self.fireTimer++;
if (self.fireTimer >= self.fireInterval) {
self.fireLaser();
@@ -260,53 +249,53 @@
self.fireInterval = 150 + Math.random() * 60;
}
};
self.fireLaser = function () {
+ if (!self.sansRef) return;
+ // Calculate Sans mouth position (slightly below center)
+ var sansX = self.sansRef.x;
+ var sansY = self.sansRef.y + 20; // Mouth position offset
+ // Flash Sans when firing
+ tween(self.sansRef, {
+ tint: 0xffffff
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ tween(self.sansRef, {
+ tint: 0xffffff
+ }, {
+ duration: 300
+ });
+ }
+ });
var laser = new LaserAttack();
// Choose random laser direction and position - now includes diagonal
var direction = Math.floor(Math.random() * 4); // 0=horizontal, 1=vertical, 2=diagonal1, 3=diagonal2
if (direction === 0) {
- // Horizontal laser spanning full battle box
+ // Horizontal laser starting from Sans mouth
laser.direction = 'horizontal';
- laser.x = battleBox.x;
- laser.y = battleBox.y - battleBox.height / 2 + Math.random() * battleBox.height;
+ laser.x = sansX;
+ laser.y = sansY;
laser.rotation = 0;
} else if (direction === 1) {
- // Vertical laser spanning full battle box
+ // Vertical laser starting from Sans mouth
laser.direction = 'vertical';
- laser.x = battleBox.x - battleBox.width / 2 + Math.random() * battleBox.width;
- laser.y = battleBox.y;
+ laser.x = sansX;
+ laser.y = sansY;
laser.rotation = Math.PI / 2;
} else if (direction === 2) {
- // Diagonal laser (top-left to bottom-right)
+ // Diagonal laser (top-left to bottom-right) from Sans mouth
laser.direction = 'diagonal1';
- laser.x = battleBox.x;
- laser.y = battleBox.y;
+ laser.x = sansX;
+ laser.y = sansY;
laser.rotation = Math.PI / 4;
} else {
- // Diagonal laser (top-right to bottom-left)
+ // Diagonal laser (top-right to bottom-left) from Sans mouth
laser.direction = 'diagonal2';
- laser.x = battleBox.x;
- laser.y = battleBox.y;
+ laser.x = sansX;
+ laser.y = sansY;
laser.rotation = -Math.PI / 4;
}
- // Flash effect when firing
- tween(entityGraphics, {
- tint: 0xffffff,
- scaleX: 2.5,
- scaleY: 2.5
- }, {
- duration: 200,
- onFinish: function onFinish() {
- tween(entityGraphics, {
- tint: 0xff6600,
- scaleX: 2,
- scaleY: 2
- }, {
- duration: 300
- });
- }
- });
laser.startWarning();
laserAttacks.push(laser);
game.addChild(laser);
};
@@ -731,13 +720,11 @@
// Create heart
heart = game.addChild(new Heart());
heart.x = 1024;
heart.y = 1366;
-// Create laser entity
+// Create laser entity and link it to Sans
var laserEntity = new LaserEntity();
-laserEntity.x = 1800;
-laserEntity.y = 800;
-game.addChild(laserEntity);
+laserEntity.setSansReference(enemyDisplay);
// Touch/drag handlers
game.down = function (x, y, obj) {
// Allow dragging from anywhere on screen for mobile
isDragging = true;
@@ -1094,9 +1081,9 @@
// Sans dodging cooldown management
if (sansDodgeCooldown > 0) {
sansDodgeCooldown--;
}
- // Update laser entity
+ // Update laser entity (Sans-controlled)
if (laserEntity && laserEntity.isActive) {
laserEntity.update();
}
// Update and check bullet collisions