Interface en HTML+Javascript (à l'ancienne)
- Une archive contenant les fichiers est téléchargeable [ ici ]
Exercice 1
- Le fichier model.js. :
var itemCats = [ 'helmet', 'crown', 'armor', 'clothes', 'weapon', 'lighter', 'purse', 'potion', 'spell', 'food'];
var itemLimits = [
{slot:'head', limit:1, types: [ 'helmet' , 'crown' ]},
{slot:'body', limit:1, types: [ 'armor', 'clothes' ]},
{slot:'hands', limit:2, types: [ 'weapon', 'lighter']},
{slot:'belt', limit:3, types: [ 'weapon', 'purse']},
{slot:'bag', limit:10, types: [ 'helmet', 'crown', 'clothes', 'lighter', 'potion', 'spell', 'food', 'purse' ]}
];
class Item {
static counter = 0;
constructor(name, type, price, effect) {
Item.counter++;
this.id = Item.counter
this.name = name
// test si le type donné en param est valide
if (itemCats.includes(type)) {
this.type = type
}
else {
this.type = ''
}
if (price>=0) {
this.price = price
}
else {
this.price = 0
}
this.effect = effect
}
static fromJSON(obj) {
let it = new Item(obj.name, obj.type, obj.price, obj.effect)
it.id = obj.id
return it
}
}
var items = [
new Item('conic helmet', 'helmet', 200, 'A+10'),
new Item('great crown of apologia', 'crown', 200, 'A+20'),
new Item('band of joy', 'crown', 100, 'L+10'),
new Item('leather armor', 'armor', 100, 'A+10'),
new Item('broigne', 'armor', 200, 'A+20'),
new Item('hauberk', 'armor', 500, 'A+40'),
new Item('plate armor', 'armor', 1000, 'A+60'),
new Item('tuxedo', 'clothes', 600, 'L+1'),
new Item('cursed swimsuit', 'clothes', 10, 'A-10'),
new Item('unicorn cosplay', 'clothes', 200, 'L+10'),
new Item('dagger', 'weapon', 100, 'S+5'),
new Item('cursed dagger', 'weapon', 100, 'S-5'),
new Item('short sword', 'weapon', 200, 'S+10'),
new Item('cursed short sword', 'weapon', 200, 'S-10'),
new Item('long sword', 'weapon', 300, 'S+20'),
new Item('cursed long sword', 'weapon', 300, 'S-20'),
new Item('axe', 'weapon', 100, 'S+10'),
new Item('cursed axe', 'weapon', 100, 'S-10'),
new Item('great axe', 'weapon', 200, 'S+20'),
new Item('cursed great axe', 'weapon', 200, 'S-20'),
new Item('torch', 'lighter', 2, ''),
new Item('oil lamp', 'lighter', 10, ''),
new Item('leather purse', 'purse', 10, ''),
new Item('protection potion', 'potion', 100, 'a+10'),
new Item('health potion', 'potion', 100, 'l+10'),
new Item('strength potion', 'potion', 100, 's+10'),
new Item('fireball', 'spell', 1000, ''),
new Item('ice cone', 'spell', 1000, ''),
new Item('total healing', 'spell', 1000, ''),
new Item('invisibility', 'spell', 1000, ''),
new Item('levitation', 'spell', 1000, ''),
new Item('apple', 'food', 1, 'l+1'),
new Item('chicken', 'food', 10, 'l+5'),
new Item('beef', 'food', 15, 'l+10'),
new Item('wine', 'food', 2, 'l+2')
];
class Slot {
constructor(id, name) {
this.id = id
this.name = name
this.items = []
}
static fromJSON(obj) {
let s = new Slot(obj.id, obj.name)
obj.items.forEach(it => s.items.push(Item.fromJSON(it)))
return s
}
}
class Perso {
static counter = 0;
constructor(name, level) {
Perso.counter++;
this.id = Perso.counter;
this.name = name;
this.level = level;
this.slots = [];
this.slots.push(new Slot(1,'head'))
this.slots.push(new Slot(2,'body'))
this.slots.push(new Slot(3,'hands'))
this.slots.push(new Slot(4,'belt'))
this.slots.push(new Slot(5,'bag'))
this.boughtItems = []; // list of item bought but not yet assigned
this.vitality = this.level*50
this.life = this.vitality
this.strength = this.level*20
this.armor = 0
this.gold = 450
}
buy(item) {
if (item.price > this.gold) return "not enough gold"
this.boughtItems.push(item);
this.gold -= item.price
return ""
}
assign(boughtItemIndex, slotIndex) {
let item = this.boughtItems[boughtItemIndex]
// find which limits corresponds to the target slot
let lim = itemLimits.find(e => e.slot === this.slots[slotIndex].name)
// check if item number is already reached
if (this.slots[slotIndex].items.length === lim.limit) return "slot "+this.slots[slotIndex].name+" is full"
// check if item type is allowed
if (!lim.types.includes(item.type)) return "wrong item type ["+item.type+"] for slot "+this.slots[slotIndex].name
this.boughtItems.splice(boughtItemIndex,1);
this.slots[slotIndex].items.push(item);
return ""
}
static fromJSON(obj) {
let p = new Perso(obj.name, obj.level)
p.id = obj.id
p.gold = obj.gold
p.life = obj.life
p.vitality = obj.vitality
p.strength = obj.strength
p.armor = obj.armor
p.slots.splice(0)
obj.slots.forEach(slot => p.slots.push(Slot.fromJSON(slot)) )
p.boughtItems.splice(0)
// POSSIBLE ALTERNATIVE: use map() instead of forEach to assign bouthItems
p.boughtItems = obj.boughtItems.map(it => Item.fromJSON(it) )
return p
}
}
var players = [
new Perso("Conan",1), new Perso("Xena",2)
];
Remarques :
- A retenir, les fonctions essentielles de manipulation des tableaux : includes(), push(), splice(), find(), forEach() et map()
Exercice 2
- Le fichier controller.js :
// put the content of array at the head of the page
// to check if all is initialized correctly
var pshow = document.getElementById("showjson");
pshow.innerHTML += JSON.stringify(itemCats)+"<br>"+JSON.stringify(items)+"<br>"+JSON.stringify(players)+"<br>";
// retrieve some of the element of the page (not all)
var sum = document.getElementById("summary");
var headItems = document.getElementById("itemhead");
var bodyItems = document.getElementById("itembody");
var handsItems = document.getElementById("itemhands");
var beltItems = document.getElementById("itembelt");
var bagItems = document.getElementById("itembag");
var gold = document.getElementById("gold");
var bought = document.getElementById("bought");
// put some items to test
players[0].slots[0].items.push(items[0]);
players[0].slots[2].items.push(items[11]);
players[0].slots[4].items.push(items[26]);
players[0].slots[4].items.push(items[34]);
players[1].slots[1].items.push(items[5]);
players[1].slots[3].items.push(items[16]);
players[1].slots[4].items.push(items[20]);
players[1].slots[4].items.push(items[33]);
// CAUTION: all in the following and the HTML is using var player
// so that it is easier to change of player
var player = players[0];
function updateHeadItems() {
let items = ""
for(let i=0;i<player.slots[0].items.length;i++) {
items += player.slots[0].items[i].name+" ";
}
headItems.innerHTML = items
}
function updateBodyItems() {
let items = ""
for(let i=0;i<player.slots[1].items.length;i++) {
items += player.slots[1].items[i].name+" ";
}
bodyItems.innerHTML = items
}
function updateHandsItems() {
let items = ""
handsItems.innerHTML = ""
for(let i=0;i<player.slots[2].items.length;i++) {
items += player.slots[2].items[i].name+" ";
}
handsItems.innerHTML = items
}
function updateBeltItems() {
let items = ""
for(let i=0;i<player.slots[3].items.length;i++) {
items += player.slots[3].items[i].name+" ";
}
beltItems.innerHTML = items
}
function updateBagItems() {
let items = ""
for(let i=0;i<player.slots[4].items.length;i++) {
items += player.slots[4].items[i].name+" ";
}
bagItems.innerHTML = items;
}
function updateItems() {
updateHeadItems();
updateBodyItems();
updateHandsItems();
updateBeltItems();
updateBagItems();
}
function updateGold() {
gold.value = player.gold;
}
function updateBought() {
let items = "";
for(let i=0;i<player.boughtItems.length;i++) {
items += player.boughtItems[i].name+" ";
}
bought.value = items
}
function buy() {
let numIt = parseInt(document.getElementById("numit").value);
if ((isNaN(numIt)) || (numIt <0)||(numIt >= items.length)) {
alert("invalid item number");
return;
}
let item = items[numIt];
let ret = player.buy(item);
if (ret !== "") {
alert(ret);
}
else {
updateGold();
updateBought();
}
}
function assign() {
if (player.boughtItems.length === 0) {
alert("no bought items");
return;
}
let bNum = parseInt(document.getElementById("boughtnum").value);
let sNum = parseInt(document.getElementById("slotnum").value);
if ((isNaN(bNum)) || (bNum < 0) || (bNum > player.boughtItems.length)) {
alert("invalid bought item index");
return;
}
if ((isNaN(sNum)) || (sNum < 0) || (sNum >= player.slots.length)) {
alert("invalid slot index");
return;
}
let ret = player.assign(bNum,sNum);
if (ret !== "") {
alert(ret);
return
}
updateItems();
updateBought();
}
// update DOM
sum.innerHTML += player.name+', level '+player.level+', life = '+player.life+', strength = '+player.strength;
updateItems();
updateGold();