Hier
This commit is contained in:
parent
746f92557c
commit
7fdcba3f7b
1 changed files with 109 additions and 124 deletions
|
@ -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 }
|
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 = {
|
const JOB = {
|
||||||
VILLAGER: {
|
VILLAGER: {
|
||||||
name: "Habitant",
|
name: "Habitant",
|
||||||
dialogues: [
|
dialogues: [
|
||||||
"Bien le bonjour, étranger.",
|
"Bien le bonjour, étranger.",
|
||||||
"J'espère que la récolte sera bonne cette année.",
|
"J'espère que la récolte sera bonne cette année.",
|
||||||
"Faites attention aux loups dans la forêt.",
|
"Faites attention aux loups dans la forêt.",
|
||||||
"Le forgeron a de nouvelles marchandises, je crois."
|
"Le forgeron a de nouvelles marchandises, je crois."
|
||||||
]
|
]
|
||||||
}, FARMER: {
|
}, FARMER: {
|
||||||
name: "Fermier",
|
name: "Fermier",
|
||||||
dialogues: [
|
dialogues: [
|
||||||
"Le temps est parfait pour les cultures.",
|
"Le temps est parfait pour les cultures.",
|
||||||
"Ces sangliers n'arrêtent pas de saccager mes champs !",
|
"Ces sangliers n'arrêtent pas de saccager mes champs !",
|
||||||
"Une bonne terre, c'est tout ce qui compte."
|
"Une bonne terre, c'est tout ce qui compte."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
BANDIT: {
|
BANDIT: {
|
||||||
name: "Bandit",
|
name: "Bandit",
|
||||||
dialogues: [
|
dialogues: [
|
||||||
"Qu'est-ce que tu regardes ?",
|
"Qu'est-ce que tu regardes ?",
|
||||||
"Dégage d'ici avant que je me fâche.",
|
"Dégage d'ici avant que je me fâche.",
|
||||||
"Ta bourse ou la vie !"
|
"Ta bourse ou la vie !"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Affinities = ['water','fire','sand','rock','dark','life','ice','wood','wind','metal','time','space','lava','light','spirit'];
|
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 = {
|
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', 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 } },
|
||||||
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', 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 } },
|
||||||
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 } },
|
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 ---
|
// --- Global Asset Variables ---
|
||||||
|
@ -329,10 +329,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
this.position = new Position(x, y);
|
this.position = new Position(x, y);
|
||||||
this.biome = null;
|
this.biome = null;
|
||||||
this.structure = null;
|
this.structure = null;
|
||||||
|
this.animal = null;
|
||||||
this.visibility = 0; // 0: Unseen, 1: Seen, 2: Visible
|
this.visibility = 0; // 0: Unseen, 1: Seen, 2: Visible
|
||||||
this.setBiome();
|
this.setBiome();
|
||||||
this.setElevation();
|
this.setElevation();
|
||||||
this.setStructure();
|
this.setStructure();
|
||||||
|
this.setEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
setBiome() {
|
setBiome() {
|
||||||
|
@ -428,6 +430,31 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
this.structure=new structure(this.position);
|
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 {
|
class Map {
|
||||||
constructor(size) {
|
constructor(size) {
|
||||||
|
@ -499,7 +526,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Creature {
|
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.name = name;
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
@ -508,7 +535,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
this.alignments = alignments;
|
this.alignments = alignments;
|
||||||
this.species = species;
|
this.species = species;
|
||||||
this.race = race;
|
this.race = race;
|
||||||
this.tile=tile;
|
this.position=position;
|
||||||
this.items=items;
|
this.items=items;
|
||||||
this.hp=hp;
|
this.hp=hp;
|
||||||
}
|
}
|
||||||
|
@ -598,16 +625,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
this.creature=creature;
|
this.creature=creature;
|
||||||
this.equipments=equipments;
|
this.equipments=equipments;
|
||||||
}
|
}
|
||||||
get position() {
|
|
||||||
return this.creature.tile.position;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDesign(ctx) {
|
setDesign(ctx) {
|
||||||
const tile = this.creature.tile
|
const position = this.creature.position
|
||||||
if(!tile) return;
|
if(!position) return;
|
||||||
|
|
||||||
const screenPos = tile.position.cartToIso();
|
const screenPos = position.cartToIso();
|
||||||
const elevationHeight = tile.position.h * ELEVATION_STEP;
|
const elevationHeight = position.h * ELEVATION_STEP;
|
||||||
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.translate(screenPos.x, screenPos.y - elevationHeight);
|
ctx.translate(screenPos.x, screenPos.y - elevationHeight);
|
||||||
|
@ -620,12 +644,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
move(dx, dy, gameMap) {
|
move(dx, dy, gameMap) {
|
||||||
const newX = this.position.x + dx;
|
const newX = this.creature.position.x + dx;
|
||||||
const newY = this.position.y + dy;
|
const newY = this.creature.position.y + dy;
|
||||||
if (newX >= 0 && newX < gameMap.size && newY >= 0 && newY < gameMap.size) {
|
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')) {
|
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.map = new Map(200);
|
||||||
this.currentTime=new Time();
|
this.currentTime=new Time();
|
||||||
this.animals = [];
|
this.animals = [];
|
||||||
this.npcs = [];
|
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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
class Camera {
|
class Camera {
|
||||||
constructor(x=0,y=0,canvas) {
|
constructor(x=0,y=0,canvas) {
|
||||||
|
@ -712,11 +697,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
update(currentTime) {
|
update(currentTime) {
|
||||||
this.handleMovement(currentTime);
|
this.handleMovement(currentTime);
|
||||||
this.updateVisibility();
|
this.updateVisibility();
|
||||||
|
// a changer!
|
||||||
this.world.animals.forEach(animal => animal.update(currentTime, this.world.map));
|
this.world.animals.forEach(animal => animal.update(currentTime, this.world.map));
|
||||||
this.world.npcs.forEach(npc => npc.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
|
// Update all biome sprites
|
||||||
for (const key in Biome) {
|
for (const key in Biome) {
|
||||||
|
@ -730,8 +715,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
updateVisibility() {
|
updateVisibility() {
|
||||||
const map = this.world.map;
|
const map = this.world.map;
|
||||||
const px = this.player.position.x;
|
const px = this.player.creature.position.x;
|
||||||
const py = this.player.position.y;
|
const py = this.player.creature.position.y;
|
||||||
const radius = VISION_RADIUS;
|
const radius = VISION_RADIUS;
|
||||||
const radiusSq = radius * radius;
|
const radiusSq = radius * radius;
|
||||||
|
|
||||||
|
@ -763,7 +748,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
spawnX = Math.floor(Math.random() * this.world.map.size);
|
spawnX = Math.floor(Math.random() * this.world.map.size);
|
||||||
spawnY = 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') );
|
} 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();
|
this.updateVisibility();
|
||||||
}
|
}
|
||||||
setControls() {
|
setControls() {
|
||||||
|
@ -849,40 +834,40 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
if (controls.right) { this.player.move(1, 0,this.world.map); moved = true; }
|
if (controls.right) { this.player.move(1, 0,this.world.map); moved = true; }
|
||||||
if(moved) lastMoveTime = currentTime;
|
if(moved) lastMoveTime = currentTime;
|
||||||
}
|
}
|
||||||
handleInteraction() {
|
handleInteraction() {
|
||||||
if (!controls.interact) return;
|
if (!controls.interact) return;
|
||||||
controls.interact = false; // Consume the action
|
controls.interact = false; // Consume the action
|
||||||
|
|
||||||
const px = this.player.position.x;
|
const px = this.player.creature.position.x;
|
||||||
const py = this.player.position.y;
|
const py = this.player.creature.position.y;
|
||||||
|
|
||||||
let targetNpc = null;
|
let targetNpc = null;
|
||||||
for (const npc of this.world.npcs) {
|
for (const npc of this.world.npcs) {
|
||||||
const dx = Math.abs(npc.tile.position.x - px);
|
const dx = Math.abs(npc.tile.position.x - px);
|
||||||
const dy = Math.abs(npc.tile.position.y - py);
|
const dy = Math.abs(npc.tile.position.y - py);
|
||||||
if (dx <= 1 && dy <= 1) { // Check adjacent tiles
|
if (dx <= 1 && dy <= 1) { // Check adjacent tiles
|
||||||
targetNpc = npc;
|
targetNpc = npc;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(targetNpc) {
|
if(targetNpc) {
|
||||||
const dialogueData = targetNpc.interact();
|
const dialogueData = targetNpc.interact();
|
||||||
this.showDialogue(dialogueData.name, dialogueData.text);
|
this.showDialogue(dialogueData.name, dialogueData.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showDialogue(name, text) {
|
showDialogue(name, text) {
|
||||||
const dialogueBox = document.getElementById('dialogue-box');
|
const dialogueBox = document.getElementById('dialogue-box');
|
||||||
document.getElementById('dialogue-name').textContent = name;
|
document.getElementById('dialogue-name').textContent = name;
|
||||||
document.getElementById('dialogue-text').textContent = text;
|
document.getElementById('dialogue-text').textContent = text;
|
||||||
dialogueBox.classList.remove('hidden');
|
dialogueBox.classList.remove('hidden');
|
||||||
this.isDialogueActive = true;
|
this.isDialogueActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
hideDialogue() {
|
hideDialogue() {
|
||||||
document.getElementById('dialogue-box').classList.add('hidden');
|
document.getElementById('dialogue-box').classList.add('hidden');
|
||||||
this.isDialogueActive = false;
|
this.isDialogueActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,12 +1052,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
if (Biome[key].design) { Biome[key].sprite = new Sprite(Biome[key]);}
|
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 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));
|
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(
|
[forestSVG, villageSVG, citySVG, playerSVG, enchantedForestSVG, swampSVG, wolfPackSVG, boarSVG, birdSVG, farmSVG, campSVG, npcSVG,houseSVG,cultSVG,marketSVG,mineSVG] = await Promise.all(
|
||||||
assetElements.map(el => loadSvgAsImage(el))
|
assetElements.map(el => loadSvgAsImage(el))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
console.log("All assets loaded.");
|
console.log("All assets loaded.");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue