User prompt
Hataları düzelt
User prompt
Level yazısını biraz sağa al
User prompt
Her level de biraz hızlı mermi olsun
User prompt
Her level de biraz daha hızlı olsun
User prompt
Oyundaki en üste kadar level ekleyebilir misiniz
User prompt
Oyundaki en üste kadar level ekleyebilir misiniz
User prompt
Mermi biraz daha yavaş ateş etsin
User prompt
Biraz daha yavaş ateş etsin mermi
User prompt
Mermi biraz daha yavaş ateş etsin
User prompt
Mermi biraz yavaş ateş etsin
User prompt
Puanın biraz Coin olarak versin mesala 2 puan 1 Coin ha öldükten sonra hesapladım ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Para yazısını Coin olarak yapar mısınız
User prompt
Parayı Coin olarakyaz
User prompt
Başla demeden oynama
User prompt
Ana menü ekleyebilir misiniz
User prompt
obstacleyi yok ederek point kazansın 5
User prompt
obstacleyi mermile yok etsin
User prompt
Ekrana tıklayarak ateş etsin mermile
Code edit (1 edits merged)
Please save this source code
User prompt
Kaç saniye oynadığımı ekle
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var facekit = LK.import("@upit/facekit.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bullet = Container.expand(function (initialSpeed) { var self = Container.call(this); // Added initialSpeed parameter //Create and attach asset. self.visual = self.attachAsset('bullet', { // Uses the existing 'bullet' image asset anchorX: 0.5, anchorY: 0.5 }); self.speed = initialSpeed; // Use the passed initialSpeed for movement // If this instance of bullet is attached, this method will be called every tick by the LK engine automatically. self.update = function () { self.y += self.speed; }; return self; }); // Coin collectible class (was PointCollectible) var CoinCollectible = Container.expand(function () { var self = Container.call(this); var coin = self.attachAsset('coin_icon', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0; self.update = function () { self.y += self.speed; }; return self; }); // Player character controlled by face var FaceChar = Container.expand(function () { var self = Container.call(this); var _char = self.attachAsset('faceChar', { anchorX: 0.5, anchorY: 0.5 }); // For possible future effects self.flash = function () { LK.effects.flashObject(self, 0xffffff, 300); }; return self; }); var Gun = Container.expand(function () { var self = Container.call(this); // The visual asset for the gun self.visual = self.attachAsset('gun_visual', { anchorX: 0.5, // Anchor to its horizontal center anchorY: 1.0 // Anchor to its bottom edge (base of the gun) }); return self; }); // Obstacle class var Obstacle = Container.expand(function () { var self = Container.call(this); var obs = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); // Speed is set on creation self.speed = 0; self.update = function () { self.y += self.speed; }; return self; }); // Shop class for purchasing items var Shop = Container.expand(function () { var self = Container.call(this); var items = [{ name: "Speed Boost", cost: 10 }, { name: "Extra Life", cost: 20 }, { name: "Shield", cost: 15 }]; var shopText = new Text2("Shop", { size: 100, fill: 0xFFFFFF }); shopText.anchor.set(0.5, 0); self.addChild(shopText); shopText.y = -200; // Show current persistent points var pointsText = new Text2("", { size: 70, fill: 0xFFFF00 }); pointsText.anchor.set(0.5, 0); pointsText.y = -100; self.addChild(pointsText); function updatePointsText() { var totalPoints = 0; var extraLives = 0; var shields = 0; if (typeof storage !== "undefined") { totalPoints = storage.totalPoints || 0; extraLives = typeof storage.extraLives !== "undefined" ? storage.extraLives : 3; shields = storage.shields || 0; } pointsText.setText("Points: " + totalPoints + " | Extra Lives: " + extraLives + " | Shields: " + shields); // Also update global scoreTxt if shop is open if (typeof scoreTxt !== "undefined") { scoreTxt.setText(totalPoints); } } updatePointsText(); // Add shop items and purchase logic items.forEach(function (item, index) { var itemText = new Text2(item.name + " - " + item.cost + " points", { size: 70, fill: 0xFFFFFF }); itemText.anchor.set(0.5, 0); itemText.y = index * 100; self.addChild(itemText); // Enable purchase on tap/click itemText.interactive = true; itemText.buttonMode = true; itemText.down = function (x, y, obj) { var totalPoints = 0; if (typeof storage !== "undefined") { totalPoints = storage.totalPoints || 0; } if (totalPoints >= item.cost) { // Deduct cost and update storage totalPoints -= item.cost; if (typeof storage !== "undefined") { storage.totalPoints = totalPoints; } updatePointsText(); if (typeof updatePersistentPointsDisplay === "function") { updatePersistentPointsDisplay(); } // Show feedback (flash) LK.effects.flashObject(itemText, 0x00FF00, 400); // Apply item effect in game if (item.name === "Extra Life") { // Give player an extra life (persist for next game) if (typeof storage !== "undefined") { var extraLives = storage.extraLives || 0; storage.extraLives = extraLives + 1; if (typeof updateLivesDisplay === "function") { updateLivesDisplay(); } // Update heart icons UI // updatePointsText(); // This is already called after storage.totalPoints update, which also updates lives text in shop } } if (item.name === "Shield") { // Give player a shield (persist for next game) if (typeof storage !== "undefined") { var shields = storage.shields || 0; storage.shields = shields + 1; } } // Optionally: disable item after purchase (one-time buy) // itemText.alpha = 0.5; // itemText.interactive = false; } else { // Not enough points, flash red LK.effects.flashObject(itemText, 0xFF0000, 400); } }; }); return self; }); /**** * Initialize Game ****/ // var game = new LK.Game({ backgroundColor: 0x181c2c }); /**** * Game Code ****/ // Level variables var currentLevel = 1; var levelText; var levelUpInterval = 30 * 60; // Level up every 30 seconds (1800 ticks) var lastLevelUpTick = 0; // Show shop on demand (e.g. after game over or via button) // --- Shop display --- // Asset for life display // New asset for Kimchi function showShop() { var shop = new Shop(); // Center shop based on its size shop.x = GAME_W / 2; shop.y = GAME_H / 2; shop.anchorX = 0.5; shop.anchorY = 0.5; game.addChild(shop); // Bring shop to top (after all gameplay elements) if (shop.parent && shop.parent.children) { shop.parent.removeChild(shop); shop.parent.addChild(shop); } // Remove shop after 5 seconds LK.setTimeout(function () { if (shop && shop.parent) { shop.destroy(); } }, 5000); } // --- Main Menu Overlay --- var mainMenuOverlay; function showMainMenu() { // Prevent duplicate overlays if (mainMenuOverlay && mainMenuOverlay.parent) return; mainMenuOverlay = new Container(); // Semi-transparent background var bg = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 30, scaleY: 40, x: GAME_W / 2, y: GAME_H / 2, tint: 0x000000 }); bg.alpha = 0.7; mainMenuOverlay.addChild(bg); // Game Title var title = new Text2("Ana Menü", { size: 180, fill: 0xFFF700 }); title.anchor.set(0.5, 0.5); title.x = GAME_W / 2; title.y = GAME_H / 2 - 350; mainMenuOverlay.addChild(title); // Start Button var startBtn = new Text2("Başla", { size: 140, fill: 0xFFFFFF }); startBtn.anchor.set(0.5, 0.5); startBtn.x = GAME_W / 2; startBtn.y = GAME_H / 2 + 100; startBtn.interactive = true; startBtn.buttonMode = true; startBtn.down = function (x, y, obj) { if (mainMenuOverlay && mainMenuOverlay.parent) { mainMenuOverlay.destroy(); } // Activate gameplay gameActive = true; // Reset timer for new session gameStartTime = LK.ticks; lastLevelUpTick = LK.ticks; // Initialize level timer with current game ticks elapsedSeconds = 0; if (elapsedTimeText) { elapsedTimeText.setText('Time: 0s'); } // Optionally, reset other game state here if needed }; mainMenuOverlay.addChild(startBtn); // Optionally, add instructions var info = new Text2("Ekrana tıklayarak ateş et\nYüzünü hareket ettirerek karakteri kontrol et", { size: 70, fill: 0xFFFFFF }); info.anchor.set(0.5, 0.5); info.x = GAME_W / 2; info.y = GAME_H / 2 + 300; mainMenuOverlay.addChild(info); game.addChild(mainMenuOverlay); } // --- Gameplay lock until Başla is pressed --- var gameActive = false; // Only true after Başla is pressed // Show main menu at game start LK.setTimeout(function () { showMainMenu(); }, 10); // Timer variables var elapsedTimeText; var gameStartTime = 0; // To store LK.ticks at the start of the game var elapsedSeconds = 0; // To store the calculated elapsed seconds // Obstacle: red rectangle // Character: main player controlled by face // Game area dimensions var GAME_W = 2048; var GAME_H = 2732; // Player character var faceChar = new FaceChar(); game.addChild(faceChar); // Create and add the gun gun = new Gun(); game.addChild(gun); // Initial position: bottom center, 400px from bottom faceChar.x = GAME_W / 2; faceChar.y = GAME_H - 400; // Arrays for obstacles and points var obstacles = []; var points = []; var gun; // Gun instance var bullets = []; // Array to store active bullets // Score display var scoreTxt = new Text2('0', { size: 120, fill: 0xFFF700 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Level Display levelText = new Text2('Level: 1', { size: 80, fill: 0xADD8E6 // A nice light blue color for the level text }); levelText.anchor.set(0, 0); // Anchor to its own top-left LK.gui.topLeft.addChild(levelText); // Position it carefully in the top-left, avoiding the 100x100px menu icon area levelText.x = 110; // 100px for menu icon + 10px padding levelText.y = 20; // 20px from the top edge of the screen // Persistent Currency ("Para") Display will be initialized by updatePersistentPointsDisplay // Lives display elements var livesContainer = new Container(); LK.gui.topRight.addChild(livesContainer); // Add to top-right GUI area // livesContainer.anchor.set(1, 0); // Removed: Containers do not have an 'anchor' property for self-positioning. livesContainer.x = -30; // Position 30px from the screen's right edge (relative to gui.topRight) livesContainer.y = 30; // Position 30px from the screen's top edge (relative to gui.topRight) var heartIcons = []; // Array to keep track of heart icon objects function updateLivesDisplay() { // Clear previously displayed hearts heartIcons.forEach(function (icon) { if (icon && icon.parent) { // Check if icon exists and is attached icon.destroy(); } }); heartIcons = []; // Reset the array var currentLives = 0; // storage.extraLives is initialized by game logic (e.g., to 3 at game start/reset) // before this function is typically called. if (typeof storage !== "undefined" && typeof storage.extraLives === "number") { currentLives = storage.extraLives; } // If storage.extraLives were somehow not a number here, 0 hearts would be displayed, // accurately reflecting an issue with the life count data, rather than masking it. // Optionally cap the number of hearts displayed to avoid UI clutter var displayableLives = Math.min(currentLives, 5); // e.g., display max 5 hearts for (var i = 0; i < displayableLives; i++) { var heart = LK.getAsset('heart_icon', { anchorX: 1, anchorY: 0.5 }); // Anchor heart's right-middle if (heart) { // Position hearts horizontally from right to left within the livesContainer // The rightmost heart (i=0) is at x=0 relative to container's (anchored) right edge heart.x = -i * (heart.width + 10); // 10px spacing between hearts heart.y = heart.height / 2; // Vertically center hearts in the container livesContainer.addChild(heart); heartIcons.push(heart); } } } // For keeping track of score // Load score from storage if available (after game over) var score = 0; if (typeof storage !== "undefined") { // Use lastScore for current run, totalPoints for shop var lastScore = storage.lastScore; if (typeof lastScore === "number" && !isNaN(lastScore)) { score = lastScore; LK.setScore(score); } // Ensure extraLives, shields and totalPoints are defined if (typeof storage.extraLives === "undefined" || storage.extraLives === 0) { storage.extraLives = 3; } if (typeof storage.shields === "undefined") { storage.shields = 0; } if (typeof storage.totalPoints === "undefined") { storage.totalPoints = 0; } // Ensure totalPoints is initialized updateLivesDisplay(); // Initialize hearts display if (typeof updatePersistentPointsDisplay === "function") { updatePersistentPointsDisplay(); } // Initialize Para display } // Elapsed Time Display elapsedTimeText = new Text2('Time: 0s', { size: 70, fill: 0xFFFFFF // White color for the text }); elapsedTimeText.anchor.set(0, 1); // Anchor to the bottom-left of the text LK.gui.bottomLeft.addChild(elapsedTimeText); // Position it 30px from the left and 30px from the bottom of the screen elapsedTimeText.x = 30; elapsedTimeText.y = -30; // Initialize timer variables for the current game session gameStartTime = LK.ticks; elapsedSeconds = 0; elapsedTimeText.setText('Time: ' + elapsedSeconds + 's'); // Set initial text // For obstacle/point spawn timing var lastObstacleTick = 0; var lastPointTick = 0; var lastShotTick = 0; // Tracks the game tick of the last shot var fireCooldownTicks = 60; // Minimum ticks between shots (60 ticks = 1 second at 60 FPS) var initialBulletSpeed = -30; // Base speed for bullets at level 1 var bulletSpeedIncrementPerLevel = 2; // How much faster (more negative) bullets get per level // For difficulty scaling var minObstacleInterval = 45; // ticks var minPointInterval = 60; // ticks var obstacleSpeed = 12; // px per frame, increases over time // For collision state var lastCollided = false; // For point collection state var lastPointCollided = {}; // Facekit smoothing var lastFaceX = faceChar.x; var lastFaceY = faceChar.y; // Persistent currency display var persistentPointsContainer; var persistentPointsText; var persistentCoinIcon; function updatePersistentPointsDisplay() { var spacing = 15; // Spacing between text and icon // Ensure container exists and is on GUI if (!persistentPointsContainer) { persistentPointsContainer = new Container(); LK.gui.topRight.addChild(persistentPointsContainer); // Attach to top-right persistentPointsContainer.x = -30; // Position 30px from the screen's right edge persistentPointsContainer.y = 140; // Position below lives display (lives at y=30, hearts ~70px high) } // Ensure Text2 object for points exists if (!persistentPointsText) { persistentPointsText = new Text2("Coin: 0", { size: 70, fill: 0xFFFF00 }); persistentPointsText.anchor.set(1, 0.5); // Anchor right-middle for positioning } // Ensure text is child of container if (persistentPointsText.parent !== persistentPointsContainer) { if (persistentPointsText.parent) { persistentPointsText.parent.removeChild(persistentPointsText); } persistentPointsContainer.addChild(persistentPointsText); } // Ensure coin icon asset exists if (!persistentCoinIcon) { persistentCoinIcon = LK.getAsset('coin_icon', { // width/height will come from asset definition in Assets section anchorX: 1, // Anchor right anchorY: 0.5 // Anchor middle for vertical alignment with text }); } // Ensure icon is child of container if (persistentCoinIcon.parent !== persistentPointsContainer) { if (persistentCoinIcon.parent) { persistentCoinIcon.parent.removeChild(persistentCoinIcon); } persistentPointsContainer.addChild(persistentCoinIcon); } // Update text content var currentPoints = 0; if (typeof storage !== "undefined" && typeof storage.totalPoints === "number") { currentPoints = storage.totalPoints; } persistentPointsText.setText("Coin: " + currentPoints); // Position text and icon within the container for right alignment. // The container's top-left is positioned by persistentPointsContainer.x and .y relative to LK.gui.topRight. // Children x,y are relative to the container's top-left. // persistentCoinIcon is rightmost. Its anchor (1, 0.5) means its right-middle point is at its x,y. // We position its right-middle point at (0,0) relative to container's origin (top-left). persistentCoinIcon.x = 0; persistentCoinIcon.y = 0; // Vertically centered due to anchorY 0.5 and container's y // persistentPointsText is to the left. Its anchor (1, 0.5) means its right-middle point is at its x,y. // We position its right-middle point to be (persistentCoinIcon.width + spacing) to the left of the icon's right-middle. persistentPointsText.x = -(persistentCoinIcon.width + spacing); persistentPointsText.y = 0; // Vertically centered due to anchorY 0.5 and container's y } // Handle screen tap to fire bullets game.down = function (x, y, obj) { if (!gameActive) return; // Prevent firing if game not started // Check cooldown: If current time (LK.ticks) minus last shot time is less than the cooldown period, do nothing. if (LK.ticks - lastShotTick < fireCooldownTicks) { return; // Still in cooldown period, prevent firing } if (gun && gun.visual && faceChar) { // Ensure gun, its visual, and character exist var currentBulletSpeed = initialBulletSpeed - (currentLevel - 1) * bulletSpeedIncrementPerLevel; var newBullet = new Bullet(currentBulletSpeed); newBullet.x = gun.x; // Gun's anchorY is 1.0 (bottom). gun.y is its base. // Gun's tip is gun.y - gun.visual.height. // Bullet's anchorY is 0.5 (center). newBullet.y = gun.y - gun.visual.height; // Initialize lastY for off-screen detection logic newBullet.lastY = newBullet.y; bullets.push(newBullet); game.addChild(newBullet); lastShotTick = LK.ticks; // Update the time of the last shot // Optional: Play a shooting sound if an asset 'shoot' is available // if (LK.getSound('shoot')) { // LK.getSound('shoot').play(); // } } }; // Main update loop game.update = function () { if (!gameActive) return; // Block all gameplay updates until Başla is pressed // --- Timer Update --- // Calculate total elapsed seconds since the game started var currentTotalSeconds = Math.floor((LK.ticks - gameStartTime) / 60); // Update the text only if the number of seconds has changed if (currentTotalSeconds !== elapsedSeconds) { elapsedSeconds = currentTotalSeconds; if (elapsedTimeText) { // Check if the text object exists elapsedTimeText.setText('Time: ' + elapsedSeconds + 's'); } } // --- Level Progression --- if (LK.ticks - lastLevelUpTick > levelUpInterval) { currentLevel++; if (levelText) { levelText.setText('Level: ' + currentLevel); } lastLevelUpTick = LK.ticks; // Increase difficulty with the new level obstacleSpeed += 1.0; // Make obstacles faster // Decrease spawn intervals (more frequent spawns), but with a minimum cap if (minObstacleInterval > 15) { // Don't let obstacles spawn too frenetically minObstacleInterval -= 2; } if (minPointInterval > 20) { // Same for points/coins minPointInterval -= 2; } // Optional: Cap the maximum obstacle speed to prevent it from becoming unplayably fast if (obstacleSpeed > 40) { obstacleSpeed = 40; } // You could add other effects or difficulty adjustments here when a new level is reached! } // --- Facekit control --- // Use mouthCenter for X/Y, clamp to game area var fx = facekit.mouthCenter && typeof facekit.mouthCenter.x === "number" ? facekit.mouthCenter.x : GAME_W / 2; var fy = facekit.mouthCenter && typeof facekit.mouthCenter.y === "number" ? facekit.mouthCenter.y : GAME_H - 400; // Optionally, if mouth is open, move faster (boost) var boost = facekit.mouthOpen ? 1.7 : 1.0; // Smooth movement (lerp) lastFaceX += (fx - lastFaceX) * 0.25 * boost; lastFaceY += (fy - lastFaceY) * 0.25 * boost; // Clamp to bounds (keep inside screen) var charW = faceChar.width; var charH = faceChar.height; var minX = charW / 2 + 40; var maxX = GAME_W - charW / 2 - 40; var minY = charH / 2 + 120; var maxY = GAME_H - charH / 2 - 40; faceChar.x = Math.max(minX, Math.min(maxX, lastFaceX)); faceChar.y = Math.max(minY, Math.min(maxY, lastFaceY)); // --- Spawn obstacles --- // Update gun position to follow faceChar if (gun && faceChar) { gun.x = faceChar.x; // Position the base of the gun (anchorY = 1.0) at the top edge of faceChar gun.y = faceChar.y - faceChar.height / 2; } // --- Manage Bullets --- for (var k = bullets.length - 1; k >= 0; k--) { var bullet = bullets[k]; // Initialize lastY for tracking changes on Y if not already done (e.g. if not set at creation) if (bullet.lastY === undefined) { bullet.lastY = bullet.y; } // bullet.update(); // Bullet's own update method is called automatically by LK engine if bullet is added to game stage // Off-Screen Detection (top of screen) // A bullet's y is its center (anchorY: 0.5). // It's off-screen if its center y is < -(bullet.visual.height / 2). var bulletHeight = bullet.visual ? bullet.visual.height : 50; // Fallback height var offScreenThreshold = -(bulletHeight / 2) - 10; // Add a small buffer beyond the edge if (bullet.y < offScreenThreshold) { // More robust check: if it *crossed* the boundary in this frame if (bullet.lastY >= offScreenThreshold) { bullet.destroy(); // Destroy can only be called from the main 'Game' class bullets.splice(k, 1); continue; // Skip further processing for this bullet } else if (bullet.y < -GAME_H) { // Failsafe: if it's way off screen (e.g. due to lag/teleport) bullet.destroy(); bullets.splice(k, 1); continue; } } bullet.lastY = bullet.y; // Update last known Y position // Bullet-Obstacle Collision // Iterate through obstacles to check for collision with the current bullet for (var obs_idx = obstacles.length - 1; obs_idx >= 0; obs_idx--) { var obstacle = obstacles[obs_idx]; // Ensure the bullet still exists and is part of the game scene. // This check is important because the bullet might have been destroyed by off-screen logic // or by a previous collision in this same frame if multiple collisions were possible. if (!bullet || !bullet.parent) { // If bullet is no longer valid (e.g., already destroyed and removed from its parent container), // then stop checking it against further obstacles. break; } // Ensure the obstacle also still exists and is part of the game scene. if (obstacle && obstacle.parent && bullet.intersects(obstacle)) { // Collision detected! // Destroy the obstacle obstacle.destroy(); obstacles.splice(obs_idx, 1); // Award points for destroying obstacle score += 5; LK.setScore(score); if (scoreTxt) { scoreTxt.setText(score); } // Destroy the bullet bullet.destroy(); bullets.splice(k, 1); // k is the index from the outer bullets loop // Since this bullet has been destroyed, break from iterating through more obstacles for it. // The outer loop (for bullets) will correctly handle the modified bullets array due to the splice. break; } } // End of Bullet-Obstacle Collision logic for the current bullet } // --- Spawn obstacles --- if (LK.ticks - lastObstacleTick > minObstacleInterval + Math.floor(Math.random() * 40)) { var obs = new Obstacle(); // Random X, avoid leftmost 100px (menu) var obsW = obs.width; var obsX = 100 + obsW / 2 + Math.random() * (GAME_W - obsW - 200); obs.x = obsX; obs.y = -obs.height / 2; obs.speed = obstacleSpeed + Math.random() * 3; obstacles.push(obs); game.addChild(obs); lastObstacleTick = LK.ticks; } // --- Spawn points --- if (LK.ticks - lastPointTick > minPointInterval + Math.floor(Math.random() * 60)) { var pt = new CoinCollectible(); var ptW = pt.width; var ptX = 100 + ptW / 2 + Math.random() * (GAME_W - ptW - 200); pt.x = ptX; pt.y = -pt.height / 2; pt.speed = obstacleSpeed * 0.8 + Math.random() * 2; points.push(pt); game.addChild(pt); lastPointTick = LK.ticks; } // --- Move obstacles, check collision --- var collided = false; for (var i = obstacles.length - 1; i >= 0; i--) { var o = obstacles[i]; o.update(); // Off screen if (o.y - o.height / 2 > GAME_H + 100) { o.destroy(); obstacles.splice(i, 1); continue; } // Collision with player if (faceChar.intersects(o)) { collided = true; } } // --- Move points, check collection --- for (var j = points.length - 1; j >= 0; j--) { var p = points[j]; p.update(); // Off screen if (p.y - p.height / 2 > GAME_H + 100) { p.destroy(); points.splice(j, 1); continue; } // Collision with player var pointId = p._lkid || p._id || j; if (!lastPointCollided[pointId]) { if (faceChar.intersects(p)) { // Collect point score += 1; LK.setScore(score); scoreTxt.setText(score); // Flash effect LK.effects.flashObject(p, 0xffffff, 200); p.destroy(); points.splice(j, 1); lastPointCollided[pointId] = true; continue; } } } // --- Collision state transitions --- if (!lastCollided && collided) { // Check for shield first var usedShield = false; if (typeof storage !== "undefined" && storage.shields && storage.shields > 0) { storage.shields = storage.shields - 1; usedShield = true; LK.effects.flashScreen(0x00ffff, 600); faceChar.flash(); // Don't trigger game over, just consume shield } // If no shield, check for extra life else if (typeof storage !== "undefined" && storage.extraLives && storage.extraLives > 0) { storage.extraLives = storage.extraLives - 1; if (typeof updateLivesDisplay === "function") { updateLivesDisplay(); } // Update hearts display LK.effects.flashScreen(0x00ff00, 600); faceChar.flash(); // Don't trigger game over, just consume extra life } // No shield or extra life, trigger game over else { LK.effects.flashScreen(0xff0000, 800); faceChar.flash(); LK.showGameOver(); return; } } lastCollided = collided; // --- Difficulty scaling --- if (LK.ticks % 300 === 0 && obstacleSpeed < 32) { obstacleSpeed += 1.2; if (minObstacleInterval > 20) { minObstacleInterval -= 2; } if (minPointInterval > 30) { minPointInterval -= 2; } } }; // --- Instructions text removed --- // --- Center score text --- scoreTxt.x = 0; scoreTxt.y = 20; // --- Clean up on game over --- game.on('destroy', function () { // Save score to persistent storage before reset if (typeof storage !== "undefined") { storage.lastScore = score; // Only add this run's score to totalPoints if score > 0 if (score > 0) { var totalPoints = storage.totalPoints || 0; // Convert 2 game points to 1 Coin storage.totalPoints = totalPoints + Math.floor(score / 2); } if (typeof updatePersistentPointsDisplay === "function") { updatePersistentPointsDisplay(); } } // Destroy all active bullets for (var i_bullet_cleanup = bullets.length - 1; i_bullet_cleanup >= 0; i_bullet_cleanup--) { if (bullets[i_bullet_cleanup] && bullets[i_bullet_cleanup].destroy) { bullets[i_bullet_cleanup].destroy(); } } bullets = []; obstacles = []; points = []; lastPointCollided = {}; lastCollided = false; lastFaceX = GAME_W / 2; lastFaceY = GAME_H - 400; score = 0; LK.setScore(0); scoreTxt.setText('0'); // Reset level variables currentLevel = 1; if (levelText) { levelText.setText('Level: ' + currentLevel); } // lastLevelUpTick will be reset correctly when the game starts again via the main menu button. // Setting to 0 here is a safe default if the game could restart without the menu. lastLevelUpTick = 0; if (gun) { // gun instance is a child of game, so it will be destroyed automatically by LK. // We just need to nullify the reference. gun = null; } // Reset lives to 3 for new game if (typeof storage !== "undefined") { storage.extraLives = 3; if (typeof updateLivesDisplay === "function") { updateLivesDisplay(); } // Update hearts display } // Show shop after game over showShop(); // Reset scoreTxt to show 0 for new game if (typeof scoreTxt !== "undefined") { scoreTxt.setText('0'); } });
===================================================================
--- original.js
+++ change.js
@@ -7,17 +7,18 @@
/****
* Classes
****/
-var Bullet = Container.expand(function () {
+var Bullet = Container.expand(function (initialSpeed) {
var self = Container.call(this);
+ // Added initialSpeed parameter
//Create and attach asset.
self.visual = self.attachAsset('bullet', {
// Uses the existing 'bullet' image asset
anchorX: 0.5,
anchorY: 0.5
});
- self.speed = -30; // Negative speed for upward movement
+ self.speed = initialSpeed; // Use the passed initialSpeed for movement
// If this instance of bullet is attached, this method will be called every tick by the LK engine automatically.
self.update = function () {
self.y += self.speed;
};
@@ -412,8 +413,10 @@
var lastObstacleTick = 0;
var lastPointTick = 0;
var lastShotTick = 0; // Tracks the game tick of the last shot
var fireCooldownTicks = 60; // Minimum ticks between shots (60 ticks = 1 second at 60 FPS)
+var initialBulletSpeed = -30; // Base speed for bullets at level 1
+var bulletSpeedIncrementPerLevel = 2; // How much faster (more negative) bullets get per level
// For difficulty scaling
var minObstacleInterval = 45; // ticks
var minPointInterval = 60; // ticks
var obstacleSpeed = 12; // px per frame, increases over time
@@ -494,9 +497,10 @@
return; // Still in cooldown period, prevent firing
}
if (gun && gun.visual && faceChar) {
// Ensure gun, its visual, and character exist
- var newBullet = new Bullet();
+ var currentBulletSpeed = initialBulletSpeed - (currentLevel - 1) * bulletSpeedIncrementPerLevel;
+ var newBullet = new Bullet(currentBulletSpeed);
newBullet.x = gun.x;
// Gun's anchorY is 1.0 (bottom). gun.y is its base.
// Gun's tip is gun.y - gun.visual.height.
// Bullet's anchorY is 0.5 (center).
A tiny bomb. In-Game asset. 2d. High contrast. No shadows
Gold coin. In-Game asset. 2d. High contrast. No shadows
Mermi. In-Game asset. 2d. High contrast. No shadows
Kırmızı kalp. In-Game asset. 2d. High contrast. No shadows
Silah. In-Game asset. 2d. High contrast. No shadows
faceChar. In-Game asset. 2d. High contrast. No shadows