Trip to Python

파이썬 Pong game 만들기

Kestrel 2022. 12. 20. 23:49

개발을 공부한지 얼마 안된거 같은데 이상하게 지치고 피곤하고 하기도 귀찮고.....의지가 무너졌었다. 어제 생일이었는데 겨우 마음을 다잡고 오늘 파이썬 공부를 다시금 시작했다. 뭔가 조금씩 만들어가고 있는데 작동될 때마다 참 신기하다. 이번에는 Pong 게임을 만들었는데 뭔가를 만들어 간다는게 동기 부여가 된다.

 

1. 화면 세팅

from turtle import Screen

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

screen.exitonclick()

 

- 화면을 세팅한다.

 

2. Paddle 만들기

from turtle import Turtle

class Paddle(Turtle):

  def __init__(self):
      super().__init__()
      self.penup()
      self.shape("square")
      self.shapesize(stretch_wid=5, stretch_len=1)
      self.color("white")
      self.goto(350, 0)

- 새로운 파일을 생성하여 패들을 하나 생성하게 해주는 클래스를 생성하였다. turtle class 상속을 통해 바로 작업을하였다. 다음 작업으로는 이 패들이 두 개 필요하다는 것이다. 그리고 이 패들을 위 아래로 조정이 가능하게 만들어야한다.  

 

3. Paddle 개체화 및 위 아래 조정

class Paddle(Turtle):

    def __init__(self, position):
        super().__init__()
        self.penup()
        self.shape("square")
        self.shapesize(stretch_wid=5, stretch_len=1)
        self.color("white")
        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)

- position을 변수로 할당하여 새로운 개체를 만들기 용이하게 만들고 goto를 통해 위 아래 위치 값을 조정하여 위 아래 이동을 가능한 함수를 Paddle 클래스에 구성하였다.

 

from turtle import Screen
from paddle import Paddle

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

r_paddle = Paddle((350, 0))
l_paddle = Paddle((-350, 0))

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")

screen.exitonclick()

- main에는 각 위치값을 넣어 왼쪽,오른쪽 패달을 구성하고 키값을 부여하여 위 아래 작동이 가능하도록 만들었다.

 

4. ball 개체 생성

 

from turtle import Turtle

class Ball(Turtle):

    def __init__(self):
        super().__init__()
        self.penup()
        self.shape("circle")
        self.color("white")
        self.x_move = 10
        self.y_move = 10
        
    def move(self):
        new_x = self.xcor() + self.x_move
        new_y = self.ycor() + self.y_move
        self.goto(new_x, new_y)

- ball을 구성하고 처음 시작을 우상향으로 공이 가도록 설정하였다. self.x_move는 원래 10으로 설정해 하드코딩하였으나 나중에 변경하였다. 다음으로는 가장 어려웠던 공을 튀는 설정이다. 사실 나는 물리적인 내용이 필요한 것이 아니었나 싶었는데 강사님은 그냥 +, - 를 변경하여 90도로 꺾이게 만들었다.

 

5. 공이 어떨 때 튀기게 할 것인가1 (위아래 벽에 부딫일 경우)

 

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()

- 이 부분은 저번 snake 게임 만든 것과 마찬가지로 개체의 좌표값이 일정 수치를 넘어가면 반응하는 조건으로 만들었다. 튀기게하는 것은 이전에 언급했던 부호를 바꾸어 이동 방향을 변경해주었다. 그것을 bounce 함수로 ball 클래스에 만들었다.

 

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

6. 공이 어떨 때 튀기게 할 것인가1 (패들에 부딫일 경우)

 

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

 

- 사실 이 부분을 떠올리기 어려웠는데 패들 이하로 내려가지 않으면서 동시에 패들의 좌표값과 공의 좌표값의 거리 기준을 설정하 튀기 만들었다. 보면 쉽지만 초보자라 떠올리는 것은 어려웠다. 다음은 스코어보드로 snake 게임과 거의 비슷하다.

 

7. Scoreboard 설정하기

 

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(x=-100, y=200)
        self.write(self.l_score, align="center", font=("Courier", 80, "normal"))
        self.goto(x=100, y=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()

-딱히 설명할 필요가 없을 듯하다. 개체를 만들고 위치로 보내고 점수를 올려주는 함수를 구성한다. 다음으로는 또 어려웠던 언제 점수를 얻을 것인가이다.

 

8. 점수를 얻는 기준 세우기

 

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()

 

- 패들 아래로 공의 좌표값이 이동하면 포인트를 어디로 빠져나가는지에 따라 상대방에게 점수를 주면 된다. 추가로 공의 위치를 재조정하는 함수를 추가하여 자동으로 재시작하도록 설정하였다.

 

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

- 강사님이 서브 방향을 매번 바꿔주는 것이 좋겠다고 생각해 bounce 함수를 추가