JavaScript로 게임 만들기 - 10

Fantazindy·2022년 4월 12일
0

JSFightGame

목록 보기
11/12

피격모션도 모션에 속하므로 이전 단계들과 유사하다.

const enemy = new Fighter({
  ...
  sprites: {
    ...
    takeHit: {
      imageSrc: "./img/kenji/Take hit.png",
      framesMax: 3,
    },
  },

player쪽에도 Take hit을 추가해주고

    takeHit: {
      imageSrc: "./img/samuraiMack/Take Hit - white silhouette.png",
      framesMax: 4,
    },
  },
  switchSprite(sprite) {
    ...
      case "takeHit":
        if (this.image !== this.sprites.takeHit.image) {
          this.image = this.sprites.takeHit.image;
          this.framesMax = this.sprites.takeHit.framesMax;
          this.framesCurrent = 0;
        }
        break;

피격은 takeHit이란 메소드를 새로 만들어 관리하자 충돌부분에서 체력감소부분을 지우고 메소드를 호출하자

  //detect collision & enemy get hit
  if (
    rectangularCollision({ rectangle1: player, rectangle2: enemy }) &&
    player.isAttacking &&
    player.framesCurrent === 4
  ) {
    enemy.takeHit()
    player.isAttacking = false;
    enemy.health -= 20;
    document.querySelector("#enemyHealth").style.width = enemy.health + "%";
    console.log("player attack");
  }
  //detect collision & player get hit
  if (
    rectangularCollision({ rectangle1: enemy, rectangle2: player }) &&
    enemy.isAttacking &&
    enemy.framesCurrent === 2
  ) {
    player.takeHit();
    enemy.isAttacking = false;
    player.health -= 20;
    document.querySelector("#playerHealth").style.width = player.health + "%";
    console.log("enemy attack");
  }
  takeHit() {
    this.switchSprite("takeHit");
    this.health -= 20;
  }


takeHit 모션이 나오지 않는데 이전과 동일하게 idle모션이 덮어씌워지기 때문이다.
attack의 경우와 동일하게 기본 모션에 덮어씌워지도록 해야한다.

switchSprite(sprite) {
    //override other animation with in attack animation
    if (
      this.image === this.sprites.attack1.image &&
      this.framesCurrent < this.sprites.attack1.framesMax - 1
    )
      return;

    //override other animation with in takehit animation
    if (
      this.image === this.sprites.takeHit.image &&
      this.framesCurrent < this.sprites.takeHit.framesMax - 1
    )
      return;

다음으로는 체력이 0이 되면 쓰러지는 모션을 추가하자
똑같이 death도 추가해주고

    death: {
      imageSrc: "./img/samuraiMack/Death.png",
      framesMax: 6,
    },
  },
    death: {
      imageSrc: "./img/kenji/Death.png",
      framesMax: 7,
    },
      case "death":
        if (this.image !== this.sprites.death.image) {
          this.image = this.sprites.death.image;
          this.framesMax = this.sprites.death.framesMax;
          this.framesCurrent = 0;
        }
        break;

동작은 takeHit메소드에 추가로 작성해주자

  takeHit() {
    this.health -= 20;

    if (this.health <= 0) {
      this.switchSprite("death");
    } else this.switchSprite("takeHit");
  }

death모션 또한 덮어씌워지는 모션이므로 attackt, takehit과 같이 override해준다.

  switchSprite(sprite) {
    //overrride other animation with in death animation
    if (this.image === this.sprites.death.image) return;


그런데 death모션이 계속해서 반복된다.

Fighter 클래스에 dead를 false로 추가하고

class Fighter extends Sprite {
  constructor({
    ...
    this.dead = false
update() {
    this.draw();
    if (!this.dead) this.animateFrames();

dead가 false일 때만 이후 동작을 실행하도록 한 뒤

  switchSprite(sprite) {
    //overrride other animation with in death animation
    if (this.image === this.sprites.death.image) {
      if (this.framesCurrent === this.sprites.death.framesMax - 1)
        this.dead = true;
      return;
    }

death모션이 나올 때 dead를 true로 바꿔 다른 동작을 실행하지 않도록 한다.

그런데 계속해서 움직일 수 있다.
방금 적용한 것과 동일하게 이벤트리스너에서

window.addEventListener("keydown", (event) => {
  //player key
  if (!player.dead) {
    switch (event.key) {
      case "d":
        keys.d.pressed = true;
        player.lastKey = "d";
        break;
      case "a":
        keys.a.pressed = true;
        player.lastKey = "a";
        break;
      case "w":
        player.velocity.y = -15;
        break;
      // if ((player.position.y = canvas.height - player.height)) {
      // }
      case " ":
        player.attack();
        break;
    }
  }

  //enemy key
  if (!enemy.dead) {
    switch (event.key) {
      case "ArrowRight":
        keys.ArrowRight.pressed = true;
        enemy.lastKey = "ArrowRight";
        break;
      case "ArrowLeft":
        keys.ArrowLeft.pressed = true;
        enemy.lastKey = "ArrowLeft";
        break;
      case "ArrowUp":
        enemy.velocity.y = -15;
        break;
      case "ArrowDown":
        enemy.attack();
        break;
    }
  }
});

각 동작을 if문으로 감싸주면 된다.

동작부분은 마무리가 다 되었다.

다음 포스팅에선 UI와 세부 애니메이션을 다뤄보자.

profile
풀스택 개발자를 목표로 성장중입니다!

0개의 댓글