User prompt
the player start on center of screen
User prompt
make that vision of player when the player moving it could go black area optimized that problem
User prompt
when game started the player has to be in center of screen
User prompt
make center of vision size for player optimize that in center of vision for moving on map
User prompt
make vision moving more faster than player moving optimize that
User prompt
make vision size bigger
User prompt
make that vision of player optimized moving
User prompt
make more slower than vision moving the player moving
User prompt
make player moving is more slower
User prompt
fix when game started seeing allwhere and optimize the character moving in center of vision
User prompt
optimize the character moving and vision angle and make that vision angle max 3 block and when player saw the are save it like memory
User prompt
the player may dont want to catch that creature so when we saw it there is to be leave section
User prompt
optimized both character moving and vision siize moving
User prompt
the player has to be in center of vision size
User prompt
the player and vision is not optimized make it together
User prompt
that vision works wrong but when player discovered the area it still looking
User prompt
the player should have vision angle like max 3 blocks
User prompt
player should have a vision like max 3 blocks
User prompt
make blocks bigger than character
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'gridY')' in or related to this line: 'for (var y = player.gridY - visibleRadius; y <= player.gridY + visibleRadius; y++) {' Line Number: 866
User prompt
fix it
User prompt
Compilation error[L861]: TypeError: Cannot read properties of undefined (reading 'gridY')
User prompt
Compilation error[L700]: Cannot read properties of undefined (reading 'parse')
User prompt
Generate the first version of the source code of my game: PokéQuest: Elemental Explorers. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
PokéQuest: Elemental Explorers
/**** * Plugins ****/ var storage = LK.import("@upit/storage.v1", { discoveredCreatures: {}, playerPosition: { x: 10, y: 10 }, unlockedAreas: { starter: true } }); var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Collection class to manage discovered creatures var Collection = Container.expand(function () { var self = Container.call(this); // Collection components self.visible = false; self.background = null; self.scrollContainer = null; self.closeButton = null; // Initialize collection screen self.init = function () { // Create darkened background self.background = self.attachAsset('grassTile', { anchorX: 0, anchorY: 0, width: 2048, height: 2732 }); self.background.alpha = 0.9; self.background.tint = 0x000000; // Create scroll container for creatures self.scrollContainer = new Container(); self.addChild(self.scrollContainer); self.scrollContainer.x = 50; self.scrollContainer.y = 200; // Add title var titleText = new Text2('CREATURE COLLECTION', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.x = 1024; titleText.y = 50; self.addChild(titleText); // Create close button self.closeButton = self.attachAsset('dpadButton', { anchorX: 0.5, anchorY: 0.5, x: 1900, y: 100 }); self.closeButton.interactive = true; // Add X to close button var closeText = new Text2('X', { size: 60, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeText.x = 1900; closeText.y = 100; self.addChild(closeText); // Hide initially self.visible = false; return self; }; // Show collection screen and populate with discovered creatures self.show = function () { self.visible = true; // Clear existing creatures while (self.scrollContainer.children.length > 0) { self.scrollContainer.removeChild(self.scrollContainer.children[0]); } // Get discovered creatures from storage var discoveredCreatures = storage.discoveredCreatures || {}; var creatureCount = Object.keys(discoveredCreatures).length; // Show count var countText = new Text2('DISCOVERED: ' + creatureCount + ' / 90', { size: 50, fill: 0xFFFFFF }); countText.anchor.set(0.5, 0); countText.x = 1024; countText.y = 150; self.addChild(countText); // Create grid of discovered creatures var gridX = 0; var gridY = 0; var itemsPerRow = 5; var cellSize = 380; // First add "undiscovered" placeholders for all possible combinations var allTypes = ['bug', 'dark', 'dragon', 'electric', 'fairy', 'fighting', 'fire', 'flying', 'ghost', 'grass', 'ground', 'ice', 'normal', 'poison', 'psychic', 'rock', 'steel', 'water']; var allRarities = ['common', 'uncommon', 'rare', 'epic', 'legendary']; for (var t = 0; t < allTypes.length; t++) { for (var r = 0; r < allRarities.length; r++) { var type = allTypes[t]; var rarity = allRarities[r]; var key = type + '-' + rarity; // Calculate grid position gridX = (allRarities.length * t + r) % itemsPerRow; gridY = Math.floor((allRarities.length * t + r) / itemsPerRow); // Create cell container var cell = new Container(); cell.x = gridX * cellSize; cell.y = gridY * cellSize; self.scrollContainer.addChild(cell); if (discoveredCreatures[key]) { // Discovered creature var creatureGraphic = LK.getAsset(type + 'Creature', { anchorX: 0.5, anchorY: 0.5, x: cellSize / 2, y: cellSize / 2 - 40 }); // Apply rarity styling var rarityColor = 0xFFFFFF; if (rarity === 'uncommon') rarityColor = 0x00FF00; if (rarity === 'rare') rarityColor = 0x0000FF; if (rarity === 'epic') rarityColor = 0xFF00FF; if (rarity === 'legendary') rarityColor = 0xFFD700; // Make rarer creatures slightly larger var scale = 1.0; if (rarity === 'uncommon') scale = 1.1; if (rarity === 'rare') scale = 1.2; if (rarity === 'epic') scale = 1.3; if (rarity === 'legendary') scale = 1.5; creatureGraphic.scale.set(scale, scale); cell.addChild(creatureGraphic); // Add info text var infoText = new Text2(type.toUpperCase() + '\n' + rarity.toUpperCase(), { size: 30, fill: 0xFFFFFF }); infoText.anchor.set(0.5, 0); infoText.x = cellSize / 2; infoText.y = cellSize / 2 + 40; cell.addChild(infoText); } else { // Undiscovered creature (shadow) var undiscoveredGraphic = LK.getAsset(type + 'Creature', { anchorX: 0.5, anchorY: 0.5, x: cellSize / 2, y: cellSize / 2 }); undiscoveredGraphic.alpha = 0.2; undiscoveredGraphic.tint = 0x000000; cell.addChild(undiscoveredGraphic); // Add question mark var questionText = new Text2('?', { size: 60, fill: 0x999999 }); questionText.anchor.set(0.5, 0.5); questionText.x = cellSize / 2; questionText.y = cellSize / 2; cell.addChild(questionText); } } } }; // Hide collection screen self.hide = function () { self.visible = false; }; return self; }); // Game dimensions and settings // Creature class for encounters var Creature = Container.expand(function () { var self = Container.call(this); // Creature properties self.type = 'normal'; // Default type self.rarity = 'common'; // Default rarity self.gridX = 0; self.gridY = 0; self.captured = false; // Rarity colors self.rarityColors = { common: 0xFFFFFF, uncommon: 0x00FF00, rare: 0x0000FF, epic: 0xFF00FF, legendary: 0xFFD700 }; // Type to biome mapping self.typeBiomeMap = { bug: 'forest', dark: 'mountain', dragon: 'mountain', electric: 'grass', fairy: 'forest', fighting: 'mountain', fire: 'desert', flying: 'grass', ghost: 'mountain', grass: 'grass', ground: 'desert', ice: 'mountain', normal: 'grass', poison: 'forest', psychic: 'grass', rock: 'mountain', steel: 'mountain', water: 'water' }; // Initialize creature with specific type, rarity, and position self.init = function (type, rarity, gridX, gridY) { self.type = type || self.getRandomType(); self.rarity = rarity || self.getRandomRarity(); self.gridX = gridX; self.gridY = gridY; // Create creature graphic var creatureGraphics = self.attachAsset(self.type + 'Creature', { anchorX: 0.5, anchorY: 0.5 }); // Apply rarity visual effect (glow or color) var rarityColor = self.rarityColors[self.rarity] || 0xFFFFFF; // Add glow effect for rare+ creatures if (self.rarity !== 'common') { // Make rarer creatures slightly larger var scale = 1.0; if (self.rarity === 'uncommon') scale = 1.1; if (self.rarity === 'rare') scale = 1.2; if (self.rarity === 'epic') scale = 1.3; if (self.rarity === 'legendary') scale = 1.5; creatureGraphics.scale.set(scale, scale); } // Position creature self.x = self.gridX * 100 + 50; // Center of tile self.y = self.gridY * 100 + 50; // Center of tile return self; }; // Generate a random creature type, weighted by biome self.getRandomType = function (biome) { // Default types for each biome var biomeTypes = { grass: ['normal', 'grass', 'bug', 'flying', 'electric', 'psychic'], water: ['water', 'ice', 'flying'], desert: ['ground', 'fire', 'rock'], forest: ['bug', 'grass', 'poison', 'fairy'], mountain: ['rock', 'fighting', 'dragon', 'dark', 'ghost', 'steel', 'ice'] }; // Get types for the provided biome, or use all types var types = biome ? biomeTypes[biome] : Object.keys(self.typeBiomeMap); // Select random type from available options return types[Math.floor(Math.random() * types.length)]; }; // Generate a random rarity based on configured probabilities self.getRandomRarity = function () { var rand = Math.random(); if (rand < 0.65) return 'common'; if (rand < 0.85) return 'uncommon'; if (rand < 0.95) return 'rare'; if (rand < 0.99) return 'epic'; return 'legendary'; }; // Animate creature during encounter self.animate = function () { // Bounce animation var originalY = self.y; // Use tween to create a bouncing effect tween(self, { y: originalY - 20 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { y: originalY }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { // Repeat animation self.animate(); } }); } }); }; // Stop animations self.stopAnimation = function () { tween.stop(self, { y: true }); }; return self; }); // Directional pad control for player movement var DPad = Container.expand(function () { var self = Container.call(this); // DPad components self.padBase = null; self.upButton = null; self.downButton = null; self.leftButton = null; self.rightButton = null; // Initialize dpad with buttons self.init = function () { // Create base of DPad self.padBase = self.attachAsset('dpad', { anchorX: 0.5, anchorY: 0.5 }); // Create directional buttons self.upButton = self.createButton(0, -65); self.downButton = self.createButton(0, 65); self.leftButton = self.createButton(-65, 0); self.rightButton = self.createButton(65, 0); // Position the entire DPad in the bottom left of the screen self.x = 200; self.y = 2500; return self; }; // Create a directional button at relative x,y from center self.createButton = function (relX, relY) { var button = self.attachAsset('dpadButton', { anchorX: 0.5, anchorY: 0.5, x: relX, y: relY }); button.interactive = true; return button; }; return self; }); // Encounter class to handle creature encounters var Encounter = Container.expand(function () { var self = Container.call(this); // Encounter state self.active = false; self.creature = null; self.captureRing = null; self.captureTarget = null; self.targetSpeed = 5; self.targetDirection = 1; self.captureAttempts = 0; self.maxAttempts = 3; // Initialize encounter screen self.init = function () { // Darkened background var bg = self.attachAsset('grassTile', { anchorX: 0, anchorY: 0, width: 2048, height: 2732 }); bg.alpha = 0.7; bg.tint = 0x000000; // Initially hidden self.visible = false; return self; }; // Start encounter with a specific creature self.startEncounter = function (creature) { self.active = true; self.visible = true; self.creature = creature; self.captureAttempts = 0; // Add creature to encounter screen self.addChild(creature); creature.x = 1024; // Center horizontally creature.y = 1000; // Position in upper portion of screen // Start creature animation creature.animate(); // Create capture interface self.createCaptureInterface(); // Play encounter sound LK.getSound('encounter').play(); }; // Create the capture ring and target interface self.createCaptureInterface = function () { // Capture ring self.captureRing = self.attachAsset('captureRing', { anchorX: 0.5, anchorY: 0.5, x: 1024, // Center horizontally y: 1800 // Lower portion of screen }); // Moving target self.captureTarget = self.attachAsset('captureTarget', { anchorX: 0.5, anchorY: 0.5, x: 964, // Start position (left side of ring) y: 1800 // Same Y as ring }); // Capture button var captureButton = self.attachAsset('grassTile', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 2200, width: 300, height: 100 }); captureButton.tint = 0xFF0000; // Capture button text var captureText = new Text2('CAPTURE', { size: 60, fill: 0xFFFFFF }); captureText.anchor.set(0.5, 0.5); captureText.x = 1024; captureText.y = 2200; self.addChild(captureText); // Capture button event captureButton.interactive = true; captureButton.down = function () { self.attemptCapture(); }; // Info text about the creature var infoText = new Text2('TYPE: ' + self.creature.type.toUpperCase() + '\n' + 'RARITY: ' + self.creature.rarity.toUpperCase() + '\n' + 'ATTEMPTS: ' + (self.maxAttempts - self.captureAttempts) + ' REMAINING', { size: 50, fill: 0xFFFFFF }); infoText.anchor.set(0.5, 0); infoText.x = 1024; infoText.y = 2300; self.addChild(infoText); }; // Update function for moving the target self.update = function () { if (!self.active || !self.captureTarget) return; // Move target back and forth across the ring self.captureTarget.x += self.targetSpeed * self.targetDirection; // Reverse direction at edges if (self.captureTarget.x > 1084) { // Right edge of ring self.targetDirection = -1; } else if (self.captureTarget.x < 964) { // Left edge of ring self.targetDirection = 1; } // Make target move faster based on creature rarity var speedMultiplier = 1; if (self.creature) { if (self.creature.rarity === 'uncommon') speedMultiplier = 1.2; if (self.creature.rarity === 'rare') speedMultiplier = 1.5; if (self.creature.rarity === 'epic') speedMultiplier = 1.8; if (self.creature.rarity === 'legendary') speedMultiplier = 2.2; } self.targetSpeed = 5 * speedMultiplier; }; // Attempt to capture the creature self.attemptCapture = function () { // Play capture sound LK.getSound('capture').play(); self.captureAttempts++; // Check if target is in center zone (successful capture) var distanceFromCenter = Math.abs(self.captureTarget.x - 1024); var successZone = 15; // Size of "perfect" zone // Adjust success zone based on rarity (harder for rarer creatures) if (self.creature.rarity === 'uncommon') successZone = 13; if (self.creature.rarity === 'rare') successZone = 10; if (self.creature.rarity === 'epic') successZone = 8; if (self.creature.rarity === 'legendary') successZone = 5; var captured = distanceFromCenter <= successZone; if (captured) { // Success! self.captureSuccess(); } else if (self.captureAttempts >= self.maxAttempts) { // Failed after max attempts self.captureFail(); } else { // Update attempts remaining text var remainingText = self.children.filter(function (child) { return child instanceof Text2 && child.y === 2300; })[0]; if (remainingText) { remainingText.setText('TYPE: ' + self.creature.type.toUpperCase() + '\n' + 'RARITY: ' + self.creature.rarity.toUpperCase() + '\n' + 'ATTEMPTS: ' + (self.maxAttempts - self.captureAttempts) + ' REMAINING'); } } }; // Handle successful capture self.captureSuccess = function () { // Play success sound LK.getSound('success').play(); // Add to collection if (!storage.discoveredCreatures) { storage.discoveredCreatures = {}; } var creatureKey = self.creature.type + '-' + self.creature.rarity; storage.discoveredCreatures[creatureKey] = true; // Show success message var successText = new Text2('CAPTURED!', { size: 100, fill: 0x00FF00 }); successText.anchor.set(0.5, 0.5); successText.x = 1024; successText.y = 1400; self.addChild(successText); // Flash screen LK.effects.flashScreen(0x00FF00, 500); // End encounter after delay LK.setTimeout(function () { self.endEncounter(); }, 1500); }; // Handle failed capture self.captureFail = function () { // Show fail message var failText = new Text2('ESCAPED!', { size: 100, fill: 0xFF0000 }); failText.anchor.set(0.5, 0.5); failText.x = 1024; failText.y = 1400; self.addChild(failText); // Flash screen LK.effects.flashScreen(0xFF0000, 500); // End encounter after delay LK.setTimeout(function () { self.endEncounter(); }, 1500); }; // End the current encounter self.endEncounter = function () { if (self.creature) { self.creature.stopAnimation(); } self.active = false; self.visible = false; // Remove all children while (self.children.length > 0) { self.removeChild(self.children[0]); } self.creature = null; self.captureRing = null; self.captureTarget = null; // Reinitialize for next encounter self.init(); }; return self; }); // GameMap represents the entire game map with different biomes var GameMap = Container.expand(function () { var self = Container.call(this); self.mapWidth = 30; // Number of tiles horizontally self.mapHeight = 30; // Number of tiles vertically self.tileSize = 100; // Size of each tile in pixels self.tiles = []; // 2D array to hold all map tiles // Biome generation parameters self.biomeTypes = ['grass', 'water', 'desert', 'forest', 'mountain']; self.biomeSeeds = []; // Points from which biomes spread // Initialize map with biomes self.initMap = function () { // Create empty 2D array for tiles for (var y = 0; y < self.mapHeight; y++) { self.tiles[y] = []; for (var x = 0; x < self.mapWidth; x++) { self.tiles[y][x] = null; } } // Place biome seeds self.placeBiomeSeeds(); // Generate biomes from seeds self.generateBiomes(); // Create tiles based on biome map self.createTiles(); return self; }; // Place seed points for biome generation self.placeBiomeSeeds = function () { // Place one seed for each biome for (var i = 0; i < self.biomeTypes.length; i++) { var seed = { x: Math.floor(Math.random() * self.mapWidth), y: Math.floor(Math.random() * self.mapHeight), biome: self.biomeTypes[i] }; self.biomeSeeds.push(seed); } }; // Generate biomes from seed points using a simple distance-based algorithm self.generateBiomes = function () { for (var y = 0; y < self.mapHeight; y++) { for (var x = 0; x < self.mapWidth; x++) { // Find closest biome seed var closestDist = Number.MAX_VALUE; var closestBiome = 'grass'; // Default for (var i = 0; i < self.biomeSeeds.length; i++) { var seed = self.biomeSeeds[i]; var dist = Math.sqrt(Math.pow(x - seed.x, 2) + Math.pow(y - seed.y, 2)); // Add some randomness to make borders less regular dist += Math.random() * 3 - 1.5; if (dist < closestDist) { closestDist = dist; closestBiome = seed.biome; } } self.tiles[y][x] = closestBiome; } } // Add some randomness and blending between biomes self.refineBiomes(); }; // Add more natural transitions between biomes self.refineBiomes = function () { var tempTiles = JSON.parse(JSON.stringify(self.tiles)); for (var y = 1; y < self.mapHeight - 1; y++) { for (var x = 1; x < self.mapWidth - 1; x++) { // Count neighboring biomes var biomeCount = {}; for (var ny = y - 1; ny <= y + 1; ny++) { for (var nx = x - 1; nx <= x + 1; nx++) { var neighborBiome = tempTiles[ny][nx]; if (!biomeCount[neighborBiome]) { biomeCount[neighborBiome] = 0; } biomeCount[neighborBiome]++; } } // Random chance to convert to most common neighbor if (Math.random() < 0.4) { var mostCommon = tempTiles[y][x]; var maxCount = 0; for (var biome in biomeCount) { if (biomeCount[biome] > maxCount) { maxCount = biomeCount[biome]; mostCommon = biome; } } self.tiles[y][x] = mostCommon; } } } }; // Create actual tile objects based on the biome map self.createTiles = function () { for (var y = 0; y < self.mapHeight; y++) { for (var x = 0; x < self.mapWidth; x++) { var biomeType = self.tiles[y][x]; var tile = new MapTile().initTile(biomeType, x, y); self.addChild(tile); } } }; // Get tile at grid coordinates self.getTileAt = function (gridX, gridY) { // Ensure coordinates are within bounds if (gridX < 0 || gridX >= self.mapWidth || gridY < 0 || gridY >= self.mapHeight) { return null; } // Find the tile in the children for (var i = 0; i < self.children.length; i++) { var tile = self.children[i]; if (tile.gridX === gridX && tile.gridY === gridY) { return tile; } } return null; }; return self; }); // MapTile represents a single tile in the game grid var MapTile = Container.expand(function () { var self = Container.call(this); self.biomeType = 'grass'; // Default biome self.tileSize = 100; self.hasCreature = false; self.explored = false; self.x = 0; self.y = 0; self.gridX = 0; self.gridY = 0; // Initialize the tile with a specific biome self.initTile = function (biomeType, gridX, gridY) { self.biomeType = biomeType; self.gridX = gridX; self.gridY = gridY; self.x = gridX * self.tileSize; self.y = gridY * self.tileSize; // Get the appropriate tile asset based on biome var assetId = self.biomeType + 'Tile'; var tileGraphics = self.attachAsset(assetId, { anchorX: 0, anchorY: 0 }); // Add lighter border for visibility tileGraphics.alpha = 0.9; // Random chance to spawn a creature based on biome if (Math.random() < 0.15) { self.hasCreature = true; var indicator = self.attachAsset('encounterIndicator', { anchorX: 0.5, anchorY: 0.5, x: self.tileSize / 2, y: self.tileSize / 2 }); indicator.alpha = 0.7; } return self; }; // Mark tile as explored self.explore = function () { if (!self.explored) { self.explored = true; // Add to explored areas in storage var exploredKey = self.gridX + "," + self.gridY; if (!storage.exploredTiles) storage.exploredTiles = {}; storage.exploredTiles[exploredKey] = true; } }; return self; }); // MiniMap class to show explored areas var MiniMap = Container.expand(function () { var self = Container.call(this); // MiniMap components self.mapBackground = null; self.playerMarker = null; self.tileMarkers = []; self.mapSize = 300; self.scale = 0.1; // How much of the full map to show // Initialize minimap self.init = function () { // Create background self.mapBackground = self.attachAsset('minimap', { anchorX: 0, anchorY: 0, width: self.mapSize, height: self.mapSize }); // Create player marker self.playerMarker = self.attachAsset('minimapMarker', { anchorX: 0.5, anchorY: 0.5, x: self.mapSize / 2, y: self.mapSize / 2 }); // Position minimap in top right corner self.x = 2048 - self.mapSize - 20; self.y = 20; return self; }; // Update minimap with current player position and explored tiles self.update = function (player, gameMap) { // Update player marker position var centerX = self.mapSize / 2; var centerY = self.mapSize / 2; // Position marker relative to center self.playerMarker.x = centerX; self.playerMarker.y = centerY; // Clear existing tile markers for (var i = 0; i < self.tileMarkers.length; i++) { self.removeChild(self.tileMarkers[i]); } self.tileMarkers = []; // Add markers for visible tiles around player var visibleRadius = Math.floor(self.mapSize / (2 * 10)); // 10px per tile for (var y = player.gridY - visibleRadius; y <= player.gridY + visibleRadius; y++) { for (var x = player.gridX - visibleRadius; x <= player.gridX + visibleRadius; x++) { var tile = gameMap.getTileAt(x, y); if (tile && tile.explored) { // Create marker with biome color var color = 0x33cc33; // Default grass if (tile.biomeType === 'water') color = 0x3399ff; if (tile.biomeType === 'desert') color = 0xe6cc99; if (tile.biomeType === 'forest') color = 0x006600; if (tile.biomeType === 'mountain') color = 0x999999; var marker = new Container(); var markerGraphics = LK.getAsset('grassTile', { anchorX: 0, anchorY: 0, width: 10, height: 10 }); markerGraphics.tint = color; marker.addChild(markerGraphics); // Position marker relative to player marker.x = centerX + (x - player.gridX) * 10; marker.y = centerY + (y - player.gridY) * 10; self.addChild(marker); self.tileMarkers.push(marker); } } } }; return self; }); // Player character var Player = Container.expand(function () { var self = Container.call(this); // Player properties self.gridX = 10; // Starting X position on grid self.gridY = 10; // Starting Y position on grid self.moveSpeed = 0.2; // Movement animation speed self.moving = false; self.lastGridX = 10; self.lastGridY = 10; // Initialize player with graphics self.init = function () { var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Load position from storage if available if (storage.playerPosition) { self.gridX = storage.playerPosition.x; self.gridY = storage.playerPosition.y; self.lastGridX = self.gridX; self.lastGridY = self.gridY; } // Update position based on grid coordinates self.updatePosition(); return self; }; // Move player to specific grid coordinates self.moveToGrid = function (newGridX, newGridY) { if (self.moving) return; // Don't interrupt current movement // Store last position for comparison self.lastGridX = self.gridX; self.lastGridY = self.gridY; // Update grid position self.gridX = newGridX; self.gridY = newGridY; // Save position to storage storage.playerPosition = { x: self.gridX, y: self.gridY }; // Animate movement self.moving = true; var targetX = self.gridX * 100 + 50; // Center of tile var targetY = self.gridY * 100 + 50; // Center of tile tween(self, { x: targetX, y: targetY }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { self.moving = false; } }); }; // Update position based on current grid coordinates (no animation) self.updatePosition = function () { self.x = self.gridX * 100 + 50; // Center of tile self.y = self.gridY * 100 + 50; // Center of tile }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game dimensions and settings // Tween for animations // Storage for saving game progress // Player character // Map tiles // Creatures by elemental type // UI elements // Encounter indicator // Sounds var TILE_SIZE = 100; var MAP_WIDTH = 30; var MAP_HEIGHT = 30; // Initialize game objects var gameMap = game.addChild(new GameMap().initMap()); var player = game.addChild(new Player().init()); var dpad = game.addChild(new DPad().init()); var minimap = game.addChild(new MiniMap().init()); var encounter = game.addChild(new Encounter().init()); var collection = game.addChild(new Collection().init()); // Collection button (top right corner) var collectionButton = game.attachAsset('dpadButton', { anchorX: 0.5, anchorY: 0.5, x: 1900, y: 150 }); collectionButton.interactive = true; // Collection button icon var collectionText = new Text2('COL', { size: 30, fill: 0xFFFFFF }); collectionText.anchor.set(0.5, 0.5); collectionText.x = 1900; collectionText.y = 150; game.addChild(collectionText); // Game stats text display var statsText = new Text2('Collected: 0/90\nExplored: 0%', { size: 40, fill: 0xFFFFFF }); statsText.anchor.set(0, 0); statsText.x = 150; statsText.y = 50; game.addChild(statsText); // Game variables var encounterActive = false; var exploredCount = 0; var totalTiles = MAP_WIDTH * MAP_HEIGHT; // Update stats display function updateStats() { var discoveredCount = Object.keys(storage.discoveredCreatures || {}).length; var exploredPercent = Math.floor(exploredCount / totalTiles * 100); statsText.setText('Collected: ' + discoveredCount + '/90\n' + 'Explored: ' + exploredPercent + '%'); } // Center the game view on player function centerViewOnPlayer() { // Calculate offset to center player var offsetX = 1024 - player.x; var offsetY = 1366 - player.y; // Move map to center player gameMap.x = offsetX; gameMap.y = offsetY; } // Handle player movement from DPad dpad.upButton.down = function () { if (!encounterActive && !player.moving) { var newY = player.gridY - 1; if (newY >= 0) { player.moveToGrid(player.gridX, newY); } } }; dpad.downButton.down = function () { if (!encounterActive && !player.moving) { var newY = player.gridY + 1; if (newY < MAP_HEIGHT) { player.moveToGrid(player.gridX, newY); } } }; dpad.leftButton.down = function () { if (!encounterActive && !player.moving) { var newX = player.gridX - 1; if (newX >= 0) { player.moveToGrid(newX, player.gridY); } } }; dpad.rightButton.down = function () { if (!encounterActive && !player.moving) { var newX = player.gridX + 1; if (newX < MAP_WIDTH) { player.moveToGrid(newX, player.gridY); } } }; // Handle collection button collectionButton.down = function () { if (!encounterActive) { collection.show(); } }; // Handle collection close button collection.closeButton.down = function () { collection.hide(); }; // Track last player position to detect changes var lastPlayerGridX = player.gridX; var lastPlayerGridY = player.gridY; // Main game update loop game.update = function () { // Skip updates if in an active encounter if (encounterActive) { encounter.update(); return; } // Check if collection is visible if (collection.visible) { return; } // Center view on player centerViewOnPlayer(); // Update minimap minimap.update(player, gameMap); // Check if player has moved to a new tile if (player.gridX !== lastPlayerGridX || player.gridY !== lastPlayerGridY) { // Get the current tile var currentTile = gameMap.getTileAt(player.gridX, player.gridY); if (currentTile) { // Mark tile as explored if it's new if (!currentTile.explored) { currentTile.explore(); exploredCount++; updateStats(); } // Check for creature encounter if (currentTile.hasCreature && Math.random() < 0.7) { // 70% chance to trigger encounter // Start encounter encounterActive = true; // Create creature based on biome var creatureType = new Creature().getRandomType(currentTile.biomeType); var creature = new Creature().init(creatureType, null, player.gridX, player.gridY); // Start encounter with this creature encounter.startEncounter(creature); // Remove creature from tile currentTile.hasCreature = false; // Remove indicator from tile for (var i = 0; i < currentTile.children.length; i++) { var child = currentTile.children[i]; if (child.assetId === 'encounterIndicator') { currentTile.removeChild(child); break; } } } } // Update last position lastPlayerGridX = player.gridX; lastPlayerGridY = player.gridY; } }; // Listen for encounter end var checkEncounterInterval = LK.setInterval(function () { if (encounterActive && !encounter.active) { encounterActive = false; updateStats(); } }, 100); // Initialize stats updateStats(); // Initial centering centerViewOnPlayer();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,1041 @@
-/****
+/****
+* Plugins
+****/
+var storage = LK.import("@upit/storage.v1", {
+ discoveredCreatures: {},
+ playerPosition: {
+ x: 10,
+ y: 10
+ },
+ unlockedAreas: {
+ starter: true
+ }
+});
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Collection class to manage discovered creatures
+var Collection = Container.expand(function () {
+ var self = Container.call(this);
+ // Collection components
+ self.visible = false;
+ self.background = null;
+ self.scrollContainer = null;
+ self.closeButton = null;
+ // Initialize collection screen
+ self.init = function () {
+ // Create darkened background
+ self.background = self.attachAsset('grassTile', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 2048,
+ height: 2732
+ });
+ self.background.alpha = 0.9;
+ self.background.tint = 0x000000;
+ // Create scroll container for creatures
+ self.scrollContainer = new Container();
+ self.addChild(self.scrollContainer);
+ self.scrollContainer.x = 50;
+ self.scrollContainer.y = 200;
+ // Add title
+ var titleText = new Text2('CREATURE COLLECTION', {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ titleText.anchor.set(0.5, 0);
+ titleText.x = 1024;
+ titleText.y = 50;
+ self.addChild(titleText);
+ // Create close button
+ self.closeButton = self.attachAsset('dpadButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1900,
+ y: 100
+ });
+ self.closeButton.interactive = true;
+ // Add X to close button
+ var closeText = new Text2('X', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ closeText.anchor.set(0.5, 0.5);
+ closeText.x = 1900;
+ closeText.y = 100;
+ self.addChild(closeText);
+ // Hide initially
+ self.visible = false;
+ return self;
+ };
+ // Show collection screen and populate with discovered creatures
+ self.show = function () {
+ self.visible = true;
+ // Clear existing creatures
+ while (self.scrollContainer.children.length > 0) {
+ self.scrollContainer.removeChild(self.scrollContainer.children[0]);
+ }
+ // Get discovered creatures from storage
+ var discoveredCreatures = storage.discoveredCreatures || {};
+ var creatureCount = Object.keys(discoveredCreatures).length;
+ // Show count
+ var countText = new Text2('DISCOVERED: ' + creatureCount + ' / 90', {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ countText.anchor.set(0.5, 0);
+ countText.x = 1024;
+ countText.y = 150;
+ self.addChild(countText);
+ // Create grid of discovered creatures
+ var gridX = 0;
+ var gridY = 0;
+ var itemsPerRow = 5;
+ var cellSize = 380;
+ // First add "undiscovered" placeholders for all possible combinations
+ var allTypes = ['bug', 'dark', 'dragon', 'electric', 'fairy', 'fighting', 'fire', 'flying', 'ghost', 'grass', 'ground', 'ice', 'normal', 'poison', 'psychic', 'rock', 'steel', 'water'];
+ var allRarities = ['common', 'uncommon', 'rare', 'epic', 'legendary'];
+ for (var t = 0; t < allTypes.length; t++) {
+ for (var r = 0; r < allRarities.length; r++) {
+ var type = allTypes[t];
+ var rarity = allRarities[r];
+ var key = type + '-' + rarity;
+ // Calculate grid position
+ gridX = (allRarities.length * t + r) % itemsPerRow;
+ gridY = Math.floor((allRarities.length * t + r) / itemsPerRow);
+ // Create cell container
+ var cell = new Container();
+ cell.x = gridX * cellSize;
+ cell.y = gridY * cellSize;
+ self.scrollContainer.addChild(cell);
+ if (discoveredCreatures[key]) {
+ // Discovered creature
+ var creatureGraphic = LK.getAsset(type + 'Creature', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: cellSize / 2,
+ y: cellSize / 2 - 40
+ });
+ // Apply rarity styling
+ var rarityColor = 0xFFFFFF;
+ if (rarity === 'uncommon') rarityColor = 0x00FF00;
+ if (rarity === 'rare') rarityColor = 0x0000FF;
+ if (rarity === 'epic') rarityColor = 0xFF00FF;
+ if (rarity === 'legendary') rarityColor = 0xFFD700;
+ // Make rarer creatures slightly larger
+ var scale = 1.0;
+ if (rarity === 'uncommon') scale = 1.1;
+ if (rarity === 'rare') scale = 1.2;
+ if (rarity === 'epic') scale = 1.3;
+ if (rarity === 'legendary') scale = 1.5;
+ creatureGraphic.scale.set(scale, scale);
+ cell.addChild(creatureGraphic);
+ // Add info text
+ var infoText = new Text2(type.toUpperCase() + '\n' + rarity.toUpperCase(), {
+ size: 30,
+ fill: 0xFFFFFF
+ });
+ infoText.anchor.set(0.5, 0);
+ infoText.x = cellSize / 2;
+ infoText.y = cellSize / 2 + 40;
+ cell.addChild(infoText);
+ } else {
+ // Undiscovered creature (shadow)
+ var undiscoveredGraphic = LK.getAsset(type + 'Creature', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: cellSize / 2,
+ y: cellSize / 2
+ });
+ undiscoveredGraphic.alpha = 0.2;
+ undiscoveredGraphic.tint = 0x000000;
+ cell.addChild(undiscoveredGraphic);
+ // Add question mark
+ var questionText = new Text2('?', {
+ size: 60,
+ fill: 0x999999
+ });
+ questionText.anchor.set(0.5, 0.5);
+ questionText.x = cellSize / 2;
+ questionText.y = cellSize / 2;
+ cell.addChild(questionText);
+ }
+ }
+ }
+ };
+ // Hide collection screen
+ self.hide = function () {
+ self.visible = false;
+ };
+ return self;
+});
+// Game dimensions and settings
+// Creature class for encounters
+var Creature = Container.expand(function () {
+ var self = Container.call(this);
+ // Creature properties
+ self.type = 'normal'; // Default type
+ self.rarity = 'common'; // Default rarity
+ self.gridX = 0;
+ self.gridY = 0;
+ self.captured = false;
+ // Rarity colors
+ self.rarityColors = {
+ common: 0xFFFFFF,
+ uncommon: 0x00FF00,
+ rare: 0x0000FF,
+ epic: 0xFF00FF,
+ legendary: 0xFFD700
+ };
+ // Type to biome mapping
+ self.typeBiomeMap = {
+ bug: 'forest',
+ dark: 'mountain',
+ dragon: 'mountain',
+ electric: 'grass',
+ fairy: 'forest',
+ fighting: 'mountain',
+ fire: 'desert',
+ flying: 'grass',
+ ghost: 'mountain',
+ grass: 'grass',
+ ground: 'desert',
+ ice: 'mountain',
+ normal: 'grass',
+ poison: 'forest',
+ psychic: 'grass',
+ rock: 'mountain',
+ steel: 'mountain',
+ water: 'water'
+ };
+ // Initialize creature with specific type, rarity, and position
+ self.init = function (type, rarity, gridX, gridY) {
+ self.type = type || self.getRandomType();
+ self.rarity = rarity || self.getRandomRarity();
+ self.gridX = gridX;
+ self.gridY = gridY;
+ // Create creature graphic
+ var creatureGraphics = self.attachAsset(self.type + 'Creature', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Apply rarity visual effect (glow or color)
+ var rarityColor = self.rarityColors[self.rarity] || 0xFFFFFF;
+ // Add glow effect for rare+ creatures
+ if (self.rarity !== 'common') {
+ // Make rarer creatures slightly larger
+ var scale = 1.0;
+ if (self.rarity === 'uncommon') scale = 1.1;
+ if (self.rarity === 'rare') scale = 1.2;
+ if (self.rarity === 'epic') scale = 1.3;
+ if (self.rarity === 'legendary') scale = 1.5;
+ creatureGraphics.scale.set(scale, scale);
+ }
+ // Position creature
+ self.x = self.gridX * 100 + 50; // Center of tile
+ self.y = self.gridY * 100 + 50; // Center of tile
+ return self;
+ };
+ // Generate a random creature type, weighted by biome
+ self.getRandomType = function (biome) {
+ // Default types for each biome
+ var biomeTypes = {
+ grass: ['normal', 'grass', 'bug', 'flying', 'electric', 'psychic'],
+ water: ['water', 'ice', 'flying'],
+ desert: ['ground', 'fire', 'rock'],
+ forest: ['bug', 'grass', 'poison', 'fairy'],
+ mountain: ['rock', 'fighting', 'dragon', 'dark', 'ghost', 'steel', 'ice']
+ };
+ // Get types for the provided biome, or use all types
+ var types = biome ? biomeTypes[biome] : Object.keys(self.typeBiomeMap);
+ // Select random type from available options
+ return types[Math.floor(Math.random() * types.length)];
+ };
+ // Generate a random rarity based on configured probabilities
+ self.getRandomRarity = function () {
+ var rand = Math.random();
+ if (rand < 0.65) return 'common';
+ if (rand < 0.85) return 'uncommon';
+ if (rand < 0.95) return 'rare';
+ if (rand < 0.99) return 'epic';
+ return 'legendary';
+ };
+ // Animate creature during encounter
+ self.animate = function () {
+ // Bounce animation
+ var originalY = self.y;
+ // Use tween to create a bouncing effect
+ tween(self, {
+ y: originalY - 20
+ }, {
+ duration: 500,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(self, {
+ y: originalY
+ }, {
+ duration: 500,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ // Repeat animation
+ self.animate();
+ }
+ });
+ }
+ });
+ };
+ // Stop animations
+ self.stopAnimation = function () {
+ tween.stop(self, {
+ y: true
+ });
+ };
+ return self;
+});
+// Directional pad control for player movement
+var DPad = Container.expand(function () {
+ var self = Container.call(this);
+ // DPad components
+ self.padBase = null;
+ self.upButton = null;
+ self.downButton = null;
+ self.leftButton = null;
+ self.rightButton = null;
+ // Initialize dpad with buttons
+ self.init = function () {
+ // Create base of DPad
+ self.padBase = self.attachAsset('dpad', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Create directional buttons
+ self.upButton = self.createButton(0, -65);
+ self.downButton = self.createButton(0, 65);
+ self.leftButton = self.createButton(-65, 0);
+ self.rightButton = self.createButton(65, 0);
+ // Position the entire DPad in the bottom left of the screen
+ self.x = 200;
+ self.y = 2500;
+ return self;
+ };
+ // Create a directional button at relative x,y from center
+ self.createButton = function (relX, relY) {
+ var button = self.attachAsset('dpadButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: relX,
+ y: relY
+ });
+ button.interactive = true;
+ return button;
+ };
+ return self;
+});
+// Encounter class to handle creature encounters
+var Encounter = Container.expand(function () {
+ var self = Container.call(this);
+ // Encounter state
+ self.active = false;
+ self.creature = null;
+ self.captureRing = null;
+ self.captureTarget = null;
+ self.targetSpeed = 5;
+ self.targetDirection = 1;
+ self.captureAttempts = 0;
+ self.maxAttempts = 3;
+ // Initialize encounter screen
+ self.init = function () {
+ // Darkened background
+ var bg = self.attachAsset('grassTile', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 2048,
+ height: 2732
+ });
+ bg.alpha = 0.7;
+ bg.tint = 0x000000;
+ // Initially hidden
+ self.visible = false;
+ return self;
+ };
+ // Start encounter with a specific creature
+ self.startEncounter = function (creature) {
+ self.active = true;
+ self.visible = true;
+ self.creature = creature;
+ self.captureAttempts = 0;
+ // Add creature to encounter screen
+ self.addChild(creature);
+ creature.x = 1024; // Center horizontally
+ creature.y = 1000; // Position in upper portion of screen
+ // Start creature animation
+ creature.animate();
+ // Create capture interface
+ self.createCaptureInterface();
+ // Play encounter sound
+ LK.getSound('encounter').play();
+ };
+ // Create the capture ring and target interface
+ self.createCaptureInterface = function () {
+ // Capture ring
+ self.captureRing = self.attachAsset('captureRing', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ // Center horizontally
+ y: 1800 // Lower portion of screen
+ });
+ // Moving target
+ self.captureTarget = self.attachAsset('captureTarget', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 964,
+ // Start position (left side of ring)
+ y: 1800 // Same Y as ring
+ });
+ // Capture button
+ var captureButton = self.attachAsset('grassTile', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 2200,
+ width: 300,
+ height: 100
+ });
+ captureButton.tint = 0xFF0000;
+ // Capture button text
+ var captureText = new Text2('CAPTURE', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ captureText.anchor.set(0.5, 0.5);
+ captureText.x = 1024;
+ captureText.y = 2200;
+ self.addChild(captureText);
+ // Capture button event
+ captureButton.interactive = true;
+ captureButton.down = function () {
+ self.attemptCapture();
+ };
+ // Info text about the creature
+ var infoText = new Text2('TYPE: ' + self.creature.type.toUpperCase() + '\n' + 'RARITY: ' + self.creature.rarity.toUpperCase() + '\n' + 'ATTEMPTS: ' + (self.maxAttempts - self.captureAttempts) + ' REMAINING', {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ infoText.anchor.set(0.5, 0);
+ infoText.x = 1024;
+ infoText.y = 2300;
+ self.addChild(infoText);
+ };
+ // Update function for moving the target
+ self.update = function () {
+ if (!self.active || !self.captureTarget) return;
+ // Move target back and forth across the ring
+ self.captureTarget.x += self.targetSpeed * self.targetDirection;
+ // Reverse direction at edges
+ if (self.captureTarget.x > 1084) {
+ // Right edge of ring
+ self.targetDirection = -1;
+ } else if (self.captureTarget.x < 964) {
+ // Left edge of ring
+ self.targetDirection = 1;
+ }
+ // Make target move faster based on creature rarity
+ var speedMultiplier = 1;
+ if (self.creature) {
+ if (self.creature.rarity === 'uncommon') speedMultiplier = 1.2;
+ if (self.creature.rarity === 'rare') speedMultiplier = 1.5;
+ if (self.creature.rarity === 'epic') speedMultiplier = 1.8;
+ if (self.creature.rarity === 'legendary') speedMultiplier = 2.2;
+ }
+ self.targetSpeed = 5 * speedMultiplier;
+ };
+ // Attempt to capture the creature
+ self.attemptCapture = function () {
+ // Play capture sound
+ LK.getSound('capture').play();
+ self.captureAttempts++;
+ // Check if target is in center zone (successful capture)
+ var distanceFromCenter = Math.abs(self.captureTarget.x - 1024);
+ var successZone = 15; // Size of "perfect" zone
+ // Adjust success zone based on rarity (harder for rarer creatures)
+ if (self.creature.rarity === 'uncommon') successZone = 13;
+ if (self.creature.rarity === 'rare') successZone = 10;
+ if (self.creature.rarity === 'epic') successZone = 8;
+ if (self.creature.rarity === 'legendary') successZone = 5;
+ var captured = distanceFromCenter <= successZone;
+ if (captured) {
+ // Success!
+ self.captureSuccess();
+ } else if (self.captureAttempts >= self.maxAttempts) {
+ // Failed after max attempts
+ self.captureFail();
+ } else {
+ // Update attempts remaining text
+ var remainingText = self.children.filter(function (child) {
+ return child instanceof Text2 && child.y === 2300;
+ })[0];
+ if (remainingText) {
+ remainingText.setText('TYPE: ' + self.creature.type.toUpperCase() + '\n' + 'RARITY: ' + self.creature.rarity.toUpperCase() + '\n' + 'ATTEMPTS: ' + (self.maxAttempts - self.captureAttempts) + ' REMAINING');
+ }
+ }
+ };
+ // Handle successful capture
+ self.captureSuccess = function () {
+ // Play success sound
+ LK.getSound('success').play();
+ // Add to collection
+ if (!storage.discoveredCreatures) {
+ storage.discoveredCreatures = {};
+ }
+ var creatureKey = self.creature.type + '-' + self.creature.rarity;
+ storage.discoveredCreatures[creatureKey] = true;
+ // Show success message
+ var successText = new Text2('CAPTURED!', {
+ size: 100,
+ fill: 0x00FF00
+ });
+ successText.anchor.set(0.5, 0.5);
+ successText.x = 1024;
+ successText.y = 1400;
+ self.addChild(successText);
+ // Flash screen
+ LK.effects.flashScreen(0x00FF00, 500);
+ // End encounter after delay
+ LK.setTimeout(function () {
+ self.endEncounter();
+ }, 1500);
+ };
+ // Handle failed capture
+ self.captureFail = function () {
+ // Show fail message
+ var failText = new Text2('ESCAPED!', {
+ size: 100,
+ fill: 0xFF0000
+ });
+ failText.anchor.set(0.5, 0.5);
+ failText.x = 1024;
+ failText.y = 1400;
+ self.addChild(failText);
+ // Flash screen
+ LK.effects.flashScreen(0xFF0000, 500);
+ // End encounter after delay
+ LK.setTimeout(function () {
+ self.endEncounter();
+ }, 1500);
+ };
+ // End the current encounter
+ self.endEncounter = function () {
+ if (self.creature) {
+ self.creature.stopAnimation();
+ }
+ self.active = false;
+ self.visible = false;
+ // Remove all children
+ while (self.children.length > 0) {
+ self.removeChild(self.children[0]);
+ }
+ self.creature = null;
+ self.captureRing = null;
+ self.captureTarget = null;
+ // Reinitialize for next encounter
+ self.init();
+ };
+ return self;
+});
+// GameMap represents the entire game map with different biomes
+var GameMap = Container.expand(function () {
+ var self = Container.call(this);
+ self.mapWidth = 30; // Number of tiles horizontally
+ self.mapHeight = 30; // Number of tiles vertically
+ self.tileSize = 100; // Size of each tile in pixels
+ self.tiles = []; // 2D array to hold all map tiles
+ // Biome generation parameters
+ self.biomeTypes = ['grass', 'water', 'desert', 'forest', 'mountain'];
+ self.biomeSeeds = []; // Points from which biomes spread
+ // Initialize map with biomes
+ self.initMap = function () {
+ // Create empty 2D array for tiles
+ for (var y = 0; y < self.mapHeight; y++) {
+ self.tiles[y] = [];
+ for (var x = 0; x < self.mapWidth; x++) {
+ self.tiles[y][x] = null;
+ }
+ }
+ // Place biome seeds
+ self.placeBiomeSeeds();
+ // Generate biomes from seeds
+ self.generateBiomes();
+ // Create tiles based on biome map
+ self.createTiles();
+ return self;
+ };
+ // Place seed points for biome generation
+ self.placeBiomeSeeds = function () {
+ // Place one seed for each biome
+ for (var i = 0; i < self.biomeTypes.length; i++) {
+ var seed = {
+ x: Math.floor(Math.random() * self.mapWidth),
+ y: Math.floor(Math.random() * self.mapHeight),
+ biome: self.biomeTypes[i]
+ };
+ self.biomeSeeds.push(seed);
+ }
+ };
+ // Generate biomes from seed points using a simple distance-based algorithm
+ self.generateBiomes = function () {
+ for (var y = 0; y < self.mapHeight; y++) {
+ for (var x = 0; x < self.mapWidth; x++) {
+ // Find closest biome seed
+ var closestDist = Number.MAX_VALUE;
+ var closestBiome = 'grass'; // Default
+ for (var i = 0; i < self.biomeSeeds.length; i++) {
+ var seed = self.biomeSeeds[i];
+ var dist = Math.sqrt(Math.pow(x - seed.x, 2) + Math.pow(y - seed.y, 2));
+ // Add some randomness to make borders less regular
+ dist += Math.random() * 3 - 1.5;
+ if (dist < closestDist) {
+ closestDist = dist;
+ closestBiome = seed.biome;
+ }
+ }
+ self.tiles[y][x] = closestBiome;
+ }
+ }
+ // Add some randomness and blending between biomes
+ self.refineBiomes();
+ };
+ // Add more natural transitions between biomes
+ self.refineBiomes = function () {
+ var tempTiles = JSON.parse(JSON.stringify(self.tiles));
+ for (var y = 1; y < self.mapHeight - 1; y++) {
+ for (var x = 1; x < self.mapWidth - 1; x++) {
+ // Count neighboring biomes
+ var biomeCount = {};
+ for (var ny = y - 1; ny <= y + 1; ny++) {
+ for (var nx = x - 1; nx <= x + 1; nx++) {
+ var neighborBiome = tempTiles[ny][nx];
+ if (!biomeCount[neighborBiome]) {
+ biomeCount[neighborBiome] = 0;
+ }
+ biomeCount[neighborBiome]++;
+ }
+ }
+ // Random chance to convert to most common neighbor
+ if (Math.random() < 0.4) {
+ var mostCommon = tempTiles[y][x];
+ var maxCount = 0;
+ for (var biome in biomeCount) {
+ if (biomeCount[biome] > maxCount) {
+ maxCount = biomeCount[biome];
+ mostCommon = biome;
+ }
+ }
+ self.tiles[y][x] = mostCommon;
+ }
+ }
+ }
+ };
+ // Create actual tile objects based on the biome map
+ self.createTiles = function () {
+ for (var y = 0; y < self.mapHeight; y++) {
+ for (var x = 0; x < self.mapWidth; x++) {
+ var biomeType = self.tiles[y][x];
+ var tile = new MapTile().initTile(biomeType, x, y);
+ self.addChild(tile);
+ }
+ }
+ };
+ // Get tile at grid coordinates
+ self.getTileAt = function (gridX, gridY) {
+ // Ensure coordinates are within bounds
+ if (gridX < 0 || gridX >= self.mapWidth || gridY < 0 || gridY >= self.mapHeight) {
+ return null;
+ }
+ // Find the tile in the children
+ for (var i = 0; i < self.children.length; i++) {
+ var tile = self.children[i];
+ if (tile.gridX === gridX && tile.gridY === gridY) {
+ return tile;
+ }
+ }
+ return null;
+ };
+ return self;
+});
+// MapTile represents a single tile in the game grid
+var MapTile = Container.expand(function () {
+ var self = Container.call(this);
+ self.biomeType = 'grass'; // Default biome
+ self.tileSize = 100;
+ self.hasCreature = false;
+ self.explored = false;
+ self.x = 0;
+ self.y = 0;
+ self.gridX = 0;
+ self.gridY = 0;
+ // Initialize the tile with a specific biome
+ self.initTile = function (biomeType, gridX, gridY) {
+ self.biomeType = biomeType;
+ self.gridX = gridX;
+ self.gridY = gridY;
+ self.x = gridX * self.tileSize;
+ self.y = gridY * self.tileSize;
+ // Get the appropriate tile asset based on biome
+ var assetId = self.biomeType + 'Tile';
+ var tileGraphics = self.attachAsset(assetId, {
+ anchorX: 0,
+ anchorY: 0
+ });
+ // Add lighter border for visibility
+ tileGraphics.alpha = 0.9;
+ // Random chance to spawn a creature based on biome
+ if (Math.random() < 0.15) {
+ self.hasCreature = true;
+ var indicator = self.attachAsset('encounterIndicator', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: self.tileSize / 2,
+ y: self.tileSize / 2
+ });
+ indicator.alpha = 0.7;
+ }
+ return self;
+ };
+ // Mark tile as explored
+ self.explore = function () {
+ if (!self.explored) {
+ self.explored = true;
+ // Add to explored areas in storage
+ var exploredKey = self.gridX + "," + self.gridY;
+ if (!storage.exploredTiles) storage.exploredTiles = {};
+ storage.exploredTiles[exploredKey] = true;
+ }
+ };
+ return self;
+});
+// MiniMap class to show explored areas
+var MiniMap = Container.expand(function () {
+ var self = Container.call(this);
+ // MiniMap components
+ self.mapBackground = null;
+ self.playerMarker = null;
+ self.tileMarkers = [];
+ self.mapSize = 300;
+ self.scale = 0.1; // How much of the full map to show
+ // Initialize minimap
+ self.init = function () {
+ // Create background
+ self.mapBackground = self.attachAsset('minimap', {
+ anchorX: 0,
+ anchorY: 0,
+ width: self.mapSize,
+ height: self.mapSize
+ });
+ // Create player marker
+ self.playerMarker = self.attachAsset('minimapMarker', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: self.mapSize / 2,
+ y: self.mapSize / 2
+ });
+ // Position minimap in top right corner
+ self.x = 2048 - self.mapSize - 20;
+ self.y = 20;
+ return self;
+ };
+ // Update minimap with current player position and explored tiles
+ self.update = function (player, gameMap) {
+ // Update player marker position
+ var centerX = self.mapSize / 2;
+ var centerY = self.mapSize / 2;
+ // Position marker relative to center
+ self.playerMarker.x = centerX;
+ self.playerMarker.y = centerY;
+ // Clear existing tile markers
+ for (var i = 0; i < self.tileMarkers.length; i++) {
+ self.removeChild(self.tileMarkers[i]);
+ }
+ self.tileMarkers = [];
+ // Add markers for visible tiles around player
+ var visibleRadius = Math.floor(self.mapSize / (2 * 10)); // 10px per tile
+ for (var y = player.gridY - visibleRadius; y <= player.gridY + visibleRadius; y++) {
+ for (var x = player.gridX - visibleRadius; x <= player.gridX + visibleRadius; x++) {
+ var tile = gameMap.getTileAt(x, y);
+ if (tile && tile.explored) {
+ // Create marker with biome color
+ var color = 0x33cc33; // Default grass
+ if (tile.biomeType === 'water') color = 0x3399ff;
+ if (tile.biomeType === 'desert') color = 0xe6cc99;
+ if (tile.biomeType === 'forest') color = 0x006600;
+ if (tile.biomeType === 'mountain') color = 0x999999;
+ var marker = new Container();
+ var markerGraphics = LK.getAsset('grassTile', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 10,
+ height: 10
+ });
+ markerGraphics.tint = color;
+ marker.addChild(markerGraphics);
+ // Position marker relative to player
+ marker.x = centerX + (x - player.gridX) * 10;
+ marker.y = centerY + (y - player.gridY) * 10;
+ self.addChild(marker);
+ self.tileMarkers.push(marker);
+ }
+ }
+ }
+ };
+ return self;
+});
+// Player character
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ // Player properties
+ self.gridX = 10; // Starting X position on grid
+ self.gridY = 10; // Starting Y position on grid
+ self.moveSpeed = 0.2; // Movement animation speed
+ self.moving = false;
+ self.lastGridX = 10;
+ self.lastGridY = 10;
+ // Initialize player with graphics
+ self.init = function () {
+ var playerGraphics = self.attachAsset('player', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Load position from storage if available
+ if (storage.playerPosition) {
+ self.gridX = storage.playerPosition.x;
+ self.gridY = storage.playerPosition.y;
+ self.lastGridX = self.gridX;
+ self.lastGridY = self.gridY;
+ }
+ // Update position based on grid coordinates
+ self.updatePosition();
+ return self;
+ };
+ // Move player to specific grid coordinates
+ self.moveToGrid = function (newGridX, newGridY) {
+ if (self.moving) return; // Don't interrupt current movement
+ // Store last position for comparison
+ self.lastGridX = self.gridX;
+ self.lastGridY = self.gridY;
+ // Update grid position
+ self.gridX = newGridX;
+ self.gridY = newGridY;
+ // Save position to storage
+ storage.playerPosition = {
+ x: self.gridX,
+ y: self.gridY
+ };
+ // Animate movement
+ self.moving = true;
+ var targetX = self.gridX * 100 + 50; // Center of tile
+ var targetY = self.gridY * 100 + 50; // Center of tile
+ tween(self, {
+ x: targetX,
+ y: targetY
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.moving = false;
+ }
+ });
+ };
+ // Update position based on current grid coordinates (no animation)
+ self.updatePosition = function () {
+ self.x = self.gridX * 100 + 50; // Center of tile
+ self.y = self.gridY * 100 + 50; // Center of tile
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/****
+* Game Code
+****/
+// Game dimensions and settings
+// Tween for animations
+// Storage for saving game progress
+// Player character
+// Map tiles
+// Creatures by elemental type
+// UI elements
+// Encounter indicator
+// Sounds
+var TILE_SIZE = 100;
+var MAP_WIDTH = 30;
+var MAP_HEIGHT = 30;
+// Initialize game objects
+var gameMap = game.addChild(new GameMap().initMap());
+var player = game.addChild(new Player().init());
+var dpad = game.addChild(new DPad().init());
+var minimap = game.addChild(new MiniMap().init());
+var encounter = game.addChild(new Encounter().init());
+var collection = game.addChild(new Collection().init());
+// Collection button (top right corner)
+var collectionButton = game.attachAsset('dpadButton', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1900,
+ y: 150
+});
+collectionButton.interactive = true;
+// Collection button icon
+var collectionText = new Text2('COL', {
+ size: 30,
+ fill: 0xFFFFFF
+});
+collectionText.anchor.set(0.5, 0.5);
+collectionText.x = 1900;
+collectionText.y = 150;
+game.addChild(collectionText);
+// Game stats text display
+var statsText = new Text2('Collected: 0/90\nExplored: 0%', {
+ size: 40,
+ fill: 0xFFFFFF
+});
+statsText.anchor.set(0, 0);
+statsText.x = 150;
+statsText.y = 50;
+game.addChild(statsText);
+// Game variables
+var encounterActive = false;
+var exploredCount = 0;
+var totalTiles = MAP_WIDTH * MAP_HEIGHT;
+// Update stats display
+function updateStats() {
+ var discoveredCount = Object.keys(storage.discoveredCreatures || {}).length;
+ var exploredPercent = Math.floor(exploredCount / totalTiles * 100);
+ statsText.setText('Collected: ' + discoveredCount + '/90\n' + 'Explored: ' + exploredPercent + '%');
+}
+// Center the game view on player
+function centerViewOnPlayer() {
+ // Calculate offset to center player
+ var offsetX = 1024 - player.x;
+ var offsetY = 1366 - player.y;
+ // Move map to center player
+ gameMap.x = offsetX;
+ gameMap.y = offsetY;
+}
+// Handle player movement from DPad
+dpad.upButton.down = function () {
+ if (!encounterActive && !player.moving) {
+ var newY = player.gridY - 1;
+ if (newY >= 0) {
+ player.moveToGrid(player.gridX, newY);
+ }
+ }
+};
+dpad.downButton.down = function () {
+ if (!encounterActive && !player.moving) {
+ var newY = player.gridY + 1;
+ if (newY < MAP_HEIGHT) {
+ player.moveToGrid(player.gridX, newY);
+ }
+ }
+};
+dpad.leftButton.down = function () {
+ if (!encounterActive && !player.moving) {
+ var newX = player.gridX - 1;
+ if (newX >= 0) {
+ player.moveToGrid(newX, player.gridY);
+ }
+ }
+};
+dpad.rightButton.down = function () {
+ if (!encounterActive && !player.moving) {
+ var newX = player.gridX + 1;
+ if (newX < MAP_WIDTH) {
+ player.moveToGrid(newX, player.gridY);
+ }
+ }
+};
+// Handle collection button
+collectionButton.down = function () {
+ if (!encounterActive) {
+ collection.show();
+ }
+};
+// Handle collection close button
+collection.closeButton.down = function () {
+ collection.hide();
+};
+// Track last player position to detect changes
+var lastPlayerGridX = player.gridX;
+var lastPlayerGridY = player.gridY;
+// Main game update loop
+game.update = function () {
+ // Skip updates if in an active encounter
+ if (encounterActive) {
+ encounter.update();
+ return;
+ }
+ // Check if collection is visible
+ if (collection.visible) {
+ return;
+ }
+ // Center view on player
+ centerViewOnPlayer();
+ // Update minimap
+ minimap.update(player, gameMap);
+ // Check if player has moved to a new tile
+ if (player.gridX !== lastPlayerGridX || player.gridY !== lastPlayerGridY) {
+ // Get the current tile
+ var currentTile = gameMap.getTileAt(player.gridX, player.gridY);
+ if (currentTile) {
+ // Mark tile as explored if it's new
+ if (!currentTile.explored) {
+ currentTile.explore();
+ exploredCount++;
+ updateStats();
+ }
+ // Check for creature encounter
+ if (currentTile.hasCreature && Math.random() < 0.7) {
+ // 70% chance to trigger encounter
+ // Start encounter
+ encounterActive = true;
+ // Create creature based on biome
+ var creatureType = new Creature().getRandomType(currentTile.biomeType);
+ var creature = new Creature().init(creatureType, null, player.gridX, player.gridY);
+ // Start encounter with this creature
+ encounter.startEncounter(creature);
+ // Remove creature from tile
+ currentTile.hasCreature = false;
+ // Remove indicator from tile
+ for (var i = 0; i < currentTile.children.length; i++) {
+ var child = currentTile.children[i];
+ if (child.assetId === 'encounterIndicator') {
+ currentTile.removeChild(child);
+ break;
+ }
+ }
+ }
+ }
+ // Update last position
+ lastPlayerGridX = player.gridX;
+ lastPlayerGridY = player.gridY;
+ }
+};
+// Listen for encounter end
+var checkEncounterInterval = LK.setInterval(function () {
+ if (encounterActive && !encounter.active) {
+ encounterActive = false;
+ updateStats();
+ }
+}, 100);
+// Initialize stats
+updateStats();
+// Initial centering
+centerViewOnPlayer();
\ No newline at end of file
water tile just water and top viewing. In-Game asset. 2d
dpad. In-Game asset. 2d. High contrast. No shadows
red button square. In-Game asset. 2d. High contrast. No shadows
grass tile on top viewing. In-Game asset. 2d. High contrast. No shadows
Mountain tile on top viewing. In-Game asset. 2d
sand tile on top viewing. In-Game asset. 2d. High contrast. No shadows
forest tile on top viewing. In-Game asset. 2d. No shadows
square grass tile on top viewing. In-Game asset. 2d. High contrast. No shadows
urban tile on viewing. In-Game asset. 2d
street tile on top viewing. In-Game asset. 2d. High contrast
street tile on top viewing with street way. In-Game asset. 2d
street tile on top viewing with street way horizontal. In-Game asset. 2d. High contrast. No shadows
make creature image for grass elemental name is sproutle. In-Game asset. 2d. High contrast. No shadows
make creature image for rock elemental name is boulder but dont write name on image. In-Game asset. 2d. High contrast. No shadows
make creature image for electrical elemental name is voltix but dont write name on image. In-Game asset. 2d. High contrast. No shadows
player human viewing on behind of him with all of body. In-Game asset. 2d
make a cube but like a pokeball and change the colour of original and make it the basic one make with purple and yellow but do diffrently. In-Game asset. 2d. High contrast. No shadows
make a cube but like a pokeball and make it the legendary one make with red and golden and blue but do diffrently. In-Game asset. 2d. High contrast. No shadows
make a cube but like a pokeball and make it for rare one make with grey and silver and white but do diffrently. In-Game asset. 2d. High contrast. No shadows
make a cube but like a pokeball and make it for uncommon one make with green and white and bronze but do diffrently. In-Game asset. 2d. High contrast. No shadows