진행했던 프로젝트들이 너무 React위주로만 진행되어서 JS를 사용한 프로젝트를 진행해보려고 한다.
최근 유행하였던 뱀파이어 서바이버도 JS로 만든 게임이라고 하기에 좀 알아보았더니 Phaser라는 것을 사용하였다 하여 알아보았는데 조금 더 공부가 필요해보여 일단은 별다른 패키지 없이 만들것이다.
index.html
<canvas></canvas>
<script src="index.js"></script>
캔버스를 만들고 스크립트로
index.js
const canvas = document.querySelector("canvas");
const c = canvas.getContext("2d");
canvas.width = 1024;
canvas.height = 576;
c.fillRect(0, 0, canvas.width, canvas.height);
캔버스를 채운다.
class Sprite {
constructor(position) {
this.position = position;
}
draw() {
c.fillStyle = "red";
c.fillRect(this.position.x, this.position.y, 50, 150);
}
}
player와 enemy를 그려줄 class를 만들고
const player = new Sprite({
x: 0,
y: 0,
});
player.draw();
const enemy = new Sprite({
x: 400,
y: 100
})
enemy.draw();
캔버스에 그려보면
지정한 위치에 빨간 사각형이 그려졌다.
이제 이것을 움직이는 애니메이션을 만들자.
애니메이션은 플레이어가 조작하는동안 계속 작동해야하기때문에 무한루프를 돌려야한다.
function animate() {
window.requestAnimationFrame(animate);
console.log("go");
}
animate();
무한루프 함수를 하나 만들고
이동하는 상태를 저장해야하기 때문에 position뿐만 아니라 velocity도 추가하고 constructor로 넘겨주는 두 값을 {}로 묶어준다
class Sprite {
constructor( {position, velocity} ) {
this.position = position;
this.velocity = velocity;
}
draw() {
c.fillStyle = "red";
c.fillRect(this.position.x, this.position.y, 50, 150);
}
}
const player = new Sprite({
position: {
x: 0,
y: 0,
},
velocity: {
x: 0,
y: 0,
},
});
이제 Sprite클래스 안에
update() {
this.draw();
this.position.y += 10;
}
}
update 도 추가하고
function animate() {
window.requestAnimationFrame(animate);
player.update();
enemy.update();
}
animate();
animate로 실행시켜보면
세로로 10씩 빨간 사각형이 쭉 그려진다.
캔버스의 색을 바꾸고 동작할 때 마다 빈공간을 채우도록 하면 animate하면
조금 나아져보인다.
잘 작동하는걸 확인했으니 10으로 줬던 velocity를 this.velocity로 바꿔주고 다시 테스트해보자.
update() {
this.draw();
this.position.y += this.velocity.y;
}
값을 바꿔주고 player의 velocity를 10으로 주면
const player = new Sprite({
position: {
x: 0,
y: 0,
},
velocity: {
x: 0,
y: 10,
},
});
player사각형만 animate된다.
이제 캐릭터 사각형이 canvas밖으로 나가버리는 문제를 해결해보자
gravity전역변수와 Sprite클래스 내에 캐릭터 높이를 지정해주고
const gravity = 0.2;
class Sprite {
constructor({ position, velocity }) {
this.position = position;
this.velocity = velocity;
this.height = 150;
}
update 메소드에
update() {
this.draw();
this.position.y += this.velocity.y;
if (this.position.y + this.height + this.velocity.y >= canvas.height) {
this.velocity.y = 0;
} else this.velocity.y += gravity;
}
if문으로 캐릭터 사각형이 있는 위치와 캔버스높이를 비교해 바닥에 닿으면 velocity를 0으로 만들어 멈추고 아니면 gravity만큼 계속 가속하며 떨어지는 조건을 잡아준다.
캐릭터 생성은 대략 마무리 된 듯 하다.
다음에는 이벤트리스너를 통해 이 캐릭터를 움직이게 해볼 예정이다.