/**** * 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