포시코딩

javascript - 구글 공룡 게임 구현(7) - 이미지 씌우기 본문

개인프로젝트/구글 공룡 게임

javascript - 구글 공룡 게임 구현(7) - 이미지 씌우기

포시 2022. 6. 23. 15:32
728x90

캐릭터가 달랑 네모로만 표현되면 미완성으로 보이니 

이미지를 씌워보자

응애

위 이미지를 초록네모 대신 출력시킬거임

let dinoImg = new Image();
dinoImg.src = 'dinosaur.png';

변수로 만들고 이미지 경로를 지정해준다. 

그 다음 dino 의 draw 함수 안에서 fillRect 하는 부분 대신 

drawImage 를 해주면 완료

draw() {
        //ctx.fillStyle = 'green';
        //ctx.fillRect(this.x, this.y, this.width, this.height);
        ctx.drawImage(dinoImg, this.x, this.y);
    }

주의할점은 장애물이 부딪히는 히트박스 판정이 

전에 있던 네모로 생각해야된다는 점이다. 

때문에 진짜 게임이라면 캐릭터의 좌표, 크기를 이미지와 일치화시켜야 할것임

선인장도 똑같이 해주면 된다. 

나는 맘에드는 이미지도 없고 편집하기도 귀찮아서 패스

크기가 다르게 나오는건 애초에 크기가 다른 이미지를 구해서 랜덤으로 나온 width 에 따라 

이미지를 지정해주는 방법으로 하거나

한 이미지로 그때그때 width 값을 다르게 주면 되지 않을까 싶다. 

 

마지막으로 전체 코드를 올리며 이번 공부는 마무리

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <span>목숨: <i id="life">5</i></span>
        <span style="margin-left: 10px;">점수: <i id="score">0</i></span>
        <h2>스페이스를 눌러 게임을 시작</h2>
        <canvas id="canvas"></canvas>
    </div>
    <script src="main.js"></script>
</body>
</html>
let canvas = document.querySelector('#canvas');
let ctx = canvas.getContext('2d'); // context 란 뜻으로 ctx

canvas.width = window.innerWidth - 100;
canvas.height = window.innerHeight - 100;


let dinoImg = new Image();
dinoImg.src = 'dinosaur.png';
let dino = {
    x: 10,
    y: 200,
    width: 40,
    height: 50,
    draw() {
        // ctx.fillStyle = 'green';
        // ctx.fillRect(this.x, this.y, this.width, this.height);
        ctx.drawImage(dinoImg, this.x, this.y);
    }
}

class Cactus {
    constructor() {
        this.width = 20 + getRandomInt(-3, 4);
        this.height = 30 + getRandomInt(-3, 4);
        this.x = 500;
        this.y = 250 - this.height;
    }
    draw() {
        ctx.fillStyle = 'red';
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

let timer = 0;
let cactusArr = [];
let gameState = 0; // 0: end, 1: start
let jumpState = 0; // 0: default, 1: jumping
let jumpTimer = 0;
let animation;
let life = 5;
let score = 0;

function frameAction() {
    animation = requestAnimationFrame(frameAction);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    timer += 1;
    
    if(timer % 120 == 0){
        let cactus = new Cactus();
        cactusArr.push(cactus);
    }
    cactusArr.forEach((a, i, o)=>{
        if(a.x < 0){
            o.splice(i, 1);
            score += 10;
            document.querySelector('#score').innerHTML = score;
        } else if(collisionDetection(dino, a) < 0){
            o.splice(i, 1);
        }
        
        a.x -= 2;
        a.draw();
    })    

    if(jumpState == 1){
        jumpTimer++; 
        dino.y -= 2;
    }
    if(jumpTimer > 50){
        jumpState = 0;
        jumpTimer = 0;
    }
    if(jumpState == 0){
        if(dino.y < 200){
            dino.y += 2;
        }
    }

    drawLine();
    dino.draw();
}

document.addEventListener('keydown', (e)=>{
    if(e.code == 'Space'){
        if(gameState == 0){
            gameState = 1; // 게임실행
            frameAction();
            document.querySelector('h2').style.display = 'none';
        } else if(gameState == 1){ // 게임실행중일때 스페이스누르면
            jumpState = 1; // 점프중으로 변경
        }
    }
})

function collisionDetection(dino, cactus){
    let xValue = cactus.x - ( dino.x + dino.width );
    let yValue = cactus.y - ( dino.y + dino.height );
    if( xValue < 0 && yValue < 0 ){ // 충돌!
        // 충돌 시 실행되는 코드
        life--;
        document.querySelector('#life').innerHTML = life;
        if(life == 0){
            alert('게임오버');
            gameState = 0;
            cancelAnimationFrame(animation);
            // ctx.clearRect(0, 0, canvas.width, canvas.height); // 작동이 안되서 새로고침으로 대체
            location.reload();
        }
        return -1;
    } else {
        return 1;
    }
}

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min)) + min; //최댓값은 제외, 최솟값은 포함
}

function drawLine(){
    ctx.beginPath();
    ctx.moveTo(0, 250);
    ctx.lineTo(600, 250);
    ctx.stroke();
}
728x90