diff --git a/assets/game-map.json b/assets/game-map.json index 0bfaf90..33d9f08 100644 --- a/assets/game-map.json +++ b/assets/game-map.json @@ -307,6 +307,129 @@ "type":"bool", "value":true }] + }, + { + "id":1, + "properties":[ + { + "name":"forestTree", + "type":"int", + "value":40 + }] + }, + { + "id":2, + "properties":[ + { + "name":"forestTree", + "type":"int", + "value":2 + }] + }, + { + "id":3, + "properties":[ + { + "name":"forestTree", + "type":"int", + "value":5 + }, + { + "name":"palmTree", + "type":"int", + "value":2 + }] + }, + { + "id":4, + "properties":[ + { + "name":"forestTree", + "type":"int", + "value":0 + }] + }, + { + "id":7, + "properties":[ + { + "name":"forestTree", + "type":"int", + "value":8 + }] + }, + { + "id":8, + "properties":[ + { + "name":"forestTree", + "type":"int", + "value":15 + }, + { + "name":"palmTree", + "type":"int", + "value":2 + }] + }, + { + "id":10, + "properties":[ + { + "name":"palmTree", + "type":"int", + "value":15 + }] + }, + { + "id":11, + "properties":[ + { + "name":"palmTree", + "type":"int", + "value":10 + }] + }, + { + "id":12, + "properties":[ + { + "name":"boulder", + "type":"int", + "value":2 + }] + }, + { + "id":13, + "properties":[ + { + "name":"boulder", + "type":"int", + "value":8 + }] + }, + { + "id":14, + "properties":[ + { + "name":"boulder", + "type":"int", + "value":20 + }] + }, + { + "id":16, + "properties":[ + { + "name":"boulder", + "type":"int", + "value":15 + }, + { + "name":"forestTree", + "type":"int", + "value":2 + }] }], "tilewidth":100 }], diff --git a/assets/images/objects.png b/assets/images/objects.png new file mode 100644 index 0000000..a4f45fe Binary files /dev/null and b/assets/images/objects.png differ diff --git a/raw/game-map.tmx b/raw/game-map.tmx index 369f08b..9980f79 100644 --- a/raw/game-map.tmx +++ b/raw/game-map.tmx @@ -10,6 +10,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/raw/items.psd b/raw/items.psd new file mode 100644 index 0000000..48a9373 Binary files /dev/null and b/raw/items.psd differ diff --git a/raw/objects.psd b/raw/objects.psd new file mode 100644 index 0000000..addc6fd Binary files /dev/null and b/raw/objects.psd differ diff --git a/src/cycle.js b/src/cycle.js new file mode 100644 index 0000000..c8a50af --- /dev/null +++ b/src/cycle.js @@ -0,0 +1,74 @@ +export class CycleManager { + constructor(scene) { + this.scene = scene; + this.currentCycle = 'day'; + this.cycleTimer = 0; + this.cycleDuration = 120; // 3 minutes + this.cycles = ['day', 'evening', 'night', 'morning']; + + // Cycle tint values + this.tintValues = { + 'day': 0xffffff, // White (no tint) + 'evening': 0xffb085, // Orange tint + 'night': 0x222244, // Dark blue tint + 'morning': 0xffffaa // Light yellow tint + }; + + // Cycle tint values + this.playerTintValues = { + 'day': 0xffffff, // White (no tint) + 'evening': 0xffccaa, // Orange tint + 'night': 0x8888ff, // Dark blue tint + 'morning': 0xffffdd // Light yellow tint + }; + + this.cycleText = null; + } + + init() { + // Create cycle display text in upper right corner + this.cycleText = this.scene.add.text( + 40, + 40, + 'Day', + { fontSize: '24px', fill: '#ffffff' } + ).setShadow(3,3, '#333', 5).setScrollFactor(0); + } + + update(delta) { + // Handle cycle timing + this.cycleTimer += delta / 1000; // Convert ms to seconds + + if (this.cycleTimer >= this.cycleDuration) { + this.nextCycle(); + this.cycleTimer = 0; + } + } + + nextCycle() { + const currentIndex = this.cycles.indexOf(this.currentCycle); + const nextIndex = (currentIndex + 1) % this.cycles.length; + + this.currentCycle = this.cycles[nextIndex]; + + // Update display text + if (this.cycleText) { + this.cycleText.setText(this.currentCycle.charAt(0).toUpperCase() + this.currentCycle.slice(1)); + } + + // Apply tint to the terrain layer + this.applyTint(this.scene.mainLayer); + } + + applyTint(layer) { + if (layer && this.tintValues[this.currentCycle]) { + layer.setTint(this.tintValues[this.currentCycle]); + this.scene.player.setTint(this.playerTintValues[this.currentCycle]); + this.scene.objects.setTint(this.playerTintValues[this.currentCycle]); + } + } + + getCurrentCycle() { + return this.currentCycle; + } +} \ No newline at end of file diff --git a/src/objects.js b/src/objects.js new file mode 100644 index 0000000..9b428d3 --- /dev/null +++ b/src/objects.js @@ -0,0 +1,102 @@ +export class ObjectManager { + constructor(scene) { + this.scene = scene; + this.objects = []; + } + + init() { + // Parse main layer for object properties and create objects + this.parseLayerForObjects(); + } + + parseLayerForObjects() { + const map = this.scene.mainLayer.tilemap; + const layerData = this.scene.mainLayer.layer; + + // Iterate through all tiles in the layer + for (let y = 0; y < layerData.height; y++) { + for (let x = 0; x < layerData.width; x++) { + const tile = this.scene.mainLayer.getTileAt(x, y); + + if (tile && tile.properties) { + // Check for object-related properties + this.createObjectFromTile(tile, x*100+50, y*100+50); + } + } + } + } + + createObjectFromTile(tile, x, y) { + // Example: Look for a "type" property to determine what object to create + const objectType = tile.properties; + + Object.keys(objectType).forEach(key => { + const rand = Phaser.Math.Between(1,300); + + if (key === 'palmTree' && rand <= objectType[key]) { + const palmTree = this.scene.physics.add.sprite(x, y, 'objects', 0); + this.scene.objects.add(palmTree); + palmTree.setImmovable(true).setSize(60,100); + } else if (key === 'forestTree' && rand <= objectType[key]) { + const forestRand = Phaser.Math.Between(1,4); + const forestTree = this.scene.physics.add.sprite(x, y, 'objects', forestRand); + this.scene.objects.add(forestTree); + forestTree.setImmovable(true).setSize(50,100); + } else if (key === 'boulder' && rand <= objectType[key]) { + const boulder = this.scene.physics.add.sprite(x, y, 'objects', 20); + this.scene.objects.add(boulder); + boulder.setImmovable(true); + } + }); + + } + + createEnemy(x, y, properties) { + // Placeholder for enemy creation logic + console.log(`Creating enemy at (${x}, ${y}) with properties:`, properties); + + // Example implementation: + // const enemy = this.scene.physics.add.sprite( + // x * tileWidth + tileWidth / 2, + // y * tileHeight + tileHeight / 2, + // 'enemy-sprite' + // ); + // this.objects.push(enemy); + } + + createCollectible(x, y, properties) { + // Placeholder for collectible creation logic + console.log(`Creating collectible at (${x}, ${y}) with properties:`, properties); + + // Example implementation: + // const collectible = this.scene.physics.add.sprite( + // x * tileWidth + tileWidth / 2, + // y * tileHeight + tileHeight / 2, + // 'collectible-sprite' + // ); + // this.objects.push(collectible); + } + + createPlatform(x, y, properties) { + // Placeholder for platform creation logic + console.log(`Creating platform at (${x}, ${y}) with properties:`, properties); + + // Example implementation: + // const platform = this.scene.physics.add.sprite( + // x * tileWidth + tileWidth / 2, + // y * tileHeight + tileHeight / 2, + // 'platform-sprite' + // ); + // platform.setImmovable(true); + // this.objects.push(platform); + } + + update(delta) { + // Update all created objects + this.objects.forEach(object => { + if (object.update) { + object.update(delta); + } + }); + } +} \ No newline at end of file diff --git a/src/player.js b/src/player.js index f0c6490..cf7cd08 100644 --- a/src/player.js +++ b/src/player.js @@ -6,6 +6,7 @@ export class Player extends Phaser.GameObjects.Sprite { scene.add.existing(this); scene.physics.world.enable(this); this.body.setCollideWorldBounds(true); + this.body.setSize(50,100); // Set player properties this.speed = 200; @@ -15,7 +16,6 @@ export class Player extends Phaser.GameObjects.Sprite { // Add input listener for mouse clicks scene.input.on('pointerdown', (pointer) => { - console.log(pointer); this.moveToPoint(pointer.worldX, pointer.worldY); }); diff --git a/src/scenes/Game.js b/src/scenes/Game.js index b2b099e..aa5e1c1 100644 --- a/src/scenes/Game.js +++ b/src/scenes/Game.js @@ -1,8 +1,13 @@ import { Player } from '../player.js'; +import { CycleManager } from '../cycle.js'; +import { ObjectManager } from '../objects.js'; export class Game extends Phaser.Scene { constructor() { super({ key: 'Game' }); + this.cycleManager = null; + this.objectManager = null; + this.mainLayer = null; } preload() { @@ -11,6 +16,12 @@ export class Game extends Phaser.Scene { frameWidth: 100, frameHeight: 100 }); + + // Load objects sprite + this.load.spritesheet('objects', 'assets/images/objects.png', { + frameWidth: 100, + frameHeight: 100 + }); // Load tilemap this.load.tilemapTiledJSON('game-map', 'assets/game-map.json'); @@ -26,7 +37,7 @@ export class Game extends Phaser.Scene { const terrainTileset = map.addTilesetImage('terrain', 'terrain-tileset'); // Create layer named "main" - const mainLayer = map.createLayer('main', terrainTileset, 0, 0) + this.mainLayer = map.createLayer('main', terrainTileset, 0, 0) .setCollisionByProperty({ collides: true }); // Set world bounds based on tilemap dimensions @@ -34,21 +45,46 @@ export class Game extends Phaser.Scene { const worldHeight = map.heightInPixels; this.physics.world.setBounds(0, 0, worldWidth, worldHeight); + // Initialize object manager + this.objects = this.physics.add.group(); + this.objectManager = new ObjectManager(this); + this.objectManager.init(); + // Create player at center of screen this.player = new Player(this, 1600, 3100); // Physics Collisions - this.physics.add.collider(this.player, mainLayer); + this.physics.add.collider(this.player, this.mainLayer); + this.physics.add.collider(this.player, this.objects); // Make camera follow the player this.cameras.main.startFollow(this.player); this.cameras.main.setBounds(0, 0, worldWidth, worldHeight); + + // Initialize cycle manager + this.cycleManager = new CycleManager(this); + this.cycleManager.init(); } - update() { + update(time, delta) { // Update player if (this.player) { this.player.update(); } + + // Update cycle manager + if (this.cycleManager) { + this.cycleManager.update(delta); + + // Apply tint to main layer when needed + if (this.mainLayer && this.cycleManager.getCurrentCycle() !== 'day') { + this.cycleManager.applyTint(this.mainLayer); + } + } + + // Update object manager + if (this.objectManager) { + this.objectManager.update(delta); + } } } \ No newline at end of file