Files
2025-02-20 13:46:55 -10:00

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()