JavaScript로 게임 만들기 - 7

Fantazindy·2022년 4월 12일
0

JSFightGame

목록 보기
7/12

저번에 이어 배경에 다른 요소를 추가해 볼건데 그려주는 방법은 이전의 배경과 거의 유사하다.

const shop = new Sprite({
  position: {
    x: 0,
    y: 0,
  },
  imageSrc: "./img/shop.png",
});
...
function animate() {
  window.requestAnimationFrame(animate);
  c.fillStyle = "black";
  c.fillRect(0, 0, canvas.width, canvas.height);
  background.update();
  shop.update();
  player.update();
  enemy.update();

배경과 같이 Sprite로 shop을 선언해주고 animate에 update하면

shop의 이미지가 나타난다.

크기와 위치가 좀 이상한데 먼저 크기를 조절해주자.
Sprite클래스에 고정값으로 추가해서 조정할 수도 있겠지만 배경에도 영향을 주니 프로퍼티와 파라미터를 추가하는 방법으로 해결해보자.

class Sprite {
  constructor({ position, imageSrc, scale = 1 }) {
    this.position = position;
    this.width = 50;
    this.height = 150;
    this.image = new Image();
    this.image.src = imageSrc;
    this.scale = scale
  }

  draw() {
    c.drawImage(
      this.image,
      this.position.x,
      this.position.y,
      this.image.width * this.scale,
      this.image.height * this.scale
    );
  }

  update() {
    this.draw();
  }
}

scale을 추가하였고 기본으로 1을 준 상태에서 받아오는 image에 scale을 파라미터로 받아 그만큼 곱하는 방식이다.

const shop = new Sprite({
  position: {
    x: 0,
    y: 0,
  },
  imageSrc: "./img/shop.png",
  scale: 1.5,
});

scale을 추가하고 나서 보면 이전보다 사이즈가 커져있는걸 볼 수 있다.

이제 position과 scale을 적절히 바꿔주면

위치가 잘 잡힌것 같다.
이제 상점이미지 중 1/6에 해당하는 부분만 보여줘야 하는데 잘라내기를 사작할 x, y좌표와 잘라내기 할 등분값을 더해서 아규먼트에 추가하면

  draw() {
    c.drawImage(
      this.image,
      0,
      0,
      this.image.width / 6,
      this.image.height,
      this.position.x,
      this.position.y,
      (this.image.width / 6) * this.scale,
      this.image.height * this.scale
    );


화면이 좀 이상하지만 상점 이미지는 잘 나온다 이것도 scale과 동일한 방법으로 해결할 수 있다.
파라미터로 framesMax를 추가하고 프로퍼티에도 넣은뒤 고정값이던 6을 framesMax로 바꾸고 shop을 그려줄 때 이 값을 추가하면

class Sprite {
  constructor({ position, imageSrc, scale = 1, framesMax = 1 }) {
    this.position = position;
    this.width = 50;
    this.height = 150;
    this.image = new Image();
    this.image.src = imageSrc;
    this.scale = scale;
    this.framesMax = framesMax
  }

  draw() {
    c.drawImage(
      this.image,
      0,
      0,
      this.image.width / this.framesMax,
      this.image.height,
      this.position.x,
      this.position.y,
      (this.image.width / this.framesMax) * this.scale,
      this.image.height * this.scale
    );
  }
const shop = new Sprite({
  position: {
    x: 610,
    y: 130,
  },
  imageSrc: "./img/shop.png",
  scale: 2.75,
  framesMax: 6,
});


shop만 잘 잘려서 그려지고있다.

이제 이 shop의 애니메이션 효과를 위해선 6개로 이어진 shop들을 각각 잘라서 보여줘야 하는데 x축만 이동하면 되므로 이전에 설정한 프로퍼티 중 x에 해당하는 첫 0을 수정하자

class Sprite {
  constructor({ position, imageSrc, scale = 1, framesMax = 1 }) {
    this.position = position;
    this.width = 50;
    this.height = 150;
    this.image = new Image();
    this.image.src = imageSrc;
    this.scale = scale;
    this.framesMax = framesMax;
    this.framesCurrent = 0;
  }

  draw() {
    c.drawImage(
      this.image,
      this.framesCurrent * (this.image.width / this.framesMax),
      0,
      this.image.width / this.framesMax,
      this.image.height,
      this.position.x,
      this.position.y,
      (this.image.width / this.framesMax) * this.scale,
      this.image.height * this.scale
    );
  }

  update() {
    this.draw();
    if (this.framesCurrent < this.framesMax - 1) {
      this.framesCurrent++;
    } else {
      this.framesCurrent = 0;
    }
  }
}

배경화면에는 영향을 주지 않도록 framesCurrent라는 아규먼트를 추가해 기본값을 0으로 주고 update에서 framesMax-1 보다 작을때 framesCurrent를 ++해 배경에서는 잘라내는 지점에 변화가 없게 하였다.

상점 애니메이션이 너무 빠른것 같으니 수정해주자.

class Sprite {
  constructor({ position, imageSrc, scale = 1, framesMax = 1 }) {
    ...
    this.framesElapsed = 0;
    this.framesHold = 10;
  }

...

  update() {
    this.draw();
    this.framesElapsed++;
    if (this.framesElapsed % this.framesHold === 0) {
      if (this.framesCurrent < this.framesMax - 1) {
        this.framesCurrent++;
      } else {
        this.framesCurrent = 0;
      }
    }
  }
}

framesElapsed, framesHold 두 프로퍼티를 추가해주고 framesCurrent++가 있는 부분을 if조건문으로 한번 더 감싸면 된다.
이 조건문은 framesElapsed가 계속 증가하는데 이 값을 framesHold로 나누었을 때 나머지가 없으면 기존 framesCurrent++를 실행하도록 하여 지금과 같이 framesHold가 10일 때 기존 속도의 1/10으로 프레임을 바꿔주는 효과를 낸다.

배경은 이정도면 완벽한듯 하다.
다음 포스팅에선 캐릭터들을 만져보도록 하자.

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

0개의 댓글