The Pong Game

  1. Create the screen
  2. Create and move a paddle
  3. Create another paddle
  4. Create the ball and make it move
  5. Detect collision with wall and bounce
  6. Detect collision with paddle
  7. Detect when paddle misses
  8. Keep score



Create the screen

1



Create and move a paddle

1️⃣ paddle 생성

2


2️⃣ 위, 아래로 움직이게 설정

3

  • 함수를 인자로 넣을 때 괄호 붙이면 안됨
  • xcor()와 같은 메서드는 괄호를 필요로 함
    ⭐️ 괄호가 있으면 그것은 함수나 메서드를 호출하고 반환값
    ⭐️ 괄호가 없으면 함수나 메서드 자체를 참조


3️⃣ paddle이 자리로 이동하는 애니메이션 제거

  • paddle이 만들어 지기 전 tracer(0)으로 화면 끄기
  • paddle이 만들어 진 후 화면 계속 업데이트 하도록 while반복문
game_is_on = True
while game_is_on:
    screen.update()



Create another paddle

1️⃣ paddle클래스 만들기

6


한꺼번에 수정하는 방법

5


2️⃣ 좌우 패들 객체 만들고 터플로 좌표 설정하기

tuple을 쓰는 이유

4


3️⃣ 좌우 패들 키 설정

7



Create the ball and make it move

1️⃣ 볼 클래스 생성

8


2️⃣ 볼 객체 생성, 속도 조정

  • 화면을 갱신하기 전에 약간의 지연을 만듦
  • 볼은 게임이 진행되는 내내 움직이므로 반복문 안에

9



Detect collision with wall and bounce

  • 상단벽과 하단벽에 부딪혔을 때만 충돌 감지

1️⃣ 움직이는 좌표를 속성으로 설정

  • 공의 좌표를 얼마씩 증가시킬지 정의

2️⃣ 튕겨 나가는 기능 메소드 생성
벽에 팅겨 나갈 때 좌표가 +10이었다면 -10으로
-10이면 +10으로 되어야 하므로 곱하기 -1

10


3️⃣ main.py에 조건문 써주기

11



Detect collision with paddle

1️⃣ 공과 패들 사이 거리 측정하기

  • distance메소드는 공의 중앙에서 패들 중앙 사이의 거리만 측정함
💡패들 100x20, 공 20x20, 패들 위치 (350,0) or (-350,0)
공의 x좌표가 패들안쪽면 x값인 ~~340보다 크고~~(공이 겹쳐서 320으로 수정)
공과 패들 사이의 거리가 50보다 가깝게 설정


2️⃣ x축도 y축과 마찬가지로 팅겨나가는 메소드 만들어주기

def bounce_x(self):
    self.x_move *= -1


3️⃣ 조건문 작성

12



Detect when paddle misses

  • 패들은 340에서 360까지 걸쳐 있음
  • 370은 공이 20x20이므로 패들과 겹쳐있는 상태임
  • 380(혹은 -380)을 지나면 확실히 공을 놓친 것

1️⃣ 공을 원점으로 돌려놓는 메소드 생성
리셋되면 이전 공 방향과 반대로 갈 수 있게 bounce_x메소드 넣어줌

def reset_position(self):
    self.goto(0, 0)
    self.bounce_x()


2️⃣ 양쪽 패들 공 놓쳤을 때 조건문 따로 써주기

  • 점수를 누가 땄는지 확인하기 위해서

13



Keep score

1️⃣ Scoreboard 클래스 생성 후 main.py에 객체 생성

  • 속성값 넣어주기


2️⃣ 점수 올리는 메소드 생성

  • 점수 쓰는 코드를 따로 메소드 생성
  • 점수 갱신되기 전에 clear() 넣어주기

14



공 스피드 증가시키기

1️⃣ Ball클래스의 속성값 추가

2️⃣ 공을 팅겼을 때 메소드에 스피드 증가 코드 넣어주기

3️⃣ 리셋시 속도 되돌리기

15

16



Final code for paddle.py

from turtle import Turtle


class Paddle(Turtle):
    def __init__(self, position):
        super().__init__()
        self.shape("square")
        self.color("white")
        self.shapesize(stretch_wid=5, stretch_len=1)
        self.penup()
        self.goto(position)

    def go_up(self):
        new_y = self.ycor() + 20
        self.goto(self.xcor(), new_y)

    def go_down(self):
        new_y = self.ycor() - 20
        self.goto(self.xcor(), new_y)



Final code for ball.py

from turtle import Turtle


class Ball(Turtle):
    def __init__(self):
        super().__init__()
        self.color("white")
        self.shape("circle")
        self.penup()
        self.x_move = 10
        self.y_move = 10
        self.move_speed = 0.1

    def move(self):
        new_x = self.xcor() + self.x_move
        new_y = self.ycor() + self.y_move
        self.goto(new_x, new_y)

    def bounce_y(self):
        self.y_move *= -1

    def bounce_x(self):
        self.x_move *= -1
        self.move_speed *= 0.9

    def reset_position(self):
        self.goto(0, 0)
        self.move_speed = 0.1
        self.bounce_x()



Final code for scoreboard.py

from turtle import Turtle


class Scoreboard(Turtle):
    def __init__(self):
        super().__init__()
        self.color("white")
        self.penup()
        self.hideturtle()
        self.l_score = 0
        self.r_score = 0
        self.update_scoreboard()

    def update_scoreboard(self):
        self.clear()
        self.goto(-100, 200)
        self.write(self.l_score, align="center", font=("Courier", 80, "normal"))
        self.goto(100, 200)
        self.write(self.r_score, align="center", font=("Courier", 80, "normal"))

    def l_point(self):
        self.l_score += 1
        self.update_scoreboard()

    def r_point(self):
        self.r_score += 1
        self.update_scoreboard()



Final code for main.py

from turtle import Screen, Turtle
from paddle import Paddle
from ball import Ball
from scoreboard import Scoreboard
import time

screen = Screen()
screen.bgcolor("black")
screen.setup(width=800, height=600)
screen.title("Pong")
screen.tracer(0)

r_paddle = Paddle((350, 0))
l_paddle = Paddle((-350, 0))
ball = Ball()
scoreboard = Scoreboard()

screen.listen()
screen.onkey(r_paddle.go_up, "Up")
screen.onkey(r_paddle.go_down, "Down")
screen.onkey(l_paddle.go_up, "w")
screen.onkey(l_paddle.go_down, "s")


game_is_on = True
while game_is_on:
    time.sleep(ball.move_speed)
    screen.update()
    ball.move()

    if ball.ycor() > 280 or ball.ycor() < -280:
        ball.bounce_y()

    if ball.distance(r_paddle) < 50 and ball.xcor() > 320 or ball.distance(l_paddle) < 50 and ball.xcor() < -320:
        ball.bounce_x()

    if ball.xcor() > 380:
        ball.reset_position()
        scoreboard.l_point()

    if ball.xcor() < -380:
        ball.reset_position()
        scoreboard.r_point()

screen.exitonclick()