164 lines
4.7 KiB
Python
164 lines
4.7 KiB
Python
import pygame
|
|
import pygame.freetype
|
|
import math
|
|
import random
|
|
import gobjs
|
|
|
|
class Display:
|
|
def __init__(self, screen, clock):
|
|
self.screen = screen
|
|
self.clock = clock
|
|
self.run = True
|
|
self.delta = 0
|
|
self.font = None
|
|
|
|
def draw_gobj(self, gobj):
|
|
pygame.draw.circle(
|
|
self.screen,
|
|
gobj.color,
|
|
gobj.pos(),
|
|
gobj.radius)
|
|
def draw_text(self, msg, x, y, color):
|
|
surface, rect = self.font.render(msg, color)
|
|
self.screen.blit(surface, (x-rect.w//2, y-rect.h))
|
|
|
|
|
|
def init_display(sw, sh):
|
|
pygame.init()
|
|
screen = pygame.display.set_mode((sw,sh))
|
|
clock = pygame.time.Clock()
|
|
display = Display(screen, clock)
|
|
display.font = pygame.freetype.Font('JuliaMono-Bold.ttf', 18)
|
|
return display
|
|
|
|
def handle_input(keys, dt, player, win_w, win_h):
|
|
pos = player.pos()
|
|
r = player.radius
|
|
|
|
if keys[pygame.K_a]:
|
|
player.turn(dt, -1)
|
|
elif keys[pygame.K_d]:
|
|
player.turn(dt, 1)
|
|
if keys[pygame.K_w]:
|
|
player.move(dt)
|
|
elif keys[pygame.K_s]:
|
|
player.move(dt, -1.0)
|
|
|
|
def gather_perecpts(enemy, player):
|
|
return enemy.can_see(player)
|
|
|
|
def game_loop(display):
|
|
|
|
win_w, win_h = pygame.display.get_window_size()
|
|
d_rect = (0, 0, win_w, win_h)
|
|
|
|
# NOTE: You are welcome to modify some aspects of the following
|
|
# The player and enemy classes do take additional parameters
|
|
# which are currently set to defaults. You are welcome to
|
|
# override them to get a different scenario.
|
|
|
|
# Possible Player start locations (x, y, heading)
|
|
start_locs = [
|
|
(50,50, math.pi/4),
|
|
(win_w//2, 50, math.pi/2),
|
|
(win_w-50, 50, 3*math.pi/4),
|
|
(50, win_h//2, 0),
|
|
(win_w-50, win_h//2, math.pi),
|
|
(50, win_h-50, -math.pi/4),
|
|
(win_w//2, win_h-50, -math.pi/2),
|
|
(win_w-50, win_h-50, -3*math.pi/4)
|
|
]
|
|
# Randomly choose one.
|
|
player_start = random.choice(start_locs)
|
|
player = gobjs.Player(player_start[0], player_start[1], heading=player_start[2])
|
|
|
|
# Goals. The number passed into the Goal contructor are the x,y coords.
|
|
goals = [
|
|
gobjs.Goal(200, 200),
|
|
gobjs.Goal(win_w-200, 200),
|
|
gobjs.Goal(200, win_h-200),
|
|
gobjs.Goal(win_w-200, win_h-200),
|
|
gobjs.Goal(win_w//2, win_h//2)
|
|
]
|
|
|
|
# The enemies.
|
|
enemy1 = gobjs.EnemyYellow(win_w//2+50, win_h//2, heading=0)
|
|
enemy2 = gobjs.EnemyBlue(win_w//2-50, win_h//2, heading=math.pi)
|
|
enemy3 = gobjs.EnemyRed(win_w//2, win_h//2-50, heading=-math.pi/2)
|
|
enemies = [enemy1, enemy2, enemy3]
|
|
comms = {
|
|
"R": None,
|
|
"B": None,
|
|
"Y": None
|
|
}
|
|
|
|
tick = 0
|
|
goal_count = 0
|
|
winner = "Draw"
|
|
msgs = []
|
|
|
|
|
|
# You probably don't need to modify anything in the main loop
|
|
while display.run:
|
|
dt = display.clock.tick(60) / 1000
|
|
|
|
# Check event queue for quit
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
display.run = False
|
|
|
|
display.screen.fill("black")
|
|
|
|
next_msgs = []
|
|
for msg in msgs:
|
|
if pygame.time.get_ticks() - msg[2] < msg[0][1]:
|
|
display.draw_text(msg[0][0], msg[1].x, msg[1].y-(msg[1].radius+3), msg[1].color)
|
|
next_msgs.append(msg)
|
|
msgs = next_msgs
|
|
|
|
for g in goals:
|
|
if not g.is_touched():
|
|
if g.check_collision(player):
|
|
g.touch()
|
|
goal_count += 1
|
|
if goal_count == len(goals):
|
|
display.run = False
|
|
winner = "Player"
|
|
g.draw(display.screen)
|
|
|
|
# Call Enemy AI and draw
|
|
for e in enemies:
|
|
mt = e.ai(e.update(player), goals, comms)
|
|
e.turn(dt, mt[0])
|
|
e.move(dt, mt[1])
|
|
if mt[2] is not None:
|
|
msgs.append( (mt[2], e, pygame.time.get_ticks()) )
|
|
if e.check_collision(player):
|
|
display.run = False
|
|
winner = "AI"
|
|
if not e.onscreen(d_rect):
|
|
display.run = False
|
|
winner = "Player"
|
|
e.draw(display.screen)
|
|
|
|
# Move and draw the player
|
|
keys = pygame.key.get_pressed()
|
|
handle_input(keys, dt, player, win_w, win_h)
|
|
player.draw(display.screen)
|
|
|
|
if not player.onscreen(d_rect):
|
|
winner = "AI"
|
|
display.run=False
|
|
|
|
pygame.display.flip()
|
|
|
|
print(f"The winner is the {winner}.")
|
|
|
|
|
|
def main():
|
|
display = init_display(800, 800)
|
|
game_loop(display)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|