본문 바로가기

Code-note

[프로젝트] PingPong 게임 만들기 -python

 

파이썬의 게임 라이브러리 turtle !
기초적인 형태의 ping pong 게임만들기
https://www.imperialusa.com/post/table-tennis-and-ping-pong-terms

** 핑퐁 게임 **
- 이동하는 공을 좌우의 패들을 움직여서 받아치는 게임
- 상단 위에 점수를 띄우고 양 끝 벽에 부딛힐 때, 점수를 1점 올림
- 위치 정보 : 중앙(0,0) / 좌측 끝(-390, y) / 우측 끝(+390, y) / 위 끝(x, +250) / 아래 끝(x, -240)
- 막대 이동 방법 : w/s(paddle A), Up/Down(paddle B)

핑퐁 게임 스크린 화면

import turtle
import time

* turtle : https://docs.python.org/3/library/turtle.html#tutorial

 

turtle — Turtle graphics

Source code: Lib/turtle.py Introduction: Turtle graphics is an implementation of the popular geometric drawing tools introduced in Logo, developed by Wally Feurzeig, Seymour Papert and Cynthia Solo...

docs.python.org

 

## 문제 1: 화면 설정 및 초기화
win = turtle.Screen() # screen object return
win.title("Ping Pong")
win.bgcolor("black")
win.setup(width=800, height=600)
win.tracer(0) # screen update stop

 

## 문제 2: 패들 생성
# paddle A
paddle_a = turtle.Turtle() # turtle object 생성됨
paddle_a.speed(0)
paddle_a.shape("square")
paddle_a.color("white")
paddle_a.shapesize(stretch_wid=6, stretch_len=1)
paddle_a.penup()
paddle_a.goto(-350,0) # 좌측 패들은 좌측 끝 중앙

# paddle B
paddle_b = turtle.Turtle() # turtle object 생성됨
paddle_b.speed(0)
paddle_b.shape("square")
paddle_b.color("white")
paddle_b.shapesize(stretch_wid=6, stretch_len=1)
paddle_b.penup()
paddle_b.goto(350,0) # 우측 패들은 우측 끝 중앙

* paddle A/B는 공을 받아 치는 양쪽 끝 막대를 의미함

## 문제 3: 공 생성 및 초기화
ball = turtle.Turtle()
ball.speed(1)
ball.shape("square")
ball.color("red")
ball.penup()
ball.goto(0,0) # 공은 중앙에 위치
ball.dx = 3 # 공의 x축 이동속도
ball.dy = -3 # 공의 y축 이동속도

* ball.dx/dy의 값을 수정하면 공의 속도를 바꿀수 있음

## 문제 4: 점수판 생성 및 초기화
score_a = 0 
score_b = 0

pen = turtle.Turtle()
pen.speed(0)
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0, 260)
pen.write("Player A: 0  Player B: 0", align="center", font=("Courier", 24, "normal"))

 

## 문제 5: 패들 움직임 함수 작성
# paddle은 y좌표로만 움직일 수 있다. 

# paddle A
def paddle_a_up():
    y= paddle_a.ycor() # 현재 y좌표
    if y < 250:
        y += 20
    paddle_a.sety(y) # y좌표 업데이트
def paddle_a_down():
    y= paddle_a.ycor() # 현재 y좌표
    if y > -240:
        y -= 20
    paddle_a.sety(y) # y좌표 업데이트

# paddle B
def paddle_b_up():
    y = paddle_b.ycor() 
    if y < 250:  
        y += 20
    paddle_b.sety(y) 

def paddle_b_down():
    y = paddle_b.ycor() 
    if y > -240: 
        y -= 20
    paddle_b.sety(y)

 

## 문제 6: 키보드 바인딩
win.listen() # 키보드 입력 기다림
win.onkeypress(paddle_a_up, "w")
win.onkeypress(paddle_a_down, "s")  
win.onkeypress(paddle_b_up, "Up")
win.onkeypress(paddle_b_down, "Down")

 

## 문제 7: 게임 메인 루프 및 공 이동
while True:
    win.update()
    
    # 공 이동
    ball.setx(ball.xcor() + ball.dx)
    ball.sety(ball.ycor() + ball.dy)
    
    # 위쪽 벽과 아래쪽 벽에 닿을 때 공의 반사
    if ball.ycor() > 290:
        ball.sety(290)
        ball.dy *= -1
    if ball.ycor() <-290:
        ball.sety(-290)
        ball.dy *= -1
    # 왼쪽 벽과 오른쪽 벽에 닿을 때 점수 및 공 위치 초기화
    if ball.xcor() > 390:
        ball.goto(0,0)
        win.update()
        time.sleep(2)
        ball.dx *= -1
        score_a += 1
        pen.clear()
        pen.write(f"Player A: {score_a}  Player B: {score_b}", align="center", font=("Courier", 24, "normal"))
        
    if ball.xcor() < -390:
        ball.goto(0,0)
        win.update()
        time.sleep(2)
        ball.dx *= -1
        score_b += 1
        pen.clear()
        pen.write(f"Player A: {score_a}  Player B: {score_b}", align="center", font=("Courier", 24, "normal"))
        
    # 패들과 공의 충돌 처리
    if (ball.dx > 0 and ball.xcor() > 340 and ball.xcor() < 350 and
        ball.ycor() < paddle_b.ycor() + 50 and ball.ycor() > paddle_b.ycor() - 50):
        ball.setx(340)
        ball.dx *= -1
    if (ball.dx < 0 and ball.xcor() < -340 and ball.xcor() > -350 and
        ball.ycor() < paddle_a.ycor() + 50 and ball.ycor() > paddle_a.ycor() - 50):
        ball.setx(-340)
        ball.dx *= -1

 

# 해당 코드는 오즈코딩스쿨의 프로젝트 과제의 일부 입니다.