Inventaire

Charger des images

load.js
const PNG = [
"apple", "pineapple", "watermelon", "grape",
"bean", ]

Charger deux effets sonores

load.js
const MP3 = [
"get", "met",
"wooosh", "off", "hit", ]

Créer deux nouveaux composants

component.js
function item(type, p) { const param = { offset: vec2(0, -20), ...p } return { type: type, id: "item", collectItem() { if (this.is("respawn")) this.hideObject() else destroy(this) splashFX(this.pos, { offset: param.offset }) play("get") } } } function inventory(p) { const param = { giveKey: "space", numbers: false, payDistance: 200, itemSize: 40, speakHeight: 60, speakPadding: 4, stackMargin: 20, margin: 10, updateDelay: 0.2, displayDelay: 4, textSize: 40, textOffset: vec2(10, 34), deleteOnRespawn: false, ...p } return { currentCondition: null, currentInventory: [], inventoryVisible: false, inventorySavedTime: 0, speakBox: null, id: "inventory", add() { this.onCollide("item", (c) => this.collectItem(c)) this.onCollide("condition", (c) => (this.currentCondition = c)) onKeyPress(param.giveKey, () => this.payCondition()) }, update() { if (!this.speakBox) this.inventorySetup() if ( this.currentCondition != null && this.pos.dist(this.currentCondition.pos) < param.payDistance ) this.showInventory() else if (this.inventoryVisible && time() - this.inventorySavedTime > param.displayDelay) this.showInventory(false) }, resetInventory() { if (param.deleteOnRespawn) { for (const e of this.currentInventory) e.count = 0 } this.updateInventoryDisplay() this.showInventory(true) }, showInventory(b = true) { const h = param.speakHeight + param.speakPadding * 2 if (!b) tween( 0, -h, param.updateDelay, (v) => (this.speakBox.pos.y = v), easings.easeInSin ) else if (!this.inventoryVisible) tween( -h, 0, param.updateDelay, (v) => (this.speakBox.pos.y = v), easings.easeInSin ) this.inventoryVisible = b if (b) this.inventorySavedTime = time() }, payCondition(d) { if ( this.currentCondition != null && this.pos.dist(this.currentCondition.pos) < param.payDistance ) { for (const e of this.currentCondition.conditions) { for (const el of this.currentInventory) { if (el.type == e.type) { const n = Math.min(e.count, el.count) el.count -= n e.count -= n this.updateInventoryDisplay() this.currentCondition.updateInventoryDisplay() } } } this.currentCondition.checkCondition(this.pos) } }, collectItem(c) { if (!c.beenHidden) { c.collectItem() let b = false for (const e of this.currentInventory) { if (e.type == c.type) { b = true e.count++ if (!param.numbers) { while (e.icons.length < e.count) { const obj = this.initInventoryIcon(e.type) e.icons.push(obj) } } } } if (!b) { if (param.numbers) { const obj = this.initInventoryIcon(c.type) const textObj = this.speakBox.add([ text("ok", { size: param.textSize }), pos(0, 0), fixed(), ]) this.currentInventory.push({ type: c.type, count: 1, icon: obj, textObj: textObj, }) } else { const obj = this.initInventoryIcon(c.type) this.currentInventory.push({ type: c.type, count: 1, icons: [obj] }) } } this.updateInventoryDisplay() this.showInventory() } }, inventorySetup() { const h = param.speakHeight + param.speakPadding * 2 this.speakBox = add([opacity(0.5), pos(0, -h), fixed()]) for (const e of this.currentInventory) { e.icons = [] for (let i = 0; i < e.count; i++) e.icons.push(this.initInventoryIcon(e.type)) } this.updateInventoryDisplay() }, initInventoryIcon(type) { return this.speakBox.add([ sprite(type, { width: param.itemSize }), pos(0, param.speakHeight / 2), fixed(), scale(0), anchor("center"), { visible: false }, ]) }, updateInventoryDisplay() { if (param.numbers) this.numbersDisplay() else this.iconsDisplay() }, numbersDisplay() { let m = param.speakPadding + param.itemSize / 2 for (const e of this.currentInventory) { if (e.count > 0) { const newPos = m if (!e.icon.visible) { e.textObj.hidden = false e.icon.pos.x = newPos e.textObj.pos.x = m + param.textOffset.x tween( 0, 1, param.updateDelay, (v) => (e.icon.scaleTo(v)), easings.easeInSin ) } else { tween( e.icon.pos.x, newPos, param.updateDelay, (v) => { e.icon.pos.x = v e.textObj.pos.x = v + param.textOffset.y }, easings.easeInSin ) } e.icon.visible = true e.textObj.text = e.count e.textObj.pos.y = param.textOffset.y m += param.margin + Math.max(e.icon.width, e.icon.width / 2 + e.textObj.width + paaram.textOffset.x) } else if (e.icon.visible) { e.icon.visible = false e.textObj.hidden = true tween( 1, 0, param.updateDelay, (v) => (e.icon.scaleTo(v)), easings.easeInSin ) } } }, iconsDisplay() { let m = param.speakPadding + param.itemSize / 2 for (const e of this.currentInventory) { for (let i = 0; i < e.icons.length; i++) { if (i < e.count) { const newPos = m if (!e.icons[i].visible) { e.icons[i].pos.x = newPos tween( 0, 1, param.updateDelay, (v) => (e.icons[i].scaleTo(v)), easings.easeInSin ) } else tween( e.icons[i].pos.x, newPos, param.updateDelay, (v) => (e.icons[i].pos.x = v), easings.easeInSin ) e.icons[i].visible = true e.icons[i].z = m m += param.stackMargin } else { if (e.icons[i].visible) { tween( 1, 0, param.updateDelay, (v) => (e.icons[i].scaleTo(v)), easings.easeInSin ) } e.icons[i].visible = false } } if (e.count > 0) { m -= param.stackMargin m += e.icons[0].width m += param.margin } } init = true }, } }

Déclarer des symboles

levelConf.js
const LEVEL_CONFIG = { // paramètres du niveau tileWidth: 64, tileHeight: 64, backgroundColor: "afe1ff", gravity: 3200, tiles: { // listes des objets à placer dans les niveaux
"q": () => [ // pastèque sprite("watermelon"), item("watermelon"), area(), anchor("bot"), offscreen({ hide: true }), ], "p": () => [ // pomme sprite("apple"), item("apple"), area(), anchor("bot"), offscreen({ hide: true }), ], "r": () => [ // raisins sprite("grape"), item("grape"), area(), anchor("bot"), offscreen({ hide: true }), ], "n": () => [ // ananas sprite("pineapple"), item("pineapple"), area(), anchor("bot"), offscreen({ hide: true }), ],
"#": () => [ // player sprite("bean"), platformerController(), alive(), opacity(), scale(), health(1, 4), area(), anchor("bot"), body(), respawn(), falling(), coloring(), animator(), ], "=": () => [ // block sprite("grass"), area(), body({ isStatic: true }), anchor("bot"), offscreen({ hide: true }), ], }, }

Modifier un symbole

levelConf.js
levelConf
"#": () => [ // player inventory(), sprite("bean"), platformerController(), alive(), opacity(), scale(), health(1, 4), area(), anchor("bot"), body(), respawn(), falling(), coloring(), animator(), ],

Placer les objets

level.js
const LEVELS = [ // liste des niveaux du jeu { map: ` p p === = q r r === === n === # ====== `, }, ];

item

levelConf.js
tiles :
item( "watermelon", // type { offset: vec2(0, -20), } ),