파이썬/파이썬(python) 중급

[23-1 파이썬] 장애물 게임 만들기(터틀 명령어 실습)

Olivia-BlackCherry 2022. 9. 2. 23:51

오늘 함께 풀어볼 미션 최종본이다.

파이썬 터틀 라이브러리로

장애물 게임을 만들어보자.

 

 

미션을 해결하는 시작은

문제를 여러 개로 쪼개는 것부터이다. 

 

내가 해결해야 할 문제를 여러 개로 세분화하고,

작은 것, 쉬운 것부터 차근차근 해결해나가며

연결고리를 찾아 이어붙이면 된다. 

 

이 게임을 만드는 해결 방법은 수십가지가 있을 것이다. 

내가 제시하는 방법은 그 중 한 가지일 뿐이다! 

 

총 만들어야 하는 파일은 4가지다.

main.py

player.py

car_manager.py

board.py

 

그럼, 파이썬 능력을 향상시켜줄 미션을 풀어보자!

1. 빈 화면 만들기(600 *600)

main.py

from turtle import Screen

screen = Screen()
screen.setup(600,600)

screen.exitonclick()

 

 

 

2. 플레이어(거북이) 생성하기
- 시작 위치, 모양 등 기본 속성 부여하기
- 키보드 Up 방향 누르면 위로 가게 만들기

main.py

from turtle import Screen
from player import Player

screen = Screen()


player = Player()
screen.listen()
screen.onkey(player.up, "Up")

screen.exitonclick()

player.py

from turtle import Turtle

STARTPOSITION = (0, -280)
STEP = 20

class Player(Turtle):
    def __init__(self):
        super().__init__()
        self.penup()
        self.setheading(90)
        self.shape("turtle")
        self.goto(STARTPOSITION)

    def up(self):
        self.forward(STEP)

 

 

 

3. 장애물 생성하기
- 장애물 기본 속성 정하기
- 장애물이 연속으로 움직이게 만들기

main.py

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

screen = Screen()
screen.setup(600,600)
player = Player()
screen.listen()
screen.onkey(player.up, "Up")

car_manager = CarManager()

keep_going=True
while keep_going:
    car_manager.make_car()
    car_manager.move_car()
    time.sleep(0.1)



screen.exitonclick()

player.py

from turtle import Turtle
import random

COLORS = ["orange", "yellow", "red", "green", "black", "purple", "blue"]
CARSTEP = 10


class CarManager:
    def __init__(self):
        self.cars = []

    def make_car(self):
        car = Turtle()
        car.shape("square")
        car.shapesize(stretch_len=2, stretch_wid=1)
        car.penup()
        car.color(random.choice(COLORS))
        new_y = random.randint(-280, 280)
        car.goto(290, new_y)
        self.cars.append(car)

    def move_car(self):
        for car in self.cars:
            car.backward(CARSTEP)

 

 

 

4. 출력 화면 정돈하기
- screen.tracer(), screen.update() 활용하여 중간 과정 생략하여 최종화면만 보이게 하는 기술 구현하기
from turtle import Screen
from player import Player
from car_manager import CarManager
import time

screen = Screen()
screen.setup(600,600)
screen.tracer(0)
player = Player()
screen.listen()
screen.onkey(player.up, "Up")

car_manager = CarManager()

keep_going=True
while keep_going:
    car_manager.make_car()
    car_manager.move_car()
    time.sleep(0.1)
    screen.update()



screen.exitonclick()

 

 

 

5. 플레이어가 끝지점 도착하면, 다시 처음 위치로 돌아가고 장애물 움직이는 속도 높이기

main.py

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

screen = Screen()
screen.setup(600,600)
screen.tracer(0)
player = Player()
screen.listen()
screen.onkey(player.up, "Up")

car_manager = CarManager()

keep_going=True
while keep_going:
    time.sleep(0.1)
    screen.update()
    car_manager.make_car()
    car_manager.move_car()

    if player.ycor() > 280:
        player.start_position()
        car_manager.speed_up()



screen.exitonclick()

car_manager.py

from turtle import Turtle
import random

COLORS = ["orange", "yellow", "red", "green", "black", "purple", "blue"]
CARSTEP = 20

class CarManager:
    def __init__(self):
        self.cars = []
        self.car_step = CARSTEP

    def make_car(self):
        car = Turtle()
        car.shape("square")
        car.shapesize(stretch_len=2, stretch_wid=1)
        car.penup()
        car.color(random.choice(COLORS))
        new_y = random.randint(-280, 280)
        car.goto(290, new_y)
        self.cars.append(car)


    def move_car(self):
        for car in self.cars:
            car.backward(self.car_step)

    def speed_up(self):
        self.car_step += CARSTEP

player.py

from turtle import Turtle

STARTPOSITION = (0, -280)
STEP = 100

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

    def up(self):
        self.forward(STEP)

    def start_position(self):
        self.goto(STARTPOSITION)

 

 

 

6. 장애물이 너무 많으니, 장애물을 줄이자

car_manager.py

def make_car(self):
    x = random.randint(1, 6)
    if x == 6:
        car = Turtle()
        car.shape("square")
        car.shapesize(stretch_len=2, stretch_wid=1)
        car.penup()
        car.color(random.choice(COLORS))
        new_y = random.randint(-280, 280)
        car.goto(290, new_y)
        self.cars.append(car)

 

 

7. 장애물에 부딛치면, 잠깐 멈췄다가 다시 원점으로 돌아가기

main.py

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

screen = Screen()
screen.setup(600,600)
screen.tracer(0)
player = Player()
screen.listen()
screen.onkey(player.up, "Up")

car_manager = CarManager()

keep_going=True
while keep_going:
    time.sleep(0.1)
    screen.update()
    car_manager.make_car()
    car_manager.move_car()

    if player.ycor() > 280:
        player.start_position()
        car_manager.speed_up()

    for car in car_manager.cars:
        if player.distance(car) <20:
            player.start_position()
            time.sleep(1)



screen.exitonclick()

 

 

8. 점수판 만들기
9. 재도전, 게임오버 문구 출력하기

main.py

from turtle import Screen
from player import Player
from car_manager import CarManager
import time
from board import Board

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

player = Player()
screen.listen()
screen.onkey(player.up, "Up")
car_manager = CarManager()
succeed = Board()
succeed.present_score()
fail = Board()


keep_going=True
while keep_going:
    time.sleep(0.1)
    screen.update()
    car_manager.make_car()
    car_manager.move_car()

    if player.ycor() > 280:
        player.start_position()
        car_manager.speed_up()
        succeed.add_score()
        succeed.present_score()

    for car in car_manager.cars:
        if player.distance(car) < 20:
            fail.try_notice()
            player.start_position()
            time.sleep(1)



screen.exitonclick()

board.py

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

class Board(Turtle):
    def __init__(self):
        super().__init__()
        self.score = 0
        self.penup()
        self.hideturtle()
        self.goto(-200, 250)

    def present_score(self):
        self.clear()
        self.write(arg=f"Level : {self.score}", align="center", font=FONT)

    def try_notice(self):
        self.goto(0, 0)
        self.write(arg="Try again!", align="center", font=FONT)
        time.sleep(3)
        self.clear()

    def add_score(self):
        self.score +=1

 

 

 

 

10. 5번 기회 주고, 5번 실패하면 게임오버 화면 출력하기

main.py(최종)

from turtle import Screen
from player import Player
from car_manager import CarManager
import time
from board import Board

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

player = Player()
screen.listen()
screen.onkey(player.up, "Up")
car_manager = CarManager()
succeed = Board()
succeed.present_score()
fail = Board()

chance = 2
keep_going=True
while keep_going:
    time.sleep(0.1)
    screen.update()
    car_manager.make_car()
    car_manager.move_car()

    if player.ycor() > 280:
        player.start_position()
        car_manager.speed_up()
        succeed.add_score()
        succeed.present_score()

    for car in car_manager.cars:
        if player.distance(car) < 20:
            if chance ==0:
                fail.finish_notice()
                keep_going =False
                break
            else:
                chance -= 1
                fail.try_notice()
                player.start_position()
                time.sleep(1)


screen.exitonclick()

board.py(최종)

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

class Board(Turtle):
    def __init__(self):
        super().__init__()
        self.score = 0
        self.penup()
        self.hideturtle()
        self.goto(-200, 250)

    def present_score(self):
        self.clear()
        self.write(arg=f"Level : {self.score}", align="center", font=FONT)

    def try_notice(self):
        self.goto(0, 0)
        self.write(arg="Try again!", align="center", font=FONT)
        time.sleep(3)
        self.clear()

    def finish_notice(self):
        self.goto(0, 0)
        self.write(arg="Game over", align="center", font=FONT)
        time.sleep(3)
        self.clear()

    def add_score(self):
        self.score +=1

 

 

 

나머지 최종코드이다.

car_manager.py(최종)

from turtle import Turtle
import random

COLORS = ["orange", "yellow", "red", "green", "black", "purple", "blue"]
CARSTEP = 20

class CarManager:
    def __init__(self):
        self.cars = []
        self.car_step = CARSTEP

    def make_car(self):
        x = random.randint(1, 6)
        if x == 6:
            car = Turtle()
            car.shape("square")
            car.shapesize(stretch_len=2, stretch_wid=1)
            car.penup()
            car.color(random.choice(COLORS))
            new_y = random.randint(-280, 280)
            car.goto(290, new_y)
            self.cars.append(car)


    def move_car(self):
        for car in self.cars:
            car.backward(self.car_step)

    def speed_up(self):
        self.car_step += CARSTEP

player(최종)

from turtle import Turtle

STARTPOSITION = (0, -280)
STEP = 30

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

    def up(self):
        self.forward(STEP)

    def start_position(self):
        self.goto(STARTPOSITION)

 

 

 

 

- 시간을 이용해서, 장애물 이동 속도를 조정할 수도 있다. 

관련 코드를 함께 첨부한다. 

다만 변수명은 조금 다르다. 

second= 0.1
def game():
    global second
    time.sleep(second)
    screen.update()
    car_manager.create_car()
    car_manager.move_car()

    if player.is_at_finish_line():
        player.start_position()
        score_board.score +=1
        score_board.write_score()
        second -= 0.025
        car_manager.level_up()

    if second ==0:
        global keep_going
        keep_going = False
        another_board.finishnotice()
        print("시간 초과입니다!")



keep_going =True
while keep_going:
    game()
    for car in car_manager.cars:
        if car.distance(player) < 20:
            print("충격")
            another_board.try_notice()
            time.sleep(3)

            player.start_position()