Javscript를 활용한 도형탈출

박태현·2022년 7월 27일

Javascript

목록 보기
7/8
// canvas에 그림을 그리려면 먼저 context를 가져와야 함
// context에 대한 참조는 getContext() 메서드에 context 이름을 넘김
// 좌표는 canvas 요소 왼쪽 위에서 시작하며, 이 지점을 (0, 0)으로 간주
// x는 오른쪽, y는 아래쪽으로 픽셀 단위로 증가

const canvas = document.getElementById('myCanvas');        //아이디를 가지고 특정 태그에 접근을 한다.
const context = canvas.getContext('2d'); 
canvas.style.backgroundColor = "white";

class Brick {
    constructor(left, top, right, bottom, color) 
    {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
        this.color = color;
        // this.isAlive = true;
    }
    draw() 
    {
        context.rect(this.left, this.top, rectWidth, rectHeight);
        context.fillStyle = this.color;
        context.fill();
    }
}

class Monster {
    constructor(left, top, right, bottom, color) 
    {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
        this.color = color;
        // this.isAlive = true; // 지우는용
    }
    draw() 
    {
        context.rect(this.left, this.top, monsterWidth, monsterWidth);
        context.fillStyle = this.color;
        context.fill();
    }
}

// 몬스터관련
let monsterWidth = 40;
let monsterHeight = 40;
let monsterPosX = 0;
let monsterPosY = 0;
let monsters = [];

let mobs = {
    left:0, right:0, top:0, bottom:0,
};

// 움직일 플레이어의 크기
let rectWidth = 40;
let rectHeight = 40;
let rectPosX = 0;
let rectPosY = 0;

let endCanvas = 369;

let paddle = {
    left:0, right:rectPosX, top:0, bottom:rectPosY,
};

// 타일 크기
let tileWidth = 40;
let tileHeight = 40;
let tileColumn = 10;
let tileRow = 10;
let tiles = [];
let colors = ["green", "brown", "lightgreen"];

// 가위바위보

let gameState = 0;

let shopWidth = 40;
let shopHeight = 40;
let shopPosX = canvas.width / 2;
let shopPosY = canvas.height / 2;

// 초기화, true로 되면 해당 방향으로 이동
// 이벤트 객체의 keyCode 속성에서 눌려진 키의 코드를 얻을 수 있고, 어떤 키인지 확인한 다음 적절한 변수 설정
let rightPressed = false;
let leftPressed = false;
let upPressed = false;
let downPressed = false;

document.addEventListener('keydown', keyDownHandler, false);   // 이벤트가 잇을때 해당함수를 호출해준다.

// 키보드가 눌렸을 때 일어나는 함수 (매개변수: e)
// 각 방향키의 keycode와 방향이 맞다면, 해당 변수들 true 
function keyDownHandler(e) {
    if(gameState == 0)
    {
        if(e.key == "ArrowRight") {
            if(rectPosX < endCanvas) {
                rectPosX += 41;
                paddle.left = rectPosX;
                paddle.right = rectPosX + 40;
            }
        }
        else if(e.key == "ArrowLeft") {
            if(rectPosX > 0) {
                rectPosX -= 41;
                paddle.left = rectPosX;
                paddle.right = rectPosX + 40;
            }
        }
        else if(e.key == "ArrowUp") {
            if(rectPosY > 0) {
                rectPosY -= 41;
                paddle.top = rectPosY;
                paddle.bottom = rectPosY + 40;
            }
        }
        else if(e.key == "ArrowDown") {
            if(rectPosY < endCanvas) {
                rectPosY += 41;
                paddle.top = rectPosY;
                paddle.bottom = rectPosY + 40;
            }
        }
        if(!flag) flag = true; // setInterval을 멈추고 한번만 실행을 시키고 싶을때
    }
	
    gameWin(1000);
}

let flag = true; // 조건문을 판단하기 위해서 쓰는 변수

function update() 
{
    player = new Brick(rectPosX, rectPosY, 0, 0, 'white');
    for(let i = 0; i < monsters.length; i++)
    {
        mobs.left = monsters[i].left;
        mobs.top = monsters[i].top;
        mobs.right = monsters[i].right;
        mobs.bottom = monsters[i].bottom;
        if(isCollisionRectToRect(player, mobs)){ //플레이어와 몬스터가 만났을 때 충돌
            if (flag) {
                gameState = 1 
                document.getElementById('rspBtn').style.display="block";
            if(monsters[i].color == 'green') {
                document.getElementById('mon_1').style.display="block";
                // disPlayMonsterImage('mon_1', 'block');
            }
            if(monsters[i].color == 'brown') {
                document.getElementById('mon_2').style.display="block";
            }
            if(monsters[i].color == 'lightgreen') {
                document.getElementById('mon_3').style.display="block";
            }
	        } 
        }
    }
}

// 조금이라도 겹쳣을떄 충돌이 되게끔 
function isCollisionRectToRect(rectA, rectB)
{
    // a의 왼쪽과 b의 오른쪽
    // a의 오른쪾 b의 왼쪽
    // a의 아래쪽 b의 위쪽
    // a의 위쪽과 b의 아래쪽
    if (rectA.left == rectB.left &&
        rectA.top == rectB.top  )
        {
            return true;
        }
    return false;
    
}
function setTiles() 
{
    for(let i = 0; i < tileRow; i++) //  가로 5 줄 
    {
        tiles[i] = [];
        for(let j = 0; j < tileColumn; j++)   // 세로 4줄
        {
            // TODO : right : left + 50 해보기
            tiles[i][j] = { //2차원 배열안의 요소에 접근을 해야 left,right,top,bottom,
                left:0 + j * (tileWidth + 1), // 시작위치(왼쪽에서 얼마나 뛰어서 시작할건가) + j  * (벽돌위치 + 각각의 간격)
                right:0 + j * (tileWidth + 1) + 50, 
                top:0 + i * (tileHeight + 1),
                bottom:0 + i * (tileHeight + 1) + 25, 
                column:i, row:j,
                // color: Math.floor(Math.random() * 3),
                isAlive:true,
            };
            
        }
    }
}

// document.getElementById(Id).style.display=type;을 간소화 하기 위해 disPlayMonsterImage를 호출해준다.
function disPlayMonsterImage(eleMentId, displayType) {
    document.getElementById(eleMentId).style.display=displayType;
}

function rspGame(i) { //onclick rspGame의 값을 본다. (i)
    let computer = Math.round(Math.random() * 2) // floor 3 round 2
    let me = i
    if((me - computer + 2) % 3 == 0) {// 나머지가 0일때 이김
        console.log('이김');
        gameState = 0;
        flag = false;
        document.getElementById('rspBtn').style.visibility="hidden";
        document.getElementById('coin').innerHTML = parseInt(document.getElementById('coin').innerHTML) + Math.floor(Math.random() * 100);
        disPlayMonsterImage('mon_1','none'); //
        disPlayMonsterImage('mon_2','none');
        disPlayMonsterImage('mon_3','none');
    }
    else if ((me - computer + 2 ) % 3 == 1) {// 나머지가 1일때짐
        console.log('패배');
        gameState = 0;
        flag = false;
        document.getElementById('rspBtn').style.visibility="hidden";
        document.getElementById('hp').innerHTML = parseInt(document.getElementById('hp').innerHTML) -1;
        disPlayMonsterImage('mon_1','none');
        disPlayMonsterImage('mon_2','none');
        disPlayMonsterImage('mon_3','none');
    }else { // 나머지가 2일때 비김 
        console.log('비김'); 
    }
}

async function gameWin(timeout)
{
    if((rectPosY >= endCanvas) && (rectPosX >= endCanvas)) {
        // alert('gamewin')
        setTimeout(()=> {
            window.location.reload(true);
            alert('gamewin')
        },timeout);
    }
}

let coords = []; // (x, y) //index[x, y]
let monsterCount = Math.floor(Math.random() * 11) + 20; // 0~10 // 몬스터의 숫자 

function setMonster() {
    for (let i = 0; i < monsterCount; i++) {
        let x = Math.round(Math.random()*9) // 0~9 index [] row와 column의 값이 10x10 이기 때문에 *9
        let y = Math.ceil(Math.random()*9) // 0~9
        if (coords.includes(y * 10 + x)) { // index[x,y]값에 대한 식
            console.log(x,y);
        }else{
            coords.push(y * 10 + x);
            let mob = new Monster(
                x * (monsterWidth+1),
                y * (monsterHeight+1),
                x * (monsterWidth+1) + monsterWidth,
                y * (monsterHeight+1) + monsterHeight,
                colors[Math.floor(Math.random() * 3)]
            )
            monsters.push(mob)
        }
    }
}

function drawMonster() 
{
    for(let i = 0; i < monsters.length; i++) { // monsters의 길이만큼 for문을 돈다.
        context.beginPath();
        monsters[i].draw();
        context.closePath();
    }
}

function drawPlayer() {
    context.beginPath();
    player.draw();
    context.closePath();
}

function drawTile() 
{
    
    for(let i = 0; i < tileRow; i++) 
    {
        for(let j = 0; j < tileColumn; j++)   
        {
            if (tiles[i][j].isAlive) {
                context.beginPath();
                context.rect(tiles[i][j].left, tiles[i][j].top, tileWidth, tileHeight);
                // context.fillStyle = colors[tiles[i][j].color];
                context.fillStyle = 'gray';
                context.fill();
                context.closePath();
            }
        }
    }
}

function draw()
{
    // 화면 클리어
    context.clearRect(0, 0, canvas.width, canvas.height);
    drawTile();
    drawPlayer();
    drawMonster();
}

setTiles();
setMonster();
setInterval(update, 10);
setInterval(draw, 10);
profile
꿈을 찾는 Frontend 개발자 입니다.

0개의 댓글