User prompt
rüzgarın yönü bayrak ile belli edilsin ve topun hızını etkileyecek şekilde bir rüzgar olmalı
User prompt
ekranın 4 tarafından rastgele bir şekilde her kartopu fırlatılmadan önce bir rüzgar mekaniği istiyorum
User prompt
ortadaki sura kar topu hiçbir şekilde çarpmasın
User prompt
kartopunu fırlatma mekaniği mouse çektiğimiz yöne doğru olmasın hep karşısındaki penguene doğru olsun mouseu ne kadar uzun basılı tutarsak kartopunun gittiği mesafe o kadar artsın
User prompt
penguenin altındaki uzun çubuğun rengi kırmızı olsun
User prompt
penguenin altında topun ne yöne gideceğini gösteren bir uzun çubuk çıksın
User prompt
penguenin yanındaki barın içinde kırmızı renkli bir bar dolsun basılı tuttukça
User prompt
kartopunu fırlatabilmek için penguenin üzerine basılı tutmak gerekiyor.penguenin yanında bir bar dolsun o bar ile kartopunun hızını ayarlayabilelim
User prompt
arka plana bir resim istiyorum 3 boyutlu gibi görünen bir ortam resmi
User prompt
penguenin arkası dönük olsun
User prompt
Please fix the bug: 'Timeout.tick error: Cannot set properties of null (setting 'canThrow')' in or related to this line: 'dragPenguin.canThrow = true;' Line Number: 233
User prompt
elindeki kartopunu silelim eli biraz daha uzun olsun ve kartopu fırlatmak istediğimde eli ileri ve geri hareket edebilsin
User prompt
aradaki sur yatay şekilde dursun
Code edit (1 edits merged)
Please save this source code
User prompt
Penguin Snowball Siege
Initial prompt
penguenlerin birbirleri ile kartopu savaşı yaptığı bir oyun yapmak istiyorum arada kale suru şeklinde duvar olsun
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Penguin class var Penguin = Container.expand(function () { var self = Container.call(this); // Penguin id: 1 or 2 self.penguinId = 1; // Attach penguin asset var penguinGfx = self.attachAsset(self.penguinId === 1 ? 'penguin1' : 'penguin2', { anchorX: 0.5, anchorY: 0.5, scaleX: -1 // Flip horizontally to show penguin's back }); // Used for drag self.isDragging = false; // Used for aiming self.aimLine = null; // Used for touch start position self.startDragX = 0; self.startDragY = 0; // Used for aiming vector self.aimVX = 0; self.aimVY = 0; // Used for aiming bar self.aimBar = null; // Used for cooldown self.canThrow = true; // Used for tracking last position for drag self.lastDragX = 0; self.lastDragY = 0; // Used for showing aim self.showAim = function (x, y) { // Not implemented: no line drawing in LK, so skip }; // Used for hiding aim self.hideAim = function () { // Not implemented: no line drawing in LK, so skip }; return self; }); // Class for falling snowball (visual only, no collision) var SnowShowerBall = Container.expand(function () { var self = Container.call(this); // Attach snowball asset var gfx = self.attachAsset('snowball', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7 + Math.random() * 0.5, scaleY: 0.7 + Math.random() * 0.5 }); // Random X across the screen, avoid top left 100x100 self.x = 120 + Math.random() * (GAME_WIDTH - 240); self.y = -60 - Math.random() * 200; // Random speed self.vy = 7 + Math.random() * 4; // Slight wind drift self.vx = -2 + Math.random() * 4; // Fade in/out gfx.alpha = 0.7 + Math.random() * 0.3; // Wobble self.wobblePhase = Math.random() * Math.PI * 2; self.update = function () { self.y += self.vy; self.x += self.vx + Math.sin(Date.now() / 300 + self.wobblePhase) * 1.2; // Remove if out of bounds if (self.y > GAME_HEIGHT + 80) { self.destroy(); // Remove from array in main update } }; return self; }); // Function to spawn a snowball shower ball // Snowball class var Snowball = Container.expand(function () { var self = Container.call(this); // Add black outline as a slightly larger ellipse behind the snowball var outline = self.attachAsset('snowball', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.18, scaleY: 1.18, color: 0x000000 }); // Attach snowball asset (white, on top) var snowballGfx = self.attachAsset('snowball', { anchorX: 0.5, anchorY: 0.5 }); // Who fired this snowball? 1 or 2 self.owner = 1; // Velocity self.vx = 0; self.vy = 0; // Used for bounce cooldown self.bounced = false; // Update method self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Light blue sky }); /**** * Game Code ****/ // Flag asset for wind direction (simple colored box) // Game constants // Penguin (player 1) // Penguin (player 2) // Snowball // Castle wall (center) var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; // Center wall var wall = LK.getAsset('castleWall', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2, rotation: Math.PI / 2 // Rotate 90 degrees to make it horizontal }); game.addChild(wall); // --- Penguin selection screen --- var selectedPenguinId = null; var penguin1 = null; var penguin2 = null; var aiPenguin = null; var playerPenguin = null; var selectionScreen = new Container(); game.addChild(selectionScreen); // Penguin 1 preview var penguin1Preview = LK.getAsset('penguin1', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2 - 300, y: GAME_HEIGHT / 2, scaleX: 1, scaleY: 1 }); selectionScreen.addChild(penguin1Preview); // Penguin 2 preview var penguin2Preview = LK.getAsset('penguin2', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2 + 300, y: GAME_HEIGHT / 2, scaleX: 1, scaleY: 1 }); selectionScreen.addChild(penguin2Preview); // Penguin 1 label var penguin1Label = new Text2("Penguin 1", { size: 90, fill: 0x222222 }); penguin1Label.anchor.set(0.5, 0); penguin1Label.x = penguin1Preview.x; penguin1Label.y = penguin1Preview.y + 140; selectionScreen.addChild(penguin1Label); // Penguin 2 label var penguin2Label = new Text2("Penguin 2", { size: 90, fill: 0x222222 }); penguin2Label.anchor.set(0.5, 0); penguin2Label.x = penguin2Preview.x; penguin2Label.y = penguin2Preview.y + 140; selectionScreen.addChild(penguin2Label); // Title var selectTitle = new Text2("Choose your Penguin!", { size: 120, fill: 0x4fc3f7 }); selectTitle.anchor.set(0.5, 0.5); selectTitle.x = GAME_WIDTH / 2; selectTitle.y = GAME_HEIGHT / 2 - 300; selectionScreen.addChild(selectTitle); // Selection logic selectionScreen.down = function (x, y, obj) { // Check if touch is on penguin1Preview var dx1 = x - penguin1Preview.x; var dy1 = y - penguin1Preview.y; var dx2 = x - penguin2Preview.x; var dy2 = y - penguin2Preview.y; var r = 120; if (dx1 * dx1 + dy1 * dy1 < r * r) { selectedPenguinId = 1; } else if (dx2 * dx2 + dy2 * dy2 < r * r) { selectedPenguinId = 2; } if (selectedPenguinId) { // Remove selection screen selectionScreen.destroy(); // Remove preview penguins from the game (ensure they are not left in the background) if (penguin1Preview && penguin1Preview.parent) penguin1Preview.destroy(); if (penguin2Preview && penguin2Preview.parent) penguin2Preview.destroy(); if (penguin1Label && penguin1Label.parent) penguin1Label.destroy(); if (penguin2Label && penguin2Label.parent) penguin2Label.destroy(); if (selectTitle && selectTitle.parent) selectTitle.destroy(); // Setup penguins penguin1 = new Penguin(); penguin1.penguinId = 1; penguin1.x = GAME_WIDTH / 2; penguin1.y = GAME_HEIGHT - 350; game.addChild(penguin1); penguin2 = new Penguin(); penguin2.penguinId = 2; penguin2.x = GAME_WIDTH / 2; penguin2.y = 350; game.addChild(penguin2); // Set correct asset for penguin2 penguin2.removeChildAt(0); penguin2.attachAsset('penguin2', { anchorX: 0.5, anchorY: 0.5, scaleX: -1 }); // Assign player and AI if (selectedPenguinId === 1) { playerPenguin = penguin1; aiPenguin = penguin2; } else { playerPenguin = penguin2; aiPenguin = penguin1; } // Mark for AI logic aiPenguin.isAI = true; playerPenguin.isAI = false; // Set up initial canThrow playerPenguin.canThrow = true; aiPenguin.canThrow = true; // (Optional) Add a little effect to show selection LK.effects.flashObject(playerPenguin, 0x4fc3f7, 600); } }; selectionScreen.interactive = true; selectionScreen.on('down', selectionScreen.down); // The rest of the game logic will use playerPenguin and aiPenguin instead of penguin1/penguin2 directly. // Score var score1 = 0; var score2 = 0; // Score text var scoreTxt = new Text2('0 : 0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Snowballs array var snowballs = []; // --- Wind mechanic --- // Wind directions: 0=left, 1=right, 2=up, 3=down var windDirections = [{ name: "←", dx: -1, dy: 0 }, { name: "→", dx: 1, dy: 0 }, { name: "↑", dx: 0, dy: -1 }, { name: "↓", dx: 0, dy: 1 }]; var windStrengthMin = 0; // minimum wind var windStrengthMax = 22; // maximum wind var windStrength = 0; // current wind strength (0-22) var windDir = 0; // current wind direction index (0-3) var windIndicator = null; var windText = null; // Helper to randomize wind before each throw function setRandomWind() { windDir = Math.floor(Math.random() * windDirections.length); windStrength = Math.floor(Math.random() * (windStrengthMax + 1)); // 0 to max // Remove old indicator if (windIndicator) { windIndicator.destroy(); windIndicator = null; } if (windText) { windText.destroy(); windText = null; } if (typeof windFlag !== "undefined" && windFlag) { windFlag.destroy(); windFlag = null; } // Show wind visually at top center (keep arrow for reference) var arrowLen = 120 + windStrength * 3; var arrowColor = 0x4fc3f7; windIndicator = LK.getAsset('snowball', { anchorX: 0.5, anchorY: 0.5, width: 30, height: arrowLen, color: arrowColor }); windIndicator.x = GAME_WIDTH / 2; windIndicator.y = 160; if (windDir === 0) windIndicator.rotation = Math.PI; // left else if (windDir === 1) windIndicator.rotation = 0; // right else if (windDir === 2) windIndicator.rotation = -Math.PI / 2; // up else if (windDir === 3) windIndicator.rotation = Math.PI / 2; // down game.addChild(windIndicator); // Add flag to indicate wind direction and strength windFlag = LK.getAsset('windFlag', { anchorX: 0.1, anchorY: 0.5, width: 90 + windStrength * 2, // flag length grows with wind height: 60 + Math.floor(windStrength / 3), // flag height grows a bit with wind color: 0xffe066 }); // Place wind flag at the top right corner, leaving a margin from the edge windFlag.x = GAME_WIDTH - 120; windFlag.y = 120; // Rotate flag to match wind direction if (windDir === 0) windFlag.rotation = Math.PI; // left else if (windDir === 1) windFlag.rotation = 0; // right else if (windDir === 2) windFlag.rotation = -Math.PI / 2; // up else if (windDir === 3) windFlag.rotation = Math.PI / 2; // down game.addChild(windFlag); // Animate flag waving (simple waving effect) if (typeof windFlagTween !== "undefined" && windFlagTween) { windFlagTween.stop(); windFlagTween = null; } // Animate flag waving (simple waving effect) using correct tween API tween(windFlag, { scaleY: 1.15 }, { duration: 400, easing: tween.sineInOut, onFinish: function onFinish() { // Reverse the tween for yoyo effect tween(windFlag, { scaleY: 1.0 }, { duration: 400, easing: tween.sineInOut, onFinish: function onFinish() { // Loop the waving animation LK.setTimeout(function () { if (windFlag && windFlag.parent) { // Only continue if flag still exists // Recursively start waving again // (This is a simple infinite yoyo loop) tween(windFlag, { scaleY: 1.15 }, { duration: 400, easing: tween.sineInOut, onFinish: arguments.callee }); } }, 0); } }); } }); // Add wind text var txt = windDirections[windDir].name + " " + windStrength; windText = new Text2(txt, { size: 80, fill: 0x4fc3f7 }); windText.anchor.set(0.5, 0.5); // Place wind text near the flag, but offset to the left to avoid overlap windText.x = GAME_WIDTH - 260; windText.y = 120; LK.gui.top.addChild(windText); } // Call once at start setRandomWind(); // Drag/aim state var dragPenguin = null; var dragStartX = 0; var dragStartY = 0; var dragCurrentX = 0; var dragCurrentY = 0; // Power bar state var powerBar = null; var powerBarBg = null; var powerBarValue = 0; var powerBarInterval = null; var powerBarMax = 1.0; // max fill var powerBarMin = 0.2; // min fill var powerBarSpeed = 0.012; // fill per tick // Turn-based state var currentTurn = "player"; // "player" or "ai" var turnInProgress = false; // Prevents double actions in a turn // Only allow one penguin to be dragged at a time function isTouchOnPenguin(x, y, penguin) { if (!penguin) return false; // Defensive: penguin may be null // Simple bounding box check var px = penguin.x; var py = penguin.y; var w = penguin.width || 140; var h = penguin.height || 180; return x > px - w / 2 && x < px + w / 2 && y > py - h / 2 && y < py + h / 2; } // Only allow dragging own penguin (player 1: bottom, player 2: top) game.down = function (x, y, obj) { // Don't allow drag in top 100x100 (menu) if (x < 100 && y < 100) return; // Only allow drag on playerPenguin (single player) and only if it's player's turn and not in progress if (typeof playerPenguin !== "undefined" && isTouchOnPenguin(x, y, playerPenguin) && currentTurn === "player" && !turnInProgress) { turnInProgress = true; dragPenguin = playerPenguin; dragStartX = x; dragStartY = y; dragCurrentX = x; dragCurrentY = y; playerPenguin.isDragging = true; // Show power bar next to playerPenguin if (powerBarBg) { powerBarBg.destroy(); powerBarBg = null; } if (powerBar) { powerBar.destroy(); powerBar = null; } // Background bar powerBarBg = LK.getAsset('snowball', { anchorX: 0, anchorY: 0.5, width: 40, height: 180, color: 0xcccccc }); powerBarBg.x = playerPenguin.x + 90; powerBarBg.y = playerPenguin.y; game.addChild(powerBarBg); // Foreground (fill) bar powerBar = LK.getAsset('snowball', { anchorX: 0, anchorY: 0.5, width: 36, height: 0, // will be set by fill color: 0x4fc3f7 }); powerBar.x = playerPenguin.x + 92; powerBar.y = playerPenguin.y + 90; // start at bottom game.addChild(powerBar); powerBarValue = powerBarMin; // Animate fill if (powerBarInterval) LK.clearInterval(powerBarInterval); powerBarInterval = LK.setInterval(function () { if (!dragPenguin) return; powerBarValue += powerBarSpeed; if (powerBarValue > powerBarMax) powerBarValue = powerBarMax; // Update bar height and position var maxHeight = 180; var fillHeight = Math.max(0, Math.floor(maxHeight * powerBarValue)); powerBar.height = fillHeight; powerBar.y = playerPenguin.y + 90 - fillHeight; }, 16); } }; game.move = function (x, y, obj) { if (!dragPenguin) return; // Clamp drag to own half (playerPenguin only) if (dragPenguin === playerPenguin) { if (playerPenguin.penguinId === 1 && y < GAME_HEIGHT / 2 + 100) y = GAME_HEIGHT / 2 + 100; if (playerPenguin.penguinId === 2 && y > GAME_HEIGHT / 2 - 100) y = GAME_HEIGHT / 2 - 100; } // Clamp to game area var minX = 120, maxX = GAME_WIDTH - 120; var minY = 120, maxY = GAME_HEIGHT - 120; x = Math.max(minX, Math.min(maxX, x)); y = Math.max(minY, Math.min(maxY, y)); dragCurrentX = x; dragCurrentY = y; // Move penguin dragPenguin.x = x; dragPenguin.y = y; // --- Aiming bar logic --- var penguin = dragPenguin; if (penguin) { // Remove old aimBar if exists if (penguin.aimBar) { penguin.aimBar.destroy(); penguin.aimBar = null; } // Only show aim bar if drag distance is enough var dx = dragCurrentX - dragStartX; var dy = dragCurrentY - dragStartY; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 20) { // Always aim toward the AI penguin var target = aiPenguin; var tx = target.x - penguin.x; var ty = target.y - penguin.y; var angle = Math.atan2(ty, tx); // Bar length var barLen = 220; // Create bar as a thin tall rectangle (use a box shape) var bar = LK.getAsset('snowball', { anchorX: 0.5, anchorY: 1, width: 18, height: barLen, color: 0x4fc3f7 }); // Place under penguin bar.x = penguin.x; bar.y = penguin.y + 90; // Rotate to aim direction bar.rotation = angle + Math.PI / 2; game.addChild(bar); penguin.aimBar = bar; } } // Move power bar if visible if (powerBarBg && dragPenguin) { powerBarBg.x = dragPenguin.x + 90; powerBarBg.y = dragPenguin.y; } if (powerBar && dragPenguin) { powerBar.x = dragPenguin.x + 92; // keep y at bottom, height is set by interval } }; game.up = function (x, y, obj) { if (!dragPenguin) return; // Hide power bar if (powerBarBg) { powerBarBg.destroy(); powerBarBg = null; } if (powerBar) { powerBar.destroy(); powerBar = null; } if (powerBarInterval) { LK.clearInterval(powerBarInterval); powerBarInterval = null; } // Only allow throw if drag distance is enough and cooldown is over var dx = dragCurrentX - dragStartX; var dy = dragCurrentY - dragStartY; var dist = Math.sqrt(dx * dx + dy * dy); // Only allow throw if drag is a "flick" (distance > 80) if (dist > 80 && dragPenguin.canThrow && currentTurn === "player") { // Set new wind before each throw setRandomWind(); // Always throw toward the AI penguin, power only affects distance var basePower = powerBarValue || powerBarMin; var thrower = dragPenguin; var target = aiPenguin; // Calculate direction vector from thrower to target var tx = target.x - thrower.x; var ty = target.y - thrower.y; var len = Math.sqrt(tx * tx + ty * ty); // Normalize direction var dirX = tx / len; var dirY = ty / len; // Set velocity magnitude based on power var minV = 18; var maxV = 55; var velocity = minV + (maxV - minV) * ((basePower - powerBarMin) / (powerBarMax - powerBarMin)); // Clamp velocity if (velocity < minV) velocity = minV; if (velocity > maxV) velocity = maxV; // Final velocity var vx = dirX * velocity; var vy = dirY * velocity; // --- Apply wind effect --- // Wind is a constant added to vx/vy, scaled by windStrength var wind = windDirections[windDir]; var windEffect = windStrength * 0.18; // tune this for balance vx += wind.dx * windEffect; vy += wind.dy * windEffect; // Create snowball var snowball = new Snowball(); snowball.owner = playerPenguin.penguinId; snowball.x = dragPenguin.x; snowball.y = dragPenguin.y + (snowball.owner === 1 ? -90 : 90); snowball.vx = vx; snowball.vy = vy; snowballs.push(snowball); game.addChild(snowball); // Play snowball throw sound LK.getSound('kartopusesi').play(); // Cooldown: prevent spamming dragPenguin.canThrow = false; var cooldownPenguin = dragPenguin; LK.setTimeout(function () { if (cooldownPenguin) { cooldownPenguin.canThrow = true; } }, 600); // End player's turn, start AI's turn after a 2 second delay currentTurn = "ai"; turnInProgress = true; LK.setTimeout(function () { turnInProgress = false; }, 2000); } // Remove aim bar if exists if (dragPenguin && dragPenguin.aimBar) { dragPenguin.aimBar.destroy(); dragPenguin.aimBar = null; } dragPenguin.isDragging = false; dragPenguin = null; }; /** * Helper: check collision between two containers (bounding box) */ function isIntersect(a, b) { var ax = a.x, ay = a.y, aw = a.width || 100, ah = a.height || 100; var bx = b.x, by = b.y, bw = b.width || 100, bh = b.height || 100; return ax - aw / 2 < bx + bw / 2 && ax + aw / 2 > bx - bw / 2 && ay - ah / 2 < by + bh / 2 && ay + ah / 2 > by - bh / 2; } // Update score text function updateScore() { scoreTxt.setText(score1 + " : " + score2); } // Game update loop game.update = function () { // --- AI logic for non-player penguin --- // AI only acts on its turn and if not in progress (wait for 2s after player) if (typeof aiPenguin !== "undefined" && aiPenguin && aiPenguin.isAI && aiPenguin.canThrow && currentTurn === "ai" && !turnInProgress) { // AI throws at intervals, only if no snowball is currently flying from AI var aiHasActiveSnowball = false; for (var aiCheck = 0; aiCheck < snowballs.length; aiCheck++) { if (snowballs[aiCheck].owner === (aiPenguin.penguinId || 2)) { aiHasActiveSnowball = true; break; } } if (!aiHasActiveSnowball) { turnInProgress = true; // Set new wind before each throw setRandomWind(); // Aim at playerPenguin var target = playerPenguin; var thrower = aiPenguin; // Add some random offset to aim for realism var tx = target.x + (Math.random() - 0.5) * 80 - thrower.x; var ty = target.y + (Math.random() - 0.5) * 80 - thrower.y; var len = Math.sqrt(tx * tx + ty * ty); var dirX = tx / len; var dirY = ty / len; // AI power: random between 0.5 and 1.0 var basePower = 0.5 + Math.random() * 0.5; var minV = 18; var maxV = 55; var velocity = minV + (maxV - minV) * basePower; if (velocity < minV) velocity = minV; if (velocity > maxV) velocity = maxV; var vx = dirX * velocity; var vy = dirY * velocity; // Apply wind var wind = windDirections[windDir]; var windEffect = windStrength * 0.18; vx += wind.dx * windEffect; vy += wind.dy * windEffect; // Create snowball var snowball = new Snowball(); snowball.owner = aiPenguin.penguinId || 2; snowball.x = aiPenguin.x; snowball.y = aiPenguin.y + (snowball.owner === 1 ? -90 : 90); snowball.vx = vx; snowball.vy = vy; snowballs.push(snowball); game.addChild(snowball); // Play snowball throw sound LK.getSound('kartopusesi').play(); // Cooldown for AI aiPenguin.canThrow = false; var cooldownAI = aiPenguin; LK.setTimeout(function () { if (cooldownAI) { cooldownAI.canThrow = true; } // After AI throw, switch back to player turn currentTurn = "player"; turnInProgress = false; }, 1200 + Math.random() * 800); } } // Update snowballs for (var i = snowballs.length - 1; i >= 0; i--) { var sb = snowballs[i]; sb.update(); // Gravity sb.vy += 0.7; // Friction sb.vx *= 0.99; sb.vy *= 0.99; // Out of bounds: remove if (sb.x < -100 || sb.x > GAME_WIDTH + 100 || sb.y < -100 || sb.y > GAME_HEIGHT + 100) { sb.destroy(); snowballs.splice(i, 1); continue; } // No snowball-wall collision or bounce (disabled per requirements) // Hit penguin (opponent only) if (sb.owner === 1 && isIntersect(sb, penguin2)) { // Score for player 1 score1 += 1; updateScore(); LK.effects.flashObject(penguin2, 0xffffff, 400); sb.destroy(); snowballs.splice(i, 1); // Win condition if (score1 >= 5) { LK.showYouWin(); } continue; } if (sb.owner === 2 && isIntersect(sb, penguin1)) { // Score for player 2 score2 += 1; updateScore(); LK.effects.flashObject(penguin1, 0xffffff, 400); sb.destroy(); snowballs.splice(i, 1); // Lose condition if (score2 >= 5) { LK.showGameOver(); } continue; } } }; // Initial score updateScore(); // --- Snowball Shower Effect (Doğa olayı olarak kartopu yağma efekti) --- // Array to hold falling snowballs for the effect var snowShowerBalls = []; // How often to spawn a new snowball (ms) var snowShowerInterval = 220; // How many snowballs at once (max) var snowShowerMax = 18; // Used to randomize spawn var snowShowerTimer = null; // Function to spawn a snowball shower ball function spawnSnowShowerBall() { if (snowShowerBalls.length >= snowShowerMax) return; var ball = new SnowShowerBall(); snowShowerBalls.push(ball); game.addChild(ball); } // Start the snowball shower effect if (snowShowerTimer) LK.clearInterval(snowShowerTimer); snowShowerTimer = LK.setInterval(function () { spawnSnowShowerBall(); }, snowShowerInterval); // Update snowShowerBalls in game.update var oldGameUpdate = game.update; game.update = function () { // Update snow shower balls for (var i = snowShowerBalls.length - 1; i >= 0; i--) { var b = snowShowerBalls[i]; if (b && b.update) b.update(); if (b.y > GAME_HEIGHT + 80) { if (b.parent) b.destroy(); snowShowerBalls.splice(i, 1); } } // Call original game update logic if (oldGameUpdate) oldGameUpdate.apply(this, arguments); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Penguin class
var Penguin = Container.expand(function () {
var self = Container.call(this);
// Penguin id: 1 or 2
self.penguinId = 1;
// Attach penguin asset
var penguinGfx = self.attachAsset(self.penguinId === 1 ? 'penguin1' : 'penguin2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: -1 // Flip horizontally to show penguin's back
});
// Used for drag
self.isDragging = false;
// Used for aiming
self.aimLine = null;
// Used for touch start position
self.startDragX = 0;
self.startDragY = 0;
// Used for aiming vector
self.aimVX = 0;
self.aimVY = 0;
// Used for aiming bar
self.aimBar = null;
// Used for cooldown
self.canThrow = true;
// Used for tracking last position for drag
self.lastDragX = 0;
self.lastDragY = 0;
// Used for showing aim
self.showAim = function (x, y) {
// Not implemented: no line drawing in LK, so skip
};
// Used for hiding aim
self.hideAim = function () {
// Not implemented: no line drawing in LK, so skip
};
return self;
});
// Class for falling snowball (visual only, no collision)
var SnowShowerBall = Container.expand(function () {
var self = Container.call(this);
// Attach snowball asset
var gfx = self.attachAsset('snowball', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7 + Math.random() * 0.5,
scaleY: 0.7 + Math.random() * 0.5
});
// Random X across the screen, avoid top left 100x100
self.x = 120 + Math.random() * (GAME_WIDTH - 240);
self.y = -60 - Math.random() * 200;
// Random speed
self.vy = 7 + Math.random() * 4;
// Slight wind drift
self.vx = -2 + Math.random() * 4;
// Fade in/out
gfx.alpha = 0.7 + Math.random() * 0.3;
// Wobble
self.wobblePhase = Math.random() * Math.PI * 2;
self.update = function () {
self.y += self.vy;
self.x += self.vx + Math.sin(Date.now() / 300 + self.wobblePhase) * 1.2;
// Remove if out of bounds
if (self.y > GAME_HEIGHT + 80) {
self.destroy();
// Remove from array in main update
}
};
return self;
});
// Function to spawn a snowball shower ball
// Snowball class
var Snowball = Container.expand(function () {
var self = Container.call(this);
// Add black outline as a slightly larger ellipse behind the snowball
var outline = self.attachAsset('snowball', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.18,
scaleY: 1.18,
color: 0x000000
});
// Attach snowball asset (white, on top)
var snowballGfx = self.attachAsset('snowball', {
anchorX: 0.5,
anchorY: 0.5
});
// Who fired this snowball? 1 or 2
self.owner = 1;
// Velocity
self.vx = 0;
self.vy = 0;
// Used for bounce cooldown
self.bounced = false;
// Update method
self.update = function () {
self.x += self.vx;
self.y += self.vy;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Light blue sky
});
/****
* Game Code
****/
// Flag asset for wind direction (simple colored box)
// Game constants
// Penguin (player 1)
// Penguin (player 2)
// Snowball
// Castle wall (center)
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
// Center wall
var wall = LK.getAsset('castleWall', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2,
y: GAME_HEIGHT / 2,
rotation: Math.PI / 2 // Rotate 90 degrees to make it horizontal
});
game.addChild(wall);
// --- Penguin selection screen ---
var selectedPenguinId = null;
var penguin1 = null;
var penguin2 = null;
var aiPenguin = null;
var playerPenguin = null;
var selectionScreen = new Container();
game.addChild(selectionScreen);
// Penguin 1 preview
var penguin1Preview = LK.getAsset('penguin1', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2 - 300,
y: GAME_HEIGHT / 2,
scaleX: 1,
scaleY: 1
});
selectionScreen.addChild(penguin1Preview);
// Penguin 2 preview
var penguin2Preview = LK.getAsset('penguin2', {
anchorX: 0.5,
anchorY: 0.5,
x: GAME_WIDTH / 2 + 300,
y: GAME_HEIGHT / 2,
scaleX: 1,
scaleY: 1
});
selectionScreen.addChild(penguin2Preview);
// Penguin 1 label
var penguin1Label = new Text2("Penguin 1", {
size: 90,
fill: 0x222222
});
penguin1Label.anchor.set(0.5, 0);
penguin1Label.x = penguin1Preview.x;
penguin1Label.y = penguin1Preview.y + 140;
selectionScreen.addChild(penguin1Label);
// Penguin 2 label
var penguin2Label = new Text2("Penguin 2", {
size: 90,
fill: 0x222222
});
penguin2Label.anchor.set(0.5, 0);
penguin2Label.x = penguin2Preview.x;
penguin2Label.y = penguin2Preview.y + 140;
selectionScreen.addChild(penguin2Label);
// Title
var selectTitle = new Text2("Choose your Penguin!", {
size: 120,
fill: 0x4fc3f7
});
selectTitle.anchor.set(0.5, 0.5);
selectTitle.x = GAME_WIDTH / 2;
selectTitle.y = GAME_HEIGHT / 2 - 300;
selectionScreen.addChild(selectTitle);
// Selection logic
selectionScreen.down = function (x, y, obj) {
// Check if touch is on penguin1Preview
var dx1 = x - penguin1Preview.x;
var dy1 = y - penguin1Preview.y;
var dx2 = x - penguin2Preview.x;
var dy2 = y - penguin2Preview.y;
var r = 120;
if (dx1 * dx1 + dy1 * dy1 < r * r) {
selectedPenguinId = 1;
} else if (dx2 * dx2 + dy2 * dy2 < r * r) {
selectedPenguinId = 2;
}
if (selectedPenguinId) {
// Remove selection screen
selectionScreen.destroy();
// Remove preview penguins from the game (ensure they are not left in the background)
if (penguin1Preview && penguin1Preview.parent) penguin1Preview.destroy();
if (penguin2Preview && penguin2Preview.parent) penguin2Preview.destroy();
if (penguin1Label && penguin1Label.parent) penguin1Label.destroy();
if (penguin2Label && penguin2Label.parent) penguin2Label.destroy();
if (selectTitle && selectTitle.parent) selectTitle.destroy();
// Setup penguins
penguin1 = new Penguin();
penguin1.penguinId = 1;
penguin1.x = GAME_WIDTH / 2;
penguin1.y = GAME_HEIGHT - 350;
game.addChild(penguin1);
penguin2 = new Penguin();
penguin2.penguinId = 2;
penguin2.x = GAME_WIDTH / 2;
penguin2.y = 350;
game.addChild(penguin2);
// Set correct asset for penguin2
penguin2.removeChildAt(0);
penguin2.attachAsset('penguin2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: -1
});
// Assign player and AI
if (selectedPenguinId === 1) {
playerPenguin = penguin1;
aiPenguin = penguin2;
} else {
playerPenguin = penguin2;
aiPenguin = penguin1;
}
// Mark for AI logic
aiPenguin.isAI = true;
playerPenguin.isAI = false;
// Set up initial canThrow
playerPenguin.canThrow = true;
aiPenguin.canThrow = true;
// (Optional) Add a little effect to show selection
LK.effects.flashObject(playerPenguin, 0x4fc3f7, 600);
}
};
selectionScreen.interactive = true;
selectionScreen.on('down', selectionScreen.down);
// The rest of the game logic will use playerPenguin and aiPenguin instead of penguin1/penguin2 directly.
// Score
var score1 = 0;
var score2 = 0;
// Score text
var scoreTxt = new Text2('0 : 0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Snowballs array
var snowballs = [];
// --- Wind mechanic ---
// Wind directions: 0=left, 1=right, 2=up, 3=down
var windDirections = [{
name: "←",
dx: -1,
dy: 0
}, {
name: "→",
dx: 1,
dy: 0
}, {
name: "↑",
dx: 0,
dy: -1
}, {
name: "↓",
dx: 0,
dy: 1
}];
var windStrengthMin = 0; // minimum wind
var windStrengthMax = 22; // maximum wind
var windStrength = 0; // current wind strength (0-22)
var windDir = 0; // current wind direction index (0-3)
var windIndicator = null;
var windText = null;
// Helper to randomize wind before each throw
function setRandomWind() {
windDir = Math.floor(Math.random() * windDirections.length);
windStrength = Math.floor(Math.random() * (windStrengthMax + 1)); // 0 to max
// Remove old indicator
if (windIndicator) {
windIndicator.destroy();
windIndicator = null;
}
if (windText) {
windText.destroy();
windText = null;
}
if (typeof windFlag !== "undefined" && windFlag) {
windFlag.destroy();
windFlag = null;
}
// Show wind visually at top center (keep arrow for reference)
var arrowLen = 120 + windStrength * 3;
var arrowColor = 0x4fc3f7;
windIndicator = LK.getAsset('snowball', {
anchorX: 0.5,
anchorY: 0.5,
width: 30,
height: arrowLen,
color: arrowColor
});
windIndicator.x = GAME_WIDTH / 2;
windIndicator.y = 160;
if (windDir === 0) windIndicator.rotation = Math.PI; // left
else if (windDir === 1) windIndicator.rotation = 0; // right
else if (windDir === 2) windIndicator.rotation = -Math.PI / 2; // up
else if (windDir === 3) windIndicator.rotation = Math.PI / 2; // down
game.addChild(windIndicator);
// Add flag to indicate wind direction and strength
windFlag = LK.getAsset('windFlag', {
anchorX: 0.1,
anchorY: 0.5,
width: 90 + windStrength * 2,
// flag length grows with wind
height: 60 + Math.floor(windStrength / 3),
// flag height grows a bit with wind
color: 0xffe066
});
// Place wind flag at the top right corner, leaving a margin from the edge
windFlag.x = GAME_WIDTH - 120;
windFlag.y = 120;
// Rotate flag to match wind direction
if (windDir === 0) windFlag.rotation = Math.PI; // left
else if (windDir === 1) windFlag.rotation = 0; // right
else if (windDir === 2) windFlag.rotation = -Math.PI / 2; // up
else if (windDir === 3) windFlag.rotation = Math.PI / 2; // down
game.addChild(windFlag);
// Animate flag waving (simple waving effect)
if (typeof windFlagTween !== "undefined" && windFlagTween) {
windFlagTween.stop();
windFlagTween = null;
}
// Animate flag waving (simple waving effect) using correct tween API
tween(windFlag, {
scaleY: 1.15
}, {
duration: 400,
easing: tween.sineInOut,
onFinish: function onFinish() {
// Reverse the tween for yoyo effect
tween(windFlag, {
scaleY: 1.0
}, {
duration: 400,
easing: tween.sineInOut,
onFinish: function onFinish() {
// Loop the waving animation
LK.setTimeout(function () {
if (windFlag && windFlag.parent) {
// Only continue if flag still exists
// Recursively start waving again
// (This is a simple infinite yoyo loop)
tween(windFlag, {
scaleY: 1.15
}, {
duration: 400,
easing: tween.sineInOut,
onFinish: arguments.callee
});
}
}, 0);
}
});
}
});
// Add wind text
var txt = windDirections[windDir].name + " " + windStrength;
windText = new Text2(txt, {
size: 80,
fill: 0x4fc3f7
});
windText.anchor.set(0.5, 0.5);
// Place wind text near the flag, but offset to the left to avoid overlap
windText.x = GAME_WIDTH - 260;
windText.y = 120;
LK.gui.top.addChild(windText);
}
// Call once at start
setRandomWind();
// Drag/aim state
var dragPenguin = null;
var dragStartX = 0;
var dragStartY = 0;
var dragCurrentX = 0;
var dragCurrentY = 0;
// Power bar state
var powerBar = null;
var powerBarBg = null;
var powerBarValue = 0;
var powerBarInterval = null;
var powerBarMax = 1.0; // max fill
var powerBarMin = 0.2; // min fill
var powerBarSpeed = 0.012; // fill per tick
// Turn-based state
var currentTurn = "player"; // "player" or "ai"
var turnInProgress = false; // Prevents double actions in a turn
// Only allow one penguin to be dragged at a time
function isTouchOnPenguin(x, y, penguin) {
if (!penguin) return false; // Defensive: penguin may be null
// Simple bounding box check
var px = penguin.x;
var py = penguin.y;
var w = penguin.width || 140;
var h = penguin.height || 180;
return x > px - w / 2 && x < px + w / 2 && y > py - h / 2 && y < py + h / 2;
}
// Only allow dragging own penguin (player 1: bottom, player 2: top)
game.down = function (x, y, obj) {
// Don't allow drag in top 100x100 (menu)
if (x < 100 && y < 100) return;
// Only allow drag on playerPenguin (single player) and only if it's player's turn and not in progress
if (typeof playerPenguin !== "undefined" && isTouchOnPenguin(x, y, playerPenguin) && currentTurn === "player" && !turnInProgress) {
turnInProgress = true;
dragPenguin = playerPenguin;
dragStartX = x;
dragStartY = y;
dragCurrentX = x;
dragCurrentY = y;
playerPenguin.isDragging = true;
// Show power bar next to playerPenguin
if (powerBarBg) {
powerBarBg.destroy();
powerBarBg = null;
}
if (powerBar) {
powerBar.destroy();
powerBar = null;
}
// Background bar
powerBarBg = LK.getAsset('snowball', {
anchorX: 0,
anchorY: 0.5,
width: 40,
height: 180,
color: 0xcccccc
});
powerBarBg.x = playerPenguin.x + 90;
powerBarBg.y = playerPenguin.y;
game.addChild(powerBarBg);
// Foreground (fill) bar
powerBar = LK.getAsset('snowball', {
anchorX: 0,
anchorY: 0.5,
width: 36,
height: 0,
// will be set by fill
color: 0x4fc3f7
});
powerBar.x = playerPenguin.x + 92;
powerBar.y = playerPenguin.y + 90; // start at bottom
game.addChild(powerBar);
powerBarValue = powerBarMin;
// Animate fill
if (powerBarInterval) LK.clearInterval(powerBarInterval);
powerBarInterval = LK.setInterval(function () {
if (!dragPenguin) return;
powerBarValue += powerBarSpeed;
if (powerBarValue > powerBarMax) powerBarValue = powerBarMax;
// Update bar height and position
var maxHeight = 180;
var fillHeight = Math.max(0, Math.floor(maxHeight * powerBarValue));
powerBar.height = fillHeight;
powerBar.y = playerPenguin.y + 90 - fillHeight;
}, 16);
}
};
game.move = function (x, y, obj) {
if (!dragPenguin) return;
// Clamp drag to own half (playerPenguin only)
if (dragPenguin === playerPenguin) {
if (playerPenguin.penguinId === 1 && y < GAME_HEIGHT / 2 + 100) y = GAME_HEIGHT / 2 + 100;
if (playerPenguin.penguinId === 2 && y > GAME_HEIGHT / 2 - 100) y = GAME_HEIGHT / 2 - 100;
}
// Clamp to game area
var minX = 120,
maxX = GAME_WIDTH - 120;
var minY = 120,
maxY = GAME_HEIGHT - 120;
x = Math.max(minX, Math.min(maxX, x));
y = Math.max(minY, Math.min(maxY, y));
dragCurrentX = x;
dragCurrentY = y;
// Move penguin
dragPenguin.x = x;
dragPenguin.y = y;
// --- Aiming bar logic ---
var penguin = dragPenguin;
if (penguin) {
// Remove old aimBar if exists
if (penguin.aimBar) {
penguin.aimBar.destroy();
penguin.aimBar = null;
}
// Only show aim bar if drag distance is enough
var dx = dragCurrentX - dragStartX;
var dy = dragCurrentY - dragStartY;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 20) {
// Always aim toward the AI penguin
var target = aiPenguin;
var tx = target.x - penguin.x;
var ty = target.y - penguin.y;
var angle = Math.atan2(ty, tx);
// Bar length
var barLen = 220;
// Create bar as a thin tall rectangle (use a box shape)
var bar = LK.getAsset('snowball', {
anchorX: 0.5,
anchorY: 1,
width: 18,
height: barLen,
color: 0x4fc3f7
});
// Place under penguin
bar.x = penguin.x;
bar.y = penguin.y + 90;
// Rotate to aim direction
bar.rotation = angle + Math.PI / 2;
game.addChild(bar);
penguin.aimBar = bar;
}
}
// Move power bar if visible
if (powerBarBg && dragPenguin) {
powerBarBg.x = dragPenguin.x + 90;
powerBarBg.y = dragPenguin.y;
}
if (powerBar && dragPenguin) {
powerBar.x = dragPenguin.x + 92;
// keep y at bottom, height is set by interval
}
};
game.up = function (x, y, obj) {
if (!dragPenguin) return;
// Hide power bar
if (powerBarBg) {
powerBarBg.destroy();
powerBarBg = null;
}
if (powerBar) {
powerBar.destroy();
powerBar = null;
}
if (powerBarInterval) {
LK.clearInterval(powerBarInterval);
powerBarInterval = null;
}
// Only allow throw if drag distance is enough and cooldown is over
var dx = dragCurrentX - dragStartX;
var dy = dragCurrentY - dragStartY;
var dist = Math.sqrt(dx * dx + dy * dy);
// Only allow throw if drag is a "flick" (distance > 80)
if (dist > 80 && dragPenguin.canThrow && currentTurn === "player") {
// Set new wind before each throw
setRandomWind();
// Always throw toward the AI penguin, power only affects distance
var basePower = powerBarValue || powerBarMin;
var thrower = dragPenguin;
var target = aiPenguin;
// Calculate direction vector from thrower to target
var tx = target.x - thrower.x;
var ty = target.y - thrower.y;
var len = Math.sqrt(tx * tx + ty * ty);
// Normalize direction
var dirX = tx / len;
var dirY = ty / len;
// Set velocity magnitude based on power
var minV = 18;
var maxV = 55;
var velocity = minV + (maxV - minV) * ((basePower - powerBarMin) / (powerBarMax - powerBarMin));
// Clamp velocity
if (velocity < minV) velocity = minV;
if (velocity > maxV) velocity = maxV;
// Final velocity
var vx = dirX * velocity;
var vy = dirY * velocity;
// --- Apply wind effect ---
// Wind is a constant added to vx/vy, scaled by windStrength
var wind = windDirections[windDir];
var windEffect = windStrength * 0.18; // tune this for balance
vx += wind.dx * windEffect;
vy += wind.dy * windEffect;
// Create snowball
var snowball = new Snowball();
snowball.owner = playerPenguin.penguinId;
snowball.x = dragPenguin.x;
snowball.y = dragPenguin.y + (snowball.owner === 1 ? -90 : 90);
snowball.vx = vx;
snowball.vy = vy;
snowballs.push(snowball);
game.addChild(snowball);
// Play snowball throw sound
LK.getSound('kartopusesi').play();
// Cooldown: prevent spamming
dragPenguin.canThrow = false;
var cooldownPenguin = dragPenguin;
LK.setTimeout(function () {
if (cooldownPenguin) {
cooldownPenguin.canThrow = true;
}
}, 600);
// End player's turn, start AI's turn after a 2 second delay
currentTurn = "ai";
turnInProgress = true;
LK.setTimeout(function () {
turnInProgress = false;
}, 2000);
}
// Remove aim bar if exists
if (dragPenguin && dragPenguin.aimBar) {
dragPenguin.aimBar.destroy();
dragPenguin.aimBar = null;
}
dragPenguin.isDragging = false;
dragPenguin = null;
};
/**
* Helper: check collision between two containers (bounding box)
*/
function isIntersect(a, b) {
var ax = a.x,
ay = a.y,
aw = a.width || 100,
ah = a.height || 100;
var bx = b.x,
by = b.y,
bw = b.width || 100,
bh = b.height || 100;
return ax - aw / 2 < bx + bw / 2 && ax + aw / 2 > bx - bw / 2 && ay - ah / 2 < by + bh / 2 && ay + ah / 2 > by - bh / 2;
}
// Update score text
function updateScore() {
scoreTxt.setText(score1 + " : " + score2);
}
// Game update loop
game.update = function () {
// --- AI logic for non-player penguin ---
// AI only acts on its turn and if not in progress (wait for 2s after player)
if (typeof aiPenguin !== "undefined" && aiPenguin && aiPenguin.isAI && aiPenguin.canThrow && currentTurn === "ai" && !turnInProgress) {
// AI throws at intervals, only if no snowball is currently flying from AI
var aiHasActiveSnowball = false;
for (var aiCheck = 0; aiCheck < snowballs.length; aiCheck++) {
if (snowballs[aiCheck].owner === (aiPenguin.penguinId || 2)) {
aiHasActiveSnowball = true;
break;
}
}
if (!aiHasActiveSnowball) {
turnInProgress = true;
// Set new wind before each throw
setRandomWind();
// Aim at playerPenguin
var target = playerPenguin;
var thrower = aiPenguin;
// Add some random offset to aim for realism
var tx = target.x + (Math.random() - 0.5) * 80 - thrower.x;
var ty = target.y + (Math.random() - 0.5) * 80 - thrower.y;
var len = Math.sqrt(tx * tx + ty * ty);
var dirX = tx / len;
var dirY = ty / len;
// AI power: random between 0.5 and 1.0
var basePower = 0.5 + Math.random() * 0.5;
var minV = 18;
var maxV = 55;
var velocity = minV + (maxV - minV) * basePower;
if (velocity < minV) velocity = minV;
if (velocity > maxV) velocity = maxV;
var vx = dirX * velocity;
var vy = dirY * velocity;
// Apply wind
var wind = windDirections[windDir];
var windEffect = windStrength * 0.18;
vx += wind.dx * windEffect;
vy += wind.dy * windEffect;
// Create snowball
var snowball = new Snowball();
snowball.owner = aiPenguin.penguinId || 2;
snowball.x = aiPenguin.x;
snowball.y = aiPenguin.y + (snowball.owner === 1 ? -90 : 90);
snowball.vx = vx;
snowball.vy = vy;
snowballs.push(snowball);
game.addChild(snowball);
// Play snowball throw sound
LK.getSound('kartopusesi').play();
// Cooldown for AI
aiPenguin.canThrow = false;
var cooldownAI = aiPenguin;
LK.setTimeout(function () {
if (cooldownAI) {
cooldownAI.canThrow = true;
}
// After AI throw, switch back to player turn
currentTurn = "player";
turnInProgress = false;
}, 1200 + Math.random() * 800);
}
}
// Update snowballs
for (var i = snowballs.length - 1; i >= 0; i--) {
var sb = snowballs[i];
sb.update();
// Gravity
sb.vy += 0.7;
// Friction
sb.vx *= 0.99;
sb.vy *= 0.99;
// Out of bounds: remove
if (sb.x < -100 || sb.x > GAME_WIDTH + 100 || sb.y < -100 || sb.y > GAME_HEIGHT + 100) {
sb.destroy();
snowballs.splice(i, 1);
continue;
}
// No snowball-wall collision or bounce (disabled per requirements)
// Hit penguin (opponent only)
if (sb.owner === 1 && isIntersect(sb, penguin2)) {
// Score for player 1
score1 += 1;
updateScore();
LK.effects.flashObject(penguin2, 0xffffff, 400);
sb.destroy();
snowballs.splice(i, 1);
// Win condition
if (score1 >= 5) {
LK.showYouWin();
}
continue;
}
if (sb.owner === 2 && isIntersect(sb, penguin1)) {
// Score for player 2
score2 += 1;
updateScore();
LK.effects.flashObject(penguin1, 0xffffff, 400);
sb.destroy();
snowballs.splice(i, 1);
// Lose condition
if (score2 >= 5) {
LK.showGameOver();
}
continue;
}
}
};
// Initial score
updateScore();
// --- Snowball Shower Effect (Doğa olayı olarak kartopu yağma efekti) ---
// Array to hold falling snowballs for the effect
var snowShowerBalls = [];
// How often to spawn a new snowball (ms)
var snowShowerInterval = 220;
// How many snowballs at once (max)
var snowShowerMax = 18;
// Used to randomize spawn
var snowShowerTimer = null;
// Function to spawn a snowball shower ball
function spawnSnowShowerBall() {
if (snowShowerBalls.length >= snowShowerMax) return;
var ball = new SnowShowerBall();
snowShowerBalls.push(ball);
game.addChild(ball);
}
// Start the snowball shower effect
if (snowShowerTimer) LK.clearInterval(snowShowerTimer);
snowShowerTimer = LK.setInterval(function () {
spawnSnowShowerBall();
}, snowShowerInterval);
// Update snowShowerBalls in game.update
var oldGameUpdate = game.update;
game.update = function () {
// Update snow shower balls
for (var i = snowShowerBalls.length - 1; i >= 0; i--) {
var b = snowShowerBalls[i];
if (b && b.update) b.update();
if (b.y > GAME_HEIGHT + 80) {
if (b.parent) b.destroy();
snowShowerBalls.splice(i, 1);
}
}
// Call original game update logic
if (oldGameUpdate) oldGameUpdate.apply(this, arguments);
};
bir penguen çizmeni istiyorum bir eli havada olsun eli biraz uzun olsun çok tatlı bir penguen olsun
penguenin arkası dönük olsun. In-Game asset. 2d. High contrast. No shadows
kale duvarı kahverengi renkte olsun eski çağ surları gibi olsun ve ekranın ortasını full kaplasın yatay şekilde. In-Game asset. 2d. High contrast. No shadows
rüzgarın yönüne doğru değişen bir dalgalanan türk bayrağı resmi. In-Game asset. 2d. High contrast. No shadows