Aller au contenu

Voler

Arthur
  1. load.js
    function loadAtlas() {
    loadSpriteAtlas("assets/sprites/bird-atlas.png", {
    "bird": {
    x: 0, y: 0,
    width: 610, height: 53,
    sliceX: 5,
    anims: {
    idle: { from: 0, to: 0 },
    run: { from: 0, to: 0 },
    sleep: { from: 4, to: 4 },
    jump: { from: 1, to: 1 },
    fly: { from: 1, to: 2 },
    worry: { from: 3, to: 3 },
    },
    },
    })
    loadSpriteAtlas("assets/sprites/bean-atlas.png", {
    "bean": {
    x: 0, y: 0,
    width: 244, height: 53,
    sliceX: 4,
    anims: {
    idle: { from: 0, to: 0 },
    run: { from: 0, to: 0 },
    sleep: { from: 1, to: 1 },
    jump: { from: 2, to: 2 },
    worry: { from: 3, to: 3 },
    },
    },
    })
    loadSpriteAtlas("assets/sprites/splash.png", {
    "splash": {
    x: 0, y: 0,
    width: 384, height: 64,
    sliceX: 6,
    anims: { explode: { from: 0, to: 5, speed:30 } },
    },
    })
    }
  2. component.js
    function flappyController(p) {
    const param = {
    jumpKey: "up",
    leftKey: "left",
    rightKey: "right",
    downKey: "down",
    jumpForce: 400,
    moveSpeed: 480,
    flySpeed: 680,
    glideDelay: 0.1,
    doubleJump: 0,
    sleepDelay: 2,
    gravityScale: 0.6,
    jump: false,
    rotationDelay: 0.04,
    barOffset: vec2(0, -64),
    barSize: vec2(64, 10),
    color: "8b57cf",
    fuelCombustionSpeed: 2,
    fuelRefillSpeed: 4,
    displayBar: true,
    radius: 4,
    outline: 4,
    ...p
    }
    return {
    id: "player",
    direction: vec2(0, 0),
    jumpCount: 0,
    facing: 1,
    require: ["alive", "body"],
    isPassingThrough: 0,
    moveSavedTime: 0,
    asleep: false,
    isFlying: false,
    isLanding: false,
    flyFuel: 1,
    flappyBar: null,
    flappyBarOn: false,
    add() {
    this.gravityScale = param.gravityScale
    if (param.displayBar) {
    this.flappyBar = this.add([
    pos(param.barOffset),
    rect(param.barSize.x, param.barSize.y, { radius: param.radius }),
    color(Color.fromHex(param.color)),
    anchor("bot"),
    outline(param.outline),
    ])
    this.flappyBar.hidden = true
    }
    onKeyPress(param.jumpKey, () => {
    if (this.isAlive && !this.isClimbing) {
    if (this.isGrounded()) {
    if (param.jump) {
    this.trigger("jump")
    this.jump(param.jumpForce)
    }
    else if (this.flyFuel > 0) {
    this.trigger("fly")
    this.isFlying = true
    }
    }
    else if (this.flyFuel > 0) {
    this.trigger("fly")
    this.isFlying = true
    this.vel = vec2(0, 0)
    }
    }
    })
    onKeyRelease(param.jumpKey, () => {
    this.isFlying = false
    this.isLanding = true
    this.trigger("landing")
    })
    onKeyDown(param.jumpKey, () => this.moveSavedTime = time())
    this.moveSavedTime = time()
    this.on("respawn", () => this.flyFuel = 1)
    },
    update() {
    if (this.isFlying) {
    this.gravityScale = 0
    const keyDown = isKeyDown([param.leftKey, param.rightKey, param.jumpKey, param.downKey])
    if (keyDown) {
    const inputDirection = (() => {
    let t = vec2(0.0, 0.0)
    if (isKeyDown(param.leftKey) && isKeyDown(param.rightKey)) t.x = 0.0
    else if (isKeyDown(param.leftKey)) t.x = -1
    else if (isKeyDown(param.rightKey)) t.x = 1
    if (isKeyDown(param.jumpKey) && isKeyDown(param.downKey)) t.y = 0.0
    else if (isKeyDown(param.jumpKey)) t.y = -1
    else if (isKeyDown(param.downKey)) t.y = 1
    return Vec2.fromAngle(t.angle())
    })()
    tween(this.direction, inputDirection, param.rotationDelay, (p) => (this.direction = p), easings.easeInQuad)
    }
    this.move(this.direction.scale(param.flySpeed))
    this.isLanding = false
    this.flyFuel = clamp(this.flyFuel - param.fuelCombustionSpeed * dt(), 0, 1)
    if (this.flyFuel == 0) this.isFlying = false
    }
    else {
    this.gravityScale = param.gravityScale
    const inputDirection = (() => {
    let t = vec2(0, 0)
    if (!this.isAlive) t.x = 0
    else if (isKeyDown(param.leftKey) && isKeyDown(param.rightKey)) t.x = 0
    else if (isKeyDown(param.leftKey)) t.x = -1
    else if (isKeyDown(param.rightKey)) t.x = 1
    return t
    })()
    const surfaceGlide = (() => {
    if (!this.isGrounded()) return 0
    else return this.curPlatform().glide || 0
    })()
    tween(
    this.direction,
    inputDirection,
    param.glideDelay + surfaceGlide,
    (p) => (this.direction = p),
    easings.easeOutQuad
    )
    this.move(this.direction.scale(param.moveSpeed))
    if (this.isGrounded() && this.isLanding) {
    this.trigger("land")
    this.isLanding = false
    }
    else if (!this.isGrounded() && !this.isLanding) {
    this.isLanding = true
    this.trigger("landing")
    }
    if (this.isGrounded()) this.flyFuel = clamp(this.flyFuel + param.fuelRefillSpeed * dt(), 0, 1)
    }
    const s = time() - this.moveSavedTime > param.sleepDelay;
    if (this.direction.len() > 0.1) this.facing = this.direction.unit().x
    if (this.direction.len() > 0.1) this.moveSavedTime = time()
    if (!this.asleep && s) this.trigger("sleep")
    else if (this.asleep && !s) this.trigger("awake")
    this.asleep = s
    if (param.displayBar) {
    this.flappyBar.width = this.flyFuel * param.barSize.x
    if (this.flyFuel == 1) this.flappyBar.hidden = true
    else if (this.flappyBar.width < param.radius * 2) this.flappyBar.hidden = true
    else this.flappyBar.hidden = false
    }
    },
    }
    }
  3. config.js
    const LEVEL_CONFIG = {
    // paramètres du niveau
    tileWidth: 64,
    tileHeight: 64,
    backgroundColor: "afe1ff",
    gravity: 3200,
    tiles: {
    "f": () => [ // player 1
    sprite("bird"),
    flappyController(),
    alive(),
    opacity(),
    scale(),
    health(1),
    area({ scale: vec2(0.5, 1) }),
    z(1),
    anchor("bot"),
    body(),
    respawn(),
    falling(),
    ],
    "#": () => [ // 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 }),
    ],
    },
    }
  4. 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('fly', 'player', (obj) => obj.play('fly',{speed: 10,loop:true}))
    on('landing', 'player', (obj) => obj.play('jump'))
    on('land', 'player', (obj) => obj.play('idle'))
    on('fly', 'player', () => play('wooosh'))
    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'))
    }
  5. level.js
    const LEVELS = [
    {
    map: `
    = =
    = =
    = = =
    =
    === === ===
    f
    =====
    `,
    },
    ]
example
config.js
flappyController({
jumpKey: "up",
leftKey: "left",
rightKey: "right",
downKey: "down",
jumpForce: 400,
moveSpeed: 480,
flySpeed: 680,
glideDelay: 0.1,
doubleJump: 0,
sleepDelay: 2,
gravityScale: 0.6,
jump: false,
rotationDelay: 0.04,
barOffset: vec2(0, -64),
barSize: vec2(64, 10),
color: "8b57cf",
fuelCombustionSpeed: 2,
fuelRefillSpeed: 4,
displayBar: true,
radius: 4,
outline: 4
}),
example
config.js
spriteFacing({
reversed: false
}),