라라리라

2023.11.14 / Step 8 [DOM_캔버스키보드] - 코딩 90일차 본문

코딩/2023 JavaScript DOM

2023.11.14 / Step 8 [DOM_캔버스키보드] - 코딩 90일차

헤실 2023. 11. 14. 17:46

fire.html

 

<!DOCTYPE html>
<html lang="ko">
<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>
    <h1>총알발사 : space</h1>
    <h1>문제점 : 총알이 한번에 여러발 발사된다.</h1>
    <canvas id="myCanvas" width="800" height="600" style="border: 1px solid black;">
    </canvas>
    <script src="fire.js"></script>
</body>
</html>

 


fire.js

 

function draw() {

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    drawRect();

    bulletFire();

    drawBullet();

    moveBullet();
   
    rect.cooldown++;
}

function drawRect(){
    ctx.beginPath();
    ctx.rect(rect.x, rect.y, rect.width, rect.height);
    ctx.fillStyle = rect.color;
    ctx.fill();
    ctx.closePath();
}

function bulletFire(){
    /*
        [키문제점]
            키가 한번에 여러번 눌려 총알이 뭉쳐서 나가게된다.
            다음 챕터에서 한번에 한발씩 발사가 되도록 수정한다.
    */
    if(key.fire == true && bulletList.length < bulletMax){
        if(rect.cooldown >= rect.cooldownmax){
            rect.cooldown = 0;
        let bullet = {
            "x" : rect.x + rect.width,
            "y" : rect.y + 15,
            "width" : 20,
            "height" : 20,
            "speed" : 5,
            "color" : "black",
            "lifeDistance" : 400,
            // 총알이 지워지는 것을 보여주기위해 400으로 짧게 설정하였다.
            // 보통은 화면 밖을 넘어가면 삭제해준다.
        };
       
        bulletList.push(bullet);
        console.log(bulletList.length);
    }
}
}

function moveBullet(){
    for(let i = 0; i < bulletList.length; i++){
        bulletList[i].x += bulletList[i].speed;
        bulletList[i].lifeDistance -=  bulletList[i].speed; // 이동한만큼 생명 거리를 감소시킨다.
        if(bulletList[i].lifeDistance <= 0){
            bulletList.splice(i , 1);  // 삭제한다.
        }
    }
}

function drawBullet(){
    ctx.beginPath();

    for(let i = 0; i < bulletList.length; i++){

        ctx.rect(bulletList[i].x, bulletList[i].y, bulletList[i].width, bulletList[i].height);
        ctx.fillStyle = bulletList[i].color;
        ctx.fill();
    }
   
    ctx.closePath();
}

//-------------------------------------------------

window.addEventListener("keydown", (e) => {
    if(e.code == 'Space') {  
        key.fire = true;
    }
    console.log(e.code);
});

window.addEventListener("keyup", (e) => {
   if(e.code == 'Space') {  
        key.fire = false;
    }
});
//----------------------------------------------------------------------------
let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");

let key = { "fire" : false };
let rect = {
    "x" : 100,
    "y" : 100,
    "width" : 50,
    "height" : 50,
    "speed" : 2,
    "color" : "blue",
    "cooldown" : 0,
    "cooldownmax" : 20
};

// 한 화면에 최대한 발사할 수 있는
// 총알의 개수를 10개로 제한한다.
let bulletMax = 10;
let bulletList = [];

setInterval(draw, 10);

 


keyOnce.html

 

<!DOCTYPE html>
<html lang="ko">
<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>
    <h1>F12 를 눌러 콘솔창을 확인한다. </h1>
    <h1> 계속눌림 : A S D W </h1>
    <h1> 한번만눌림 : space</h1>
    <canvas id="myCanvas" width="800" height="600" style="border: 1px solid black;">
    </canvas>
    <script src="keyOnce.js"></script>
</body>
</html>

 


keyOnce.js

 

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // 앞으로 키보드조작은 아래와 같이 함수를 따로만들어서 사용하길 권장한다.
    if(getKeyStay("left")){
        console.log("계속눌림left");
    }
    if(getKeyStay("up")){
        console.log("계속눌림up");
    }
    if(getKeyStay("right")){
        console.log("계속눌림right");
    }
    if(getKeyStay("down")){
        console.log("계속눌림down");
    }

    if(getKeyOnce("fire")){
        console.log("한번만눌림fire")
    }
}

//-------------------------------------------------
function getKeyOnce(key){
    // 중간값인 down을 넣어서 여러번 눌리는것을방지한다.
    if(keyOnce[key] == "true") {
        keyOnce[key] = "down";
        return true;
    }
    else if(keyOnce[key] == "down") {
        return false;
    }
}

function getKeyStay(key){
    return keyStay[key];
}

window.addEventListener("keydown", (e) => {
    if(e.code == 'KeyD') {    
        keyStay.right = true;
    }
    if(e.code == 'KeyA') {  
        keyStay.left = true;
    }
    if(e.code == 'KeyW') {  
        keyStay.up = true;
    }
    if(e.code == 'KeyS') {  
        keyStay.down = true;
    }
    if(e.code == 'Space'){
        keyOnce.fire = "true";
    }
});

window.addEventListener("keyup", (e) => {
    if(e.code == 'KeyD') {        
        keyStay.right = false;
    }
    if(e.code == 'KeyA') {  
        keyStay.left = false;
    }
    if(e.code == 'KeyW') {    
        keyStay.up = false;
    }
    if(e.code == 'KeyS') {  
        keyStay.down = false;
    }
    if(e.code == 'Space'){
        keyOnce.fire = "up";
    }
});
//----------------------------------------------------------------------------
let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");

// 키가 한번만 눌리게 만들기 위해서는 함수를 따로 만들어야한다.
// 변수명을 key에서 keyStay로 변경한다.
// 변수명을 key에서 keyOnce로 변경한다.

let keyStay = {"right":false, "left":false, "up":false, "down":false};
let keyOnce = {"fire" : "up"}; // up , true , down

setInterval(draw, 10);

 


fireOnce.html

 

<!DOCTYPE html>
<html lang="ko">
<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>
    <h1> 이동키 : A S D W </h1>
    <h1> 총알발사 : space</h1>
    <canvas id="myCanvas" width="800" height="600" style="border: 1px solid black;">
    </canvas>
    <script src="fireOnce.js"></script>
</body>
</html>

 


fireOnce.js

 

function draw() {

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    drawRect();

    bulletFire();

    drawBullet();

    moveBullet();

}

function moveBullet(){
    for(let i = 0; i < bulletList.length; i++){
        bulletList[i].x += bulletList[i].speed;
        bulletList[i].lifeDistance -=  bulletList[i].speed; // 이동한만큼 생명 거리를 감소시킨다.
        if(bulletList[i].lifeDistance <= 0){
            bulletList.splice(i , 1);  // 삭제한다.
        }
    }
}

function bulletFire(){
   
    if(getKeyOnce('fire')  && bulletList.length < bulletMax){
        let bullet = {
            "x" : myRect.x +50,  // 가운데서 발사시키기 위해 조금 아래에 위치
            "y" : myRect.y +15,
            "width" : 20,
            "height" : 20,
            "speed" : 5,
            "color" : "black",
            "lifeDistance" : 500, // 총알 생명거리 => 총알이 일정거리 이동하면 삭제해준다. 그래야 새총알을 발사할수있다.  
        };
   
        bulletList.push(bullet);

    }
}
function drawBullet(){
    ctx.beginPath();
    for(let i = 0; i < bulletList.length; i++){

        ctx.rect(bulletList[i].x, bulletList[i].y, bulletList[i].width, bulletList[i].height);
        ctx.fillStyle = bulletList[i].color;
        ctx.fill();
    }
    ctx.closePath();
}

function drawRect(){

    ctx.beginPath();

    ctx.rect(myRect.x, myRect.y, myRect.width, myRect.height);
    ctx.fillStyle = myRect.color;
    ctx.fill();
    ctx.closePath();
}


//-------------------------------------------------

function getKeyOnce(key){
    // 중간값인 down을 넣어서 여러번 눌리는것을방지한다.
    if(keyOnce[key] == "true"){ //keyOnce.fire == "true"
        keyOnce[key] = "down"; //keyOnce.fire = "down"
        return true; // getKeyOnce = true;
    }
    if(keyOnce[key] == "down") { //keyOnce.fire = down
        return false;
    }
}
function getKeyStay(key){
    return keyStay[key];
}
window.addEventListener("keydown", (e) => {
    if(e.code == 'KeyD') {         // d
        keyStay.right = true;
    }
    if(e.code == 'KeyA') {   // a
        keyStay.left = true;
    }
    if(e.code == 'KeyW') {    // w
        keyStay.up = true;
    }
    if(e.code == 'KeyS') {   // s
        keyStay.down = true;
    }
    if(e.code == 'Space'){
        if(keyOnce.fire == "up"){
            keyOnce.fire = "true";
        }
    }
});

window.addEventListener("keyup", (e) => {
    if(e.code == 'KeyD') {         // d
        keyStay.right = false;
    }
    if(e.code == 'KeyA') {   // a
        keyStay.left = false;
    }
    if(e.code == 'KeyW') {    // w
        keyStay.up = false;
    }
    if(e.code == 'KeyS') {   // s
        keyStay.down = false;
    }
    if(e.code == 'Space'){
        keyOnce.fire = "up"; //key up => fire : up
    }
});
//----------------------------------------------------------------------------
let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d");
// 변수명을 key 에서 keyStay로 변경한다.
let keyStay = { "right" : false , "left" : false, "up" : false , "down" : false , };

let keyOnce = {"fire" : "up"}; // up , true , down
let myRect = {
    "x" : 100 ,
    "y" : 100 ,
    "width" : 50,
    "height" : 50,
    "speed" : 2,
    "color" : "blue",
};
let bulletMax = 10; // 총알개수에 제한이 있어야한다.
let bulletList = [];

setInterval(draw, 10);

 


총알발사.html

 

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <canvas id="myCanvas" width="800px" height="600px" style="border: 1px solid black;"></canvas>
    <script src="./총알발사.js"></script>
</body>
</html>

 


총알발사.js

 

function drawrect(){
    cnt.clearRect(0, 0, myCanvas.width, myCanvas.height);
    draw();
    moveRect();
    bulletFire();
    drawBullet();
    moveBullet();
}
function moveRect(){
    if(key.left) myrect.x -= myrect.speed;
    if(key.up) myrect.y -= myrect.speed;
    if(key.right) myrect.x += myrect.speed;
    if(key.down) myrect.y += myrect.speed;
}
function draw(){
    cnt.beginPath()
    cnt.rect(myrect.x, myrect.y, myrect.size, myrect.size);
    cnt.fillStyle = myrect.color;
    cnt.fill();
    cnt.closePath();
}
function bulletFire(){
    if(keyOnce(key.fire) == true && bulletList.length <= bulletmax){
        let bullet = {
            "x": myrect.x + myrect.size,
            "y": myrect.y + myrect.size / 2,
            "color": "black",
            "size": 10,
            "speed" : 4
        }
        bulletList.push(bullet)        
    }
}
function keyOnce(fire){
    if(fire == "true") {
        key.fire = "down"
        return true;
    }
    if(fire == "down") return false;
}
function drawBullet(){
    cnt.beginPath();

    for(let i = 0; i < bulletList.length; i++){

        cnt.rect(bulletList[i].x, bulletList[i].y, bulletList[i].size, bulletList[i].size);
        cnt.fillStyle = bulletList[i].color;
        cnt.fill();
    }
   
    cnt.closePath();
}
function moveBullet(){
    for(let i = 0; i < bulletList.length; i++){
    bulletList[i].x += bulletList[i].speed
    if(bulletList[i].x >= myCanvas.width){
        bulletList.splice(i, 1);
    }
}
}
window.addEventListener(`keydown`, (a)=>{
    if(a.code == "ArrowLeft") key.left = true;
    else if(a.code == "ArrowUp") key.up = true;
    else if(a.code == "ArrowRight") key.right = true;
    else if(a.code == "ArrowDown") key.down = true;
    else if(a.code == "Space" && key.fire == "up") key.fire = "true";
});
window.addEventListener("keyup", (a)=>{
    if(a.code == "ArrowLeft") key.left = false;
    else if(a.code == "ArrowUp") key.up = false;
    else if(a.code == "ArrowRight") key.right = false;
    else if(a.code == "ArrowDown") key.down = false;
    else if(a.code == "Space") key.fire = "up";
})
//====================================================
let myCanvas = document.querySelector(`#myCanvas`);
let cnt = myCanvas.getContext("2d");
let bulletList = [];
let bulletmax = 10;
let key = {"left": false, "up": false, "right": false, "down": false, "fire": "up"}
let myrect = {
    "x": 100,
    "y": 100,
    "color": "blue",
    "size": 50,
    "speed": 2
}

setInterval(drawrect, 10);