User prompt
When im on the creatures place i didnt trying to catch it
User prompt
Between 4 tiles has black dot it looking they dinidt connected fix it
User prompt
Between 2 tiles has black line it looking they dinidt connected fx it
User prompt
Make vision angle smaller and center it for player
User prompt
Player can spawn randomly on map ehen game started
User prompt
Make the player moves half and when coordinates changes by 1 make it there one tiles so i mean change the size of it for it
User prompt
Player moving is too lot make it less step and when it moves it will moves to center of tile where it go
User prompt
When player moved make sure is there center of the tiles its has to be
User prompt
They it says down right or wherever it is its totaly wrong make less move
User prompt
When player move somewhere do sure for is there down left for one tile or up right or or
User prompt
One tile is not looking like same but divided by 4 for movingfor correct place
User prompt
Make all tile assests to optimize that
User prompt
Change the coordinates to 0,0 and do on left up quadrant of one tile part if u could do change the tiles size for it
User prompt
Place the player on 0,0 coordinates when game starting and 0,0 coordinate has to be one grass tiles on down left
User prompt
İ cannot see the player
User prompt
When player moved up or right or left or down its not looking like one tile divided by 4
User prompt
When im looking the tiles position of tile is not looking like where i am it says
User prompt
Make one tiles divided by 4 and show me where i am on it up right up left down right or down left
User prompt
Make that map biggest ever
User prompt
Player moving make normal not slower
User prompt
On map do all tiles diveded by 4 for moving
User prompt
Optimize the where creatures are spawning with player moves they can cross it
User prompt
When o clicked the gamepad move it but player moves half of it
User prompt
Can we get slower to the player moving
User prompt
Optimize the game about in vision are dont care in foggy place just dont show them if it there and make spawn rate more less for all creatures
/****
* 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();
};
// Leave button
var leaveButton = self.attachAsset('grassTile', {
anchorX: 0.5,
anchorY: 0.5,
x: 1700,
y: 2200,
width: 300,
height: 100
});
leaveButton.tint = 0x888888;
var leaveText = new Text2('LEAVE', {
size: 60,
fill: 0xFFFFFF
});
leaveText.anchor.set(0.5, 0.5);
leaveText.x = 1700;
leaveText.y = 2200;
self.addChild(leaveText);
leaveButton.interactive = true;
leaveButton.down = function () {
// End encounter immediately, treat as fail/escape
self.endEncounter();
};
// 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();
// Also set encounterActive to false so game resumes
if (typeof encounterActive !== "undefined") {
encounterActive = false;
}
};
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 (max size)
self.mapHeight = 30; // Number of tiles vertically (max size)
self.tileSize = 140; // 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 () {
// Create a deep copy of tiles array
var tempTiles = [];
for (var y = 0; y < self.mapHeight; y++) {
tempTiles[y] = [];
for (var x = 0; x < self.mapWidth; x++) {
tempTiles[y][x] = self.tiles[y][x];
}
}
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++) {
// Check that neighbor coordinates are valid
if (ny >= 0 && ny < self.mapHeight && nx >= 0 && nx < self.mapWidth) {
var neighborBiome = tempTiles[ny][nx];
if (neighborBiome) {
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.hasOwnProperty(biome) && 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;
// Add fog overlay for undiscovered tiles
self.fogOverlay = self.attachAsset('grassTile', {
anchorX: 0,
anchorY: 0,
width: self.tileSize,
height: self.tileSize
});
self.fogOverlay.alpha = 0.7;
self.fogOverlay.tint = 0x222222;
self.fogOverlay.visible = true;
// Random chance to spawn a creature based on biome (further reduced for less frequent spawning)
if (Math.random() < 0.02) {
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;
// Hide fog overlay if present
if (self.fogOverlay) {
self.fogOverlay.visible = false;
}
// 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) {
// Check if player and gameMap are defined
if (!player || !gameMap) return;
// 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 with integrated vision logic
var Player = Container.expand(function () {
var self = Container.call(this);
// Player properties
self.gridX = 10; // Starting X position on grid (max map)
self.gridY = 10; // Starting Y position on grid (max map)
self.moveSpeed = 0.2; // Movement animation speed
self.moving = false;
self.lastGridX = 10;
self.lastGridY = 10;
self.visionRadius = 3; // Vision radius in blocks
// New: sub-tile position (0=left, 1=right for X; 0=up, 1=down for Y)
self.subTileX = 0;
self.subTileY = 0;
// New: quadrant label
self.quadrantLabel = null;
// Initialize player with graphics
self.init = function () {
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Add quadrant label
self.quadrantLabel = new Text2('', {
size: 40,
fill: 0xffff00
});
self.quadrantLabel.anchor.set(0.5, 1);
self.quadrantLabel.x = 0;
self.quadrantLabel.y = -90;
self.addChild(self.quadrantLabel);
// 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;
self.subTileX = 0;
self.subTileY = 0;
}
// Update position based on grid coordinates
self.updatePosition();
return self;
};
// Move player to specific grid coordinates
self.moveToGrid = function (newGridX, newGridY, newSubTileX, newSubTileY) {
if (self.moving) return; // Don't interrupt current movement
// Default sub-tile values if not provided
if (typeof newSubTileX === "undefined") newSubTileX = 0;
if (typeof newSubTileY === "undefined") newSubTileY = 0;
// Clamp sub-tile values
if (newSubTileX < 0) newSubTileX = 0;
if (newSubTileX > 1) newSubTileX = 1;
if (newSubTileY < 0) newSubTileY = 0;
if (newSubTileY > 1) newSubTileY = 1;
// Store last position for comparison
self.lastGridX = self.gridX;
self.lastGridY = self.gridY;
// Prevent movement onto dark (black) blocks
if (typeof gameMap !== "undefined") {
var targetTile = gameMap.getTileAt(newGridX, newGridY);
if (targetTile && targetTile.biomeType === "dark") {
// Block movement, do not update grid position
return;
}
}
// Update grid and sub-tile position
self.gridX = newGridX;
self.gridY = newGridY;
self.subTileX = newSubTileX;
self.subTileY = newSubTileY;
// Save position to storage
storage.playerPosition = {
x: self.gridX,
y: self.gridY,
subTileX: self.subTileX,
subTileY: self.subTileY
};
// Animate movement and update vision after movement finishes
self.moving = true;
// Offset for sub-tile: 0=left/up, 1=right/down
// Each tile is divided into 4 quadrants: (0,0)=up left, (1,0)=up right, (0,1)=down left, (1,1)=down right
// So offsetX: 0 = -35, 1 = +35; offsetY: 0 = -35, 1 = +35 (centered in each quadrant)
var offsetX = self.subTileX === 0 ? -35 : 35;
var offsetY = self.subTileY === 0 ? -35 : 35;
var targetX = self.gridX * 100 + 50 + offsetX; // Center of tile + sub-tile offset
var targetY = self.gridY * 100 + 50 + offsetY; // Center of tile + sub-tile offset
// Animate vision update to be much faster than player movement
var visionTweenDuration = 250; // Vision moves much faster
var playerTweenDuration = 400; // Player moves at normal speed
// Start vision tween first
if (typeof gameMap !== "undefined" && typeof self.updateVision === "function") {
// Animate a dummy property to trigger vision update visually
var visionObj = {
progress: 0
};
tween(visionObj, {
progress: 1
}, {
duration: visionTweenDuration,
easing: tween.easeOut,
onUpdate: function onUpdate() {
// Update vision during tween for smooth effect
self.updateVision(gameMap);
}
});
}
// Then animate player movement
tween(self, {
x: targetX,
y: targetY
}, {
duration: playerTweenDuration,
// Slower movement (player is slower than vision)
easing: tween.easeOut,
onFinish: function onFinish() {
self.moving = false;
// Only update vision after movement is complete for optimized vision
if (typeof gameMap !== "undefined") {
self.updateVision(gameMap);
}
}
});
// Update quadrant label
var label = '';
if (self.subTileY === 0 && self.subTileX === 0) label = 'UP LEFT';else if (self.subTileY === 0 && self.subTileX === 1) label = 'UP RIGHT';else if (self.subTileY === 1 && self.subTileX === 0) label = 'DOWN LEFT';else if (self.subTileY === 1 && self.subTileX === 1) label = 'DOWN RIGHT';
if (self.quadrantLabel) self.quadrantLabel.setText(label);
};
// Update position based on current grid coordinates (no animation)
self.updatePosition = function () {
// Offset for sub-tile: 0=left/up, 1=right/down
// Each tile is divided into 4 quadrants: (0,0)=up left, (1,0)=up right, (0,1)=down left, (1,1)=down right
// So offsetX: 0 = -35, 1 = +35; offsetY: 0 = -35, 1 = +35 (centered in each quadrant)
var offsetX = self.subTileX === 0 ? -35 : 35;
var offsetY = self.subTileY === 0 ? -35 : 35;
self.x = self.gridX * 100 + 50 + offsetX; // Center of tile + sub-tile offset
self.y = self.gridY * 100 + 50 + offsetY; // Center of tile + sub-tile offset
// Hide player sprite if on dark (black) block
if (typeof gameMap !== "undefined") {
var tile = gameMap.getTileAt(self.gridX, self.gridY);
if (tile && tile.biomeType === "dark") {
self.visible = false;
} else {
self.visible = true;
// Mark this tile as discovered if not already
if (tile && !tile.explored) {
tile.explore();
}
}
}
// Only update vision if not moving, to optimize vision updates
if (!self.moving && typeof gameMap !== "undefined" && typeof self.updateVision === "function") {
self.updateVision(gameMap);
}
// Update quadrant label
var label = '';
if (self.subTileY === 0 && self.subTileX === 0) label = 'UP LEFT';else if (self.subTileY === 0 && self.subTileX === 1) label = 'UP RIGHT';else if (self.subTileY === 1 && self.subTileX === 0) label = 'DOWN LEFT';else if (self.subTileY === 1 && self.subTileX === 1) label = 'DOWN RIGHT';
if (self.quadrantLabel) self.quadrantLabel.setText(label);
};
// Update vision: show/hide tiles based on a larger vision angle, and save seen tiles as memory
self.updateVision = function (gameMap) {
// Vision area: always center player in the middle of the vision area for optimized movement
var visionRadius = 5; // Increased from 3 to 5 for bigger vision
var minX = Math.max(0, self.gridX - visionRadius);
var maxX = Math.min(MAP_WIDTH - 1, self.gridX + visionRadius);
var minY = Math.max(0, self.gridY - visionRadius);
var maxY = Math.min(MAP_HEIGHT - 1, self.gridY + visionRadius);
for (var y = 0; y < MAP_HEIGHT; y++) {
for (var x = 0; x < MAP_WIDTH; x++) {
var tile = gameMap.getTileAt(x, y);
if (tile) {
// Calculate distance from player
var dx = Math.abs(x - self.gridX);
var dy = Math.abs(y - self.gridY);
// Only show tiles within a diamond-shaped vision area (Manhattan distance <= visionRadius)
if (dx + dy <= visionRadius) {
tile.visible = true;
// Mark as explored and save to memory
if (!tile.explored) {
tile.explored = true;
var exploredKey = x + "," + y;
if (!storage.exploredTiles) storage.exploredTiles = {};
storage.exploredTiles[exploredKey] = true;
}
// Hide fog overlay if present (only for tiles currently in vision)
if (tile.fogOverlay) {
tile.fogOverlay.visible = false;
}
// --- Show both spawned and despawned creatures in vision ---
// In vision area: show both spawned and despawned creatures
// Remove all faded indicators first to avoid duplicates
for (var c = tile.children.length - 1; c >= 0; c--) {
if (tile.children[c].assetId === 'encounterIndicator' && tile.children[c].alpha === 0.25) {
tile.removeChild(tile.children[c]);
}
}
// If a creature is currently spawned, mark that this tile has ever had a creature
if (tile.hasCreature) {
tile._everHadCreature = true;
}
// Show indicator for spawned creature
if (tile.hasCreature) {
// If no indicator present, add one
var hasIndicator = false;
for (var c = 0; c < tile.children.length; c++) {
if (tile.children[c].assetId === 'encounterIndicator' && tile.children[c].alpha === 0.7) {
hasIndicator = true;
break;
}
}
if (!hasIndicator) {
var indicator = tile.attachAsset('encounterIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: tile.tileSize / 2,
y: tile.tileSize / 2
});
indicator.alpha = 0.7;
}
}
// Show faded indicator for despawned creature (if ever had creature, but not currently spawned)
if (tile._everHadCreature && !tile.hasCreature) {
var alreadyFaded = false;
for (var c = 0; c < tile.children.length; c++) {
if (tile.children[c].assetId === 'encounterIndicator' && tile.children[c].alpha === 0.25) {
alreadyFaded = true;
break;
}
}
if (!alreadyFaded) {
var fadedIndicator = tile.attachAsset('encounterIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: tile.tileSize / 2,
y: tile.tileSize / 2
});
fadedIndicator.alpha = 0.25;
}
}
// --- End show both spawned and despawned creatures in vision ---
} else {
// Out of vision: hide all encounter indicators (spawned and despawned) in foggy/unvision area
for (var c = tile.children.length - 1; c >= 0; c--) {
if (tile.children[c].assetId === 'encounterIndicator') {
tile.removeChild(tile.children[c]);
}
}
// Hide all creatures in foggy area: do not show any indicators or creatures
tile.visible = true;
// Show fog overlay for out-of-vision tiles
if (tile.fogOverlay) {
tile.fogOverlay.visible = true;
}
}
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Sounds
// Encounter indicator
// UI elements
// Creatures by elemental type
// Map tiles
// Player character
// Storage for saving game progress
// Tween for animations
// Game dimensions and settings
// JSON helper functions for parsing and stringifying
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
} : function (o) {
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
}, _typeof(o);
}
function parseJSON(str) {
var result = {};
if (typeof str === 'string') {
try {
var pairs = str.slice(1, -1).split(',');
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i].trim().split(':');
var key = pair[0].replace(/["']/g, '').trim();
var value = pair[1].trim();
if (value.startsWith('[') && value.endsWith(']')) {
result[key] = parseJSONArray(value);
} else if (value.startsWith('{') && value.endsWith('}')) {
result[key] = parseJSON(value);
} else if (value === 'true') {
result[key] = true;
} else if (value === 'false') {
result[key] = false;
} else if (!isNaN(value)) {
result[key] = Number(value);
} else {
result[key] = value.replace(/["']/g, '');
}
}
} catch (e) {
console.log('Error parsing JSON: ', e);
}
}
return result;
}
function parseJSONArray(str) {
var result = [];
if (typeof str === 'string') {
try {
var items = str.slice(1, -1).split(',');
for (var i = 0; i < items.length; i++) {
var item = items[i].trim();
if (item.startsWith('[') && item.endsWith(']')) {
result.push(parseJSONArray(item));
} else if (item.startsWith('{') && item.endsWith('}')) {
result.push(parseJSON(item));
} else if (item === 'true') {
result.push(true);
} else if (item === 'false') {
result.push(false);
} else if (!isNaN(item)) {
result.push(Number(item));
} else {
result.push(item.replace(/["']/g, ''));
}
}
} catch (e) {
console.log('Error parsing JSON array: ', e);
}
}
return result;
}
function stringifyJSON(obj) {
if (Array.isArray(obj)) {
var items = [];
for (var i = 0; i < obj.length; i++) {
items.push(stringifyJSON(obj[i]));
}
return '[' + items.join(',') + ']';
} else if (_typeof(obj) === 'object' && obj !== null) {
var pairs = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
pairs.push('"' + key + '":' + stringifyJSON(obj[key]));
}
}
return '{' + pairs.join(',') + '}';
} else if (typeof obj === 'string') {
return '"' + obj.replace(/"/g, '\\"') + '"';
} else {
return String(obj);
}
}
var TILE_SIZE = 140;
var MAP_WIDTH = 30;
var MAP_HEIGHT = 30;
// Initialize game objects
var gameMap = game.addChild(new GameMap().initMap());
gameMap.scale.set(1.5, 1.5);
// Set player to center of vision area at game start, but ensure not in a dark (black) area
var visionRadius = 5; // match Player.updateVision
var playerStartX = Math.floor(MAP_WIDTH / 2);
var playerStartY = Math.floor(MAP_HEIGHT / 2);
// If the center is a dark tile, find the nearest non-dark tile within vision area
if (typeof gameMap === "undefined") {
var gameMap = new GameMap().initMap();
}
var startTile = gameMap.getTileAt(playerStartX, playerStartY);
if (!startTile || startTile.biomeType === "dark") {
// Search outward in a spiral for the nearest non-dark tile within vision area
var found = false;
var maxRadius = visionRadius;
for (var r = 1; r <= maxRadius && !found; r++) {
for (var dx = -r; dx <= r; dx++) {
for (var dy = -r; dy <= r; dy++) {
if (Math.abs(dx) !== r && Math.abs(dy) !== r) continue; // Only check perimeter
var tx = playerStartX + dx;
var ty = playerStartY + dy;
var tile = gameMap.getTileAt(tx, ty);
if (tile && tile.biomeType !== "dark") {
playerStartX = tx;
playerStartY = ty;
found = true;
break;
}
}
if (found) break;
}
}
}
// Update storage and player position to match the valid starting tile
storage.playerPosition = {
x: playerStartX,
y: playerStartY
}; // Always start at center or nearest non-dark, non-water
var player = game.addChild(new Player().init());
player.gridX = playerStartX;
player.gridY = playerStartY;
player.lastGridX = playerStartX;
player.lastGridY = playerStartY;
player.updatePosition();
// Mark starting tile as explored and discovered
var startTile2 = gameMap.getTileAt(playerStartX, playerStartY);
if (startTile2 && !startTile2.explored) {
startTile2.explore();
}
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 (move exactly 1 block per input)
dpad.upButton.down = function () {
if (!encounterActive && !player.moving) {
// Move up within subtiles first, then to previous tile if at top
if (player.subTileY > 0) {
player.moveToGrid(player.gridX, player.gridY, player.subTileX, player.subTileY - 1);
} else {
var newY = player.gridY - 1;
if (newY >= 0) {
player.moveToGrid(player.gridX, newY, player.subTileX, 1);
}
}
}
};
dpad.downButton.down = function () {
if (!encounterActive && !player.moving) {
// Move down within subtiles first, then to next tile if at bottom
if (player.subTileY < 1) {
player.moveToGrid(player.gridX, player.gridY, player.subTileX, player.subTileY + 1);
} else {
var newY = player.gridY + 1;
if (newY < MAP_HEIGHT) {
player.moveToGrid(player.gridX, newY, player.subTileX, 0);
}
}
}
};
dpad.leftButton.down = function () {
if (!encounterActive && !player.moving) {
// Move left within subtiles first, then to previous tile if at left
if (player.subTileX > 0) {
player.moveToGrid(player.gridX, player.gridY, player.subTileX - 1, player.subTileY);
} else {
var newX = player.gridX - 1;
if (newX >= 0) {
player.moveToGrid(newX, player.gridY, 1, player.subTileY);
}
}
}
};
dpad.rightButton.down = function () {
if (!encounterActive && !player.moving) {
// Move right within subtiles first, then to next tile if at right
if (player.subTileX < 1) {
player.moveToGrid(player.gridX, player.gridY, player.subTileX + 1, player.subTileY);
} else {
var newX = player.gridX + 1;
if (newX < MAP_WIDTH) {
player.moveToGrid(newX, player.gridY, 0, player.subTileY);
}
}
}
};
// Always start the player centered in the vision area
player.gridX = playerStartX;
player.gridY = playerStartY;
player.lastGridX = playerStartX;
player.lastGridY = playerStartY;
player.updatePosition();
// 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
// Throttle update to 44FPS (every ~23ms)
var lastUpdateTime = 0;
game.update = function () {
var now = Date.now();
if (lastUpdateTime && now - lastUpdateTime < 23) {
return;
}
lastUpdateTime = now;
// --- Creature spawn/despawn logic ---
// We'll use a global array to track visible creatures on the map
if (typeof mapCreatures === "undefined") {
mapCreatures = [];
mapCreatureTiles = [];
mapCreatureLabels = [];
mapCreatureMax = 6; // Max creatures on map at once (reduced for harder spawning)
mapCreatureSpawnCooldown = 0;
}
// Despawn creatures sometimes (randomly, or if their tile is explored)
for (var i = mapCreatures.length - 1; i >= 0; i--) {
var tile = mapCreatureTiles[i];
// Despawn if tile is explored or random chance
if (!tile || tile.explored || Math.random() < 0.01) {
// Remove label if present
if (mapCreatureLabels[i]) {
tile && tile.removeChild(mapCreatureLabels[i]);
mapCreatureLabels.splice(i, 1);
}
// Remove indicator if present
if (tile && tile.hasCreature) {
tile.hasCreature = false;
// Remove encounterIndicator
for (var j = 0; j < tile.children.length; j++) {
if (tile.children[j].assetId === 'encounterIndicator') {
tile.removeChild(tile.children[j]);
break;
}
}
}
mapCreatures.splice(i, 1);
mapCreatureTiles.splice(i, 1);
continue;
}
}
// Spawn new creatures sometimes, up to max
if (mapCreatures.length < mapCreatureMax && mapCreatureSpawnCooldown <= 0) {
// Try to spawn a new creature
var tries = 0;
while (tries < 10 && mapCreatures.length < mapCreatureMax) {
var gx = Math.floor(Math.random() * MAP_WIDTH);
var gy = Math.floor(Math.random() * MAP_HEIGHT);
var tile = gameMap.getTileAt(gx, gy);
// Only spawn on tiles that are not explored, not dark, not already with a creature, and are crossable by the player
// Crossable: not water, not dark, not mountain (if you want to restrict more, add more biomeType checks)
var crossable = tile && tile.biomeType !== "dark";
// Optionally, restrict further: e.g. not water, not mountain
// crossable = crossable && tile.biomeType !== "water" && tile.biomeType !== "mountain";
if (tile && !tile.explored && !tile.hasCreature && crossable) {
// Mark tile as having a creature
tile.hasCreature = true;
// Add indicator
var indicator = tile.attachAsset('encounterIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: tile.tileSize / 2,
y: tile.tileSize / 2
});
indicator.alpha = 0.7;
// Pick a random type for this biome
var cType = new Creature().getRandomType(tile.biomeType);
mapCreatures.push(cType);
mapCreatureTiles.push(tile);
// No type label writing for bug ground type
mapCreatureLabels.push(null);
}
tries++;
}
// Add a much longer cooldown so we don't spawn every frame (increased for much less frequent spawning)
mapCreatureSpawnCooldown = 180 + Math.floor(Math.random() * 120); // 3-5s
} else {
mapCreatureSpawnCooldown--;
}
// --- End creature spawn/despawn logic ---
// 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);
// Vision update is now handled after player movement for optimization
// 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();
}
// Prevent encounters on dark (black) blocks
if (currentTile.biomeType !== "dark" && 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;
}
}
// Remove label if present (from mapCreatureLabels)
if (typeof mapCreatureTiles !== "undefined") {
for (var k = mapCreatureTiles.length - 1; k >= 0; k--) {
if (mapCreatureTiles[k] === currentTile) {
if (mapCreatureLabels[k]) {
currentTile.removeChild(mapCreatureLabels[k]);
mapCreatureLabels.splice(k, 1);
}
mapCreatures.splice(k, 1);
mapCreatureTiles.splice(k, 1);
break;
}
}
}
}
}
// Update last position
lastPlayerGridX = player.gridX;
lastPlayerGridY = player.gridY;
}
}; // End throttled update
// Listen for encounter end
var checkEncounterInterval = LK.setInterval(function () {
if (encounterActive && !encounter.active) {
encounterActive = false;
updateStats();
}
}, 100);
// Initialize stats
updateStats();
// Initial centering
centerViewOnPlayer();
// Fix: Only reveal vision area at game start, not the whole map
if (typeof player !== "undefined" && typeof gameMap !== "undefined" && typeof player.updateVision === "function") {
player.updateVision(gameMap);
}
// Vision mask overlay removed to fix black screen issue ===================================================================
--- original.js
+++ change.js
@@ -926,10 +926,12 @@
};
// Animate movement and update vision after movement finishes
self.moving = true;
// Offset for sub-tile: 0=left/up, 1=right/down
- var offsetX = self.subTileX === 0 ? -25 : 25;
- var offsetY = self.subTileY === 0 ? -25 : 25;
+ // Each tile is divided into 4 quadrants: (0,0)=up left, (1,0)=up right, (0,1)=down left, (1,1)=down right
+ // So offsetX: 0 = -35, 1 = +35; offsetY: 0 = -35, 1 = +35 (centered in each quadrant)
+ var offsetX = self.subTileX === 0 ? -35 : 35;
+ var offsetY = self.subTileY === 0 ? -35 : 35;
var targetX = self.gridX * 100 + 50 + offsetX; // Center of tile + sub-tile offset
var targetY = self.gridY * 100 + 50 + offsetY; // Center of tile + sub-tile offset
// Animate vision update to be much faster than player movement
var visionTweenDuration = 250; // Vision moves much faster
@@ -974,10 +976,12 @@
};
// Update position based on current grid coordinates (no animation)
self.updatePosition = function () {
// Offset for sub-tile: 0=left/up, 1=right/down
- var offsetX = self.subTileX === 0 ? -25 : 25;
- var offsetY = self.subTileY === 0 ? -25 : 25;
+ // Each tile is divided into 4 quadrants: (0,0)=up left, (1,0)=up right, (0,1)=down left, (1,1)=down right
+ // So offsetX: 0 = -35, 1 = +35; offsetY: 0 = -35, 1 = +35 (centered in each quadrant)
+ var offsetX = self.subTileX === 0 ? -35 : 35;
+ var offsetY = self.subTileY === 0 ? -35 : 35;
self.x = self.gridX * 100 + 50 + offsetX; // Center of tile + sub-tile offset
self.y = self.gridY * 100 + 50 + offsetY; // Center of tile + sub-tile offset
// Hide player sprite if on dark (black) block
if (typeof gameMap !== "undefined") {
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