정보실

웹학교

정보실

javascript 탁구게임을 코딩하는 방법!

본문

왜 탁구?


이 시리즈의 아이디어는 게임의 진화와 함께 진행되는 것이므로 우리는 처음부터 탁구부터 시작합니다. 

매주 저는 마지막 것보다 새로운 게임을 만드는 방법에 대한 블로그 튜토리얼을 발표 할 예정입니다. 

결국 약 50 주 만에 블로그는“Fortite를 코딩하는 방법입니다! (2017) -51 ″ 또는 아닙니다. p5.js 및 구문에 익숙하지 않은 경우 이전 블로그를 확인하십시오.


https://codeheir.com/2019/02/04/how-to-code-pong-1972-1/ 


Google에서 '첫 번째 게임을 만들었습니다'라는 Pong이 표시 될 경우 공식적으로 첫 번째 게임은 아니지만 상업적으로 성공한 첫 번째 게임입니다. 1972 년 6 월에 만들어졌습니다!

Image result for First game created 


설정 


웹 편집기를 여십시오!


위 이미지의 크기를 보면 높이 351, 너비 624, 검은 색 배경만으로 복사 해 보겠습니다.

function setup() {
  createCanvas(624, 351);
}
 
function draw() {
  background(0);
}


패들 (Paddles) 


패들의 경우 새 패들 클래스를 만들고 프로젝트 폴더 | 파일 추가 | 그것을 Paddle.js라고 부릅니다


new-file.png?w=1060 


그런 다음 index.html에서 이 파일을 참조하면 스케치에서 파일에 액세스 할 수 있습니다.


Index.html 

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />
 
  </head>
  <body>
    <script src="sketch.js"></script>
    <script src="Paddle.js"></script> <!-- add this! -->
  </body>
</html>


Paddle.js 


따라서 우리의 패들 클래스는 생성자에서 숫자를 가져옵니다.이 숫자는 패들의 x 위치를 나타냅니다. 두 개의 패들을 만들 때 두 패들 사이에서 유일한 것이기 때문에 x 위치 만 지정하면 됩니다. 클래스와 생성자에 익숙하지 않은 경우 이 기능을 간단히 익히고 속도를 높이는 것이 좋습니다.

class Paddle {
 
    constructor(x) {
        this.x = x;
        this.y = height / 2; // height is height of display window
        this.height = 80;
        this.width = 20;
    }
     
     
    display() {
        fill(255);
        rect(this.x, this.y, this.width, this.height);
    }
 
}


우리는 display()라는 함수를 만들었습니다. 이것은 우리의 패들이 캔버스에 보이도록 호출 될 것입니다!


sketch.js 


sketch.js로 돌아가서 setup()에서 패들 객체를 만든 다음 그 패들에서 display()를 호출합니다. 이는 display() 함수가 초당 60 번 호출됨을 의미합니다!

let playerPaddle;
 
function setup() {
  createCanvas(624, 351);
  playerPaddle = new Paddle(26);
}
 
function draw() {
  background(0);
  playerPaddle.display();
}


당신은 이것처럼 피 묻은 화려함을 가져야 합니다.

rectange.png?w=1060 


다른 것을 빨리 추가합시다! 아주 기본적인 인공 지능을 추가 할 때 iPaddle이라고 불렀습니다!

let playerPaddle;
let aiPaddle;
 
function setup() {
  createCanvas(624, 351);
  playerPaddle = new Paddle(26);
  aiPaddle = new Paddle(width - 48);
}
 
function draw() {
  background(0);
  playerPaddle.display();
  aiPaddle.display();
}


image-1.png?w=1060 


패들을 움직이게 만들기 


패들은 두 방향 중 하나만 위 또는 아래로 이동하면 됩니다. 패들 클래스에 up()과 down()이라는 함수를 만들어 봅시다.


class Paddle {
 
    constructor(x) {
        this.x = x;
        this.y = height / 2;
        this.height = 80;
        this.width = 20;
    }
     
     
    display() {
        fill(255);
        rect(this.x, this.y, 20, 80);
    }
     
    // add these little buggers
    up() {
        this.y -= 2;
    }
     
    down() {
        this.y += 2;
    }
     
}


player.Paddle을 sketch.js의 draw 함수에서 호출하여 위로 올려서 이것을 테스트 해 봅시다.


function draw() {
  background(0);
  playerPaddle.display();
  aiPaddle.display();
   
  // make that paddle fly!!!
  playerPaddle.up();
}


paddle-moving-up-2.gif?w=1060 


Key presses 


이상적으로, 실제로 게임을 하려면 패들을 제어해야 합니다.


가장 먼저 할 일은 Paddle 클래스에 커플 플래그를 추가하여 패들이 현재 움직이고 있는지 또는 아래로 움직이고 있는지를 추적하는 것입니다.이 플래그는 부울 값, isUp 및 isDown이며 true 또는 false입니다.

class Paddle {
 
    constructor(x) {
        this.x = x;
        this.y = height / 2;
        this.height = 80;
        this.width = 20;
         
        this.isUp = false;
        this.isDown = false;
    }


그런 다음 키 누르기에 p5.js 내장 함수를 사용할 수 있습니다! keyPressed 및 keyReleased. 따라서 위쪽 화살표를 클릭하면 Paddle 클래스의 isUp 플래그를 true로 설정하고 isDown 플래그를 false로 설정하여 현재 작동 중인 경우 중지 되도록 합니다. 그리고 화살표 (keyReleased)를 놓으면 플래그를 false로 설정합니다. 이 코드는 sketch.js에 있으며 draw() 함수 바로 아래에 있습니다.


function keyPressed() {
    if (keyCode == UP_ARROW) {
        playerPaddle.isUp = true;
    } else if (keyCode == DOWN_ARROW) {
        playerPaddle.isDown = true;
    }
}
 
function keyReleased() {
    if (keyCode == UP_ARROW) {
        playerPaddle.isUp = false;
    } else if (keyCode == DOWN_ARROW) {
        playerPaddle.isDown = false;
    }
}


그런 다음 실제로 플래그에 따라 up() 및 down() 함수를 호출해야 합니다. draw() 함수에서 이 기능을 사용했습니다.


function draw() {
  background(0);
     
  playerPaddle.display();
  aiPaddle.display();
 
  // make the player move according to the flag
  if (playerPaddle.isUp) {
    playerPaddle.up();
  } else if (playerPaddle.isDown) {
    playerPaddle.down();
  }
     
}


그런 다음 프로그램을 실행하고 버튼을 클릭하면!


paddle-moving.gif?w=1060 

아아, 화면에서 벗어날 수 있는 문제가 있음을 알 수 있습니다.


또한 다른 패들을 움직 일까 걱정하지 마십시오. 그러나 먼저 볼의 위치를 ​​알아야 합니다!


게임에서 패들을 유지 


그래서, 우리는 외륜이 화면 밖으로 움직일 수 없도록 막아야 합니다. 우리는 어떻게 지구에서 그렇게 합니까? up() 및 down() 함수에 로직을 추가해 봅시다.

up() {
    if (this.y > 0) {
        this.y -= 2;
    }
}
 
down() {
    if (this.y < height - this.height) {
        this.y += 2;   
    }
}


사각형의 x 및 y 위치는 왼쪽 상단을 나타냅니다. 따라서 전체 패들을 구속하기 위해 패들의 높이를 제거합니다!


image-2.png?w=1060 


constrain.gif?w=1060 


공을 추가! 


이 부분은 벽에서 튀어 나온 공을 추가함에 따라 p5.js 블로그에 대한 나의 소개와 매우 유사합니다! 나 자신을 너무 많이 반복하지 않기 위해 여기서 자세히 설명하지 않겠습니다.

  1. 새 파일을 Ball.js라고 부릅니다.
  2. index.html에서 이전에 했던 것과 같은 파일을 추가하십시오

공은 화면 중앙에 생성되며 -3에서 3까지의 임의의 방향이 주어지면 xSpeed ​​및 ySpeed로 정의되며,이 값은 업데이트 기능 내에서 각 프레임의 x 및 y에 추가됩니다!

class Ball{
 
 
    constructor() {
        this.r = 10;
        this.reset();
    }
     
     
    update() {
        // if it hits the top or bottom change direction
        if (this.y < this.r || this.y > height - this.r) {
            this.ySpeed = -this.ySpeed;
        }
        // if it goes to the end of the sreen restart the game
        if (this.x < this.r || this.x > width + this.r) {
            this.reset();
        }
         
        this.x += this.xSpeed;
        this.y += this.ySpeed;
     
    }
     
    reset() {
        this.x = width/2;
        this.y = height/2;
         
        this.xSpeed = random(3, 4);
         
        // determines if it's going left or right
        let isLeft = random(1) > .5;
        if (isLeft) {
            this.xSpeed = -this.xSpeed;
        }
         
        this.ySpeed = random(-3, 3);
    }
     
    display() {
        ellipse(this.x, this.y, this.r * 2, this.r * 2);
    }
     
     
}


이제 sketch.js에서 객체를 생성하고 스케치 그리기에서 ball objects update() 및 display() 함수를 호출하면 됩니다! (변경 사항을 보다 쉽게 ​​볼 수 있도록 추가 한 각 코드 줄 끝에 주석을 달았습니다)

let playerPaddle;
let aiPaddle;
let ball; // define the ball
 
function setup() {
  createCanvas(624, 351);
    playerPaddle = new Paddle(26);
    aiPaddle = new Paddle(width - 48);
    ball = new Ball(); // create the ball object
}
 
function draw() {
  background(0);
     
    playerPaddle.display();
    aiPaddle.display();
     
    if (playerPaddle.isUp) {
        playerPaddle.up();
    } else if (playerPaddle.isDown) {
        playerPaddle.down();
    }
     
    ball.update(); // call the update function within ball
    ball.display(); // call the display function within ball
     
}


ball-moving.gif?w=1060 


인공 지능 만들기 !! 


이것은 관심이 많은 장이 될 것입니다 .Google 심층을 조심하십시오! 인공 지능을 추가하겠습니다.


가장 먼저 해야 할 일은이 코드를 sketch.js 파일에서 꺼내는 것입니다. 두 플레이어 모두 이 코드를 사용하려면 패들 클래스에 넣습니다.


if (playerPaddle.isUp) {
    playerPaddle.up();
} else if (playerPaddle.isDown) {
    playerPaddle.down();
}


이제 우리는 update()라는 패들 클래스에 새로운 함수를 가지고 있습니다. 이것은 sketch.js에서 호출됩니다.


update() {
  if (this.isUp) {
    this.up();
  } else if (this.isDown) {
    this.down();
  }
}


AI! 


패들을 위해 AI를 만들려고 한다면 어떻게 할 것입니까? 글쎄, 여기 내 생각 과정이 있습니다. 내가 패 들인 경우 공이 내 위에 있으면 위로 올라가고, 공이 내 아래에 있으면 내려가십시오. 이것이 제가 코딩 한 것입니다.


아름다운 함수 processAI()를 만나보십시오. 패들의 중앙을 잡고 공이 위 또는 아래인지 결정합니다!


function draw() {
  background(0);
     
  playerPaddle.display();
  aiPaddle.display();
     
  playerPaddle.update(); // add this
  aiPaddle.update();     // and this
     
  processAI();   // andddd thiss
     
  ball.update();
  ball.display();
     
}
 
function processAI() {
  let middleOfPaddle = aiPaddle.y + aiPaddle.height / 2;
     
  if (middleOfPaddle > ball.y) {
    aiPaddle.isUp = true;
    aiPaddle.isDown = false;
  } else {
    aiPaddle.isDown = true;
    aiPaddle.isUp = false;
 
  }
}


그녀는 약간 불안하지만 지금은 할 것입니다 😀


my-ai.gif?w=1060 


공을 때리는! 


이제 우리는 실제로 패들을 튕겨 내기 위해 공이 필요합니다.


이를 위해서는 패들이 어떻게 다른지 고려해야 합니다. 가장 큰 차이점은 서로 다른 x 위치에 있다는 것입니다. 이는 동일한 적중 감지가 두 가지 모두에서 작동하지 않음을 의미합니다.


우리는 이것을 볼 클래스로 끌어 들인 3 가지 기능이 필요합니다. hasHitPlayer()는 플레이어 객체를 전달할 때 플레이어의 좌표를 사용하여 볼이 플레이어를 때렸는지 확인합니다! hasHitAi()는 동일하지만 x 위치가 다르므로 hasHamePlayer()와 hasHitAi() 모두에서 isSameHeight()를 사용할 수 있습니다.

hasHitPlayer(player) {
  if (this.x - this.r <= player.x + player.width && this.x > player.x) {
    if (this.isSameHeight(player)) {
      this.xSpeed = -this.xSpeed;
    }
  }
}
     
hasHitAi(ai) {
  if (this.x + this.r >= ai.x && this.x <= ai.x + ai.width) {
    if (this.isSameHeight(ai)) {
      this.xSpeed = -this.xSpeed;
    }
  }
}
         
isSameHeight(player) {
  return this.y >= player.y && this.y <= player.y + player.height
}



ball-collision.png?w=1060 


그리고 이제 우리는 실제로 게임을 할 수 있습니다 !!!


actual-game2.gif?w=1060 


중간 선! 


실제로 중요하지는 않지만 반은 줄을 추가합니다. 이것은 단지 2 줄의 코드이므로 휴식을 취하십시오!


sketch.js에서

function draw() {
  background(0);
     
  playerPaddle.display();
  aiPaddle.display();
     
  playerPaddle.update();
  aiPaddle.update();    
  processAI();
     
  ball.update();
  ball.display();
     
  ball.hasHitPlayer(playerPaddle);
  ball.hasHitAi(aiPaddle);
     
  stroke(255); // gives a white stroke
  line(width/2, 0, width/2, height); // draws a line between two points line(x,y,x1,y1)
     
}


half-way-line.gif?w=1060 


마지막으로 점수를 추가하겠습니다! 


스코어링 시스템이 없는 게임이 아닙니다. 자, 우리가 목표로 하는 것은 다음과 같습니다.

finished.gif?w=1060 


도전 


블로그에서 이 과정을 완료했습니다. 축하합니다. 점수 시스템을 구현하고 새로운 클래스를 추가하고 객체에 함수라는 객체를 만든 방법을 기억하십시오. 이것을 어떻게 구성 할 수 있는지 생각해보십시오. 배우는 가장 좋은 방법은 그렇게 하는 것이라 생각합니다. 따라서 손을 더럽히고 코드를 작성해야 합니다.


정말로 붙어 있다면 이 시리즈의 github에서 참조하기 위해 어떻게 했는지 확인하십시오. 이미 직접 구현 한 경우에도 어떻게 했는지 살펴 보는 것이 좋습니다. 다른 프로그래머가 문제를 해결하는 방법을 보는 것이 좋습니다. 완전히 새로운 관점을 제공 할 것입니다. 나는 당신과 다르게 해왔음을 거의 보장 할 수 있습니다. 그것이 프로그래밍의 아름다움입니다 !!








  • 트위터로 보내기
  • 페이스북으로 보내기
  • 구글플러스로 보내기
  • 카카오톡으로 보내기

페이지 정보

조회 45회 ]  작성일19-08-25 11:00

웹학교