Added Turtle Crossing (finished), also added start of Drone Invaders (very unfinished)

This commit is contained in:
ben 2022-07-21 16:07:13 -05:00
parent 88f86dc04f
commit 79469d1bae
31 changed files with 377 additions and 1 deletions

View file

@ -0,0 +1,14 @@
from turtle import Turtle
class Car(Turtle):
def __init__(self, shape, start_position, direction, speed):
super().__init__(shape)
self.penup()
self.goto(start_position)
self.setheading(direction)
self.car_speed = speed
def move(self):
self.forward(self.car_speed)

View file

@ -0,0 +1,87 @@
from car import Car
import random
import turtle
COLORS = ["red", "orange", "yellow", "green", "blue", "purple"]
CAR_TYPES = [["BlueCarRight.gif", "BrightGreenCarRight.gif", "DarkBlueCarRight.gif",
"GreenCarRight.gif", "BMW-Z4Right.gif"],
["BlueCarLeft.gif", "BrightGreenCarLeft.gif", "DarkBlueCarLeft.gif", "GreenCarLeft.gif", "BMW-Z4Left.gif"]]
STARTING_POSITIONS = [(0, (-350, -205)), (0, (-350, -145)), (0, (-350, -80)),
(180, (350, 80)), (180, (350, 145)), (180, (350, 205))]
BASE_MOVE_DISTANCE = 5
MOVE_INCREMENT = 10
class CarManager:
def __init__(self):
self.cars = []
self.lanes = [0, 1, 2, 3, 4, 5]
self.last_lane = -1
for car_shape_list in CAR_TYPES:
for car_shape in car_shape_list:
car_shape = 'graphics/' + car_shape
turtle.register_shape(car_shape)
def create_car(self):
# Makes sure don't get 2 cars in a row in same lane
if len(self.lanes) == 0:
self.lanes = [0, 1, 2, 3, 4, 5]
lane = random.choice(self.lanes)
while lane == self.last_lane:
lane = random.choice(self.lanes)
self.lanes.remove(lane)
self.last_lane = lane
# Set up the car
starting_info = STARTING_POSITIONS[lane]
# Get car type (left or right) by using first index in starting_info, then set random shape (gif) accordingly
index = 0 if starting_info[0] == 0 else 1
shape = random.choice(CAR_TYPES[index])
shape = 'graphics/' + shape
# Create and add car
self.cars.append(Car(shape, starting_info[1], starting_info[0], BASE_MOVE_DISTANCE + random.randint(-1, 5)))
def update_cars(self):
# Remove cars that are finished going on road (off-screen and not coming back)
self.cars = [car for car in self.cars if (car.heading() == 0 and car.xcor() < 350)
or (car.heading() == 180 and car.xcor() > -350)]
# Iterate over remaining cars, and move them
for car in self.cars:
car.move()
def is_collision(self, other):
"""
:param other: A turtle object, or object of a child class of turtle
:return:
"""
# Get edges of other
other_top_edge = other.ycor() + 12
other_bottom_edge = other.ycor() - 12
other_left_edge = other.xcor() - 12
other_right_edge = other.xcor() + 12
# Check each car for whether the distance between edges overlaps
for car in self.cars:
car_top_edge = car.ycor() + 11
car_bottom_edge = car.ycor() - 11
car_left_edge = car.xcor() - 20
car_right_edge = car.xcor() + 20
# It's mom's spaghetti (code)
if (
(
(other_top_edge - car_bottom_edge > 0 and car_top_edge - other_top_edge > 0)
or
(car_top_edge - other_bottom_edge > 0 and other_bottom_edge - car_bottom_edge > 0)
)
and
(
(other_left_edge - car_left_edge > 0 and car_right_edge - other_left_edge > 0)
or
(other_right_edge - car_left_edge > 0 and car_right_edge - other_right_edge > 0)
)
):
return True
return False

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -0,0 +1,21 @@
from turtle import Turtle
STARTING_POSITION = (0, -280)
MOVE_DISTANCE = 10
FINISH_LINE_Y = 280
class Player(Turtle):
def __init__(self):
super().__init__('turtle')
self.penup()
self.setheading(90)
self.reset_player()
def reset_player(self):
self.goto(STARTING_POSITION)
def move(self):
if self.ycor() <= FINISH_LINE_Y:
self.forward(MOVE_DISTANCE)

View file

@ -0,0 +1,33 @@
from turtle import Turtle
FONT = ("Courier", 20, "bold")
GAMEOVER_FONT = ("Courier", 28, "bold")
class Scoreboard(Turtle):
def __init__(self):
super().__init__()
self.level = 1
self.penup()
self.hideturtle()
self.goto(-280, 280 - 15)
self.delay = 0.1
self.car_prob = 0.1
self.display()
def update_level(self):
self.level += 1
self.delay *= 0.9
self.car_prob *= 1.02
self.display()
def display(self):
self.clear()
self.write(f'Level: {self.level}', font=FONT)
print(f'Delay: {self.delay}')
print(f'Car probability {self.car_prob}')
def game_over(self):
self.goto(0, -20)
self.write('GAME OVER', align='center')

View file

@ -0,0 +1,53 @@
import time
from turtle import Screen
from player import Player, FINISH_LINE_Y
from car_manager import CarManager
from scoreboard import Scoreboard
import random
def soft_exit():
screen.bye()
exit(0)
screen = Screen()
screen.setup(width=600, height=600)
screen.bgpic('graphics/highway_lanes.png')
screen.tracer(False) # Turns off auto screen updates
screen.title('Turtle Crossing - *Definitely* not Frogger')
player = Player()
scoreboard = Scoreboard()
car_manager = CarManager()
car_manager.create_car()
screen.listen()
screen.onkey(fun=player.move, key='u') # Listens for 'w' key, and moves
screen.onkey(fun=soft_exit, key='q')
game_is_on = True
# The game loop
while game_is_on:
time.sleep(scoreboard.delay)
# Update cars (move the cars)
car_manager.update_cars()
# Check if turtle made it across
if player.ycor() >= FINISH_LINE_Y:
scoreboard.update_level()
player.reset_player()
# Check if another car should be added (10% chance at level 1)
if random.random() < scoreboard.car_prob:
car_manager.create_car()
# Check for collision with car
if car_manager.is_collision(player):
scoreboard.game_over()
game_is_on = False
screen.update()
screen.exitonclick()