User prompt
Let the yellow heart last from 09:00->07:00
User prompt
Let the yellow shot key be under the bell key and make it large
User prompt
Time 09:00 Let the Heart be yellow when it is And when it's 07:00 time Let it end. And let there be a special button for the yellow health, when you click on it, it sends bullets up ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Timer 8:00 When it happens Let the yellow heart come. When it's 6:00 , let it go. When you click on the yellow spirit let it shoot Bullets like a Gun. Destroy the attacks that touch the bullet ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Don't Damage the Shield Bitek heart Let it take damage, let the bidet shield be around the green spirit and turn wherever our finger clicks, bidet x (That is, length) Increase ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the shield destroy everything, no health, no damage. If the attack touches our hearts Let our lives decrease ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Let the green heart Let it begin when the timer is 12:00 and end when the timer is 10:00
User prompt
Health Cooldown 10->20 Seconds
User prompt
Keep the health button at the bottom of the box (not inside, outside)
User prompt
Add Health button When we click the Health button, our health increases by 20, but we cannot use it for 10 seconds ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add green heart. Let the green heart come in 12 minutes and end in 10 minutes. The green heart is right in the middle of the box, it can't move, but it has a shield, we destroy Attacks by moving that shield ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make assets for blue heart
User prompt
My heart still stays blue
User prompt
Make the stay time in the blue Heart 4 seconds
User prompt
We stay in the blue heart for too long. Reduce the duration a lot (when the chance attacks, it ends after 7 seconds, for example) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When we are blue, let's stand in the air for a little longer and jump higher ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When sans attack Let our hearts be blue, not black ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When Sans Attack Our heart will be blue (We can move left and right, but when we go up, let it pull down, so let's jump) ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add time. Time is 900 seconds (15 minutes) Write "THREE LEFT" in Red Under Time
User prompt
Delete attack button and target select
User prompt
Even though I clicked on it, it still doesn't work and still monsters attack me
User prompt
I clicked sans at the place of attack did not attack and at the place of attack the attacks of the Monsters do not come.
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'tween(targetScreen, {' Line Number: 656 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Have the attack key at the bottom of the box. Let's click on it when the game stops. And let the screen come where we will determine who we are going to shootHave the attack key at the bottom of the box. Let's click on it when the game stops. And let the screen come where we will determine who we are going to shoot (Sans,asgore and flowey) For example, you chose sans It reads: "Sans escaped your attack." ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: Cannot use 'in' operator to search for 'alpha' in null' in or related to this line: 'tween(attackKey, {' Line Number: 761 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Anchor = Container.expand(function () { var self = Container.call(this); // Create anchor graphic var anchorGraphics = self.attachAsset('anchor', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 10 }); self.isBlue = true; // true = blue (stop), false = orange (move) self.damage = 6; self.lastX = 0; self.lastY = 0; self.colorChangeTimer = 0; self.colorChangeInterval = 180; // Change color every 3 seconds at 60fps self.speed = 3; self.movingRight = true; // Update anchor color self.updateColor = function () { if (self.isBlue) { anchorGraphics.tint = 0x0066ff; // Blue } else { anchorGraphics.tint = 0xff6600; // Orange } }; self.update = function () { self.lastX = self.x; self.lastY = self.y; // Move horizontally within the box boundaries var anchorHalfWidth = 60; // Half of 120px anchor width var minX = boxX + 8 + anchorHalfWidth; var maxX = boxX + boxWidth - 8 - anchorHalfWidth; if (self.movingRight) { self.x += self.speed; // Move right if (self.x >= maxX) { self.x = maxX; self.movingRight = false; // Switch to moving left } } else { self.x -= self.speed; // Move left if (self.x <= minX) { self.x = minX; self.movingRight = true; // Switch to moving right } } // Keep anchor within vertical bounds of the box var anchorHalfHeight = 600; // Half of 1200px anchor height var minY = boxY + 8 + anchorHalfHeight; var maxY = boxY + boxHeight - 8 - anchorHalfHeight; if (self.y < minY) { self.y = minY; } if (self.y > maxY) { self.y = maxY; } // Change color periodically self.colorChangeTimer++; if (self.colorChangeTimer >= self.colorChangeInterval) { self.isBlue = !self.isBlue; self.updateColor(); self.colorChangeTimer = 0; } }; // Initialize with blue color self.updateColor(); return self; }); var Asgore = Container.expand(function () { var self = Container.call(this); // Create Asgore using proper Asgore image asset var asgoreGraphics = self.attachAsset('asgore', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.attackTimer = 0; self.attackInterval = 240; // Attack every 4 seconds self.blocksLeft = 12; self.isDead = false; self.block = function () { if (self.blocksLeft > 0 && !self.isDead) { self.blocksLeft--; // Flash blue to indicate block tween(asgoreGraphics, { tint: 0x0066ff }, { duration: 100, onFinish: function onFinish() { tween(asgoreGraphics, { tint: 0xffffff }, { duration: 100 }); } }); if (self.blocksLeft <= 0) { self.isDead = true; tween(asgoreGraphics, { alpha: 0.3 }, { duration: 500 }); } return true; } return false; }; return self; }); var BoxBoundary = Container.expand(function () { var self = Container.call(this); // Create four walls for the box var topWall = self.attachAsset('boxBorder', { anchorX: 0, anchorY: 0, width: 1600, height: 8 }); var bottomWall = self.attachAsset('boxBorder', { anchorX: 0, anchorY: 0, width: 1600, height: 8 }); var leftWall = self.attachAsset('boxBorder', { anchorX: 0, anchorY: 0, width: 8, height: 1200 }); var rightWall = self.attachAsset('boxBorder', { anchorX: 0, anchorY: 0, width: 8, height: 1200 }); // Position walls topWall.x = 0; topWall.y = 0; bottomWall.x = 0; bottomWall.y = 1200 - 8; leftWall.x = 0; leftWall.y = 0; rightWall.x = 1600 - 8; rightWall.y = 0; return self; }); var Flowey = Container.expand(function () { var self = Container.call(this); // Create Flowey using proper Flowey image asset var floweyGraphics = self.attachAsset('flowey', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.attackTimer = 0; self.attackInterval = 600; // Attack every 10 seconds self.destroysLeft = 999; // Infinite until transformation self.finalFormDestroysLeft = 5; self.isFinalForm = false; self.isDead = false; self.destroyAttack = function () { if (self.isDead) return false; var destroysToUse = self.isFinalForm ? self.finalFormDestroysLeft : self.destroysLeft; if (destroysToUse > 0) { if (self.isFinalForm) { self.finalFormDestroysLeft--; if (self.finalFormDestroysLeft <= 0) { self.isDead = true; tween(floweyGraphics, { alpha: 0.3 }, { duration: 500 }); } } // Flash red to indicate destruction tween(floweyGraphics, { tint: 0xff0000 }, { duration: 100, onFinish: function onFinish() { tween(floweyGraphics, { tint: 0xffffff }, { duration: 100 }); } }); return true; } return false; }; self.transformToFinalForm = function () { if (!self.isFinalForm) { self.isFinalForm = true; self.attackInterval = 300; // Attack more frequently // Transform animation tween(floweyGraphics, { scaleX: 1.5, scaleY: 1.5, tint: 0xff00ff }, { duration: 1000, easing: tween.easeOut }); } }; return self; }); var GasterBeam = Container.expand(function () { var self = Container.call(this); // Create black border first (behind white beam) var beamBorder = self.attachAsset('beamBorder', { anchorX: 0.5, anchorY: 0.5 }); // Create white beam on top var whiteBeam = self.attachAsset('whiteBeam', { anchorX: 0.5, anchorY: 0.5 }); self.damage = 12; // Gaster beam damage self.speed = 4; self.lastX = 0; self.lastY = 0; self.targetX = 0; self.targetY = 0; self.isActive = false; self.fireBeam = function (targetX, targetY) { if (self.isActive) return; self.isActive = true; self.targetX = targetX; self.targetY = targetY; // Calculate direction to target var deltaX = targetX - self.x; var deltaY = targetY - self.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Set rotation to point towards target self.rotation = Math.atan2(deltaY, deltaX) + Math.PI / 2; // Add 90 degrees because beam asset points up // Move towards target tween(self, { x: targetX, y: targetY }, { duration: distance / self.speed * 16, // Adjust duration based on distance easing: tween.linear, onFinish: function onFinish() { self.isActive = false; } }); }; self.update = function () { self.lastX = self.x; self.lastY = self.y; }; return self; }); var GasterBlaster = Container.expand(function () { var self = Container.call(this); // Create Gaster Blaster using image asset var blasterGraphics = self.attachAsset('gasterBlaster', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.chargeTime = 60; // 1 second charge time at 60fps self.chargeTimer = 0; self.isCharging = false; self.isReady = false; self.beamDuration = 120; // 2 seconds beam duration self.beamTimer = 0; self.targetX = 0; self.targetY = 0; self.startCharge = function (targetX, targetY) { if (self.isCharging || self.isReady) return; self.isCharging = true; self.targetX = targetX; self.targetY = targetY; self.chargeTimer = 0; // Point towards target during charge var deltaX = targetX - self.x; var deltaY = targetY - self.y; self.rotation = Math.atan2(deltaY, deltaX); // Flash effect during charge tween(blasterGraphics, { alpha: 0.3 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { tween(blasterGraphics, { alpha: 1 }, { duration: 100, easing: tween.linear }); } }); }; self.fireBeam = function () { if (!self.isReady) return null; var beam = new GasterBeam(); beam.x = self.x; beam.y = self.y; beam.lastX = beam.x; beam.lastY = beam.y; beam.fireBeam(self.targetX, self.targetY); return beam; }; self.update = function () { if (self.isCharging) { self.chargeTimer++; if (self.chargeTimer >= self.chargeTime) { self.isCharging = false; self.isReady = true; self.beamTimer = 0; } } else if (self.isReady) { self.beamTimer++; if (self.beamTimer >= self.beamDuration) { self.isReady = false; } } }; return self; }); var Heart = Container.expand(function () { var self = Container.call(this); var heartGraphics = self.attachAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); var blueHeartGraphics = self.attachAsset('blueHeart', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.isBlue = false; self.velocityY = 0; self.gravity = 0.3; self.jumpPower = -18; self.onGround = false; self.groundY = 0; self.setBlueMode = function (isBlue) { self.isBlue = isBlue; if (isBlue) { heartGraphics.alpha = 0; blueHeartGraphics.alpha = 1; } else { heartGraphics.alpha = 1; blueHeartGraphics.alpha = 0; } }; return self; }); var Ivy = Container.expand(function () { var self = Container.call(this); // Create ivy graphic - anchor from top to hang down var ivyGraphics = self.attachAsset('ivy', { anchorX: 0.5, anchorY: 0 }); self.damage = 5; self.speed = 3; self.lastX = 0; self.lastY = 0; self.movingRight = true; self.update = function () { self.lastX = self.x; self.lastY = self.y; // Move downward from top to bottom of box self.y += self.speed; // Always move down }; return self; }); var Sans = Container.expand(function () { var self = Container.call(this); // Create Sans using proper Sans image asset var sansGraphics = self.attachAsset('sans', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.attackTimer = 0; self.attackInterval = 720; // Attack every 12 seconds self.dodgesLeft = 10; self.isDead = false; self.originalX = 0; self.originalY = 0; self.dodge = function () { if (self.dodgesLeft > 0 && !self.isDead) { self.dodgesLeft--; // Move to random position near original location var dodgeDistance = 100; var angle = Math.random() * Math.PI * 2; var newX = self.originalX + Math.cos(angle) * dodgeDistance; var newY = self.originalY + Math.sin(angle) * dodgeDistance; tween(self, { x: newX, y: newY }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Return to original position tween(self, { x: self.originalX, y: self.originalY }, { duration: 300, easing: tween.easeIn }); } }); if (self.dodgesLeft <= 0) { self.isDead = true; tween(sansGraphics, { alpha: 0.3 }, { duration: 500 }); } return true; } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf0f8ff }); /**** * Game Code ****/ // Box dimensions var boxX = 224; // Center the 1600px box in 2048px screen var boxY = 766; // Center the 1200px box in 2732px screen var boxWidth = 1600; var boxHeight = 1200; // Create box boundary var boundary = game.addChild(new BoxBoundary()); boundary.x = boxX; boundary.y = boxY; // Create heart character var heart = game.addChild(new Heart()); heart.x = boxX + boxWidth / 2; // Center of box heart.y = boxY + boxHeight / 2; // Center of box // Create the three characters // Sans on the left side (bone thrower) var sans = game.addChild(new Sans()); sans.x = boxX - 150; // Left side of box sans.y = boxY + boxHeight / 2; // Middle height // Asgore in the middle (anchor owner) var asgore = game.addChild(new Asgore()); asgore.x = boxX + boxWidth / 2; // Center of box horizontally asgore.y = boxY - 150; // Above the box // Flowey on the right side (ivy sender) var flowey = game.addChild(new Flowey()); flowey.x = boxX + boxWidth + 150; // Right side of box flowey.y = boxY + boxHeight / 2; // Middle height // Create lives display var livesTxt = new Text2('Lives: 92', { size: 80, fill: 0x000000 }); livesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(livesTxt); // Create timer display var gameTime = 900; // 15 minutes in seconds var timerTxt = new Text2('Time: 15:00', { size: 80, fill: 0x000000 }); timerTxt.anchor.set(1, 0); // Right align LK.gui.topRight.addChild(timerTxt); // Create "THREE LEFT" text in red under timer var threeTxt = new Text2('THREE LEFT', { size: 60, fill: 0xff0000 }); threeTxt.anchor.set(1, 0); // Right align threeTxt.y = 100; // Position below timer LK.gui.topRight.addChild(threeTxt); // Store original positions for characters sans.originalX = sans.x; sans.originalY = sans.y; // Dragging variables var isDragging = false; var dragOffsetX = 0; var dragOffsetY = 0; // Constraint function to keep heart within boundaries function constrainHeartPosition() { var heartRadius = 50; // Half of heart width/height // Left boundary if (heart.x - heartRadius < boxX + 8) { heart.x = boxX + 8 + heartRadius; } // Right boundary if (heart.x + heartRadius > boxX + boxWidth - 8) { heart.x = boxX + boxWidth - 8 - heartRadius; } // Top boundary if (heart.y - heartRadius < boxY + 8) { heart.y = boxY + 8 + heartRadius; } // Bottom boundary if (heart.y + heartRadius > boxY + boxHeight - 8) { heart.y = boxY + boxHeight - 8 - heartRadius; } } // Player control variables var targetX = 0; var targetY = 0; var isPlayerControlling = false; // Touch/mouse down event game.down = function (x, y, obj) { isPlayerControlling = true; targetX = x; targetY = y; }; // Touch/mouse move event game.move = function (x, y, obj) { if (isPlayerControlling) { targetX = x; targetY = y; } }; // Touch/mouse up event game.up = function (x, y, obj) { isPlayerControlling = false; }; // Lives system var lives = 92; // Movement variables var heartSpeed = 8; var movementDirection = { x: 1, y: 0.5 }; // Initial movement direction var lastDirectionChangeTime = 0; var directionChangeInterval = 2000; // Change direction every 2 seconds // Gaster Blaster and beam system var gasterBlasters = []; var gasterBeams = []; var maxBlasters = 10; var blasterSpawnTimer = 0; var blasterSpawnInterval = 720; // Spawn every 12 seconds at 60fps var waveIntensity = 1; // Anchor system var anchors = []; var maxAnchors = 2; var anchorSpawnTimer = 0; var anchorSpawnInterval = 240; // Spawn every 4 seconds at 60fps // Ivy system var ivies = []; var maxIvies = 5; var ivySpawnTimer = 0; var ivySpawnInterval = 600; // Spawn every 10 seconds at 60fps // Slow effect system var isSlowed = false; var slowEndTime = 0; var normalHeartSpeed = 8; // Function to spawn a new Gaster Blaster at random edge position function spawnGasterBlaster() { if (gasterBlasters.length >= maxBlasters) return; var blaster = new GasterBlaster(); var edge = Math.floor(Math.random() * 4); // 0=top, 1=right, 2=bottom, 3=left // Position blaster at random point on selected edge switch (edge) { case 0: // Top edge blaster.x = boxX + Math.random() * boxWidth; blaster.y = boxY - 100; break; case 1: // Right edge blaster.x = boxX + boxWidth + 100; blaster.y = boxY + Math.random() * boxHeight; break; case 2: // Bottom edge blaster.x = boxX + Math.random() * boxWidth; blaster.y = boxY + boxHeight + 100; break; case 3: // Left edge blaster.x = boxX - 100; blaster.y = boxY + Math.random() * boxHeight; break; } gasterBlasters.push(blaster); game.addChild(blaster); // Start charging to attack the heart blaster.startCharge(heart.x, heart.y); } // Function to spawn a new anchor at random position within the box function spawnAnchor() { if (anchors.length >= maxAnchors) return; var anchor = new Anchor(); // Position anchor within the box boundaries for horizontal movement var anchorHalfWidth = 60; // Half of 120px anchor width var startFromLeft = Math.random() < 0.5; if (startFromLeft) { anchor.x = boxX + 8 + anchorHalfWidth; // Start from left edge inside box anchor.movingRight = true; // Moving right } else { anchor.x = boxX + boxWidth - 8 - anchorHalfWidth; // Start from right edge inside box anchor.movingRight = false; // Moving left } // Random Y position within the box, constrained to keep full anchor height inside var anchorHalfHeight = 600; // Half of 1200px anchor height anchor.y = boxY + anchorHalfHeight + Math.random() * (boxHeight - 2 * anchorHalfHeight); anchor.lastX = anchor.x; anchor.lastY = anchor.y; anchors.push(anchor); game.addChild(anchor); } // Function to spawn a new ivy hanging from top of box like an anchor function spawnIvy() { if (ivies.length >= maxIvies) return; var ivy = new Ivy(); // Position ivy at the very top of box to move downward (anchor point is at top of ivy) ivy.y = boxY + 8; // Start from top edge inside box // Random X position within the box, constrained to keep full ivy width inside var ivyHalfWidth = 60; // Half of 120px ivy width ivy.x = boxX + ivyHalfWidth + Math.random() * (boxWidth - 2 * ivyHalfWidth); ivy.lastX = ivy.x; ivy.lastY = ivy.y; ivies.push(ivy); game.addChild(ivy); } // Game update loop game.update = function () { // Update timer every second (60 ticks = 1 second at 60fps) if (LK.ticks % 60 === 0 && gameTime > 0) { gameTime--; var minutes = Math.floor(gameTime / 60); var seconds = gameTime % 60; var timeString = minutes + ':' + (seconds < 10 ? '0' : '') + seconds; timerTxt.setText('Time: ' + timeString); } // Check if Sans and Asgore are both dead for Flowey transformation if (sans.isDead && asgore.isDead && !flowey.isFinalForm && !flowey.isDead) { flowey.transformToFinalForm(); // Update ivy system for final form maxIvies = 10; flowey.attackInterval = 300; } // Increase wave intensity over time if (LK.ticks % 600 === 0) { // Every 10 seconds waveIntensity = Math.min(waveIntensity + 0.5, 4); maxBlasters = Math.min(Math.floor(2 + waveIntensity), 10); blasterSpawnInterval = Math.max(Math.floor(720 - waveIntensity * 120), 300); } // Update Sans attack timer and spawn Gaster Blasters (only if alive) if (!sans.isDead) { sans.attackTimer++; if (sans.attackTimer >= sans.attackInterval) { // Sans attack: make heart blue and enable physics heart.setBlueMode(true); heart.velocityY = 0; heart.onGround = false; heart.groundY = boxY + boxHeight - 8 - 50; // Ground level accounting for heart radius // Sans spawns Gaster Blasters var spawnCount = Math.random() < 0.4 ? Math.floor(waveIntensity) : 1; for (var s = 0; s < spawnCount && gasterBlasters.length < maxBlasters; s++) { spawnGasterBlaster(); } sans.attackTimer = 0; } } // Update Asgore attack timer and spawn anchors (only if alive) if (!asgore.isDead) { asgore.attackTimer++; if (asgore.attackTimer >= asgore.attackInterval) { // Asgore sends anchors spawnAnchor(); asgore.attackTimer = 0; } } // Update Flowey attack timer and spawn ivies (only if alive) if (!flowey.isDead) { flowey.attackTimer++; if (flowey.attackTimer >= flowey.attackInterval) { // Flowey sends ivies var spawnCount = flowey.isFinalForm ? 10 : Math.floor(Math.random() * 2) + 2; // Final form sends 10, normal sends 2-3 for (var i = 0; i < spawnCount && ivies.length < maxIvies; i++) { spawnIvy(); } flowey.attackTimer = 0; } } // Handle slow effect expiry if (isSlowed && LK.ticks >= slowEndTime) { isSlowed = false; heartSpeed = normalHeartSpeed; } // Update all Gaster Blasters and spawn beams when ready for (var i = gasterBlasters.length - 1; i >= 0; i--) { var blaster = gasterBlasters[i]; // Check if blaster is ready to fire if (blaster.isReady && blaster.beamTimer === 0) { var beam = blaster.fireBeam(); if (beam) { gasterBeams.push(beam); game.addChild(beam); } } // Remove blasters that have finished their attack cycle if (!blaster.isCharging && !blaster.isReady) { blaster.destroy(); gasterBlasters.splice(i, 1); continue; } } // Update all beams and check for collisions for (var j = gasterBeams.length - 1; j >= 0; j--) { var beam = gasterBeams[j]; // Check if beam hit the heart if (beam.intersects(heart)) { // Reduce lives by beam damage (12) lives -= beam.damage; livesTxt.setText('Lives: ' + lives); // Flash screen white to indicate beam damage LK.effects.flashScreen(0xffffff, 600); // Check for game over if (lives <= 0) { LK.showGameOver(); return; } // Remove the beam that hit us beam.destroy(); gasterBeams.splice(j, 1); continue; } // Remove beams that are too far from the play area or inactive var distanceFromCenter = Math.sqrt(Math.pow(beam.x - (boxX + boxWidth / 2), 2) + Math.pow(beam.y - (boxY + boxHeight / 2), 2)); if (distanceFromCenter > 2000 || !beam.isActive) { beam.destroy(); gasterBeams.splice(j, 1); continue; } } // Update all anchors and check for collisions for (var j = anchors.length - 1; j >= 0; j--) { var anchor = anchors[j]; // Removed health decrease timer initialization // Removed anchor-based health decrease mechanic // Check if anchor hit the heart if (anchor.intersects(heart)) { var shouldTakeDamage = false; // Blue anchor: damage if player is moving if (anchor.isBlue && isPlayerControlling) { shouldTakeDamage = true; } // Orange anchor: damage if player is not moving else if (!anchor.isBlue && !isPlayerControlling) { shouldTakeDamage = true; } if (shouldTakeDamage) { // Reduce lives by anchor damage (2) lives -= anchor.damage; livesTxt.setText('Lives: ' + lives); // Flash screen purple to indicate anchor damage LK.effects.flashScreen(0x8800ff, 700); // Check for game over if (lives <= 0) { LK.showGameOver(); return; } } // Remove the anchor that hit us anchor.destroy(); anchors.splice(j, 1); continue; } // Anchors now stay within box bounds, so no need to remove them for going off screen // They will only be removed when hitting the heart } // Update all ivies and check for collisions for (var k = ivies.length - 1; k >= 0; k--) { var ivy = ivies[k]; // Check if ivy hit the heart if (ivy.intersects(heart)) { // Reduce lives by 5 lives -= ivy.damage; livesTxt.setText('Lives: ' + lives); // Apply slow effect (25% speed reduction) isSlowed = true; heartSpeed = normalHeartSpeed * 0.75; slowEndTime = LK.ticks + 300; // Slow for 5 seconds at 60fps // Flash screen green to indicate ivy damage and slow LK.effects.flashScreen(0x00ff00, 600); // Check for game over if (lives <= 0) { LK.showGameOver(); return; } // Remove the ivy that hit us ivy.destroy(); ivies.splice(k, 1); continue; } // Remove ivies that have reached the bottom of the box // Since ivy anchor is at top (anchorY: 0), check when ivy top + height reaches bottom if (ivy.y + 800 >= boxY + boxHeight - 8) { ivy.destroy(); ivies.splice(k, 1); continue; } } if (isPlayerControlling) { if (heart.isBlue) { // Blue heart physics: left/right movement and jumping var deltaX = targetX - heart.x; // Horizontal movement if (Math.abs(deltaX) > 5) { var horizontalDirection = deltaX > 0 ? 1 : -1; heart.x += horizontalDirection * heartSpeed; } // Jump if touching upward and on ground if (targetY < heart.y - 20 && heart.onGround) { heart.velocityY = heart.jumpPower; heart.onGround = false; } } else { // Normal movement when not blue // Calculate direction toward target var deltaX = targetX - heart.x; var deltaY = targetY - heart.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Move toward target if not already there if (distance > 5) { // Normalize direction and apply speed movementDirection.x = deltaX / distance; movementDirection.y = deltaY / distance; heart.x += movementDirection.x * heartSpeed; heart.y += movementDirection.y * heartSpeed; } } } // Apply blue heart physics if (heart.isBlue) { // Apply gravity heart.velocityY += heart.gravity; heart.y += heart.velocityY; // Ground collision if (heart.y >= heart.groundY) { heart.y = heart.groundY; heart.velocityY = 0; heart.onGround = true; } // Reset blue heart after 4 seconds if (sans.attackTimer > 240) { // 4 seconds at 60fps heart.setBlueMode(false); sans.attackTimer = 0; // Reset timer to prevent staying blue } } // Ensure heart stays within bounds each frame constrainHeartPosition(); };
===================================================================
--- original.js
+++ change.js
@@ -342,14 +342,29 @@
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
+ var blueHeartGraphics = self.attachAsset('blueHeart', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0
+ });
self.isBlue = false;
self.velocityY = 0;
self.gravity = 0.3;
self.jumpPower = -18;
self.onGround = false;
self.groundY = 0;
+ self.setBlueMode = function (isBlue) {
+ self.isBlue = isBlue;
+ if (isBlue) {
+ heartGraphics.alpha = 0;
+ blueHeartGraphics.alpha = 1;
+ } else {
+ heartGraphics.alpha = 1;
+ blueHeartGraphics.alpha = 0;
+ }
+ };
return self;
});
var Ivy = Container.expand(function () {
var self = Container.call(this);
@@ -661,18 +676,12 @@
if (!sans.isDead) {
sans.attackTimer++;
if (sans.attackTimer >= sans.attackInterval) {
// Sans attack: make heart blue and enable physics
- heart.isBlue = true;
+ heart.setBlueMode(true);
heart.velocityY = 0;
heart.onGround = false;
heart.groundY = boxY + boxHeight - 8 - 50; // Ground level accounting for heart radius
- // Tween heart to blue color
- tween(heart, {
- tint: 0x0066ff
- }, {
- duration: 500
- });
// Sans spawns Gaster Blasters
var spawnCount = Math.random() < 0.4 ? Math.floor(waveIntensity) : 1;
for (var s = 0; s < spawnCount && gasterBlasters.length < maxBlasters; s++) {
spawnGasterBlaster();
@@ -863,15 +872,10 @@
}
// Reset blue heart after 4 seconds
if (sans.attackTimer > 240) {
// 4 seconds at 60fps
- heart.isBlue = false;
+ heart.setBlueMode(false);
sans.attackTimer = 0; // Reset timer to prevent staying blue
- tween(heart, {
- tint: 0x000000
- }, {
- duration: 500
- });
}
}
// Ensure heart stays within bounds each frame
constrainHeartPosition();
Undertale Heart. In-Game asset. 2d. High contrast. No shadows
Undertale bone with black outline. In-Game asset. 2d. High contrast. No shadows
Undertale asgore spear. In-Game asset. 2d. High contrast. No shadows
Ivy. In-Game asset. 2d. High contrast. No shadows
Sans Undertale. In-Game asset. 2d. High contrast. No shadows
Asgore Undertale. In-Game asset. 2d. High contrast. No shadows
Flowey Undertale but with 6 souls (Orange,Green,Yellow,blue,Purple, Light Blue). In-Game asset. 2d. High contrast. No shadows
Flat staring gaster blaster Undertale. In-Game asset. 2d. High contrast. No shadows
Undertale heart but blue. In-Game asset. 2d. High contrast. No shadows
Green Heart Undertale. In-Game asset. 2d. High contrast. No shadows
Yellow heart Undertale. In-Game asset. 2d. High contrast. No shadows