Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save EncodeTheCode/27ade2389694681d7652b60ec33637e2 to your computer and use it in GitHub Desktop.
Save EncodeTheCode/27ade2389694681d7652b60ec33637e2 to your computer and use it in GitHub Desktop.
import pygame, sys, math
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
# Colors
WHITE = (255,255,255); BLACK = (0,0,0); GRAY = (50,50,50)
BLUE = (0, 128, 255); RED = (200, 0, 0); YELLOW = (255, 255, 0); GREEN = (0,200,0); ORANGE = (255,165,0)
# Simple player and enemy classes
class Player:
def __init__(self,x,y):
self.pos = pygame.math.Vector2(x,y)
self.radius = 10
def draw(self,surf): pygame.draw.circle(surf, GREEN, (int(self.pos.x),int(self.pos.y)), self.radius)
class Enemy:
def __init__(self,x,y,angle_deg=0):
self.pos = pygame.math.Vector2(x,y)
self.facing_angle = angle_deg # in degrees, 0 = right
self.radius = 12
def draw(self,surf):
# Draw enemy as an oriented triangle
ang = math.radians(self.facing_angle)
pts = []
for theta in [0, 2.5, -2.5]:
dx = math.cos(ang+theta)*self.radius
dy = math.sin(ang+theta)*self.radius
pts.append((self.pos.x+dx, self.pos.y+dy))
pygame.draw.polygon(surf, ORANGE, pts)
def is_aiming_at(self,player):
# Check if player is roughly in front of enemy (simple dot-product check)
forward = pygame.math.Vector2(math.cos(math.radians(self.facing_angle)),
math.sin(math.radians(self.facing_angle)))
to_player = (player.pos - self.pos)
if to_player.length() == 0: return False
dot = forward.dot(to_player.normalize())
return dot > 0.7
class Obstacle:
def __init__(self,x,y,w,h):
self.rect = pygame.Rect(x,y,w,h)
def draw(self,surf): pygame.draw.rect(surf, (128,128,128), self.rect)
# Line-of-sight check (raycast vs obstacles)
def line_of_sight(enemy, player, obstacles):
e = (enemy.pos.x, enemy.pos.y)
p = (player.pos.x, player.pos.y)
for obs in obstacles:
if obs.rect.clipline(e,p): # If the line intersects the obstacle
return False
return True
# Instantiate objects
player = Player(50, 300)
enemy = Enemy(100, 300, angle_deg=0) # Enemy facing right
obstacles = [Obstacle(300, 200, 50, 300)] # One blocking wall
# Player stats
max_armor = 100; armor = max_armor
max_health = 100; health = max_health
# Danger meter
danger = 0.0
max_danger = 100.0
danger_rate = 30.0 # fill speed
blink = False
blink_time = 0.0
font = pygame.font.SysFont(None, 24)
running = True
while running:
dt = clock.tick(60) / 1000.0
for ev in pygame.event.get():
if ev.type == pygame.QUIT: running=False
if ev.type == pygame.KEYDOWN:
if ev.key == pygame.K_ESCAPE: running=False
if ev.key == pygame.K_h:
# Simulate damage: reduce armor or health
if armor > 0: armor = max(0, armor-20)
else: health = max(0, health-20)
# Player movement
keys = pygame.key.get_pressed()
speed = 150 * dt
if keys[pygame.K_LEFT]: player.pos.x -= speed
if keys[pygame.K_RIGHT]: player.pos.x += speed
if keys[pygame.K_UP]: player.pos.y -= speed
if keys[pygame.K_DOWN]: player.pos.y += speed
# Danger logic: is enemy targeting player with clear LOS?
if enemy.is_aiming_at(player) and line_of_sight(enemy, player, obstacles):
danger = min(max_danger, danger + danger_rate*dt)
else:
# Reset meter when not targeted:contentReference[oaicite:21]{index=21}
danger = 0.0
blink = False; blink_time = 0.0
# Blink if danger is full
if danger >= max_danger:
blink_time += dt
if blink_time >= 0.5:
blink_time = 0.0
blink = not blink
# -- Drawing --
screen.fill(BLACK)
for obs in obstacles: obs.draw(screen)
player.draw(screen)
enemy.draw(screen)
# Draw Armor bar (blue for armor, then red for health)
bar_x, bar_y = 10, 10
bar_w, bar_h = 200, 20
pygame.draw.rect(screen, GRAY, (bar_x, bar_y, bar_w, bar_h)) # background
# Armor portion
arm_w = int(bar_w * (armor/max_armor))
pygame.draw.rect(screen, BLUE, (bar_x, bar_y, arm_w, bar_h))
# If armor is depleted, draw health in red
if armor == 0:
health_w = int(bar_w * (health/max_health))
pygame.draw.rect(screen, RED, (bar_x, bar_y, health_w, bar_h))
pygame.draw.rect(screen, WHITE, (bar_x, bar_y, bar_w, bar_h), 2)
health_text = font.render(f"Armor:{armor}/{max_armor} Health:{health}/{max_health}", True, WHITE)
screen.blit(health_text, (bar_x, bar_y+bar_h+5))
# Draw Danger meter below (yellow fill)
d_x, d_y = 10, 50
d_w, d_h = 200, 15
pygame.draw.rect(screen, GRAY, (d_x, d_y, d_w, d_h))
fill_w = int(d_w * (danger/max_danger))
# If blinking off, skip drawing the fill
if fill_w > 0 and not blink:
pygame.draw.rect(screen, YELLOW, (d_x, d_y, fill_w, d_h))
pygame.draw.rect(screen, WHITE, (d_x, d_y, d_w, d_h), 2)
danger_text = font.render("Danger Meter", True, WHITE)
screen.blit(danger_text, (d_x, d_y-20))
# Instructions
instr = font.render("Arrow keys to move, H = take damage", True, WHITE)
screen.blit(instr, (10, 580))
pygame.display.flip()
pygame.quit()
sys.exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment