Dev

[Python] 9. 터틀 크로싱 게임

mlslly 2024. 5. 6. 23:08

* Udemy PythonBootcamp 수업 내용을 참고하여 작성

 

오늘은 거북이 횡단게임을 만들어보겠다.

거북이가 아래쪽에서 위쪽으로 횡단해야 하는데, 중간에 차들이 많이 지나가고, 차와 거북이가 부딪히게 되면 게임은 종료된다. 

이전에 배웠던 것들을 종합해서 풀어보자.

https://github.com/portoduque/turtle-crossing-game

 

GitHub - portoduque/turtle-crossing-game: This project is a Mini-Game in Python, following OOP and using the Turtle module. The

This project is a Mini-Game in Python, following OOP and using the Turtle module. The goal of this game is to help a turtle to cross the street. - portoduque/turtle-crossing-game

github.com

 

 

1. 거북이 클래스 만들기 

 

거북이가 스크린 중앙 하단에서부터 출발하여 올라오도록 하는 코드를 만든다. main 파일에서 거북이는 'Up' 키로 화면상 위치가 조정되도록 한다.

 

<player.py 파일 내용>

from turtle import Turtle

STARTING_POSITION = (0, -280)
MOVE_DISTANCE = 10
FINISH_LINE_Y = 280


class Player(Turtle):
    def __init__(self) :
        super().__init__()
        self.color('black')
        self.shape('turtle')
        self.setheading(90)
        self.penup()
        self.goto(STARTING_POSITION)

    def go_up(self):
        self.forward(MOVE_DISTANCE)

 

<main.py 파일 내용>

import time
from turtle import Screen
from player import Player
from car_manager import CarManager
from scoreboard import Scoreboard

screen = Screen()
screen.setup(width=600, height=600)
screen.tracer(0)

player = Player()

screen.listen()
screen.onkey(player.go_up,'Up')

game_is_on = True
while game_is_on:
    time.sleep(0.1)

    screen.update()

 

2. 장애물 클래스 만들기 

 

이제 거북이가 무사히 지나가야 할 자동차 장애물들을 만들어보자.

높이 20픽셀, 너비 40 픽셀인 자동차들을 y축의 범위 내에서 무작위로 생성하고, 화면 제일 오른쪽 가장자리로 이동시킨다. 

맨 오른쪽에서부터 왼쪽으로 자동차들이 움직이도록 만들기 위해 move_cars 메소드를 따로 만들어준다.

자동차들을 만들고 실행해보면 자동차가 생각보다 너무 빈번하게 생성되는 것을 볼 수 있다.

자동차 생성빈도를 조절하기 위해 random.randint를 활용하여 게임 반복문이 6번 실행될 때마다 자동차를 새로 생성하도록 조정 하였다. 

속도 조정을 위해 빈도수를 조정하면 된다.

 

<car_manager.py 파일 내용>

from turtle import Turtle
import random 

COLORS = ["red", "orange", "yellow", "green", "blue", "purple"]
STARTING_MOVE_DISTANCE = 5
MOVE_INCREMENT = 10

class CarManager(Turtle):
    def __init__(self):
        super().__init__()
        self.all_cars = []

    def create_cars(self):
        # 자동차 생성의 빈도를 조절하기 
        random_chance = random.randint(1,6)
        if random_chance == 1 : 
            new_car = Turtle('square')
            new_car.penup()
            new_car.shapesize(stretch_wid=1, stretch_len=2)
            new_car.color(random.choice(COLORS))
            random_y = random.randint(-250, 250) # 위아래 50씩 띄어서 
            new_car.goto(+300, random_y)
            self.all_cars.append(new_car)

    def move_cars(self):
        for car in self.all_cars: 
            car.backward(STARTING_MOVE_DISTANCE)

 

<main.py 파일 내용>

import time
from turtle import Screen
from player import Player
from car_manager import CarManager
from scoreboard import Scoreboard

screen = Screen()
screen.setup(width=600, height=600)
screen.tracer(0)

player = Player()
car_manager = CarManager()

screen.listen()
screen.onkey(player.go_up,'Up')

game_is_on = True
while game_is_on:
    time.sleep(0.1)
    screen.update()

    car_manager.create_cars()
    car_manager.move_cars()

 

 

3. 장애물 충돌 감지하기 

 

거북이와 자동차가 충돌할 시에 게임이 멈추도록 한다. main파일에서 거북이와 자동차 충돌 조건을 설정하고, 그 경우 game_is_on을 False로 바꿔주면 될 것이다.

 

<main.py 파일 내용>

...
    # 자동차와 거북이의 충돌 
    for car in car_manager.all_cars : 
        if car.distance(player) < 20 : 
            # 게임 스탑
            game_is_on = False

screen.exitonclick()

 

4. 장애물 결승 도달 감지하기 

 

거북이가 모든 장애물을 다 피해서 결승점인 화면 최상단에 도달할 경우, 거북이는 한 단계를 성공한 셈이다.

결승에 도달할 시에 다음 라운드가 시작된다. 거북이는 시작위치로 다시 돌아오고, 차들의 속도는 빨라지도록 조정해야 한다. 이 부분을 코드로 구현해보자.

 

<main.py 파일 내용> : 작동 코드 추가

...
    # 거북이가 결승점 도달 
    if player.is_at_finish_line() :
        player.go_to_start()
        car_manager.level_up()

screen.exitonclick()

 

<player.py 파일 내용> : 거북이가 결승 도달시 메소드 (시작점으로 돌아가기, 결승점 도달 확인) 추가 

...

    def go_to_start(self):
        self.goto(STARTING_POSITION)

    # 거북이가 결승점 도달
    def is_at_finish_line(self):
        if self.ycor() > FINISH_LINE_Y : 
            return True
        else:   
            return False

 

<car_manager.py> : 자동차 속도 올리는 메소드 추가

...

    def level_up(self):
        self.car_speed *= MOVE_INCREMENT

 

 

5. 게임 점수판 만들기 및 종료 과정 (최종 코드)

 

이제 마지막으로 스코어 보드 클래스를 만들고 게임 오버 조건을 추가해주면 된다. 클래스 파일별 최종 코드는 아래와 같다.

 

<main.py 파일 내용>

import time
from turtle import Screen
from player import Player
from car_manager import CarManager
from scoreboard import Scoreboard

screen = Screen()
screen.setup(width=600, height=600)
screen.tracer(0)

player = Player()
car_manager = CarManager()
scoreboard = Scoreboard()

screen.listen()
screen.onkey(player.go_up,'Up')

game_is_on = True
while game_is_on:
    time.sleep(0.1)
    screen.update()

    car_manager.create_cars()
    car_manager.move_cars()

    # 자동차와 거북이의 충돌 
    for car in car_manager.all_cars : 
        if car.distance(player) < 20 : 
            # 게임 스탑
            game_is_on = False
            scoreboard.game_over()

    # 거북이가 결승점 도달 
    if player.is_at_finish_line() :
        player.go_to_start()
        car_manager.level_up()
        scoreboard.increase_level()

screen.exitonclick()

 

<player.py 파일 내용>

from turtle import Turtle

# STARTING_POSITION = (0, -280)
MOVE_DISTANCE = 10
FINISH_LINE_Y = 280
STARTING_POSITION = (0, -280)


class Player(Turtle):
    def __init__(self) :
        super().__init__()
        self.shape('turtle')
        self.penup()
        self.go_to_start()
        self.setheading(90)

    def go_up(self):
        self.forward(MOVE_DISTANCE)

    def game_over(self):
        self.clear()
        self.penup()
        self.goto(0,0)
        self.write('Game Over', align = 'center', font = ('Courier', 18, 'normal'))

    def go_to_start(self):
        self.goto(STARTING_POSITION)

    # 거북이가 결승점 도달
    def is_at_finish_line(self):
        if self.ycor() > FINISH_LINE_Y : 
            return True
        else:   
            return False

 

<car_manager.py 파일 내용>

from turtle import Turtle
import random 

COLORS = ["red", "orange", "yellow", "green", "blue", "purple"]
STARTING_MOVE_DISTANCE = 5
MOVE_INCREMENT = 10


class CarManager(Turtle):
    def __init__(self):
        super().__init__()
        self.all_cars = []
        self.car_speed = STARTING_MOVE_DISTANCE

    def create_cars(self):
        # 자동차 생성의 빈도를 조절하기 
        random_chance = random.randint(1,6)
        if random_chance == 1 : 
            new_car = Turtle('square')
            new_car.penup()
            new_car.shapesize(stretch_wid=1, stretch_len=2)
            new_car.color(random.choice(COLORS))
            random_y = random.randint(-250, 250) # 위아래 50씩 띄어서 
            new_car.goto(+300, random_y)
            self.all_cars.append(new_car)

    def move_cars(self):
        for car in self.all_cars: 
            car.backward(self.car_speed)

    def level_up(self):
        self.car_speed += MOVE_INCREMENT

 

<scoreboard.py 파일 내용>

from turtle import Turtle
FONT = ("Courier", 24, "normal")

class Scoreboard(Turtle):
    def __init__(self):
        super().__init__()
        self.level = 1
        self.penup()
        self.hideturtle()
        self.goto(-280, +250)
        self.update_scoreboard()

    def update_scoreboard(self):
        self.clear()
        self.write(f'Level: {self.level}', align='left', font=FONT)

    def increase_level(self):
        self.level += 1
        self.update_scoreboard()

    def game_over(self):
        self.goto(0,0)
        self.write('Game Over', align='center', font=FONT)

 

이렇게 터틀 크로싱 게임 완성!