User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'lastWasIntersecting')' in or related to this line: 'if (typeof cat2Sprite.lastWasIntersecting !== "undefined" && !cat2Sprite.lastWasIntersecting && cat.intersects(cat2Sprite)) {' Line Number: 735
User prompt
cat2. 50. seviyeye kadar gözükmesin
User prompt
cat2 karakteri 50.seviyeden sonra gelsin
User prompt
cat2 karakteri sürekli gelsin
User prompt
cat2 karakterine ana karakterimiz değince 15hp götürsün
User prompt
cat2 biraz daha ileri zıplasın
User prompt
zıplamsı lütfen ileri doğru olsun az bişey
User prompt
cat2 ye zıplama eklermsin
User prompt
cat2 karakteri sağdan cıkıp solda kaybolsun
User prompt
sağdan cıkıp sola doğru ilerlesin
User prompt
cat 2 karakteri zıplasın
User prompt
cat 2 karakterini çok az daha büyütürmüsün
User prompt
cat 2 karakteri biraz büyüsün
User prompt
cat 2 karkterini büyütürmüsün
User prompt
Please fix the bug: 'Cat is not defined' in or related to this line: 'cat = new Cat();' Line Number: 280
User prompt
Please fix the bug: 'Cloud is not defined' in or related to this line: 'var cloud = new Cloud();' Line Number: 233
User prompt
Please fix the bug: 'Sun is not defined' in or related to this line: 'sun = new Sun();' Line Number: 165
User prompt
Please fix the bug: 'Cat is not defined' in or related to this line: 'cat = new Cat();' Line Number: 269
User prompt
Please fix the bug: 'Cloud is not defined' in or related to this line: 'var cloud = new Cloud();' Line Number: 233
User prompt
Please fix the bug: 'Sun is not defined' in or related to this line: 'sun = new Sun();' Line Number: 165
User prompt
cat2 karakteri elinden kuş atsın extra
User prompt
cat 2 karateri zıplayarak sağdan sola doğru gelsin
User prompt
cat 2 sağdan çıkıp hızlı bir şekilde ilerlesin sağdan sola dogru
User prompt
cat 2 karakteri sağdan çıkıp sola doğru ilerlesin
User prompt
cat2 karakterini çok az daha büyütelim
/**** * Classes ****/ // Main Cat (player) class var Cat = Container.expand(function () { var self = Container.call(this); // Attach cat image asset var catSprite = self.attachAsset('cat', { anchorX: 0.5, anchorY: 1 }); catSprite.width = 220; catSprite.height = 220; // Physics and jump variables self.vy = 0; self.gravity = 4.5; self.jumpVelocity = -70; self.maxJumps = 2; self.jumpCount = 0; self.groundY = GROUND_Y; self.isJumping = false; self.isGliding = false; self.glideStartTick = 0; self.glideDuration = 180; // 3 seconds at 60fps // For collision and state tracking self.lastY = self.y; self.lastX = self.x; self.lastWasIntersecting = false; // Jump method self.jump = function () { if (self.isGliding) return; // Can't jump while gliding if (self.jumpCount < self.maxJumps) { self.vy = self.jumpVelocity; self.isJumping = true; self.jumpCount++; LK.getSound('kedi').play(); } }; // Glide method (optional, for long press) self.glide = function () { if (!self.isGliding && self.isJumping) { self.isGliding = true; self.glideStartTick = LK.ticks; self.vy = -8; // Slow descent } }; // End glide self.endGlide = function () { if (self.isGliding) { self.isGliding = false; self.vy = 0; } }; // Update method self.update = function () { // Save last positions for event triggers self.lastY = self.y; self.lastX = self.x; // Handle gliding if (self.isGliding) { // Glide for a limited duration if (LK.ticks - self.glideStartTick > self.glideDuration) { self.endGlide(); } else { self.y += self.vy; } } else if (self.isJumping) { self.vy += self.gravity; self.y += self.vy; } // Land on ground if (self.y >= self.groundY) { self.y = self.groundY; self.vy = 0; self.isJumping = false; self.isGliding = false; self.jumpCount = 0; } }; return self; }); // Cloud class for decorative clouds moving left across the sky var Cloud = Container.expand(function () { var self = Container.call(this); // Add cloud image asset (use 'kum' as a placeholder, or replace with a real cloud asset if available) var cloudSprite = self.attachAsset('kum', { anchorX: 0.5, anchorY: 0.5 }); // Set random scale for variety var scale = 1.2 + Math.random() * 1.2; cloudSprite.scaleX = scale; cloudSprite.scaleY = scale; // Set alpha for transparency cloudSprite.alpha = 0.7 + Math.random() * 0.2; // Set speed (clouds move slower than gameplay objects) self.speed = 2.5 + Math.random() * 2.5; // Update method to move cloud left self.update = function () { if (typeof self.lastX === "undefined") self.lastX = self.x; self.x -= self.speed; // Optionally, add a little vertical drift for realism if (typeof self.driftDir === "undefined") self.driftDir = Math.random() > 0.5 ? 1 : -1; if (typeof self.driftTick === "undefined") self.driftTick = 0; self.driftTick++; if (self.driftTick % 60 === 0) self.driftDir *= -1; self.y += self.driftDir * 0.2; self.lastX = self.x; }; return self; }); // Sun class for decorative sun in the sky var Sun = Container.expand(function () { var self = Container.call(this); // Add sun image asset (large, centered) var sunSprite = self.attachAsset('gunes', { anchorX: 0.5, anchorY: 0.5 }); sunSprite.width = 320; sunSprite.height = 320; // Optionally, animate sun rotation for effect self.update = function () { sunSprite.rotation += 0.002; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xF7E9A0 // light sand yellow, desert-like }); /**** * Game Code ****/ ; // --- GAME CODE --- // Game constants var GROUND_Y = 2200; // y position of ground (bottom of screen minus margin) var CAT_START_X = 400; var CAT_START_Y = GROUND_Y; var CACTUS_SPAWN_MIN = 70; // min frames between cacti (slower, more time to jump) var CACTUS_SPAWN_MAX = 130; // max frames between cacti (slower, more time to jump) // Add two ground images ('zemin') for seamless horizontal scrolling var groundImg = LK.getAsset('zemin', { anchorX: 0, anchorY: 1 }); groundImg.x = 0; groundImg.y = GROUND_Y + 2; // +2 for slight overlap, ensures cat and cactus are on top groundImg.width = 2048; game.addChild(groundImg); // Add a second ground image for seamless looping var groundImg2 = LK.getAsset('zemin', { anchorX: 0, anchorY: 1 }); groundImg2.x = groundImg.x + groundImg.width; groundImg2.y = GROUND_Y + 2; groundImg2.width = 2048; game.addChild(groundImg2); // Add a ground image under each cactus as well, so cactus stands on ground // This is handled by drawing the ground first, so both cat and cactus visually stand on the same ground // Sun and clouds var sun; var clouds = []; var nextCloudTick = 0; // Birds var birds = []; var nextBirdTick = 0; // Game state var cat; var cacti = []; var golds = []; var score = 0; var goldScore = 0; var scoreTxt; var goldScoreTxt; var nextCactusTick = 0; var nextGoldTick = 0; var gameOver = false; // On game start, stamina is full stamina = maxStamina; if (typeof staminaBar !== "undefined") { staminaBar.width = Math.max(1, stamina / maxStamina * staminaBarFullWidth); } // Track how many cacti have been jumped over for stamina refill var cactiJumpedOver = 0; // Track post-glide cactus counting for stamina refill var postGlideCactusCounter = 0; var postGlideCountingActive = false; // Speed multiplier for game progression var speedMultiplier = 1; var SPEED_MULTIPLIER_INCREMENT = 0.08; // how much to increase per score var SPEED_MULTIPLIER_MAX = 3; // cap the speed increase // HP bar variables var maxHp = 100; var hp = maxHp; var hpBarFullWidth = 420; var hpBarHeight = 38; // Add HP bar background (grey) var hpBarBg = LK.getAsset('centerCircle', { anchorX: 0, anchorY: 0 }); hpBarBg.width = hpBarFullWidth; hpBarBg.height = hpBarHeight; hpBarBg.x = 110; hpBarBg.y = 30; hpBarBg.tint = 0x444444; hpBarBg.alpha = 0.45; LK.gui.top.addChild(hpBarBg); // Add HP bar (red) var hpBar = LK.getAsset('centerCircle', { anchorX: 0, anchorY: 0 }); hpBar.width = hpBarFullWidth; hpBar.height = hpBarHeight; hpBar.x = 110; hpBar.y = 30; hpBar.tint = 0xff4444; hpBar.alpha = 0.95; LK.gui.top.addChild(hpBar); // --- Stamina bar variables and GUI --- var maxStamina = 100; var stamina = maxStamina; var staminaBarFullWidth = 420; var staminaBarHeight = 28; // Stamina bar background (grey, below HP bar) var staminaBarBg = LK.getAsset('centerCircle', { anchorX: 0, anchorY: 0 }); staminaBarBg.width = staminaBarFullWidth; staminaBarBg.height = staminaBarHeight; staminaBarBg.x = 110; staminaBarBg.y = 80; staminaBarBg.tint = 0x444444; staminaBarBg.alpha = 0.35; LK.gui.top.addChild(staminaBarBg); // Stamina bar (blue) var staminaBar = LK.getAsset('centerCircle', { anchorX: 0, anchorY: 0 }); staminaBar.width = staminaBarFullWidth; staminaBar.height = staminaBarHeight; staminaBar.x = 110; staminaBar.y = 80; staminaBar.tint = 0x44aaff; staminaBar.alpha = 0.95; LK.gui.top.addChild(staminaBar); // Add score text to GUI scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Gold score text (smaller, right of score) goldScoreTxt = new Text2('0', { size: 90, fill: 0xFFD700 // gold color }); goldScoreTxt.anchor.set(0, 0); goldScoreTxt.x = 120; // right of main score goldScoreTxt.y = 20; LK.gui.top.addChild(goldScoreTxt); // Add sun (top right, margin from edge) sun = new Sun(); sun.x = 2048 - 220; sun.y = 220; game.addChild(sun); // Add 'gunes1' character image to the top right var gunes1Sprite = LK.getAsset('gunes1', { anchorX: 1, anchorY: 0 }); gunes1Sprite.x = 2048 - 40; // 40px margin from right edge gunes1Sprite.y = 40; // 40px margin from top edge gunes1Sprite.width = 200; gunes1Sprite.height = 200; game.addChild(gunes1Sprite); // Add 'evet' button to the top right corner of the GUI var evetBtn = new Text2('evet', { size: 90, fill: 0xFFFFFF, font: "Arial" }); evetBtn.anchor.set(1, 0); // right-top anchor evetBtn.x = LK.gui.top.width - 40; // 40px margin from right evetBtn.y = 30; // 30px margin from top LK.gui.topRight.addChild(evetBtn); // Add 'cat2' enemy image to the bottom right on top of the ground, and make it move left with a jump arc var cat2Sprite = LK.getAsset('cat2', { anchorX: 1, anchorY: 1 }); cat2Sprite.x = 2048 - 40; // 40px margin from right edge cat2Sprite.y = GROUND_Y + 2; // on top of ground cat2Sprite.width = 540; cat2Sprite.height = 540; game.addChild(cat2Sprite); // Movement variables for cat2 cat2Sprite.speed = 22; // much faster speed for cat2 cat2Sprite.lastX = cat2Sprite.x; // Jump arc variables for cat2 cat2Sprite.vy = -60; // initial jump velocity (upwards) cat2Sprite.gravity = 4; // gravity for falling down cat2Sprite.isJumping = true; cat2Sprite.groundY = GROUND_Y + 2; cat2Sprite.jumpCooldown = 0; // ticks until next jump allowed cat2Sprite.jumpInterval = 120; // frames between jumps cat2Sprite.jumpVelocity = -60; // jump velocity cat2Sprite.jumpActive = true; // Spawn a few initial clouds for (var i = 0; i < 3; i++) { var cloud = new Cloud(); cloud.x = 400 + Math.random() * 1400; cloud.y = 200 + Math.random() * 400; cloud.lastX = cloud.x; game.addChild(cloud); clouds.push(cloud); } nextCloudTick = 60 + Math.floor(Math.random() * 120); // Create cat cat = new Cat(); cat.x = CAT_START_X; cat.y = CAT_START_Y; cat.groundY = CAT_START_Y; game.addChild(cat); // Track long press for gliding var isPressing = false; var pressStartTick = 0; var glideActive = false; // --- Bird damage immunity after stamina glide --- var birdImmunityActive = false; var birdImmunityStartTick = 0; var BIRD_IMMUNITY_DURATION = 300; // 5 seconds at 60fps // Touch/click to jump or start glide game.down = function (x, y, obj) { if (!gameOver) { cat.jump(); isPressing = true; pressStartTick = LK.ticks; glideActive = false; } // Update golds, check for collection for (var j = golds.length - 1; j >= 0; j--) { var gold = golds[j]; gold.update(); // Remove if off screen if (gold.x < -200) { gold.destroy(); golds.splice(j, 1); continue; } // Collect gold: only trigger on first intersect and not already collected if (!gold.collected && cat.intersects(gold)) { gold.collected = true; goldScore++; goldScoreTxt.setText(goldScore); gold.destroy(); golds.splice(j, 1); continue; } } }; // On release, stop pressing and gliding game.up = function (x, y, obj) { isPressing = false; // Do not forcibly end glide here; glide ends after 3s or on landing }; // Main update loop game.update = function () { if (gameOver) return; // --- Ground scrolling logic --- // Move both ground images left by cactus speed (use average cactus speed or a fixed value for smoothness) var groundScrollSpeed = 10 * speedMultiplier; // Match with cactus/bird speed for realism groundImg.x -= groundScrollSpeed; groundImg2.x -= groundScrollSpeed; // If a ground image is fully off screen to the left, move it to the right of the other if (groundImg.x <= -groundImg.width) { groundImg.x = groundImg2.x + groundImg2.width; } if (groundImg2.x <= -groundImg2.width) { groundImg2.x = groundImg.x + groundImg.width; } // Move cat2 enemy left every frame with jump arc if (typeof cat2Sprite !== "undefined") { // Horizontal movement cat2Sprite.x -= cat2Sprite.speed; // --- Bird throwing logic --- if (typeof cat2Sprite.birdThrowCooldown === "undefined") cat2Sprite.birdThrowCooldown = 0; if (typeof cat2BirdProjectiles === "undefined") cat2BirdProjectiles = []; // Throw a bird every 60-110 frames, only if on screen if (cat2Sprite.x < 2048 && cat2Sprite.x > -cat2Sprite.width) { if (cat2Sprite.birdThrowCooldown <= 0) { var birdProj = new BirdProjectile(); // Position at cat2's hand (approximate: right/center of sprite, slightly above ground) birdProj.x = cat2Sprite.x - cat2Sprite.width * 0.7; birdProj.y = cat2Sprite.y - cat2Sprite.height * 0.55; birdProj.lastX = birdProj.x; game.addChild(birdProj); cat2BirdProjectiles.push(birdProj); // Next throw in 60-110 frames cat2Sprite.birdThrowCooldown = 60 + Math.floor(Math.random() * 50); } else { cat2Sprite.birdThrowCooldown--; } } // Jumping logic if (cat2Sprite.jumpActive) { // Apply gravity if in air if (cat2Sprite.isJumping) { cat2Sprite.vy += cat2Sprite.gravity; cat2Sprite.y += cat2Sprite.vy; // Land on ground if (cat2Sprite.y >= cat2Sprite.groundY) { cat2Sprite.y = cat2Sprite.groundY; cat2Sprite.vy = 0; cat2Sprite.isJumping = false; cat2Sprite.jumpCooldown = cat2Sprite.jumpInterval; } } else { // Wait for cooldown, then jump again if (cat2Sprite.jumpCooldown > 0) { cat2Sprite.jumpCooldown--; } else { cat2Sprite.vy = cat2Sprite.jumpVelocity; cat2Sprite.isJumping = true; } } } // Destroy or reset if off screen to the left if (cat2Sprite.lastX >= -cat2Sprite.width && cat2Sprite.x < -cat2Sprite.width) { // Reset to right side for continuous movement cat2Sprite.x = 2048 + cat2Sprite.width; // Reset jump state cat2Sprite.y = cat2Sprite.groundY; cat2Sprite.vy = cat2Sprite.jumpVelocity; cat2Sprite.isJumping = true; cat2Sprite.jumpCooldown = 0; cat2Sprite.birdThrowCooldown = 0; // reset bird throw cooldown } cat2Sprite.lastX = cat2Sprite.x; } // Update cat2's bird projectiles and check for collision with cat if (typeof cat2BirdProjectiles === "undefined") cat2BirdProjectiles = []; for (var i = cat2BirdProjectiles.length - 1; i >= 0; i--) { var proj = cat2BirdProjectiles[i]; proj.update(); // Remove if off screen if (proj.x < -200) { proj.destroy(); cat2BirdProjectiles.splice(i, 1); continue; } // Collision with cat (only trigger on first intersect) if (!proj.lastWasIntersecting && cat.intersects(proj)) { // If immunity is active, skip damage if (!birdImmunityActive) { hp -= 10; if (hp < 0) hp = 0; LK.getSound('kedi1').play(); hpBar.width = Math.max(1, hp / maxHp * hpBarFullWidth); LK.effects.flashObject(cat, 0x0000ff, 400); if (hp <= 0) { LK.effects.flashScreen(0x0000ff, 800); LK.showGameOver(); LK.getSound('death').play(); LK.setTimeout(function () { LK.getSound('death').play(); }, 180); LK.setTimeout(function () { LK.getSound('death').play(); }, 360); gameOver = true; return; } } proj.destroy(); cat2BirdProjectiles.splice(i, 1); continue; } proj.lastWasIntersecting = cat.intersects(proj); } // Update clouds and spawn new ones for (var i = clouds.length - 1; i >= 0; i--) { var cloud = clouds[i]; cloud.update(); if (cloud.x < -400) { cloud.destroy(); clouds.splice(i, 1); } } if (nextCloudTick <= 0) { var cloud = new Cloud(); cloud.x = 2048 + 200; cloud.y = 120 + Math.random() * 600; cloud.lastX = cloud.x; game.addChild(cloud); clouds.push(cloud); nextCloudTick = 60 + Math.floor(Math.random() * 120); } else { nextCloudTick--; } // Deactivate bird immunity after 5 seconds if (birdImmunityActive && LK.ticks - birdImmunityStartTick >= BIRD_IMMUNITY_DURATION) { birdImmunityActive = false; } // Update birds and spawn new ones for (var i = birds.length - 1; i >= 0; i--) { var bird = birds[i]; bird.update(); if (bird.x < -200) { bird.destroy(); birds.splice(i, 1); continue; } // Bird collision detection (only trigger on first intersect) if (!bird.lastWasIntersecting && cat.intersects(bird)) { // If immunity is active, skip damage if (!birdImmunityActive) { // Decrease HP by 10 hp -= 10; if (hp < 0) hp = 0; // Play cat sound on HP loss LK.getSound('kedi1').play(); // Update HP bar hpBar.width = Math.max(1, hp / maxHp * hpBarFullWidth); // Flash red for hit LK.effects.flashObject(cat, 0xff0000, 400); // If HP is 0, game over if (hp <= 0) { LK.effects.flashScreen(0xff0000, 800); // Play 'death' sound 3 times in quick succession when game over screen is shown LK.showGameOver(); LK.getSound('death').play(); LK.setTimeout(function () { LK.getSound('death').play(); }, 180); LK.setTimeout(function () { LK.getSound('death').play(); }, 360); gameOver = true; return; } } } bird.lastWasIntersecting = cat.intersects(bird); } if (nextBirdTick <= 0) { // Spawn 2-3 birds at once, with more scattered (random) vertical and horizontal spacing var birdCount = 2 + Math.floor(Math.random() * 2); // 2 or 3 birds var minBirdY = GROUND_Y - 950; // Lowered: birds fly closer to ground var maxBirdY = GROUND_Y - 650; // Lowered: birds fly closer to ground if (minBirdY < 0) minBirdY = 0; if (maxBirdY < 0) maxBirdY = 0; var yRange = maxBirdY - minBirdY; var usedYs = []; for (var b = 0; b < birdCount; b++) { var bird = new Bird(); // Scatter birds horizontally more bird.x = 2048 + 100 + Math.random() * 200 + b * 60 + Math.random() * 60; // Scatter birds vertically, allow overlap and more randomness var baseY = minBirdY + Math.random() * yRange; // Add more jitter, and avoid birds being too close vertically var jitterY = (Math.random() - 0.5) * 180; var finalY = baseY + jitterY; // Optionally, keep birds at least 120px apart vertically var minDist = 120; var attempts = 0; while (usedYs.some(function (y) { return Math.abs(y - finalY) < minDist; }) && attempts < 10) { finalY = minBirdY + Math.random() * yRange + (Math.random() - 0.5) * 180; attempts++; } usedYs.push(finalY); bird.y = finalY; bird.lastX = bird.x; // Apply speed multiplier to bird bird.speed = bird.speed * (0.8 + 0.4 * Math.random()) * speedMultiplier; game.addChild(bird); birds.push(bird); } // Bird group appears every 220-340 ticks (increased interval for more jump time) nextBirdTick = 220 + Math.floor(Math.random() * 120); } else { nextBirdTick--; } // Update cat cat.update(); // Spawn cactus if (nextCactusTick <= 0) { var cactus = new Cactus(); cactus.x = 2048 + 100; // spawn just off right edge cactus.y = GROUND_Y; cactus.lastX = cactus.x; // Apply speed multiplier to cactus cactus.speed = cactus.speed * speedMultiplier; game.addChild(cactus); cacti.push(cactus); // Use new CACTUS_SPAWN_MIN/MAX for more consistent jump windows var spawnInterval = CACTUS_SPAWN_MIN + Math.floor(Math.random() * (CACTUS_SPAWN_MAX - CACTUS_SPAWN_MIN + 1)); nextCactusTick = Math.floor(spawnInterval); } else { nextCactusTick--; } // Spawn gold if (nextGoldTick <= 0) { var gold = new Gold(); gold.x = 2048 + 100; // Random Y: between ground and a bit above cat's jump apex var jumpApex = GROUND_Y + cat.jumpVelocity * (Math.abs(cat.jumpVelocity) / (2 * cat.gravity)); var minY = GROUND_Y - 400; var maxY = GROUND_Y - 1000; if (maxY < 0) maxY = 0; gold.y = minY - Math.random() * (minY - maxY); gold.lastX = gold.x; gold.collected = false; gold.speed = gold.speed * speedMultiplier; game.addChild(gold); golds.push(gold); // Gold appears less frequently than cacti nextGoldTick = 80 + Math.floor(Math.random() * 120); } else { nextGoldTick--; } // Update golds, check for collection for (var j = golds.length - 1; j >= 0; j--) { var gold = golds[j]; gold.update(); // Remove if off screen if (gold.x < -200) { gold.destroy(); golds.splice(j, 1); continue; } // Collect gold: only trigger on first intersect and not already collected if (!gold.collected && cat.intersects(gold)) { gold.collected = true; goldScore++; goldScoreTxt.setText(goldScore); // Increase HP by 10, up to maxHp hp += 10; if (hp > maxHp) hp = maxHp; hpBar.width = Math.max(1, hp / maxHp * hpBarFullWidth); gold.destroy(); golds.splice(j, 1); continue; } } // Update cacti, check for collision and scoring for (var i = cacti.length - 1; i >= 0; i--) { var cactus = cacti[i]; cactus.update(); // Remove if off screen if (cactus.x < -200) { cactus.destroy(); cacti.splice(i, 1); continue; } // Collision detection (only trigger on first intersect) if (!cactus.lastWasIntersecting && cat.intersects(cactus)) { // Decrease HP by 20 hp -= 20; if (hp < 0) hp = 0; // Play cat sound on HP loss LK.getSound('kedi1').play(); // Update HP bar hpBar.width = Math.max(1, hp / maxHp * hpBarFullWidth); // Flash red for hit LK.effects.flashObject(cat, 0xff0000, 400); // If HP is 0, game over if (hp <= 0) { LK.effects.flashScreen(0xff0000, 800); // Play 'death' sound 3 times in quick succession when game over screen is shown LK.showGameOver(); LK.getSound('death').play(); LK.setTimeout(function () { LK.getSound('death').play(); }, 180); LK.setTimeout(function () { LK.getSound('death').play(); }, 360); gameOver = true; return; } } // Scoring: passed cactus (cat.x > cactus.x + cactus.width/2) and not already scored if (!cactus.scored && cat.x > cactus.x + cactus.width / 2) { score++; scoreTxt.setText(score); cactus.scored = true; // Increase speed multiplier, capped at max speedMultiplier += SPEED_MULTIPLIER_INCREMENT; if (speedMultiplier > SPEED_MULTIPLIER_MAX) speedMultiplier = SPEED_MULTIPLIER_MAX; // After level 30, allow 3 jumps if (score >= 30) { cat.maxJumps = 3; } // Track cacti jumped over for stamina refill after glide if (typeof cactiJumpedOver === "undefined") { cactiJumpedOver = 0; } cactiJumpedOver++; // Handle post-glide cactus counting for stamina refill if (typeof postGlideCountingActive === "undefined") postGlideCountingActive = false; if (typeof postGlideCactusCounter === "undefined") postGlideCactusCounter = 0; if (postGlideCountingActive) { postGlideCactusCounter++; if (postGlideCactusCounter >= 10) { stamina = maxStamina; staminaBar.width = Math.max(1, stamina / maxStamina * staminaBarFullWidth); postGlideCactusCounter = 0; // Continue counting for next refill } } // (Stamina refill now handled in Cat landing after glide.) } cactus.lastWasIntersecting = cat.intersects(cactus); } };
===================================================================
--- original.js
+++ change.js
@@ -1,7 +1,85 @@
/****
* Classes
****/
+// Main Cat (player) class
+var Cat = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach cat image asset
+ var catSprite = self.attachAsset('cat', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ catSprite.width = 220;
+ catSprite.height = 220;
+ // Physics and jump variables
+ self.vy = 0;
+ self.gravity = 4.5;
+ self.jumpVelocity = -70;
+ self.maxJumps = 2;
+ self.jumpCount = 0;
+ self.groundY = GROUND_Y;
+ self.isJumping = false;
+ self.isGliding = false;
+ self.glideStartTick = 0;
+ self.glideDuration = 180; // 3 seconds at 60fps
+ // For collision and state tracking
+ self.lastY = self.y;
+ self.lastX = self.x;
+ self.lastWasIntersecting = false;
+ // Jump method
+ self.jump = function () {
+ if (self.isGliding) return; // Can't jump while gliding
+ if (self.jumpCount < self.maxJumps) {
+ self.vy = self.jumpVelocity;
+ self.isJumping = true;
+ self.jumpCount++;
+ LK.getSound('kedi').play();
+ }
+ };
+ // Glide method (optional, for long press)
+ self.glide = function () {
+ if (!self.isGliding && self.isJumping) {
+ self.isGliding = true;
+ self.glideStartTick = LK.ticks;
+ self.vy = -8; // Slow descent
+ }
+ };
+ // End glide
+ self.endGlide = function () {
+ if (self.isGliding) {
+ self.isGliding = false;
+ self.vy = 0;
+ }
+ };
+ // Update method
+ self.update = function () {
+ // Save last positions for event triggers
+ self.lastY = self.y;
+ self.lastX = self.x;
+ // Handle gliding
+ if (self.isGliding) {
+ // Glide for a limited duration
+ if (LK.ticks - self.glideStartTick > self.glideDuration) {
+ self.endGlide();
+ } else {
+ self.y += self.vy;
+ }
+ } else if (self.isJumping) {
+ self.vy += self.gravity;
+ self.y += self.vy;
+ }
+ // Land on ground
+ if (self.y >= self.groundY) {
+ self.y = self.groundY;
+ self.vy = 0;
+ self.isJumping = false;
+ self.isGliding = false;
+ self.jumpCount = 0;
+ }
+ };
+ return self;
+});
// Cloud class for decorative clouds moving left across the sky
var Cloud = Container.expand(function () {
var self = Container.call(this);
// Add cloud image asset (use 'kum' as a placeholder, or replace with a real cloud asset if available)