본문 바로가기
개발일지

개발일지 3일차 -function,while-

by 태운콩즙 2023. 11. 28.
728x90
반응형

-오늘의 작업물-

1.빙고가 실행되었을때 색 변경

2.게임만들기

script>
function colorChange(elememt){
    if(elememt.style.backgroundColor =="blue"){
        elememt.style.backgroundColor ="white";
    }else{
        elememt.style.backgroundColor ="blue";
    }
}

 

</script>
</html>
 
어제 작업물의 <script>다
<script>
function colorChange(elememt){
    if(elememt.style.backgroundColor =="blue"){
        elememt.style.backgroundColor ="";
    }else{
        elememt.style.backgroundColor ="blue";
    }

    const num= elememt.id;
   heightCheck(num);
   widthCheck(num);
}

 

작업을 실행하기전에 기존 script를 수정하였다

변수 num을 색상이 변경된 id로 지정해주었고

기존에 white를 빼주었고

세로줄 체크와

가로줄 체크를 추가하였다

수정을 한 이유는 가로영역을 두번 선택하게 되면 white가 되면 실제로 봤을땐 아무것도 선택이 안된것으로 보이지만 white가 실행이 된것이라 for문안에 if문이 실행될수 없기에 바꾸어주었다

 

function heightCheck(num){
    const a = num %5;
    let check = false;

    for(let i=1; i<=25; i++){
        if(a== i%5){
            if(document.getElementById(i).style.backgroundColor !="blue"){
                check = true;
            }
        }
    }
    if(check==false){ //해당 세로 줄이 다 파란색으로 바뀌었다.
        for(let i=1; i<=25; i++){
            if(a== i%5){
                document.getElementById(i).style.backgroundColor="gold";
            }
        }
    }
}

세로열 함수 NUM을 실행시키기 위해서는

변수값을 세로열을 5로 나눈 나머지값으로 지정을 하게되면

모든 세로열이 같은 값이 되어서 모두 지정을 할수있게된다

 

function widthCheck(num){
        const a = Math.floor((num-1) / 5);
        let check = false;

        for(let i=1; i<=25; i++){
            if(a == Math.floor((i-1) / 5)){
                if(document.getElementById(i).style.backgroundColor == ""){
                    check = true;
                }
            }
        }
        if(check == false){
            for(let i=1; i<=25; i++){
                if(a == Math.floor((i-1) / 5)){
                    document.getElementById(i).style.backgroundColor = "gold";
                }
            }
        }
    }

가로 코드는 변수가 다르다

가로영역값에 -1을 하고 5로 나누게 되면 나머지값이 4가 되어 실행이 가능하게된다

여기서Math fiool를 넣어주는 이유는 script에서는 나머지값을 소수점으로 도출하게 되어서 내림을 하기 위해 써준 문구이다

 

위 코드를 실행시키면 아래와 같다

 

 

2. 게임만들기

 

조과제로 게임 만들기를 하였는데 우리조는 크롬에 공룡 점프를 기반으로 만들기로 하였다

<!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 id="nemo">■ 초록네모의 놀라운 여정 ■</h2>
        <h3>스페이스를 눌러 게임을 시작! 5O점 달성할 때 마다 속도가 증가합니다.</h3>
        <canvas id="canvas"></canvas>
    </div>
</body>
<script>
    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(0, 50);
            this.height = 30 + getRandomInt(0, 50);
            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;
    let x = getRandomInt(80, 120);
    let lastTime = 0;

    function frameAction() {
        animation = requestAnimationFrame(frameAction);
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        timer += 1;

        if (lastTime + x == timer) {
            let cactus = new Cactus();
            cactusArr.push(cactus);
            lastTime = timer;
            x = getRandomInt(80, 120);
        }
       
        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 -= 4 + Math.floor(score / 50) * 1;
            a.draw();
        })

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

        drawLine();
        dino.draw();
    }

    document.addEventListener('keydown', keyDownHandler);
    function keyDownHandler(e) {
        if (e.code == 'Space') {
            if (gameState == 0) {
                gameState = 1; // 게임실행
                frameAction();
                document.querySelector('h2').style.display = 'none';
            } else if (gameState == 1) { // 게임실행중일때 스페이스누르면
                if (dino.y == 200) {
                    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) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function drawLine() {
        ctx.beginPath();
        ctx.moveTo(0, 250);
        ctx.lineTo(600, 250);
        ctx.stroke();
    }
</script>

</html>

 

기존에 있던 소스코드를 기반으로 수정을 해가며 만들어주었다

 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);
        }

변수 공룡의 크기와 위치값을 담당해주고 색은 green으로 지정해주었고

class Cactus {
        constructor() {
            this.width = 20 + getRandomInt(0, 50);
            this.height = 30 + getRandomInt(0, 50);
            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;
    let x = getRandomInt(80, 120);
    let lastTime = 0;

점프 시간과 처음 점수 목숨등의 기본 게임의 변수값

위의 변수 x =getRandomlnt(80,120);는

장애물이 나오는 위치를 랜덤으로 나오게 하기 위해 지정해준값이다

 function frameAction() {
        animation = requestAnimationFrame(frameAction);
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        timer += 1;

        if (lastTime + x == timer) {
            let cactus = new Cactus();
            cactusArr.push(cactus);
            lastTime = timer;
            x = getRandomInt(80, 120);
        }
   

랜덤값을 적용해서 만들면 이런식으로 나오게 된다 

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 -= 4 + Math.floor(score / 50) * 1;
            a.draw();
        })

그리고 게임의 진행을 조금 더 어렵게 하기위해 게임의 속도는 점수가 50점씩 올랄때마다 올라가게 만들어주었다

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

        drawLine();
        dino.draw();
    }

    document.addEventListener('keydown', keyDownHandler);
    function keyDownHandler(e) {
        if (e.code == 'Space') {
            if (gameState == 0) {
                gameState = 1; // 게임실행
                frameAction();
                document.querySelector('h2').style.display = 'none';
            } else if (gameState == 1) { // 게임실행중일때 스페이스누르면
                if (dino.y == 200) {
                    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) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function drawLine() {
        ctx.beginPath();
        ctx.moveTo(0, 250);
        ctx.lineTo(600, 250);
        ctx.stroke();
    }
</script>

</html>

장애물과 충돌하게되면 life가 깍이게 만들어주고 5번 죽게되면 게임오버가 출력되게 만들어주었다

사실 위의 결과물 자체는 기존 소스코드를 가져와서 수정할 부분을 찾아내서 수정을 하고 바꾸어주기만 한것이지만

변경하면서 코드끼리의 충돌과 실행하기까지의 과정을 거치면서 조금 더 코드들을 이해기에 도움이되었다

어제 느낀대로 다른 소스코드들을 분석하는 과정을 반복해 보는것도 좋은 방법이지않을까 하는 생각이 들었다

728x90
반응형