캐릭터 이미지를 넣어보자.
캐릭터는 Fighter클래스로 생성해주고 있는데 캐릭터 애니메이션을 사용하기 위해선 이전 Sprite에 사용했던 프로퍼티들이 필요하다.
Sprite를 extend하고 파라미터를 추가해주고 필요한 프로퍼티들을 추가해 사용할 수 있게 해주자.
class Fighter extends Sprite {
constructor({
position,
velocity,
color,
offset,
imageSrc,
scale = 1,
framesMax = 1,
}) {
super({
position,
imageSrc,
scale,
framesMax,
});
this.velocity = velocity;
this.width = 50;
this.height = 150;
this.lastKey;
this.attackBox = {
position: {
x: this.position.x,
y: this.position.y,
},
offset,
width: 100,
height: 50,
};
this.color = color;
this.isAttacking;
this.health = 100;
this.framesCurrent = 0;
this.framesElapsed = 0;
this.framesHold = 10;
}
super의 안에는 Sprite에만 존재하는 프로퍼티들을 써주면 된다(기존 Fighter의 position은 지워줬다).
frame관련 프로퍼티들은 따로 필요하므로 별도 추가하였다.
기존에 사각형을 그려주던 Fighter클래스 내 draw메소드는 필요 없으니 지워주자.
그리고 index.js에서 캐릭터 이미지 경로를 지정해주고 shop과 동일하게 frameMax와 scale을 지정해주면
const player = new Fighter({
position: {
x: 0,
y: 0,
},
velocity: {
x: 0,
y: 0,
},
color: "green",
offset: {
x: 0,
y: 0,
},
imageSrc: "./img/samuraiMack/Idle.png",
framesMax: 8,
scale: 2.5,
});
캐릭터 이미지가 잘 나타나긴 하지만 위치가 어색한데 캐릭터 이미지 주변에 여백이 있기 때문이다.
이전 캐릭터의 공격범위를 지정했을때와 유사하게 offset을 사용해서 해결할 것이다.
Sprite에 프로퍼티와 아규먼트로 offset을 추가하고 Fighter의 프로퍼티에도 추가한다.
class Sprite {
constructor({
...
offset = { x: 0, y: 0 },
}) {
...
this.offset = offset;
}
...
class Fighter extends Sprite {
constructor({
...
offset = { x: 0, y: 0 },
}) {
super({
...
offset
});
그리고 offset값을 추가하면
const player = new Fighter({
...
offset: {
x: 215,
y: 157,
},
});
위치가 잘 잡힌듯 하다.
아직 애니메이션이 동작하지 않는데 이를 해결해보자
Sprite의 update의
this.framesElapsed++;
if (this.framesElapsed % this.framesHold === 0) {
if (this.framesCurrent < this.framesMax - 1) {
this.framesCurrent++;
} else {
this.framesCurrent = 0;
}
}
이 부분이 애니메이션을 구현하는 조건문이었다.
이걸 추가하면 되는데 좀 더 보기 편하게 animateFrames메소드를 새로 만들어 위 내용을 붙여넣고 animateFrames만 가져다 쓰는 식으로 하면
animateFrames() {
this.framesElapsed++;
if (this.framesElapsed % this.framesHold === 0) {
if (this.framesCurrent < this.framesMax - 1) {
this.framesCurrent++;
} else {
this.framesCurrent = 0;
}
}
}
update() {
this.draw();
this.animateFrames();
}
더욱 간편하게 코드를 관리할 수 있다.
아래 Fighter클래스의 update에도 해당 메소드를 추가하면
update() {
this.draw();
this.animateFrames();
this.attackBox.position.x = this.position.x - this.attackBox.offset.x;
this.attackBox.position.y = this.position.y;
this.position.x += this.velocity.x;
this.position.y += this.velocity.y;
if (this.position.y + this.height + this.velocity.y >= canvas.height - 95) {
this.velocity.y = 0;
} else this.velocity.y += gravity;
}
정지상태일 때 캐릭터가 움직인다.
그런데 조작키가 먹히지 않는데 enemy쪽 코드에 에러가 발생해서 그렇다.
enemy쪽 코드는 나중에 수정하기로 하고 잠시 코멘트 처리 해두자.
function animate() {
window.requestAnimationFrame(animate);
c.fillStyle = "black";
c.fillRect(0, 0, canvas.width, canvas.height);
background.update();
shop.update();
player.update();
// enemy.update();
지금은 캐릭터의 움직임이 너무 단조로운데 다음 포스팅에선 캐릭터의 다른 동작 애니메이션을 추가해보자