diff --git a/js/scriptalpha.js b/js/scriptalpha.js index f6373dc..56212ec 100644 --- a/js/scriptalpha.js +++ b/js/scriptalpha.js @@ -14,31 +14,31 @@ document.addEventListener('DOMContentLoaded', () => { SWAMP: { sprite:null, design: { frames: 4,duration: 300, drawer: drawSwampFrame}, acceptStructure:false, movements:['fly'],affinities:[('water',0.6),('earth',0.2),('dark',0.2)],name: 'Marais', winterColor: '#0b2e10ff', fallColor: '#0b2e10ff', summerColor: '#0b2e10ff', autumnColor: '#0b2e10ff',maxElevation:1,minElevation:1 } } - const JOB = { - VILLAGER: { - name: "Habitant", - dialogues: [ - "Bien le bonjour, étranger.", - "J'espère que la récolte sera bonne cette année.", - "Faites attention aux loups dans la forêt.", - "Le forgeron a de nouvelles marchandises, je crois." - ] - }, FARMER: { - name: "Fermier", - dialogues: [ - "Le temps est parfait pour les cultures.", - "Ces sangliers n'arrêtent pas de saccager mes champs !", - "Une bonne terre, c'est tout ce qui compte." - ] - }, - BANDIT: { - name: "Bandit", - dialogues: [ - "Qu'est-ce que tu regardes ?", - "Dégage d'ici avant que je me fâche.", - "Ta bourse ou la vie !" - ] - } + const JOB = { + VILLAGER: { + name: "Habitant", + dialogues: [ + "Bien le bonjour, étranger.", + "J'espère que la récolte sera bonne cette année.", + "Faites attention aux loups dans la forêt.", + "Le forgeron a de nouvelles marchandises, je crois." + ] + }, FARMER: { + name: "Fermier", + dialogues: [ + "Le temps est parfait pour les cultures.", + "Ces sangliers n'arrêtent pas de saccager mes champs !", + "Une bonne terre, c'est tout ce qui compte." + ] + }, + BANDIT: { + name: "Bandit", + dialogues: [ + "Qu'est-ce que tu regardes ?", + "Dégage d'ici avant que je me fâche.", + "Ta bourse ou la vie !" + ] + } }; const Affinities = ['water','fire','sand','rock','dark','life','ice','wood','wind','metal','time','space','lava','light','spirit']; @@ -103,9 +103,9 @@ document.addEventListener('DOMContentLoaded', () => { }; const ANIMAL_TYPES = { - BIRD: { name: 'Oiseau', svgAsset: () => birdSVG, hp: 10, strength: 4, xp: 15, loot: { 'Cuir': 1, 'Os': 1 }, biomes: [Biome.FOREST, Biome.MOUNTAIN, Biome.SNOWMOUNTAIN], spawnChance: 0.01, size: { w: 40, h: 40 }, offset: { x: -20, y: -35 } }, - WOLF: { name: 'Loup', svgAsset: () => wolfPackSVG, hp: 20, strength: 4, xp: 15, loot: { 'Cuir': 1, 'Os': 1 }, biomes: [Biome.FOREST, Biome.MOUNTAIN, Biome.SNOWLAND], spawnChance: 0.01, size: { w: 40, h: 40 }, offset: { x: -20, y: -35 } }, - BOAR: { name: 'Sanglier', svgAsset: () => boarSVG, hp: 25, strength: 5, xp: 20, loot: { 'Cuir': 2 }, biomes: [Biome.FOREST, Biome.GRASSLAND], spawnChance: 0.02, size: { w: 30, h: 30 }, offset: { x: -15, y: -28 } }, + WOLF: { name: 'Loup', movement: 'walk', svgAsset: () => wolfPackSVG, hp: 20, strength: 4, xp: 15, loot: { 'Cuir': 1, 'Os': 1 }, biomes: [Biome.FOREST, Biome.MOUNTAIN, Biome.SNOWLAND], spawnChance: 0.01, size: { w: 40, h: 40 }, offset: { x: -20, y: -35 } }, + BOAR: { name: 'Sanglier', movement: 'walk', svgAsset: () => boarSVG, hp: 25, strength: 5, xp: 20, loot: { 'Cuir': 2 }, biomes: [Biome.FOREST, Biome.GRASSLAND], spawnChance: 0.02, size: { w: 30, h: 30 }, offset: { x: -15, y: -28 } }, + BIRD: { name: 'Aigle', movement: 'fly', svgAsset: () => birdSVG, hp: 10, strength: 1, xp: 5, loot: { 'Plume': 1 }, biomes: [Biome.FOREST, Biome.GRASSLAND, Biome.MOUNTAIN, Biome.BEACH], spawnChance: 0.03, size: { w: 15, h: 12 }, offset: { x: -22, y: -45 }, flightHeight: 40 }, }; // --- Global Asset Variables --- @@ -329,10 +329,12 @@ document.addEventListener('DOMContentLoaded', () => { this.position = new Position(x, y); this.biome = null; this.structure = null; + this.animal = null; this.visibility = 0; // 0: Unseen, 1: Seen, 2: Visible this.setBiome(); this.setElevation(); this.setStructure(); + this.setEntity(); } setBiome() { @@ -428,6 +430,31 @@ document.addEventListener('DOMContentLoaded', () => { this.structure=new structure(this.position); } } + setEntity(){ + // a changer! + if(this.structure) { + const structureType = this.structure.type; + let job = JOB.VILLAGER; + if(structureType === STRUCTURE_TYPE.FARM) job = JOB.FARMER; + if(structureType === STRUCTURE_TYPE.CAMP) job = JOB.BANDIT; + + for(let i = 0; i < structureType.population; i++) { + this.npc.push(new Npc(job,new Creature(job.name,null,1,null,null,this.position,'HUMAN',null,10,null),this,null )); + } + } + else { + if (this.biome) { + for (const key in ANIMAL_TYPES) { + const animalType = ANIMAL_TYPES[key]; + if (animalType.biomes.includes(this.biome) && Math.random() < animalType.spawnChance) { + if( this.biome.movements.includes(animalType.movement)) { + this.animal.push(new Animal(animalType, this.position)); + } + } + } + } + } + } } class Map { constructor(size) { @@ -499,7 +526,7 @@ document.addEventListener('DOMContentLoaded', () => { } class Creature { - constructor(name,attributes,level,affinities,alignments,tile,species,race,hp,items) { + constructor(name,attributes,level,affinities,alignments,position,species,race,hp,items) { this.name = name; this.attributes = attributes; this.level = level; @@ -508,7 +535,7 @@ document.addEventListener('DOMContentLoaded', () => { this.alignments = alignments; this.species = species; this.race = race; - this.tile=tile; + this.position=position; this.items=items; this.hp=hp; } @@ -523,7 +550,7 @@ document.addEventListener('DOMContentLoaded', () => { //f (!this.settlement){this.setSettlement()} //if (!this.equipments){this.setEquipments()} } - + setEquipments() { var i=0; const items = Object.values(ITEMS); @@ -598,16 +625,13 @@ document.addEventListener('DOMContentLoaded', () => { this.creature=creature; this.equipments=equipments; } - get position() { - return this.creature.tile.position; - } - + setDesign(ctx) { - const tile = this.creature.tile - if(!tile) return; + const position = this.creature.position + if(!position) return; - const screenPos = tile.position.cartToIso(); - const elevationHeight = tile.position.h * ELEVATION_STEP; + const screenPos = position.cartToIso(); + const elevationHeight = position.h * ELEVATION_STEP; ctx.save(); ctx.translate(screenPos.x, screenPos.y - elevationHeight); @@ -620,12 +644,12 @@ document.addEventListener('DOMContentLoaded', () => { ctx.restore(); } move(dx, dy, gameMap) { - const newX = this.position.x + dx; - const newY = this.position.y + dy; + const newX = this.creature.position.x + dx; + const newY = this.creature.position.y + dy; if (newX >= 0 && newX < gameMap.size && newY >= 0 && newY < gameMap.size) { - const targetTile = gameMap.tiles[newY][newX]; + const targetTile = gameMap.tiles[newY][newX].position; if (targetTile.biome && targetTile.biome.movements.includes('walk')) { - this.creature.tile = targetTile; + this.creature.position = targetTile; } } } @@ -637,48 +661,9 @@ document.addEventListener('DOMContentLoaded', () => { this.map = new Map(200); this.currentTime=new Time(); this.animals = []; - this.npcs = []; - this.spawnEntities(); - - } - - spawnEntities() { - console.time('Entity Spawning'); - for (let y = 0; y < this.map.size; y++) { - for (let x = 0; x < this.map.size; x++) { - const tile = this.map.tiles[y][x]; - - // Spawn NPCs in structures - if(tile.structure) { - const structureType = tile.structure.type; - let job = JOB.VILLAGER; - if(structureType === STRUCTURE_TYPE.FARM) job = JOB.FARMER; - if(structureType === STRUCTURE_TYPE.CAMP) job = JOB.BANDIT; - - for(let i = 0; i < structureType.population; i++) { - this.npcs.push(new Npc(job,new Creature(job.name,null,1,null,null,tile,'HUMAN',null,10,null),tile,null )); - } - } - - - // Spawn Animals - if (tile.biome) { - for (const key in ANIMAL_TYPES) { - const animalType = ANIMAL_TYPES[key]; - if (animalType.biomes.includes(tile.biome) && Math.random() < animalType.spawnChance) { - if(animalType.movementClass === 'ground' && tile.biome.movements.includes('walk')) { - this.animals.push(new Animal(animalType, tile)); - } else if (animalType.movementClass === 'fly') { - this.animals.push(new Animal(animalType, tile)); - } - } - } - } - } - } - console.log(`Spawned ${this.animals.length} animals and ${this.npcs.length} NPCs.`); - console.timeEnd('Entity Spawning'); + this.npcs = []; } + } class Camera { constructor(x=0,y=0,canvas) { @@ -712,11 +697,11 @@ document.addEventListener('DOMContentLoaded', () => { update(currentTime) { this.handleMovement(currentTime); this.updateVisibility(); - + // a changer! this.world.animals.forEach(animal => animal.update(currentTime, this.world.map)); this.world.npcs.forEach(npc => npc.update(currentTime, this.world.map)); - this.camera.setCamera(this.player.position); + this.camera.setCamera(this.player.creature.position); // Update all biome sprites for (const key in Biome) { @@ -730,8 +715,8 @@ document.addEventListener('DOMContentLoaded', () => { updateVisibility() { const map = this.world.map; - const px = this.player.position.x; - const py = this.player.position.y; + const px = this.player.creature.position.x; + const py = this.player.creature.position.y; const radius = VISION_RADIUS; const radiusSq = radius * radius; @@ -763,7 +748,7 @@ document.addEventListener('DOMContentLoaded', () => { spawnX = Math.floor(Math.random() * this.world.map.size); spawnY = Math.floor(Math.random() * this.world.map.size); } while (!this.world.map.tiles[spawnY][spawnX].biome || !this.world.map.tiles[spawnY][spawnX].biome.movements.includes('walk') ); - this.player = new Player(new Creature('player',new Attributes(RACE.HUMAN),1,null,null,this.world.map.tiles[spawnY][spawnX],'human',RACE.HUMAN,10,null),); + this.player = new Player(new Creature('player',new Attributes(RACE.HUMAN),1,null,null,this.world.map.tiles[spawnY][spawnX].position,'human',RACE.HUMAN,10,null),); this.updateVisibility(); } setControls() { @@ -849,40 +834,40 @@ document.addEventListener('DOMContentLoaded', () => { if (controls.right) { this.player.move(1, 0,this.world.map); moved = true; } if(moved) lastMoveTime = currentTime; } - handleInteraction() { - if (!controls.interact) return; - controls.interact = false; // Consume the action - - const px = this.player.position.x; - const py = this.player.position.y; - - let targetNpc = null; - for (const npc of this.world.npcs) { - const dx = Math.abs(npc.tile.position.x - px); - const dy = Math.abs(npc.tile.position.y - py); - if (dx <= 1 && dy <= 1) { // Check adjacent tiles - targetNpc = npc; - break; - } - } - - if(targetNpc) { - const dialogueData = targetNpc.interact(); - this.showDialogue(dialogueData.name, dialogueData.text); + handleInteraction() { + if (!controls.interact) return; + controls.interact = false; // Consume the action + + const px = this.player.creature.position.x; + const py = this.player.creature.position.y; + + let targetNpc = null; + for (const npc of this.world.npcs) { + const dx = Math.abs(npc.tile.position.x - px); + const dy = Math.abs(npc.tile.position.y - py); + if (dx <= 1 && dy <= 1) { // Check adjacent tiles + targetNpc = npc; + break; } + } + + if(targetNpc) { + const dialogueData = targetNpc.interact(); + this.showDialogue(dialogueData.name, dialogueData.text); + } } showDialogue(name, text) { - const dialogueBox = document.getElementById('dialogue-box'); - document.getElementById('dialogue-name').textContent = name; - document.getElementById('dialogue-text').textContent = text; - dialogueBox.classList.remove('hidden'); - this.isDialogueActive = true; + const dialogueBox = document.getElementById('dialogue-box'); + document.getElementById('dialogue-name').textContent = name; + document.getElementById('dialogue-text').textContent = text; + dialogueBox.classList.remove('hidden'); + this.isDialogueActive = true; } - + hideDialogue() { - document.getElementById('dialogue-box').classList.add('hidden'); - this.isDialogueActive = false; + document.getElementById('dialogue-box').classList.add('hidden'); + this.isDialogueActive = false; } } @@ -1067,13 +1052,13 @@ document.addEventListener('DOMContentLoaded', () => { if (Biome[key].design) { Biome[key].sprite = new Sprite(Biome[key]);} } - const assetIds = ['forest-svg', 'village-svg', 'city-svg', 'player-svg', 'enchanted-forest-svg', 'swamp-svg', 'wolf-pack-svg', 'boar-svg', 'bird-svg', 'farm-svg', 'camp-svg', 'npc-svg','house-svg','cult-svg','market-svg','mine-svg']; - const assetElements = assetIds.map(id => document.getElementById(id)); - - [forestSVG, villageSVG, citySVG, playerSVG, enchantedForestSVG, swampSVG, wolfPackSVG, boarSVG, birdSVG, farmSVG, campSVG, npcSVG,houseSVG,cultSVG,marketSVG,mineSVG] = await Promise.all( - assetElements.map(el => loadSvgAsImage(el)) - ); - + const assetIds = ['forest-svg', 'village-svg', 'city-svg', 'player-svg', 'enchanted-forest-svg', 'swamp-svg', 'wolf-pack-svg', 'boar-svg', 'bird-svg', 'farm-svg', 'camp-svg', 'npc-svg','house-svg','cult-svg','market-svg','mine-svg']; + const assetElements = assetIds.map(id => document.getElementById(id)); + + [forestSVG, villageSVG, citySVG, playerSVG, enchantedForestSVG, swampSVG, wolfPackSVG, boarSVG, birdSVG, farmSVG, campSVG, npcSVG,houseSVG,cultSVG,marketSVG,mineSVG] = await Promise.all( + assetElements.map(el => loadSvgAsImage(el)) + ); + console.log("All assets loaded.");