Aller au contenu

Personnage volant

  1. load.js
    const PNG = [
    "btfly",
    "grass",
    ]
  2. load.js
    const MP3 = [
    "hit",
    "wooosh",
    "off",
    ]
  3. component.js
    function fly(p) {
    const param = {
    fallSpeed: 40,
    magnetic: true,
    speed: 60,
    wanderDistance: 0,
    stopdistance: 6,
    rotateDelay: 0.8,
    collisionIgnore: true,
    ...p
    }
    return {
    magneticPos: null,
    falling: false,
    id: "fly",
    wanderTarget: null,
    wanderOrientation: vec2(0, 0),
    add() {
    this.onLand(() => this.falling = true)
    this.onCollideUpdate((obj, col) => this.checkFlyColission(obj, col))
    this.onCollideEnd(() => this.falling = false)
    requestAnimationFrame(() => {
    this.magneticPos = vec2(this.pos)
    this.setWanderTarget()
    })
    if (param.collisionIgnore) this.collisionIgnore.push("fly")
    },
    checkFlyColission(obj, col) {
    if (obj.is("body") && !obj.is("fly") && !obj.isStatic && col.isTop()) {
    this.move(0, param.fallSpeed)
    obj.move(0, param.fallSpeed)
    this.falling = true
    }
    },
    update() {
    tween(
    this.wanderOrientation,
    Vec2.fromAngle(this.wanderTarget.sub(this.pos).angle()),
    param.rotateDelay,
    (v) => this.wanderOrientation = v
    )
    if (param.magnetic) {
    if (!this.falling) {
    if (this.pos.dist(this.wanderTarget) > param.stopdistance) {
    this.move(this.wanderOrientation.scale(param.speed))
    }
    else this.setWanderTarget()
    }
    }
    if (this.falling) this.move(0, param.fallSpeed)
    },
    setWanderTarget() {
    const direction = Vec2.fromAngle(rand(360))
    const movement = direction.scale(rand(param.wanderDistance))
    this.wanderTarget = this.magneticPos.add(movement)
    },
    }
    }
    component.js
    function danger(p) {
    const param = {
    damage: 1,
    collisions: ["top", "left", "bot", "right"],
    ongoing: false,
    tag: "alive",
    ...p
    }
    return {
    add() {
    const c = param.ongoing ? "collideUpdate" : "collide"
    this.on(c, (obj, col) => this.checkDangerColission(obj, col))
    },
    checkDangerColission(obj, col) {
    if (obj.is(param.tag) && !this.hidden) {
    for (const c of param.collisions) {
    if (c == "top" && col.isTop()) obj.trigger("hit", param.damage)
    else if (c == "left" && col.isLeft()) obj.trigger("hit", param.damage)
    else if (c == "bot" && col.isBottom()) obj.trigger("hit", param.damage)
    else if (c == "right" && col.isRight()) obj.trigger("hit", param.damage)
    }
    }
    },
    }
    }
  4. config.js
    const LEVEL_CONFIG = {
    // paramètres du niveau
    tileWidth: 64,
    tileHeight: 64,
    backgroundColor: "afe1ff",
    gravity: 3200,
    tiles: {
    "I": () => [ // papillon hostile
    sprite("btfly"),
    area(),
    anchor("bot"),
    offscreen({ hide: true }),
    body({ gravityScale: 0 }),
    color("ff9696"),
    respawn(),
    fly({ wanderDistance: 400, speed: 120, stopdistance: 30 }),
    z(1),
    alive(),
    health(1),
    danger({ tag: "player" }),
    ],
    "i": () => [ // papillon passif
    sprite("btfly"),
    area(),
    anchor("bot"),
    offscreen({ hide: true }),
    body({ gravityScale: 0 }),
    respawn(),
    fly(),
    "pass through",
    ],
    "#": () => [ // 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. level.js
    const LEVELS = [
    {
    map: `
    === i
    i
    i
    i
    i I
    i
    i
    i
    i
    #
    =====
    `,
    },
    ]
  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('hurt', 'alive', (obj) => colorShiftFx(obj, { color: 'ff9b9b' }))
    on('hurt', 'alive', () => play('hit'))
    on('hurt', 'player', (obj) => obj.play('worry', { speed: 2, onEnd: () => obj.play('idle') }))
    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'))
    }
example
config.js
fly({
fallSpeed: 40,
magnetic: true,
speed: 60,
wanderDistance: 0,
stopdistance: 6,
rotateDelay: 0.8,
collisionIgnore: true
}),