배움 __IL/TIL 1기

TIL : 26번째- 230103 [1-1-화]

Mo_bi!e 2023. 1. 3. 19:17

I. INTRO : 어제것

어제 boy에게 지령을 내렸다.

우리는 창조적인 작업하고 있음, 움직임!

 

이는 우리가 넘어갈수없는 세상에 객체를 만들었다 boy라는 입주민이다

입주민은 스스로 혹은 내가 지령받은애가 움직이는 애가있다.

 

우리는 canvaswindow쓴다. canvas는 입력뿐만 아니라 출력도 해준다.

어제 클릭이라는 입력까지 해봤음 

 

이 외에도 스스로 움직이는 캐릭터가 필요하다.

 

과거 부터 히스토리 남아있는데, 과거 데이터말고 현재 데이터만 보면된다.

이런거 보면 우리가 화면을 다시 그린다.

 

II. 캐틱터 움직이기 위해서 이전 캐틱터 지우기

1. 들어가며 

- 클릭할때 마다 이벤트 발생

일단 우리는 애니메이션처럼

내가 멈춰있던 가던 간에 계속 그리게끔 하는데, 몇 프레임 그리는지를 결정하면된다.

 

60프레임으로 상정하자

멈춰있는지 여부 상관없음 본 작업을 해보자

 

2. 애니메이션처럼

그 이전에 코드가 길다.

boy 파일을 별도로 만들자.

 

<Boy.js>

//boy 라는 생성자함수
//정면바라보는 기본값 초기화하기

var Boy = function(x , y){
    this.sw = 106;
    this.sh = 148.25;

    this.ix = 1;
    this.iy = 3;

    this.sx = this.sw * this.ix;
    this.sy = this.sh * this.iy;


    //시작 기본위치 정해주기
    this.x = x || 100;
    this.y = y || 100;

    console.log(this);

}

Boy.prototype = {

    draw : function(ctx){

        // console.log(this); //
        console.log("10------------구분----------");

        var img = new Image();
        img.src = "./image/boy.png";

        img.onload = function(){
            // console.log(this); //
            console.log("11------------구분----------");

            ctx.drawImage(img,
                this.sx,this.sy,this.sw,this.sh,
                this.x,this.y,105,148.24)
        }.bind(this);
        // }

    },


    move : function(dir){
        console.log("move 구분용");

        switch(dir){
            case 1: this.y -= 10; //북
                break;
            case 2: this.x += 10; //동
                break;
            case 3: this.y += 10; //남
                break;
            case 4: this.x -= 10; //서
                break;
            // default : this.x = 0 ;
            //           this.y= 0;
        }
    }      
}

- 다만 웹에서는 파일명을 대문자로 시작 지양

소문자로 해야한다. (알아두자)

 

- 캡슐화 : 은닉화

데이터 구조화 함수를 묶어두는 것

책임을 부여하는 것(☆역할을 나누어주기)

그렇지 않으면 main함수에 다 몰려있다.

 

만약 구조화만 있고 캡슐화만 안 되어있으면 본 데이터구조는 역할을 안받는다. 데이터만 쓴다

[mo think : 담아두는 것인데, 외부에 영향을 받지 않게끔해서 수정범위를 최소화할수있다.]

 

 

3. 캡슐화

(1)이론 

intro / game / ranking

intro : 코인넣어라

game : game 화면

ranking : 랭킹화면

이라는 각각의 캔버스가 필요하다

 

gameCanvas -> Boy

 

제타위키

(가지고 있어서 채워진 마름모◆ : Composition)

(비워진 마름모 ◇: aggregation)

★예

Composition: 는 만들 때 부터 4개바퀴 다 나와야

Aggregation : 학생 DB는 다 안나와도 됨 

 

그래서 gameCanvas -> Boy

에서 내 아바타 하나만 있으면 됨 그래서 Composition로 관계를 가진다.

 

 

<클래스다이어그램>

GameCanvas --◆--> Boy

composiotion 으로 하기

(2)실습

1) 게임캔버스 해보기

function Gamecanvas (){ //생성자 만들기

    this.dom = document.querySelector(".game-canvas");
    //이미 캔버스라서 dom으로 하자
    /**@type {CanvasRenderingContext2D};*/
    this.ctx = this.dom.getContext("2d");
    this.boy = new Boy(100,100);

    this.dom.onclick = this.clickHandler.bind(this);
     //bind는 호출할때가 아니라 위임할 때
}

Gamecanvas.prototype = { //프타는 생성자에만 있다

    run : function(){
        //초당 60프레임 화면을 다시 그리는 코드
        this.update();
        this.draw();
    },

    update : function(){ //상태바뀐것 점진적으로
        //움직일것 있으면 한턴식 업데이트 (조금씩)
        //캐릭터뿐만 아니라, 맵도

        //얘가 필요없는 애는 바로 움직이는것이 충분한 애들


    },

    draw : function(){
        this.boy.draw(this.ctx);
    },


    // ------event 핸들러---------------
    clickHandler : function(){

        this.boy.move(2);
        this.boy.draw(this.ctx);

        console.log(this);
    }

}

 

 

2) JS import 순서

 

ES5는 스크립트간 관계를 자동적으로 이어주지 못한다.

그래서 html에 별도로 선언해주어야한다.

<!DOCTYPE html>
<html lang="en">
<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>canvas</title>

    <!-- 가져오는 순서 유의하기  
    요리하다가 후리아팬 사러가는게 아님
    먼저 후라이팬 부터! 즉 부품부터!--> 
    <script src="./items/boy.js"></script>
    <script src="./panel/game-canvas.js"></script>
    <script src="./app.js"></script>
    
    
    
</head>
<body>
    <!-- <img src="./img/boy.png" alt=""> -->
    <canvas class="game-canvas" width="700" height="700"></canvas>
</body>
</html>

 

이 경우 부품부터 순서대로 해야한다

요리시에 후라이팬이라는 준비물 사러가는게 아님

 

3) canvas 선언된적 없다.

this를 쓰지않아서, 만들어진 인스턴스와 관계가 적기 때문이다.

 

 

4) ctx 문제

bind가 이용되지않음

bind 를 쓰지 않으면, canvas의 객체에 바인딩이 된다.

그 결과 onclick에 함수는 Gamecanvas 객체와 관련된 것이 아니게된다.

bind를 써서 지정해주어야한다.

 

this.dom.onclick = this.clickHandler.bind(this);

function Gamecanvas (){ //생성자 만들기

    this.dom = document.querySelector(".game-canvas");
    //이미 캔버스라서 dom으로 하자
    /**@type {CanvasRenderingContext2D};*/
    this.ctx = this.dom.getContext("2d");
    this.boy = new Boy(100,100);

    this.dom.onclick = this.clickHandler.bind(this);
     //bind는 호출할때가 아니라 위임할 때
}

여기서 onclick 은 고유의 기능을 가진것으로

본 프로퍼티명을 바꾸면 click 할때 이벤트 핸들러와는 무관해진다.

 

 

☆- 위임,callback(회신전화) 함수

 

캔버스는 사용자 행위를 기다림

그러다가 사용자가 클릭 행위하면 호출해주는 함수임

일반적인 방식과 달리 내가 호출하는게 아니라 내가 클릭하면 호출해줌

이게 왜 콜백함수?

 

콜백은 지금이 아니라 나중에

함수는 내가 콜 할수있다, 그런데 어떤함수는 쟤가 콜(클릭)해야 실행

이 함수를 위임해주고 나중에 실행

상황되면 나중에 실행

 

위임해야 나중에 실행

 

this.dom.onclick = this.clickHandler;
     //bind는 호출할때가 아니라 위임할 때
 

dom 이 나중에 호출

이러면 dom이 호출해서 this는 dom이된다

.bind(this)로 하면 게임캔버스가 된다. 

 

4. 잔상없애주기

(1) Background

배경으로 하여금 잔상이 지워지게끔 덮어 씌우기로 가능하다.

 

그런데 배경은 객체인가?

캐릭터가 벽을 만나면, 더 움직이게 하기 위해서 배경이 움직이게끔 해야한다.

 

function Background(){


}

Background.prototype = {

    scroll : function(dir){

        switch(dir){
            case 1: this.y -= 10; //북
                break;
            case 2: this.x += 10; //동
                break;
            case 3: this.y += 10; //남
                break;
            case 4: this.x -= 10; //서
                break;
            // default : this.x = 0 ;
            //           this.y= 0;
        }
    },
    
    update : function(){


    },
 
    draw : function(ctx){

        var img = new Image();
        img.src = "./image/map.png";
    }
}

3개의 메소드에 대해서 이런 방식으로 선언해준다.

 

(2) update()

캐틱터가 움직일 때 그 상태는 순간이동이 아니라 점진적으로 움직여야한다

이경우 캐릭터도 그렇지만, 배경도 캐릭터가 배경 끝에 있으면 같이 움직여야한다

결국 캐릭터뿐만 아니라 배경도 update()를 이용해주어야한다.

 

III. ES6

1. 차이점

(1) ES5 -> ES6

1) 모듈 시스템이 없었다 -> 可

2) 객체지향 지원 X(정의 X , 프로토타입으로) -> 可

3) 변수 사용 지역화 개선 -> 可

4) private -> 可

5) 심볼릭 -> 可

 

(2) let

지역화 변수충돌 방지 가능하다

var를 쓴다는 것은 의도적으로 하는 것이 아니면, 좋은 방법이 아님

 

(3) const

자바의 final과 동일함

C의 const와 동일함

상수형변수로 이용함 

 

아래와 같이 하면 x=2 를 하면 오류가 발생한다.

    const x = 30; //상수형이나 일반변수 처럼 보이기 어렵다
    //타언어는 대문자로 함 그러나 JS는 이렇게 함

    x = 2;

2. 객체 선언

let kor = 20;
let eng = 30;

//------------------es6
let obj = {kor,eng,total(){
    return this.kor + this.eng;
}};

function print({kor,eng}){
    let total = obj.total();

    console.log("kor : "+ kor);
    console.log("eng : "+ eng);
    console.log("total : "+ total);
}


//------------------es5
let obj1 = {

    kor : kor,
    eng : eng,
    total:function(){
        return this.kor + this.eng;
    }

}

function print1(exam){
    let kor = exam.kor;
    let eng = exam.eng;
    let total = exam.total();

    console.log("kor : "+ kor);
    console.log("eng : "+ eng);
    console.log("total : "+ total);
}

(1) ES5

ES5의 경우 앞서 보았던 것과 마찬가지이다.

 

(2) ES6

1) obj1

kor, eng 처럼 중복되는 부분은 한번만 표기하고 마찬가지로 프로퍼티간 쉼표로 구분한다

그리고 메소드의 경우 다음과 같이 선언할수도있다.

 

2) print1

매개변수에 중괄호로 통채로 넣어주기가 가능하다.

다만 이런경우에는 변수만 가능한것이고, 메소드는 하는것이 바람직하지않다.

 

비단 이런방법 뿐만 아니라 비구조화 방식도있다.

 

2.  Destructuring(비구조화, 파괴)

비구조화 파괴는 객체뿐만 아니라 배열도 가능하다

이 경우 배열은 인덱스를 기준으로 비구조화를 한다.

 

객체의 경우에는 key를 기준으로 객체파괴되어 할당을한다.

 

let obj1 = {
    kor : kor,
    eng : eng,
    total:function(){
        return this.kor + this.eng;
    }
}

function print2(exam){
            
            let {kor, eng, aa = 9} = exam;
            //뽀개기는 변수만!!
            //let {eng, kor, aa = 9} = exam;
            //순서 바꿔도 동일함
            
            console.log(aa);
            // 세번째 aa하면 undefined
            // aa = 9 하면 9가 들어간다.
            
            let total = exam.total();

            console.log("kor : "+ kor);
            console.log("eng : "+ eng);
            console.log("total : "+ total);
        }
        
 print2(obj1); //뽀개기

위와 같이 중괄호를 이용해서 매개변수로 받은 객체를 좌측으로 파괴한뒤 할당이 가능하다

이경우 상술한바 key값을 기준으로 한다

결국 kor, eng 의 순서와 상관없이 그 값이 그대로 할당된다

 

한편 aa는 기존에 없었던 값이다.

그결과 콘솔에서 보면 undefined가 되는데, aa=9를 해주면 동적으로 가능하다!

 

 

IV. 마무리

이제 세가지 생각

1. 클래스 등장 (프로토타입 들어온 내용으로 하기)

2. 변수를 선언방법 달라짐

3. 객체 뽀개기를 자주 쓰는데, 지역변수 선언방법이 생김


1. 보충

1) 콜백함수

 

2) 디스트럭쳐링

 

를 기준으로 객체를 파괴후 할당하거나

인덱스를 기준으로 배열을 파괴후 할당하기

 

 

2. 회고 

1) 캡슐화

캡슐화의 엄밀한 의미를 잊고있었다 역할을 부여해준다는 것도 잊지말아야지

 

2) 콜백에 대해서 구글링해서 보는것과 실제가 차이가 있는거 같다 좀 더 물어보고 해야겠다.

 

3) 디스트럭쳐링의 경우 key값을 기준으로해서 받아주는값이 무엇이든 상관없이 접근한다는게 신기하다.

 

4) DOM강의와 함께보니 좀 더 이해가 되어서 다행이다.

'배움 __IL > TIL 1기' 카테고리의 다른 글

TIL : 28번째- 230105 [1-1-목]  (0) 2023.01.05
TIL : 27번째- 230104 [1-1-수]  (0) 2023.01.04
TIL : 25번째- 230102 [1-1-월]  (0) 2023.01.02
TIL : 24번째- 221230 [12-5-금]  (0) 2022.12.30
TIL : 23번째- 221229 [12-5-목]  (1) 2022.12.29