User prompt
Tint the roombas red
User prompt
Make the enemies red
User prompt
Migrate to the latest version of LK
User prompt
Please fix the bug: 'Uncaught ReferenceError: polygon is not defined' in or related to this line: 'polygon.graphics.beginFill(0xFF3300);' Line Number: 314
User prompt
Please fix the bug: 'Uncaught TypeError: LK.Shape is not a constructor' in or related to this line: 'var polygon = new LK.Shape();' Line Number: 311
User prompt
Draw a polygon when 5 points
User prompt
Give me access to the graphics API
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'width')' in or related to this line: 'var fieldOfView = LK.getAsset('gridBackground', {' Line Number: 279
User prompt
Add s field of view for the room as
User prompt
Ensure the flag asset is created on level load
User prompt
Add a flag to the hole tile on the top right corner
User prompt
Debug, the flag is not visible
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var flag = LK.getAsset('Flag', {' Line Number: 279
User prompt
Create a flag placing it on the side of the hole tile, always outside the grid
User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of undefined (reading 'x')' in or related to this line: 'enemies[0].x = floorTiles[0].x;' Line Number: 859
User prompt
Please fix the bug: 'Timeout.tick error: Cannot read properties of undefined (reading 'x')' in or related to this line: 'enemies[0].x = floorTiles[0].x;' Line Number: 859
User prompt
Create the flag tile last on the creste tile function
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var holeTile = LK.getAsset('holeTile', {' Line Number: 872
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var holeTile = LK.getAsset('holeTile', {' Line Number: 868
User prompt
Create the flag tile last on the create tile function
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var holeTile = LK.getAsset('holeTile', {' Line Number: 865
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var holeTile = LK.getAsset('holeTile', {' Line Number: 859
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'var holeTile = LK.getAsset('holeTile', {' Line Number: 806
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'flagTile.x = holeTile.x;' Line Number: 806
User prompt
Instead of placing the flag random, place it aways on top of the hole tile
/**** * Classes ****/ var Character = Container.expand(function () { var self = Container.call(this); var characterShadow = self.attachAsset('CircularShadow', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2, y: 20 }); var characterGraphics = self.attachAsset('character', { anchorX: 0.5, anchorY: 0.5 }); characterGraphics.scaleX = 1; characterGraphics.scaleY = 1; }); var Cheese = Container.expand(function () { var self = Container.call(this); // Cheese shadow attachment removed var cheeseGraphics = self.attachAsset('cheese', { anchorX: 0.5, anchorY: 0.5 }); self.lerpToPosition = function (startPos, endPos, duration, onComplete) { self.x = endPos.x; self.y = endPos.y; if (onComplete) { onComplete(); } }; }); var Enemy = Container.expand(function (type) { var self = Container.call(this); self.id = Math.random().toString(36).substr(2, 9); // Unique ID for each Roomba var shadowAssetId, enemyAssetId, shadowScale, enemySpeed; // Moved globalEnemySpeed initialization outside of Enemy class to fix 'ReferenceError' var level = 0; // Initialize level variable // Moved globalEnemySpeed initialization outside of Enemy class to fix 'ReferenceError' var defaultEnemySpeed = globalEnemySpeed; // Use global enemy speed for initial speed var EnemyTypes = { Roomba: { shadowAssetId: 'CircularShadow', enemyAssetId: 'Roomba', shadowScale: 3.2, enemySpeed: defaultEnemySpeed * (1.03 + level * 0.05) // Increase speed by 3% plus an additional 5% per level } }; var enemyStats = EnemyTypes[type]; if (!enemyStats) { console.error('Unknown enemy type:', type); return; } shadowAssetId = enemyStats.shadowAssetId; enemyAssetId = enemyStats.enemyAssetId; shadowScale = enemyStats.shadowScale; enemySpeed = enemyStats.enemySpeed; var shadowGraphics = self.attachAsset(shadowAssetId, { anchorX: 0.5, anchorY: 0.5, alpha: 0.5, scaleX: shadowScale, scaleY: shadowScale, tint: 0xFF0000 // Tint the Roombas red }); var enemyGraphics = self.attachAsset(enemyAssetId, { anchorX: 0.5, anchorY: 0.5 }); // Adjust shadow position relative to the enemy shadowGraphics.x = enemyGraphics.x; shadowGraphics.y = enemyGraphics.y + 40; // Slightly below the enemy for a realistic shadow effect // Set enemy speed self.speed = enemySpeed; // Enemy movement logic self._move_migrated = function () { // Enhanced enemy behavior with dynamic avoidance and pathfinding enemies.forEach(function (otherEnemy) { if (otherEnemy.id !== self.id) { var dx = self.x - otherEnemy.x; var dy = self.y - otherEnemy.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 250 && distance > 0) { var awayX = dx / distance; var awayY = dy / distance; // Adjust repulsion to be more dynamic based on distance var repulsionStrength = Math.max(1, 250 - distance) / 50; // Increase repulsion as enemies get closer self.x += awayX * self.speed * repulsionStrength; self.y += awayY * self.speed * repulsionStrength; // Force Roombas to change direction upon collision self.targetTile = floorTiles[Math.floor(Math.random() * floorTiles.length)]; } } }); // Pick a random floor tile as a new target to keep Roombas apart if (!self.targetTile || self.collisionCounter > 50 || Math.sqrt(Math.pow(self.x - self.targetTile.x, 2) + Math.pow(self.y - self.targetTile.y, 2)) < 15) { var randomIndex = Math.floor(Math.random() * floorTiles.length); self.targetTile = floorTiles[randomIndex]; self.collisionCounter = 0; // Reset collision counter after changing target } // Introduce a collision counter to track continuous collisions if (!self.collisionCounter) { self.collisionCounter = 0; } // Increase collision counter on collision if (self.colliding) { self.collisionCounter++; } else { self.collisionCounter = 0; // Reset counter if not colliding } // Change target tile if colliding for too long or reached current target if (!self.targetTile || self.collisionCounter > 30 || Math.sqrt(Math.pow(self.x - self.targetTile.x, 2) + Math.pow(self.y - self.targetTile.y, 2)) < 10) { self.targetTile = floorTiles[Math.floor(Math.random() * floorTiles.length)]; self.collisionCounter = 0; // Reset collision counter after changing target } // Reset colliding flag for the next tick self.colliding = false; var angleToTarget = Math.atan2(self.targetTile.y - self.y, self.targetTile.x - self.x); self.x += Math.cos(angleToTarget) * self.speed; self.y += Math.sin(angleToTarget) * self.speed; // Smoothly rotate the enemy towards the target angle var currentAngle = enemyGraphics.rotation; var targetAngle = angleToTarget; // Calculate the shortest direction to rotate var angleDifference = targetAngle - currentAngle; angleDifference += angleDifference > Math.PI ? -2 * Math.PI : angleDifference < -Math.PI ? 2 * Math.PI : 0; var rotationSpeed = 0.1; // Adjust rotation speed as needed enemyGraphics.rotation += angleDifference * rotationSpeed; }; }); // OnScreenController class encapsulating A, B buttons and D-pad var OnScreenController = Container.expand(function () { var self = Container.call(this); // Add a background for the on screen controllers var yPosAdjustment = -180; var buttonYPosAdjustment = -273.2; var dpadButtonSize = 350; // Increased size for better visibility and interaction // Removed redundant tint application on A and B buttons LK.screen = { width: 2048, height: 2732 }; // Initialize screen dimensions var aButtonPosition = { x: LK.screen.width * 0.75, y: LK.screen.height * 0.85 + buttonYPosAdjustment + LK.screen.height * 0.055 }; var buttonSize = { width: 400, height: 400 }; var dPadSize = { width: 750, height: 750 }; this.aButton = self.attachAsset('aButton', { anchorX: 0.5, anchorY: 0.5, x: aButtonPosition.x, y: aButtonPosition.y, width: buttonSize.width, height: buttonSize.height }); // D-pad var dpadBase = self.attachAsset('dpadBase', { anchorX: 0.5, anchorY: 0.5, x: LK.screen.width * 0.24, y: LK.screen.height * 0.89 + yPosAdjustment - 10, width: dPadSize.width, height: dPadSize.height }); self.setChildIndex(dpadBase, self.children.length - 1); var dpadLeft = self.attachAsset('dpadButtonLeft', { anchorX: 0.5, anchorY: 0.5, x: dpadBase.x - 300, y: dpadBase.y, width: dpadButtonSize, height: dpadButtonSize, alpha: 0, // Tint arrow yellow orientation: 3 }); var moveInterval; function startMovingCharacter(xDir, yDir) { if (moveInterval) { LK.clearInterval(moveInterval); } isCharacterMoving = true; moveCharacter(xDir, yDir); moveInterval = LK.setInterval(function () { moveCharacter(xDir, yDir); }, 150); } dpadLeft.on('down', function () { startMovingCharacter(-1, 0); }); var dpadUp = self.attachAsset('dpadButtonUp', { anchorX: 0.5, anchorY: 0.5, x: dpadBase.x, y: dpadBase.y - 300, width: dpadButtonSize, height: dpadButtonSize, alpha: 0, orientation: 0 }); dpadUp.on('down', function () { startMovingCharacter(0, -1); }); var dpadRight = self.attachAsset('dpadButtonRight', { anchorX: 0.5, anchorY: 0.5, x: dpadBase.x + 300, y: dpadBase.y, width: dpadButtonSize, height: dpadButtonSize, alpha: 0, orientation: 1 }); dpadRight.on('down', function () { startMovingCharacter(1, 0); }); var dpadDown = self.attachAsset('dpadButtonDown', { anchorX: 0.5, anchorY: 0.5, x: dpadBase.x, y: dpadBase.y + 300, width: dpadButtonSize, height: dpadButtonSize, alpha: 0, orientation: 2 }); dpadDown.on('down', function () { startMovingCharacter(0, 1); }); function stopMovingCharacter() { isCharacterMoving = false; LK.clearInterval(moveInterval); } dpadLeft.on('up', function (x, y, obj) { obj.event = obj; stopMovingCharacter(obj); }); dpadUp.on('up', function (x, y, obj) { obj.event = obj; stopMovingCharacter(obj); }); dpadRight.on('up', function (x, y, obj) { obj.event = obj; stopMovingCharacter(obj); }); dpadDown.on('up', function (x, y, obj) { obj.event = obj; stopMovingCharacter(obj); }); }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xf9e076 // Fun yellow background }); /**** * Game Code ****/ // Define points for a 5-point polygon var polygonPoints = [{ x: 1024, y: 500 }, // Top center { x: 1300, y: 800 }, // Right top { x: 1200, y: 1200 }, // Right bottom { x: 800, y: 1200 }, // Left bottom { x: 700, y: 800 } // Left top ]; // Correct approach to simulate drawing a polygon using available assets // This function creates a visual representation of a polygon by placing assets at the polygon's vertices. function simulateDrawPolygon(points) { points.forEach(function (point, index) { // Use a small shape asset to represent each vertex of the polygon var vertex = game.addChild(LK.getAsset('CircularShadow', { anchorX: 0.5, anchorY: 0.5, x: point.x, y: point.y, scaleX: 0.1, // Scale down to make the asset small scaleY: 0.1, tint: 0xFF3300 // Color the asset to match the intended polygon color })); // Optionally, connect vertices with lines using additional assets or by adjusting existing assets' positions and rotations // This part is left as an exercise due to the complexity and limitations of the current asset system }); } // Call simulateDrawPolygon function with defined points simulateDrawPolygon(polygonPoints); // characterShadow asset initialization removed // Function to spawn cheeses at random floor tile positions function spawnCheeses() { // Clear existing cheeses before spawning new ones cheeses.forEach(function (cheese) { cheese.destroy(); }); cheeses = []; // Reset the cheeses array // Spawn new cheeses for (var i = 0; i < totalCheeses; i++) { cheeses.push(game.addChild(new Cheese())); } // Place cheeses on non-corner floor tiles that are far from the character var nonCornerFloorTiles = floorTiles.filter(function (tile) { return true; }); var farthestTiles = nonCornerFloorTiles.filter(function (tile) { // Ensure character is defined before calculating distance var distanceToCharacter = typeof character !== 'undefined' && character !== null ? Math.sqrt(Math.pow(tile.x - character.x, 2) + Math.pow(tile.y - character.y, 2)) : Infinity; return distanceToCharacter > LK.screen.width / 2; // Arbitrary distance threshold }); // Exclude tiles that are too close to the hole tile var safeDistanceTiles = nonCornerFloorTiles.filter(function (tile) { var distanceToHole = Math.sqrt(Math.pow(tile.x - holeTile.x, 2) + Math.pow(tile.y - holeTile.y, 2)); return distanceToHole > LK.screen.width / 4; // Arbitrary distance threshold to keep cheese away from the hole }); // Filter out tiles that are surrounded by obstacles horizontally and vertically // Move the declaration of 'targetTiles' before its first use var targetTiles = safeDistanceTiles.length > 0 ? safeDistanceTiles : farthestTiles; var validTilesForCheese = targetTiles.filter(function (tile) { var leftTile = getTileAtPosition(tile.x - tileWidth, tile.y); var rightTile = getTileAtPosition(tile.x + tileWidth, tile.y); var topTile = getTileAtPosition(tile.x, tile.y - tileHeight); var bottomTile = getTileAtPosition(tile.x, tile.y + tileHeight); // Check if the tile is surrounded by obstacles on all four sides return !(obstacleTiles.includes(leftTile) || obstacleTiles.includes(rightTile) || obstacleTiles.includes(topTile) || obstacleTiles.includes(bottomTile)); }); var targetTiles = validTilesForCheese.length > 0 ? validTilesForCheese : nonCornerFloorTiles; // Place each cheese on a unique random floor tile cheeses.forEach(function (cheese) { var uniqueTileIndex = Math.floor(Math.random() * targetTiles.length); var uniqueFloorTile = targetTiles.splice(uniqueTileIndex, 1)[0]; // Remove the selected tile from the pool to ensure uniqueness if (uniqueFloorTile) { cheese.x = uniqueFloorTile.x; cheese.y = uniqueFloorTile.y; } }); } // Method to check if all cheeses have been delivered function allCheesesDelivered() { // Destroy grid and tiles grid.forEach(function (tile) { if (tile) { tile.destroy(); } }); grid = []; // Clear the grid array floorTiles.forEach(function (tile) { tile.destroy(); }); floorTiles = []; // Clear the floorTiles array wallTiles.forEach(function (tile) { tile.destroy(); }); wallTiles = []; // Clear the wallTiles array obstacleTiles.forEach(function (tile) { tile.destroy(); }); obstacleTiles = []; // Clear the obstacleTiles array // Destroy character and cheese icon if (character) { if (cheeseIcon) { cheeseIcon.destroy(); } character.destroy(); character = null; } // Destroy enemies enemies.forEach(function (enemy) { enemy.destroy(); }); enemies = []; // Clear the enemies array globalEnemySpeed *= 1.1; // Increase global enemy speed by 10% on each level load console.log("building next level"); // Rebuild game elements createTiles(); // Rebuild the tiles for the level var nonCornerWallTiles = wallTiles.filter(function (tile) { var x = tile.x, y = tile.y; var isCornerTile = x === gridOffsetX && y === gridOffsetY || x === gridOffsetX + (gridSize - 1) * tileWidth && y === gridOffsetY || x === gridOffsetX && y === gridOffsetY + (gridSize - 1) * tileHeight || x === gridOffsetX + (gridSize - 1) * tileWidth && y === gridOffsetY + (gridSize - 1) * tileHeight; return !isCornerTile; }); var randomWallTile = nonCornerWallTiles[Math.floor(Math.random() * nonCornerWallTiles.length)]; holeTile = LK.getAsset('holeTile', { anchorX: 0.5, anchorY: 0.5, x: randomWallTile.x, y: randomWallTile.y }); game.addChild(holeTile); game.removeChild(randomWallTile); spawnCheeses(); // Spawn cheeses for the new level // Re-instantiate character for the new level with correct shadow and position character = game.addChild(new Character()); // Attach cheese icon to the new character if cheese is collected if (cheeseIcon && cheeseIcon.visible) { cheeseIcon = character.attachAsset('cheese', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: 0, y: -character.height / 2 // Position closer to the character top }); } // Create a new cheese icon and disable it cheeseIcon = character.attachAsset('cheese', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, x: 0, y: -character.height / 2, // Position closer to the character top visible: false // Disable cheese icon after creation }); // Attach cheese icon to the new character if cheese is collected // Ensure the cheese icon is visible on the new character instance character.x = holeTile.x; // Position character at the hole's location character.y = holeTile.y - 50; // Adjust Y position to not overlap with the hole enemies.forEach(function (enemy) { enemy.destroy(); }); // Destroy existing enemies enemies = []; // Clear enemies array enemies.push(game.addChild(new Enemy('Roomba'))); // Add first Roomba enemy enemies.push(game.addChild(new Enemy('Roomba'))); // Add second Roomba enemy // Position Roombas on opposite sides of the grid if (enemies[0]) { enemies[0].x = floorTiles[0].x; // Position the first Roomba on the left side enemies[0].y = floorTiles[0].y; } if (enemies[1]) { var lastTileIndex = floorTiles.length - 1; enemies[1].x = floorTiles[lastTileIndex].x; // Position the second Roomba on the right side enemies[1].y = floorTiles[lastTileIndex].y; } } // Ensure LK.screen dimensions are defined before using them var globalEnemySpeed = 3; // Define initial global enemy speed LK.screen = { width: 2048, height: 2732 }; // Initialize screen dimensions // Instantiate and center the game logo asset on the screen var gameLogo = LK.getAsset('stickerLogo', { anchorX: 0.5, anchorY: 0.5, x: LK.screen.width / 2 + 50, y: 1955 }); game.addChild(gameLogo); var dakaloText = new Text2('@Dakalo777', { size: 50, fill: "#FFA500", x: LK.screen.width - 20, // Adjust for space from the right edge y: LK.screen.height - 20 // Adjust for space from the bottom edge }); dakaloText.anchor.set(1, 1); // Anchor to bottom right LK.gui.bottomRight.addChild(dakaloText); // Function to check if a new obstacle tile fully surrounds any cheese // Removed redundant cheese tracking variables function doesTileSurroundCheese(obstacleTile, cheeses) { return cheeses.some(function (cheese) { // Calculate adjacent tiles to the cheese var adjacentTiles = [{ x: cheese.x - tileWidth, y: cheese.y }, { x: cheese.x + tileWidth, y: cheese.y }, { x: cheese.x, y: cheese.y - tileHeight }, { x: cheese.x, y: cheese.y + tileHeight }]; // Check if all adjacent tiles are either walls, obstacles, or the new obstacle tile return adjacentTiles.every(function (tile) { return wallTiles.some(function (wallTile) { return wallTile.x === tile.x && wallTile.y === tile.y; }) || grid.some(function (gridTile) { return gridTile && gridTile.x === tile.x && gridTile.y === tile.y && gridTile !== cheese && gridTile !== obstacleTile; }); }); }); } // Add sticker02 asset to the bottom of the screen next to sticker and rotate it 32 degrees var sticker02 = game.addChild(LK.getAsset('sticker02', { anchorX: 1.0, anchorY: 1.0, x: 2100, y: 2300, rotation: -0.558 })); // Add sticker asset to the bottom of the screen and rotate it 32 degrees var sticker = LK.getAsset('sticker', { anchorX: 0.5, anchorY: 0.5, x: 900, y: 2400, scaleX: 0.7, // Scale down by 0.7 scaleY: 0.7, // Scale down by 0.7 rotation: 0.10 }); game.addChild(sticker); // Update play time display every second LK.on('tick', function () { var minutes = Math.floor(playTime / 60); var seconds = playTime % 60; playTimeDisplay.setText((minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds); }); // Create a timer to update play time every second var playTimeTimer = LK.setInterval(function () { playTime += 1; }, 1000); // Initialize play time tracking var playTime = 0; // Initialize EventManager for global event handling var EventManager = { events: {}, subscribe: function subscribe(eventType, listener) { if (!this.events[eventType]) { this.events[eventType] = []; } this.events[eventType].push(listener); }, unsubscribe: function unsubscribe(eventType, listener) { if (this.events[eventType]) { var index = this.events[eventType].indexOf(listener); if (index > -1) { this.events[eventType].splice(index, 1); } } }, publish: function publish(eventType, data) { if (this.events[eventType]) { this.events[eventType].forEach(function (listener) { listener(data); }); } } }; game.eventManager = EventManager; // Subscribe to 'gameStart' event to initialize character and game state game.eventManager.subscribe('gameStart', function () { isGameStarted = true; // Method to instantiate and return a new character function createCharacter() { return LK.getAsset('character', { anchorX: 0.5, anchorY: 0.5, x: holeTile.x, y: holeTile.y - 50, scaleX: 1, scaleY: 1 }); } character = createCharacter(); // Reset cheese score display to '0' to prevent UI text overlap on game reset cheeseScoreDisplay.setText('0'); }); // Reset UI elements correctly when playing again if (window.scoreBoardContainer) { window.scoreBoardContainer.children.forEach(function (child) { child.destroy(); // Destroy each child to ensure clean slate }); window.scoreBoardContainer.destroy(); // Ensure the container is properly destroyed window.scoreBoardContainer = null; } // Reinitialize the scoreboard container to prevent UI text overlap on game reset window.scoreBoardInitialized = false; // Initialize scoreboard container and elements once and update score dynamically if (!window.scoreBoardInitialized) { var updateCheeseScore = function updateCheeseScore(score) { cheeseScoreDisplay.setText(score.toString()); }; window.scoreBoardContainer = new Container(); var scoreBoardX = 0, scoreBoardY = 0; var cheeseIconForScore = window.scoreBoardContainer.attachAsset('cheese', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: -500, y: 55 }); // Dynamically add one character lives icon per available life var availableLives = 3; // Assuming 3 lives to start with var livesIcons = []; for (var i = availableLives - 1; i >= 0; i--) { var lifeIcon = window.scoreBoardContainer.attachAsset('characterLivesIcon', { anchorX: 0, anchorY: 0, scaleX: 1.5, scaleY: 1.5, x: (availableLives - 1 - i) * 90 + 250, y: 0 }); livesIcons.unshift(lifeIcon); } // Cheese score display added to the scoreboard var cheeseScoreDisplay = new Text2('0', { size: 50, fill: "#ffffff", stroke: "#ffffff", strokeThickness: 4, font: "Roboto, bold", x: cheeseIconForScore.x + 60, // Adjust x position to place score text right side of the cheese icon y: cheeseIconForScore.y }); cheeseScoreDisplay.anchor.set(14.5, -.8); window.scoreBoardContainer.addChild(cheeseScoreDisplay); // Update cheese score display function window.updateCheeseScore = function (score) { updateCheeseScore(score); // Initiate bounce effect var originalScaleX = cheeseScoreDisplay.scaleX; var originalScaleY = cheeseScoreDisplay.scaleY; var scaleUpDuration = 150; // Duration to scale up var scaleDownDuration = 150; // Duration to scale down back to original size var scaleAmount = 1.2; // Amount to scale up // Scale up cheeseScoreDisplay.scaleX = originalScaleX * scaleAmount; cheeseScoreDisplay.scaleY = originalScaleY * scaleAmount; // Delay before scaling down LK.setTimeout(function () { // Scale down back to original size cheeseScoreDisplay.scaleX = originalScaleX; cheeseScoreDisplay.scaleY = originalScaleY; }, scaleUpDuration); }; // Character lives text asset creation and addition to scoreBoardContainer removed // Add play time display to the scoreboard // Initialize screen dimensions for playTimeDisplay positioning LK.screen = { width: 2048, height: 2732 }; var playTimeDisplay = new Text2('00:00', { size: 50, fill: "#E0E0E0", font: "Roboto, bold", x: -LK.screen.width / 2, y: 0 }); playTimeDisplay.anchor.set(-0.75, 0); // Center the text horizontally window.scoreBoardContainer.addChild(playTimeDisplay); window.scoreBoardContainer.x = 0; window.scoreBoardContainer.y = 55; LK.gui.top.addChild(window.scoreBoardContainer); window.scoreBoardInitialized = true; } var onScreenController = game.addChild(new OnScreenController()); // Refactored event listener for A button press to manage cheese collection and scoring more efficiently onScreenController.aButton.on('down', function () { if (isWithinProximity(character, holeTile, 75) && cheeseIcon && cheeseIcon.visible) { var createFlyingCheeseEffect = function createFlyingCheeseEffect(fromX, fromY) { var flyingCheese = game.addChild(LK.getAsset('cheese', { anchorX: 0.5, anchorY: 0.5, x: fromX, y: fromY, scaleX: 1.0, // Scale up by 100% scaleY: 1.0 // Scale up by 100% })); var leftTopCornerTile = floorTiles[0]; // Assuming the first tile in the array is the top left corner var scoreBoardPos = { x: leftTopCornerTile.x - tileHeight, y: leftTopCornerTile.y - tileHeight }; var cheeseFlyDuration = 750; // Duration in milliseconds var startTime = Date.now(); LK.on('tick', function () { var currentTime = Date.now(); var progress = (currentTime - startTime) / cheeseFlyDuration; if (progress < 1) { flyingCheese.x = fromX + (scoreBoardPos.x - fromX) * progress; flyingCheese.y = fromY + (scoreBoardPos.y - fromY) * progress; // Calculate the angle to rotate the flying cheese towards the scoreboard and add 180 degrees for rotation var angle = Math.atan2(scoreBoardPos.y - fromY, scoreBoardPos.x - fromX) + Math.PI; flyingCheese.rotation = angle; } else { game.removeChild(flyingCheese); window.updateCheeseScore(LK.getScore()); // Update displayed score } }); }; // Invoke createFlyingCheeseEffect with character's position when cheese is delivered console.log('Cheese delivered!'); cheeseIcon.visible = false; // Hide the cheese icon to indicate delivery // If it's the last cheese, increment score by 2, otherwise by 1 if (cheeses.length === 0) { LK.setScore(LK.getScore() + 2); allCheesesDelivered(); // Invoke allCheesesDelivered method after scoring for the last cheese } else { LK.setScore(LK.getScore() + 1); } // Create a visual cheese flying effect towards the scoreboard on cheese delivery createFlyingCheeseEffect(holeTile.x, holeTile.y); } else { if (!cheeseIcon || !cheeseIcon.visible) { cheeses.forEach(function (cheese, index) { if (isWithinProximity(character, cheese, 75)) { console.log('Cheese collected!'); game.removeChild(cheese); // Remove cheese from game cheeses.splice(index, 1); // Remove cheese from cheeses array // Display cheese icon above character to indicate cheese collection if (!cheeseIcon) { cheeseIcon = character.attachAsset('cheese', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, // Scale down by 50% scaleY: 0.8, // Scale down by 50% x: 0, y: -character.height / 2 // Position closer to the character top }); } else { cheeseIcon.visible = true; // Make the cheese icon visible if already exists } } }); } } }); // Helper function to check if two objects are within a certain distance function isWithinProximity(obj1, obj2, threshold) { if (!obj1 || !obj2) { return false; } return Math.abs(obj1.x - obj2.x) < threshold && Math.abs(obj1.y - obj2.y) < threshold; } var isCharacterMoving = false; // Function to move character based on direction var dpadButtonSize = { width: 450, height: 450 }; function moveCharacter(xDir, yDir) { if (availableLives <= 0) { return; } if (character) { var nextX = character.x + xDir * tileWidth; var nextY = character.y + yDir * tileHeight; } // Check if the next position is within the grid boundaries if (nextX >= gridOffsetX && nextX <= gridOffsetX + gridSize * tileWidth && nextY >= gridOffsetY && nextY <= gridOffsetY + gridSize * tileHeight) { // Check if the next tile is not a wall var nextTileIndex = Math.floor((nextY - gridOffsetY) / tileHeight) * gridSize + Math.floor((nextX - gridOffsetX) / tileWidth); if (grid[nextTileIndex] && (floorTiles.includes(grid[nextTileIndex]) || holeTile && grid[nextTileIndex].x === holeTile.x && grid[nextTileIndex].y === holeTile.y)) { character.x = nextX; character.y = nextY; character.currentTile = grid[nextTileIndex]; } } } LK.screen = { width: 2048, height: 2732 }; // Initialize screen dimensions // Removed redundant globalEnemySpeed initialization var gridSize = 10; // Character initialization removed to prevent duplication var totalCheeses = Math.floor(Math.random() * 3) + 1; // Define total number of cheeses in the game as a random number between 1 and 3 var cheeses = []; // Initialize cheeses array globally // Declare cheeseIcon as a global variable var cheeseIcon; var wallTiles = []; var obstacleTiles = []; // Define obstacleTiles array var floorTiles = []; var grid = new Array(gridSize * gridSize); var tileWidth = LK.screen.width * .6 / (gridSize - 1); // Adjust tile width to ensure tiles are touching var tileHeight = tileWidth; // Ensure square tiles for a uniform grid var gridOffsetX = (LK.screen.width - tileWidth * gridSize) / 2; // Corrected grid offset X calculation var gridOffsetY = (LK.screen.height - tileHeight * gridSize) / 2 - LK.screen.height * 0.15; // Corrected grid offset Y calculation // Move the onScreenController initialization to the top of Game Code section to ensure it's available before adding event listeners var onScreenController = game.addChild(new OnScreenController()); // Removed the A button press event listener for picking up cheese based on tile comparison function createTiles() { // Create a black square background for the grid var gridBackground = LK.getAsset('gridBackground', { anchorX: 0.5, anchorY: 0.75, x: LK.screen.width / 2, y: LK.screen.height / 2, width: LK.screen.width * .9, height: LK.screen.height * .65, tint: 0xFFA500 // Apply orange tint }); game.addChild(gridBackground); var gridBackgroundShrunk = LK.getAsset('gridBackground', { anchorX: 0.5, anchorY: 0.75, x: LK.screen.width / 2, y: LK.screen.height / 2, width: LK.screen.width * .9 - 50, height: LK.screen.height * .65 - 50, tint: 0x000000 // Apply black tint }); game.addChild(gridBackgroundShrunk); game.setChildIndex(gridBackgroundShrunk, game.getChildIndex(gridBackground) + 1); for (var i = 0; i < gridSize * gridSize; i++) { var x = i % gridSize; var y = Math.floor(i / gridSize); var tile; var tileWidth = LK.screen.width * .6 / (gridSize - 1); // Adjust tile width to ensure tiles are touching var tileHeight = tileWidth; // Ensure square tiles for a uniform grid var gridOffsetX = (LK.screen.width - tileWidth * (gridSize - 1)) / 2; // Adjust grid offset to account for new tile width var gridOffsetY = (LK.screen.height - tileHeight * (gridSize - 1)) / 2 - LK.screen.height * 0.15; // Adjust grid offset to account for new tile height if (!(x === 0 || y === 0 || x === gridSize - 1 || y === gridSize - 1)) { tile = LK.getAsset('floorTile', { anchorX: 0.5, anchorY: 0.5, x: x * tileWidth + gridOffsetX, y: y * tileHeight + gridOffsetY }); // Randomly replace some floor tiles with obstacle tiles, ensuring at least one valid path remains // Placeholder logic for path validation and obstacle placement if (Math.random() < 0.3 && !(x === 1 || y === 1 || x === gridSize - 2 || y === gridSize - 2)) { // Obstacle tile creation logic removed to ensure no obstacles are added to the game } else { floorTiles.push(tile); game.addChild(tile); grid[i] = tile; // Check if the current floor tile is surrounded by obstacles and change it to an obstacle tile if true var leftTileIndex = i - 1; var rightTileIndex = i + 1; var topTileIndex = i - gridSize; var bottomTileIndex = i + gridSize; if (leftTileIndex >= 0 && obstacleTiles.includes(grid[leftTileIndex]) && rightTileIndex < grid.length && obstacleTiles.includes(grid[rightTileIndex]) && topTileIndex >= 0 && obstacleTiles.includes(grid[topTileIndex]) && bottomTileIndex < grid.length && obstacleTiles.includes(grid[bottomTileIndex])) { // Remove the current tile from floorTiles and add to obstacleTiles floorTiles.pop(); obstacleTiles.push(tile); } } // Note: The function isTileBlockingPath() needs to be implemented to check if placing an obstacle would block all paths to cheeses or the hole } } // Add walls after floor tiles to ensure they render on top for (var i = 0; i < gridSize * gridSize; i++) { var x = i % gridSize; var y = Math.floor(i / gridSize); if (x === 0 || y === 0 || x === gridSize - 1 || y === gridSize - 1) { var isCornerTile = x === 0 && y === 0 || x === 0 && y === gridSize - 1 || x === gridSize - 1 && y === 0 || x === gridSize - 1 && y === gridSize - 1; if (isCornerTile) { var tile = LK.getAsset('CornerTile', { anchorX: 0.5, anchorY: 0.5, x: x * tileWidth + gridOffsetX, y: y * tileHeight + gridOffsetY }); game.addChild(tile); grid[i] = tile; } else { var tile = LK.getAsset('wallTile', { anchorX: 0.5, anchorY: 0.5, x: x * tileWidth + gridOffsetX, y: y * tileHeight + gridOffsetY }); wallTiles.push(tile); game.addChild(tile); grid[i] = tile; } } } } createTiles(); // Function to check if a tile is in a corner // Corner logic removed var randomWallTile = wallTiles[Math.floor(Math.random() * wallTiles.length)]; var holeTile = LK.getAsset('holeTile', { anchorX: 0.5, anchorY: 0.5, x: randomWallTile.x, y: randomWallTile.y }); game.addChild(holeTile); game.removeChild(randomWallTile); var randomWallTileIndex = wallTiles.indexOf(randomWallTile); wallTiles[randomWallTileIndex] = holeTile; var isGameStarted = false; var cheesePlaced = false; LK.on('tick', function () { if (!isGameStarted) { game.eventManager.publish('gameStart', null); LK.setTimeout(function () { enemies.push(game.addChild(new Enemy('Roomba'))); enemies.push(game.addChild(new Enemy('Roomba'))); // Position Roombas on opposite sides of the grid if (enemies[0]) { // Position the first Roomba on the left side enemies[0].x = floorTiles[0].x; enemies[0].y = floorTiles[0].y; } if (enemies[1]) { // Position the second Roomba on the right side var lastTileIndex = floorTiles.length - 1; enemies[1].x = floorTiles[lastTileIndex].x; enemies[1].y = floorTiles[lastTileIndex].y; } }, 1000); // Initialize cheese instances to place them on the floor // No changes needed here as the character shadow consistency is maintained with the original creation. character.currentTile = getTileAtPosition(holeTile.x, holeTile.y); // Correctly initialize character's current tile game.addChild(character); } // Iterate over enemies array to move each enemy and check for collision with character enemies.forEach(function (enemy) { enemy._move_migrated(); // Check if enemy intersects with character if (enemy.intersects(character) && Math.sqrt(Math.pow(enemy.x - character.x, 2) + Math.pow(enemy.y - character.y, 2)) < 200 && !character.isImmune && !(Math.abs(character.x - holeTile.x) < 75 && Math.abs(character.y - holeTile.y) < 75)) { // Reduce character lives by 1 availableLives -= 1; // Update lives display and make live icons disappear when player gets hit // Update lives display and make live icons disappear when player loses a life livesIcons.forEach(function (icon, index) { icon.visible = index < availableLives; }); // Make character blink to indicate damage and grant temporary immunity character.isImmune = true; // Set immunity flag to true var blinkInterval = LK.setInterval(function () { character.visible = !character.visible; // Removed tint logic }, 100); LK.setTimeout(function () { LK.clearInterval(blinkInterval); character.visible = true; // Reset tint to normal after blinking character.tint = 0xffffff; character.isImmune = false; // Remove immunity after 1 second }, 1000); // Check if lives are depleted or all cheeses have been delivered to win the game if (availableLives <= 0) { character.visible = false; // Make character invisible LK.setTimeout(function () { LK.showGameOver("You've been caught! Better luck next time."); }, 1000); // Wait one second before showing game over } // Removed win game logic based on cheese delivery } }); }); spawnCheeses(); // Create instances of enemies and store them in an array var enemies = []; // Removed two Roomba enemies // Position enemies // Position Roombas on opposite sides of the grid if (enemies[0]) { // Position the first Roomba on the left side enemies[0].x = floorTiles[0].x; enemies[0].y = floorTiles[0].y; } if (enemies[1]) { // Position the second Roomba on the right side var lastTileIndex = floorTiles.length - 1; enemies[1].x = floorTiles[lastTileIndex].x; enemies[1].y = floorTiles[lastTileIndex].y; } // Function to select a new target tile avoiding obstacles function selectNewTargetTileAvoidingObstacles(currentX, currentY, floorTiles, obstacleTiles) { // Placeholder for pathfinding logic to select a new target tile // For simplicity, this example randomly selects a floor tile not in the obstacleTiles array var validTiles = floorTiles.filter(function (tile) { return !obstacleTiles.includes(tile); }); if (validTiles.length > 0) { var randomIndex = Math.floor(Math.random() * validTiles.length); return validTiles[randomIndex]; } else { console.error('No valid tiles found to move to.'); return null; // Return null if no valid tiles are found } } // Define a function to get the tile at a given position function getTileAtPosition(x, y) { var index = Math.floor(y / 100) * gridSize + Math.floor(x / 100); if (index >= 0 && index < grid.length && grid[index]) { return grid[index]; } else { console.error('Tile at position', x, y, 'is out of bounds or null.'); return undefined; // Return undefined to indicate no tile found or out of bounds without error } }
===================================================================
--- original.js
+++ change.js
@@ -62,9 +62,9 @@
anchorY: 0.5,
alpha: 0.5,
scaleX: shadowScale,
scaleY: shadowScale,
- tint: 0xFF0000 // Change shadow color to red
+ tint: 0xFF0000 // Tint the Roombas red
});
var enemyGraphics = self.attachAsset(enemyAssetId, {
anchorX: 0.5,
anchorY: 0.5
grey square, black border. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
simple light yellow button front view game console, clean, rounded edges, high resolution, graphic. Single Game Texture. In-Game asset. 2d. Blank background. High contrast.
Worn out sticker for a video game, 90s style, cheese, simple, vintage. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
wall view from top-down, game asset videogame, black color, simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. worn out sticker. 90's style. vintage. simple. top-down view. poster. sticker
top-down view, videogame character enemy, roomba, 90s style sticker, flat, no perspective, silhouette, black and white, cartoon, fun, simple, from above. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
top-down view, videogame heart, 90s style sticker, flat, no perspective, silhouette, white, cartoon, fun, simple, from above. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Black square with white outline. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.