User prompt
increase firerate after freaze done. Its like 3x firetrate just for 5 second. Show this with indicator. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
slider fill position is wrong fix that. It need start on slider fill image left edge
User prompt
incrase coin spawn rate
User prompt
Scale up the note slider. Change the slider background and fill image. Use new image for this. Its need to be tileable.
User prompt
Fix the note slider position. It outside of the screen
User prompt
note slider must be downside of the score text. Every time i hit the snake play hit sfx
User prompt
change slider visual. Slider x position must be centre of the screen. 5 second freeze time must be show with contdown indicator. Decrase coin spawn rate. I need to collect like Do, Re, Mi, Fa, Sol, La, Si and Do, Re, Mi, Fa, Sol, La, Si. after that freeze will be appear. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Each time I collect a coin, play a sound effect in the form of a musical note, preferably using a metal guitar. The notes should follow the order: Do, Re, Mi, Fa, Sol, La, Si. Once the final note (Si) is played, freeze all enemy snakes for 5 seconds. During this frozen state, the snakes should not be able to move, including any new snakes that spawn during this time. While frozen, their color should change to blue. Also, add a visual indicator at the top of the screen in the form of a slider that fills up with each coin collected. Each segment of the slider should correspond to a musical note. When the slider reaches the final note (Si) and is fully filled, it should display a snowflake icon to indicate that the freeze effect is active. After the 5 seconds have passed, the snakes return to normal, and the slider resets. The sequence starts again with the next coin collection, repeating the note progression and build-up to the freeze effect. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Increase music speed incrase amount. +Add snake dead sfx
User prompt
When i killed the snake dont breake the music loop. It just speed up. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add a exiting music to background. Every time i killed a enemy snake. Music speed will be incrased ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Add a circle to player snake head. Its indicate player shooting range. It shuld be slightly visiable
User prompt
Snake lenght must be increase only 1 after eatign and kill enemy.
User prompt
background image size is 1020x1065,8 . Fix tiling Fix left top corner tiling issue
User prompt
background image size is 1024x928 . Fix tiling
User prompt
- add a gorund image it should be like hexagonal tilemap (sliter io like)
User prompt
Speed up fart nuke effects. It must disappear faster.
User prompt
Those nuke farts must be an asset. So i can change their visuals.
User prompt
Enemy nuke fart need to be differnt from player snake nuke fart. Dont change the players nuke fart. Change enemy snake nuke fart visual
User prompt
add a nuke fart to enemy snake. I trigger when take hit
User prompt
incrase firerate %50
User prompt
Dont destroy enemy snake use pooling system. When enemy snake is dead it need to return to pool. When i need new snake system need to fetch from pool an initialize that snake
User prompt
-Enemies need to spawn every 2 seconds. - Reduce player firerate - player bullet must be faced to enemy(rotate)
User prompt
enemies must be spawn outsides ıof the screen. When i reach the 1000 score i need to win. Enemi
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet var Bullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.owner = null; // 'player' or 'enemy' self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // No music or sound for MVP // Countdown Timer Display var CountdownTimer = Container.expand(function () { var self = Container.call(this); self.timerText = new Text2('5', { size: 80, fill: 0x00AAFF }); self.timerText.anchor.set(0.5, 0.5); self.addChild(self.timerText); self.visible = false; self.startCountdown = function (seconds) { self.visible = true; self.remainingTime = seconds; self.timerText.setText(Math.ceil(self.remainingTime / 60).toString()); // Convert ticks to seconds }; self.update = function () { if (self.visible && self.remainingTime > 0) { self.remainingTime--; var secondsLeft = Math.ceil(self.remainingTime / 60); self.timerText.setText(secondsLeft.toString()); if (self.remainingTime <= 0) { self.visible = false; } } }; return self; }); // Enemy Snake Head var EnemyHead = Container.expand(function () { var self = Container.call(this); var head = self.attachAsset('enemyHead', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // EnemyMegaFart effect (distinct visuals for enemy snake nuke fart, now asset-based) var EnemyMegaFart = Container.expand(function () { var self = Container.call(this); var fart = self.attachAsset('enemyNukeFart', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, alpha: 0.85 }); // Animate: expand and fade out, then destroy self.play = function () { tween(fart, { scaleX: 2.2, scaleY: 2.2, alpha: 0 }, { duration: 400, easing: tween.easeOutCubic }); tween(self, {}, { duration: 400, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); // Enemy Snake Segment var EnemySegment = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('enemyBody', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Enemy Snake var EnemySnake = Container.expand(function () { var self = Container.call(this); self.segments = []; self.head = new EnemyHead(); self.addChild(self.head); self.segments.push(self.head); self.length = 4 + Math.floor(Math.random() * 3); self.speed = 13 + Math.random() * 4; self.targetX = 1024 + (Math.random() - 0.5) * 800; self.targetY = 1366 + (Math.random() - 0.5) * 1200; self.lastMoveX = 0; self.lastMoveY = 1; self.alive = true; // Initialize body for (var i = 1; i < self.length; i++) { var seg = new EnemySegment(); seg.x = self.head.x; seg.y = self.head.y + i * 80; self.addChild(seg); self.segments.push(seg); } // Move snake self.moveSnake = function (playerPos) { // Check if frozen if (freezeActive) { // Change color to blue when frozen for (var i = 0; i < self.segments.length; i++) { self.segments[i].tint = 0x4444FF; } return; // Don't move when frozen } else { // Reset color when not frozen for (var i = 0; i < self.segments.length; i++) { self.segments[i].tint = 0xFFFFFF; } } // Move toward player, but with some randomness var dx = 0, dy = 0; if (playerPos && typeof playerPos.x === "number" && typeof playerPos.y === "number" && self.head && typeof self.head.x === "number" && typeof self.head.y === "number") { dx = playerPos.x - self.head.x + (Math.random() - 0.5) * 200; dy = playerPos.y - self.head.y + (Math.random() - 0.5) * 200; } else { // fallback: move randomly if playerPos or self.head is not valid dx = (Math.random() - 0.5) * 200; dy = (Math.random() - 0.5) * 200; } var dist = Math.sqrt(dx * dx + dy * dy); var moveX = 0, moveY = 0; if (dist > 10) { moveX = dx / dist; moveY = dy / dist; self.lastMoveX = moveX; self.lastMoveY = moveY; } else { moveX = self.lastMoveX; moveY = self.lastMoveY; } self.head.x += moveX * self.speed; self.head.y += moveY * self.speed; // Rotate head to face movement direction if (Math.abs(moveX) > 0.01 || Math.abs(moveY) > 0.01) { self.head.rotation = Math.atan2(moveY, moveX); } // Move body for (var i = self.segments.length - 1; i > 0; i--) { var prev = self.segments[i - 1]; var seg = self.segments[i]; var pdx = prev.x - seg.x; var pdy = prev.y - seg.y; var pdist = Math.sqrt(pdx * pdx + pdy * pdy); if (pdist > 80) { seg.x += pdx / pdist * Math.min(self.speed, pdist - 80); seg.y += pdy / pdist * Math.min(self.speed, pdist - 80); } // Rotate segment to face previous segment if (i > 0 && (Math.abs(pdx) > 0.01 || Math.abs(pdy) > 0.01)) { seg.rotation = Math.atan2(pdy, pdx); } } }; // Update self.update = function (playerPos) { if (!self.alive) { return; } self.moveSnake(playerPos); }; // Get head position self.getHeadPos = function () { return { x: self.head.x, y: self.head.y }; }; // Get direction vector self.getDirection = function () { return { x: self.lastMoveX, y: self.lastMoveY }; }; // Die self.die = function () { self.alive = false; // Fade out all segments, then return to pool var faded = 0; var total = self.segments.length; for (var i = 0; i < self.segments.length; i++) { tween(self.segments[i], { alpha: 0 }, { duration: 400, easing: tween.linear, onFinish: function onFinish() { faded++; // When all segments faded, return to pool if (faded === total) { // Remove from parent if still attached if (self.parent) { self.parent.removeChild(self); } // Reset state for reuse self.resetForPool(); // Add to pool if (enemySnakePool.indexOf(self) === -1) { enemySnakePool.push(self); } } } }); } }; // Add a resetForPool method to clear state for reuse self.resetForPool = function () { // Reset alpha and visibility for all segments for (var i = 0; i < self.segments.length; i++) { self.segments[i].alpha = 1; } self.visible = false; self.alive = false; // Optionally reset other state if needed }; return self; }); // (Flame Fart Burst removed) // Food var Food = Container.expand(function () { var self = Container.call(this); var food = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // MegaFart effect (nuke particle, now asset-based) var MegaFart = Container.expand(function () { var self = Container.call(this); var fart = self.attachAsset('playerNukeFart', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, alpha: 0.85 }); // Animate: expand and fade out, then destroy self.play = function () { tween(fart, { scaleX: 2.2, scaleY: 2.2, alpha: 0 }, { duration: 350, easing: tween.easeOutCubic }); tween(self, {}, { duration: 350, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); // Musical Note Progress Slider var NoteSlider = Container.expand(function () { var self = Container.call(this); // Background bar - scaled up and using new tileable image var bgBar = LK.getAsset('sliderBg', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 1.5 }); self.addChild(bgBar); // Progress bar - scaled up and using new tileable image self.progressBar = LK.getAsset('sliderFill', { anchorX: 0, anchorY: 0.5, scaleX: 0, scaleY: 1.5 }); self.progressBar.x = -300; // Align with left edge of scaled background bar (600px wide / 2 = 300px offset) self.addChild(self.progressBar); // Snowflake icon (hidden initially) - scaled up self.snowflakeIcon = new Text2('❄', { size: 80, fill: 0x00AAFF }); self.snowflakeIcon.anchor.set(0.5, 0.5); self.snowflakeIcon.x = 420; self.snowflakeIcon.y = 0; self.snowflakeIcon.visible = false; self.addChild(self.snowflakeIcon); // Update progress (0-14, representing notes across two cycles) self.updateProgress = function (noteIndex) { var progress = noteIndex / 14; // Now requires 14 notes (two full cycles) tween(self.progressBar, { scaleX: progress * 2.0 }, { duration: 200, easing: tween.easeOut }); if (noteIndex >= 14) { self.snowflakeIcon.visible = true; // Animate snowflake tween(self.snowflakeIcon, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.bounceOut }); } }; // Reset slider self.reset = function () { tween(self.progressBar, { scaleX: 0 }, { duration: 300, easing: tween.easeIn }); self.snowflakeIcon.visible = false; self.snowflakeIcon.scaleX = 1; self.snowflakeIcon.scaleY = 1; }; return self; }); // Player Snake var PlayerSnake = Container.expand(function () { var self = Container.call(this); self.segments = []; self.directions = []; self.head = new SnakeHead(); self.addChild(self.head); self.segments.push(self.head); self.length = 5; self.speed = 12; self.targetX = 1024; self.targetY = 1366; self.lastMoveX = 0; self.lastMoveY = -1; self.growPending = 0; self.lastFireTick = 0; // Initialize body for (var i = 1; i < self.length; i++) { var seg = new SnakeSegment(); seg.x = self.head.x; seg.y = self.head.y + i * 80; self.addChild(seg); self.segments.push(seg); } // Move snake self.moveSnake = function () { // Only move if dragNode is playerSnake (mouse/touch is held) if (_typeof(dragNode) === "object" && dragNode === self) { // Calculate direction to target var dx = self.targetX - self.head.x; var dy = self.targetY - self.head.y; var dist = Math.sqrt(dx * dx + dy * dy); var moveX = 0, moveY = 0; if (dist > 10) { moveX = dx / dist; moveY = dy / dist; self.lastMoveX = moveX; self.lastMoveY = moveY; } else { moveX = self.lastMoveX; moveY = self.lastMoveY; } // Move head self.head.x += moveX * self.speed; self.head.y += moveY * self.speed; // Rotate head to face movement direction if (dist > 10) { self.head.updateRotation(moveX, moveY); } // Move body for (var i = self.segments.length - 1; i > 0; i--) { var prev = self.segments[i - 1]; var seg = self.segments[i]; var pdx = prev.x - seg.x; var pdy = prev.y - seg.y; var pdist = Math.sqrt(pdx * pdx + pdy * pdy); if (pdist > 80) { seg.x += pdx / pdist * Math.min(self.speed, pdist - 80); seg.y += pdy / pdist * Math.min(self.speed, pdist - 80); } // Rotate segment to face previous segment seg.updateRotation(pdx, pdy); } } }; // Grow snake self.grow = function (n) { self.growPending += n; }; // Update self.update = function () { self.moveSnake(); // Handle growth if (self.growPending > 0) { var last = self.segments[self.segments.length - 1]; var seg = new SnakeSegment(); seg.x = last.x; seg.y = last.y; self.addChild(seg); self.segments.push(seg); self.growPending--; } }; // Get head position self.getHeadPos = function () { return { x: self.head.x, y: self.head.y }; }; // Get direction vector self.getDirection = function () { return { x: self.lastMoveX, y: self.lastMoveY }; }; return self; }); // Player Snake Head (uses snakeHead asset, rotates to face movement) var SnakeHead = Container.expand(function () { var self = Container.call(this); var head = self.attachAsset('snakeHead', { anchorX: 0.5, anchorY: 0.5 }); // Add a semi-transparent shooting range circle var rangeRadius = 600; // matches minigun range in game.update var rangeCircle = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: rangeRadius * 2 / 100, // centerCircle asset is 100x100 scaleY: rangeRadius * 2 / 100, alpha: 0.05, // subtle visibility x: 0, y: 0 }); self.addChild(rangeCircle); self._lastX = 0; self._lastY = 0; self._lastRotation = 0; self.updateRotation = function (dx, dy) { // Only update if movement is significant if (Math.abs(dx) > 0.01 || Math.abs(dy) > 0.01) { self._lastRotation = Math.atan2(dy, dx); self.rotation = self._lastRotation; } else { // If not moving, keep last rotation to prevent shaking self.rotation = self._lastRotation; } }; return self; }); // Player Snake Segment (uses snakeBody asset, rotates to face previous segment) var SnakeSegment = Container.expand(function () { var self = Container.call(this); var body = self.attachAsset('snakeBody', { anchorX: 0.5, anchorY: 0.5 }); self._lastRotation = 0; self.updateRotation = function (dx, dy) { if (Math.abs(dx) > 0.01 || Math.abs(dy) > 0.01) { self._lastRotation = Math.atan2(dy, dx); self.rotation = self._lastRotation; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Start background music LK.playMusic('bgMusic'); // Game variables // Snake body segment (player) // Snake head (player) // Enemy snake body // Enemy snake head // Food // Bullet // Flame fart burst // (flame asset removed) // Nuke fart assets (player and enemy, can be replaced with custom art) function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var playerSnake; var enemySnakes = []; var enemySnakePool = []; // Pool for dead/reusable enemy snakes var foods = []; var bullets = []; // (flames array removed) var scoreTxt; var dragNode = null; var lastFireTick = 0; var spawnFoodTick = 0; var spawnEnemyTick = 0; var musicSpeed = 1.0; // Current music playback speed var enemyKillCount = 0; // Track how many enemies killed // Musical note progression system var noteNames = ['noteDo', 'noteRe', 'noteMi', 'noteFa', 'noteSol', 'noteLa', 'noteSi']; var currentNoteIndex = 0; var notesCycleCount = 0; // Track how many complete cycles we've done var freezeActive = false; var freezeEndTime = 0; var fireRateBoostActive = false; var fireRateBoostEndTime = 0; var fireRateBoostIndicator; var noteSlider; var countdownTimer; var gameArea = { x: 120, y: 120, w: 2048 - 240, h: 2732 - 240 }; // leave margin for UI // Track current enemy snake length scaling with score var currentEnemySnakeLength = 0; // 0 means default (random 4-6), will be set after 100 score // Add hexagonal tilemap ground image, tile to fill game area var groundTiles = []; var tileW = 1020; var tileH = 1065.8; // Start tiling from (0,0) to ensure no gap in top/left corner for (var y = 0; y < 2732; y += tileH) { for (var x = 0; x < 2048; x += tileW) { var tile = LK.getAsset('hexGround', { anchorX: 0, anchorY: 0, x: x, y: y }); groundTiles.push(tile); game.addChild(tile); } } // Score display scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Initialize note slider noteSlider = new NoteSlider(); noteSlider.x = 0; // Center horizontally using GUI coordinate system noteSlider.y = 180; // Position below score text LK.gui.top.addChild(noteSlider); // Initialize countdown timer countdownTimer = new CountdownTimer(); countdownTimer.x = 0; countdownTimer.y = 0; LK.gui.center.addChild(countdownTimer); // Initialize fire rate boost indicator fireRateBoostIndicator = new Text2('⚡ 3X FIRE RATE', { size: 60, fill: 0xFFFF00 }); fireRateBoostIndicator.anchor.set(0.5, 0.5); fireRateBoostIndicator.x = 0; fireRateBoostIndicator.y = -200; fireRateBoostIndicator.visible = false; LK.gui.center.addChild(fireRateBoostIndicator); // Initialize player snake playerSnake = new PlayerSnake(); playerSnake.head.x = 1024; playerSnake.head.y = 1800; for (var i = 0; i < playerSnake.segments.length; i++) { playerSnake.segments[i].x = 1024; playerSnake.segments[i].y = 1800 + i * 80; } game.addChild(playerSnake); // Spawn initial food function spawnFood() { var f = new Food(); f.x = gameArea.x + 100 + Math.random() * (gameArea.w - 200); f.y = gameArea.y + 100 + Math.random() * (gameArea.h - 200); foods.push(f); game.addChild(f); } for (var i = 0; i < 8; i++) { spawnFood(); } // Spawn enemy snake function spawnEnemy() { // Determine enemy length based on score var enemyLength = 0; if (currentEnemySnakeLength > 0) { enemyLength = currentEnemySnakeLength; } else { enemyLength = 4 + Math.floor(Math.random() * 3); // default: 4-6 } // Fetch from pool or create new var e; if (enemySnakePool.length > 0) { e = enemySnakePool.pop(); // Remove from previous parent if needed if (e.parent) { e.parent.removeChild(e); } // Reset segments while (e.segments.length > 1) { var seg = e.segments.pop(); seg.destroy(); } // Add segments to match desired length for (var i = 1; i < enemyLength; i++) { var seg = new EnemySegment(); seg.x = e.head.x; seg.y = e.head.y + i * 80; e.addChild(seg); e.segments.push(seg); } e.length = enemyLength; // Reset alpha for all segments for (var i = 0; i < e.segments.length; i++) { e.segments[i].alpha = 1; } e.visible = true; e.alive = true; } else { // Create enemy snake with custom length if needed e = new EnemySnake(); if (currentEnemySnakeLength > 0) { // Remove all but head while (e.segments.length > 1) { var seg = e.segments.pop(); seg.destroy(); } // Add segments to match desired length for (var i = 1; i < enemyLength; i++) { var seg = new EnemySegment(); seg.x = e.head.x; seg.y = e.head.y + i * 80; e.addChild(seg); e.segments.push(seg); } e.length = enemyLength; } } // Spawn at random edge OUTSIDE the visible screen var edge = Math.floor(Math.random() * 4); if (edge === 0) { // top (above screen) e.head.x = gameArea.x + Math.random() * gameArea.w; e.head.y = gameArea.y - 200; } else if (edge === 1) { // bottom (below screen) e.head.x = gameArea.x + Math.random() * gameArea.w; e.head.y = gameArea.y + gameArea.h + 200; } else if (edge === 2) { // left (left of screen) e.head.x = gameArea.x - 200; e.head.y = gameArea.y + Math.random() * gameArea.h; } else { // right (right of screen) e.head.x = gameArea.x + gameArea.w + 200; e.head.y = gameArea.y + Math.random() * gameArea.h; } for (var i = 1; i < e.segments.length; i++) { e.segments[i].x = e.head.x; e.segments[i].y = e.head.y + i * 80; } e.visible = true; e.alive = true; // Apply freeze effect if currently active if (freezeActive) { for (var i = 0; i < e.segments.length; i++) { e.segments[i].tint = 0x4444FF; } } enemySnakes.push(e); game.addChild(e); } for (var i = 0; i < 2; i++) { spawnEnemy(); } // Handle dragging game.down = function (x, y, obj) { dragNode = playerSnake; playerSnake.targetX = x; playerSnake.targetY = y; }; game.move = function (x, y, obj) { if (dragNode) { playerSnake.targetX = x; playerSnake.targetY = y; } }; game.up = function (x, y, obj) { dragNode = null; }; // Helper: check collision between two containers (circle-based) function circlesIntersect(a, b, rA, rB) { var dx = a.x - b.x; var dy = a.y - b.y; var dist = Math.sqrt(dx * dx + dy * dy); return dist < (rA + rB) * 0.5; } // Helper: clamp to game area function clampToArea(x, y) { x = Math.max(gameArea.x + 50, Math.min(gameArea.x + gameArea.w - 50, x)); y = Math.max(gameArea.y + 50, Math.min(gameArea.y + gameArea.h - 50, y)); return { x: x, y: y }; } // Main game update game.update = function () { // Handle freeze effect timing if (freezeActive && LK.ticks >= freezeEndTime) { freezeActive = false; noteSlider.reset(); // Reset enemy colors for (var i = 0; i < enemySnakes.length; i++) { var e = enemySnakes[i]; for (var j = 0; j < e.segments.length; j++) { e.segments[j].tint = 0xFFFFFF; } } // Activate fire rate boost fireRateBoostActive = true; fireRateBoostEndTime = LK.ticks + 300; // 5 seconds at 60fps fireRateBoostIndicator.visible = true; // Animate indicator appearance tween(fireRateBoostIndicator, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.bounceOut }); } // Handle fire rate boost timing if (fireRateBoostActive && LK.ticks >= fireRateBoostEndTime) { fireRateBoostActive = false; // Animate indicator disappearance tween(fireRateBoostIndicator, { alpha: 0, scaleX: 0.8, scaleY: 0.8 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { fireRateBoostIndicator.visible = false; fireRateBoostIndicator.alpha = 1; fireRateBoostIndicator.scaleX = 1; fireRateBoostIndicator.scaleY = 1; } }); } // Update countdown timer countdownTimer.update(); // Update player snake playerSnake.update(); // Clamp player head to area var clamped = clampToArea(playerSnake.head.x, playerSnake.head.y); playerSnake.head.x = clamped.x; playerSnake.head.y = clamped.y; // Update enemy snakes for (var i = enemySnakes.length - 1; i >= 0; i--) { var e = enemySnakes[i]; if (!e.alive) { // Remove from active array if dead and pooled enemySnakes.splice(i, 1); continue; } e.update(playerSnake.getHeadPos()); // Clamp enemy head to area var ce = clampToArea(e.head.x, e.head.y); e.head.x = ce.x; e.head.y = ce.y; } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var b = bullets[i]; b.update(); // Remove if out of bounds if (b.x < gameArea.x - 60 || b.x > gameArea.x + gameArea.w + 60 || b.y < gameArea.y - 60 || b.y > gameArea.y + gameArea.h + 60) { b.destroy(); bullets.splice(i, 1); continue; } // Bullet hits enemy snake if (b.owner === 'player') { for (var j = 0; j < enemySnakes.length; j++) { var e = enemySnakes[j]; if (!e.alive) { continue; } if (circlesIntersect(b, e.head, 60, 60)) { // Hit! b.destroy(); bullets.splice(i, 1); // Play hit sound effect LK.getSound('hitSnake').play(); // Shorten enemy snake or kill var killed = false; // Nuke fart effect at enemy head when hit (use EnemyMegaFart for enemy snake) var nukeFart = new EnemyMegaFart(); nukeFart.x = e.head.x; nukeFart.y = e.head.y; game.addChild(nukeFart); nukeFart.play(); if (e.segments.length > 2) { var seg = e.segments.pop(); seg.destroy(); } else { e.die(); killed = true; } LK.setScore(LK.getScore() + 5); scoreTxt.setText(LK.getScore()); // Player fart effect when enemy is killed if (killed) { playerSnake.grow(1); // Play snake death sound effect LK.getSound('snakeDeath').play(); // Flash the head and all body segments for a more visible fart effect for (var f = 0; f < playerSnake.segments.length; f++) { LK.effects.flashObject(playerSnake.segments[f], 0xcccc00, 600); } // Increase music speed when enemy is killed enemyKillCount++; var newMusicSpeed = Math.min(2.0, 1.0 + enemyKillCount * 0.25); // Cap at 2x speed if (newMusicSpeed > musicSpeed) { // Use tween to smoothly transition music speed without breaking loop tween({ speed: musicSpeed }, { speed: newMusicSpeed }, { duration: 500, easing: tween.easeOutCubic, onFinish: function onFinish() { musicSpeed = newMusicSpeed; } }); } } break; } } } // Bullet hits player (if we add enemy bullets in future) } // Player eats food for (var i = foods.length - 1; i >= 0; i--) { var food = foods[i]; if (circlesIntersect(playerSnake.head, food, 60, 35)) { food.destroy(); foods.splice(i, 1); playerSnake.grow(1); LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); // Play musical note LK.getSound(noteNames[currentNoteIndex]).play(); // Update slider currentNoteIndex++; noteSlider.updateProgress(currentNoteIndex + notesCycleCount * 7); // Check if we've completed a full cycle if (currentNoteIndex >= 7) { notesCycleCount++; currentNoteIndex = 0; // Check if we've completed two full cycles (14 notes total) if (notesCycleCount >= 2) { // Activate freeze effect freezeActive = true; freezeEndTime = LK.ticks + 300; // 5 seconds at 60fps // Flash screen blue to indicate freeze LK.effects.flashScreen(0x4444FF, 500); // Start countdown timer countdownTimer.startCountdown(300); // 5 seconds in ticks // Reset note progression currentNoteIndex = 0; notesCycleCount = 0; } } // MegaFart effect: nuke particle at player head var megaFart = new MegaFart(); megaFart.x = playerSnake.head.x; megaFart.y = playerSnake.head.y; game.addChild(megaFart); megaFart.play(); // Win condition removed } } // Player collides with enemy snake head or body for (var i = 0; i < enemySnakes.length; i++) { var e = enemySnakes[i]; if (!e.alive) { continue; } // Head to head if (circlesIntersect(playerSnake.head, e.head, 60, 60)) { LK.effects.flashScreen(0xff3300, 800); LK.showGameOver(); return; } // Head to body for (var j = 1; j < e.segments.length; j++) { if (circlesIntersect(playerSnake.head, e.segments[j], 60, 40)) { LK.effects.flashScreen(0xff3300, 800); LK.showGameOver(); return; } } } // Player collides with self (not head) for (var i = 2; i < playerSnake.segments.length; i++) { if (circlesIntersect(playerSnake.head, playerSnake.segments[i], 60, 40)) { LK.effects.flashScreen(0xff3300, 800); LK.showGameOver(); return; } } // Spawn food spawnFoodTick++; if (spawnFoodTick > 60 && foods.length < 12) { // Increased spawn rate spawnFood(); spawnFoodTick = 0; } // Spawn enemy spawnEnemyTick++; if (spawnEnemyTick > 120 && enemySnakes.length < 8) { // 120 ticks ≈ 2 seconds at 60fps spawnEnemy(); spawnEnemyTick = 0; } // Check and update enemy snake length scaling with score var score = LK.getScore(); if (score >= 1000) { LK.showYouWin(); return; } if (score >= 100) { // Every 100 points, increase enemy length by 2 (starting at 6) var newLen = 6 + Math.floor((score - 100) / 100) * 2; if (newLen !== currentEnemySnakeLength) { currentEnemySnakeLength = newLen; } } // Minigun: auto-fire at nearest enemy in range var fireInterval = fireRateBoostActive ? 7 : 20; // 3x fire rate when boosted (7 ticks vs 20 ticks) if (LK.ticks - lastFireTick > fireInterval) { // Normal: 20 ticks ≈ 0.33 seconds at 60fps (~3 shots/sec) // Boosted: 7 ticks ≈ 0.12 seconds at 60fps (~9 shots/sec, 3x faster) var nearest = null; var minDist = 99999; for (var i = 0; i < enemySnakes.length; i++) { var e = enemySnakes[i]; if (!e.alive) { continue; } var dx = e.head.x - playerSnake.head.x; var dy = e.head.y - playerSnake.head.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 600 && dist < minDist) { minDist = dist; nearest = e; } } if (nearest) { fireBulletAt(playerSnake.head.x, playerSnake.head.y, nearest.head.x, nearest.head.y, 'player'); lastFireTick = LK.ticks; } } }; // Fire bullet from (x0,y0) to (x1,y1) function fireBulletAt(x0, y0, x1, y1, owner) { var b = new Bullet(); b.x = x0; b.y = y0; var dx = x1 - x0; var dy = y1 - y0; var dist = Math.sqrt(dx * dx + dy * dy); var speed = 38; b.vx = dx / dist * speed; b.vy = dy / dist * speed; b.owner = owner; // Rotate bullet to face direction of travel if (dist > 0.01) { b.rotation = Math.atan2(dy, dx); } bullets.push(b); game.addChild(b); } // (spawnFlameBurst removed) // Center score text scoreTxt.setText(LK.getScore()); scoreTxt.anchor.set(0.5, 0);
===================================================================
--- original.js
+++ change.js
@@ -549,8 +549,11 @@
var currentNoteIndex = 0;
var notesCycleCount = 0; // Track how many complete cycles we've done
var freezeActive = false;
var freezeEndTime = 0;
+var fireRateBoostActive = false;
+var fireRateBoostEndTime = 0;
+var fireRateBoostIndicator;
var noteSlider;
var countdownTimer;
var gameArea = {
x: 120,
@@ -593,8 +596,18 @@
countdownTimer = new CountdownTimer();
countdownTimer.x = 0;
countdownTimer.y = 0;
LK.gui.center.addChild(countdownTimer);
+// Initialize fire rate boost indicator
+fireRateBoostIndicator = new Text2('⚡ 3X FIRE RATE', {
+ size: 60,
+ fill: 0xFFFF00
+});
+fireRateBoostIndicator.anchor.set(0.5, 0.5);
+fireRateBoostIndicator.x = 0;
+fireRateBoostIndicator.y = -200;
+fireRateBoostIndicator.visible = false;
+LK.gui.center.addChild(fireRateBoostIndicator);
// Initialize player snake
playerSnake = new PlayerSnake();
playerSnake.head.x = 1024;
playerSnake.head.y = 1800;
@@ -751,9 +764,40 @@
for (var j = 0; j < e.segments.length; j++) {
e.segments[j].tint = 0xFFFFFF;
}
}
+ // Activate fire rate boost
+ fireRateBoostActive = true;
+ fireRateBoostEndTime = LK.ticks + 300; // 5 seconds at 60fps
+ fireRateBoostIndicator.visible = true;
+ // Animate indicator appearance
+ tween(fireRateBoostIndicator, {
+ scaleX: 1.2,
+ scaleY: 1.2
+ }, {
+ duration: 300,
+ easing: tween.bounceOut
+ });
}
+ // Handle fire rate boost timing
+ if (fireRateBoostActive && LK.ticks >= fireRateBoostEndTime) {
+ fireRateBoostActive = false;
+ // Animate indicator disappearance
+ tween(fireRateBoostIndicator, {
+ alpha: 0,
+ scaleX: 0.8,
+ scaleY: 0.8
+ }, {
+ duration: 200,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ fireRateBoostIndicator.visible = false;
+ fireRateBoostIndicator.alpha = 1;
+ fireRateBoostIndicator.scaleX = 1;
+ fireRateBoostIndicator.scaleY = 1;
+ }
+ });
+ }
// Update countdown timer
countdownTimer.update();
// Update player snake
playerSnake.update();
@@ -945,11 +989,12 @@
currentEnemySnakeLength = newLen;
}
}
// Minigun: auto-fire at nearest enemy in range
- if (LK.ticks - lastFireTick > 20) {
- // 20 ticks ≈ 0.33 seconds at 60fps
- // ~3 shots/sec (50% faster)
+ var fireInterval = fireRateBoostActive ? 7 : 20; // 3x fire rate when boosted (7 ticks vs 20 ticks)
+ if (LK.ticks - lastFireTick > fireInterval) {
+ // Normal: 20 ticks ≈ 0.33 seconds at 60fps (~3 shots/sec)
+ // Boosted: 7 ticks ≈ 0.12 seconds at 60fps (~9 shots/sec, 3x faster)
var nearest = null;
var minDist = 99999;
for (var i = 0; i < enemySnakes.length; i++) {
var e = enemySnakes[i];
cartoon snake texture. In-Game asset. 2d. High contrast. No shadows
cartoon snake head. In-Game asset. 2d. High contrast. No shadows
red
make it red
Remove this area. Make it image looks more circle
make it red and cursed
2d white empty thin circle png.. In-Game asset. 2d. High contrast. No shadows
make it rounded edge. And color is whtie