Aller au contenu

Pièces

Marius

Les pièces peuvent permettre de donner un objectif au joueur, de lui donner des directions, ou encore de récompenser son exploration.

  1. load.js
    const PNG = [
    "coin",
    "grass",
    ]
  2. load.js
    const MP3 = [
    "score",
    "wooosh",
    "off",
    ]
  3. component.js
    function collectible(p) {
    const param = {
    tag: "player",
    offset: vec2(0, -20),
    type: "collectible",
    goesToInventory: false,
    autoDestroy: true,
    ...p
    }
    return {
    id: "collectible",
    add() {
    this.onCollide(param.tag, (obj) => {
    if (!this.is("respawn") || !this.beenHidden) {
    this.trigger("picked")
    obj.trigger("pick", { sprite: this.sprite, type: param.type, goesToInventory: param.goesToInventory })
    if (param.autoDestroy) this.trigger("disapear")
    }
    })
    this.on("disapear", () => {
    if (this.is("respawn")) this.hideFromScene()
    else destroy(this)
    })
    },
    }
    }
    component.js
    function collector(p) {
    const param = {
    deleteOnRespawn: false,
    showTotal: true,
    margin: vec2(30, 40),
    textMargin: vec2(0, 0),
    anchor: "left",
    sprite: "coin",
    detuneSpeed: 100,
    textSize: 30,
    iconSize: 30,
    iconMarign: 10,
    hideWhenEmpty: true,
    noText: false,
    textOverIcon: false,
    color: { r: 255, g: 255, b: 255 },
    type: "collectible",
    ...p,
    }
    return {
    icon: null,
    label: null,
    collected: 0,
    total: null,
    id: "collector",
    pitch: 0,
    add() {
    this.label = add([
    text("", { size: param.textSize }),
    pos(param.margin),
    fixed(),
    anchor(param.anchor),
    z(11),
    color(param.color.r, param.color.g, param.color.b),
    ])
    if (param.noText) this.label.hidden = true
    else {
    if (param.anchor == "right") this.label.pos.x = width() - param.margin.x
    if (param.sprite != null) {
    this.icon = add([
    sprite(param.sprite, { width: param.iconSize }),
    pos(param.margin),
    fixed(),
    anchor(param.anchor),
    z(10),
    ])
    this.setCollectorTextPos()
    if (param.hideWhenEmpty) this.icon.hidden = true
    }
    }
    this.on("pick", (obj) => {
    if (obj.type == param.type) {
    this.collected++
    this.pitch += 100
    if (!param.noText) this.updateCollectorText()
    this.trigger("score", { detune: this.pitch })
    }
    })
    this.on("respawn", () => {
    if (param.deleteOnRespawn) {
    this.collected = 0
    this.updateCollectorText()
    }
    })
    requestAnimationFrame(() => {
    this.total = get("collectible", { recursive: true }).length
    this.updateCollectorText()
    })
    onResize(() => this.setCollectorTextPos())
    },
    setCollectorTextPos() {
    if (param.anchor == "right") {
    this.icon.pos.x = width() - param.margin.x
    if (param.textOverIcon && param.sprite != null) {
    this.label.pos.x = width() - param.margin.x - param.iconSize / 2
    this.label.anchor = "center"
    }
    else this.label.pos.x = width() - param.iconSize - param.iconMarign - param.margin.x
    }
    else {
    if (param.textOverIcon && param.sprite != null) {
    this.label.pos.x = param.margin.x + param.textMargin.x + param.iconSize / 2
    this.label.anchor = "center"
    }
    else
    this.label.pos.x = param.margin.x + param.iconSize + param.iconMarign + param.textMargin.x
    }
    this.label.pos.y = param.margin.y + param.textMargin.y
    },
    updateCollectorText() {
    this.label.text = this.collected
    if (param.showTotal) this.label.text += "/" + this.total
    if (param.hideWhenEmpty && this.collected == 0) {
    this.label.hidden = true
    if (this.icon != null) this.icon.hidden = true
    } else {
    this.label.hidden = false
    if (this.icon != null) this.icon.hidden = false
    }
    },
    update() {
    this.pitch = Math.max(0, this.pitch - dt() * param.detuneSpeed)
    },
    }
    }
  4. config.js
    const LEVEL_CONFIG = {
    // paramètres du niveau
    tileWidth: 64,
    tileHeight: 64,
    backgroundColor: "afe1ff",
    gravity: 3200,
    tiles: {
    "$": () => [ // pièces
    sprite("coin"),
    area(),
    anchor("bot"),
    pos(0, -12),
    collectible(),
    ],
    "#": () => [ // player 1
    sprite("bean"),
    platformerController(),
    alive(),
    opacity(),
    scale(),
    health(1, 4),
    area(),
    anchor("bot"),
    body(),
    respawn(),
    falling(),
    ],
    "=": () => [ // block
    sprite("grass"),
    area(),
    body({ isStatic: true }),
    anchor("bot"),
    offscreen({ hide: true }),
    ],
    },
    }
  5. config.js
    "#": () => [ // player 1
    collector(),
    sprite("bean"),
    platformerController(),
    alive(),
    opacity(),
    scale(),
    health(1, 4),
    area(),
    anchor("bot"),
    body(),
    respawn(),
    falling(),
    ],
  6. game.js
    scene("game", () => {
    const config = { ...LEVEL_CONFIG, ...LEVELS[CURRENT_LEVEL].config }
    const map = LEVELS[CURRENT_LEVEL].map.split("\n")
    const level = addLevel(map, config)
    add([
    multiplayerCamera(),
    ])
    setGravity(config.gravity)
    setBackground(config.backgroundColor)
    on('disapear', 'collectible', (obj) => splashFX(obj.pos, { offset: vec2(0, -20) }))
    on('disapear', 'collectible', () => play('score'))
    on('jump', 'player', () => play('wooosh'))
    on('drop', 'player', () => play('off'))
    on('respawn', 'player', (obj) => obj.play('idle'))
    on('sleep', 'player', (obj) => obj.play('sleep'))
    on('awake', 'player', (obj) => obj.play('idle'))
    on('jump', 'player', (obj) => obj.play('jump', { speed: 4, onEnd: () => obj.play('idle') }))
    on('drop', 'player', (obj) => obj.play('worry'))
    }
  7. level.js
    const LEVELS = [
    {
    map: `
    $ $ $ $
    $ $ $ $ $
    # $ $ $ $ $ $
    ===== = = = = ===
    `,
    },
    ]
example
config.js
collectible({
tag: "player",
offset: vec2(0, -20),
type: "collectible",
goesToInventory: false,
autoDestroy: true
}),
example
config.js
collector({
deleteOnRespawn: false,
showTotal: true,
margin: vec2(30, 40),
textMargin: vec2(0, 0),
anchor: "left",
sprite: "coin",
detuneSpeed: 100,
textSize: 30,
iconSize: 30,
iconMarign: 10,
hideWhenEmpty: true,
noText: false,
textOverIcon: false,
color: { r: 255, g: 255, b: 255 },
type: "collectible"
}),