Terminals & Enemies
game/terminals.py provides two sprite classes: Terminal (interactive level objectives) and Enemy (virus sprites that chase the player).
Terminal class
A stationary cyberpunk terminal that the player can interact with when in range. Terminals serve as level objectives in Levels 2 and 3.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
terminal_type | str | "scan" | Semantic type tag. Used by the main loop to distinguish "network" and "quarantine" terminals. |
title | str | "SYSTEM SCANNER" | Display name shown in the interaction prompt. |
active | bool | False | Set to True automatically when the player is within interaction_range. |
interaction_range | int | 80 | Proximity threshold in pixels. |
image | pygame.Surface | 64×48 SRCALPHA | Cyberpunk terminal icon with a blue border and screen lines. |
rect | pygame.Rect | Centred at (x, y) | Collision and positioning rect. |
__init__(x, y, terminal_type, title)
Horizontal centre position of the terminal sprite in screen coordinates.
Vertical centre position of the terminal sprite in screen coordinates.
Semantic identifier for the terminal. The main game uses
"network" for the Level 2 objective and "quarantine" for the Level 3 objective.Human-readable label displayed above the terminal when the player is in range, e.g.
"NETWORK NODE" or "QUARANTINE TERMINAL".pygame.SRCALPHA. It renders a blue rounded rectangle border (0, 150, 255), a dark-blue fill (0, 50, 100), and two horizontal cyan lines (0, 200, 255) to simulate a terminal screen.
is_near(player)
Returns True if the Euclidean distance between the terminal centre and player.pos is less than interaction_range (80 px).
The player sprite instance. Must expose a
pos attribute of type pygame.Vector2.True when the player is within 80 px of the terminal centre.update(player)
Called each frame by the terminals sprite group. Sets self.active = self.is_near(player). When active becomes True, the next draw() call shows the interaction prompt and a proximity circle.
The current player sprite. Passed through to
is_near().draw(screen)
Blits the terminal image and, if active, overlays:
- A yellow
"PRESS E: {title}"prompt in 16 pt Consolas, positioned 10 px above the top of the terminal rect. - A single-pixel cyan circle of radius
interaction_rangecentred on the terminal to visualise the interaction zone.
The active Pygame display surface.
In the main game loop, the interaction prompt is also re-rendered with the screen-shake offset applied. The
Terminal.draw() version is kept for correctness, but the shaken version in main_game.py takes visual precedence.Terminal instances in the game
| Instance | Position | terminal_type | title | Active level |
|---|---|---|---|---|
network_terminal | (3w/4, h/4) | "network" | "NETWORK NODE" | 2 |
quarantine_terminal | (w/2, 3h/4) | "quarantine" | "QUARANTINE TERMINAL" | 3 |
Enemy class
A hostile virus sprite that pursues the player each frame. Contact with the player deals 15 damage and removes the enemy.
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
pos | pygame.Vector2 | (x, y) | Sub-pixel position, updated each frame. |
speed | int | 2 | Movement speed in pixels per frame. |
health | int | 30 | Hit points. Enemies are removed instantly on bullet or player contact (no health deduction mechanic is currently used). |
image | pygame.Surface | 24×24 SRCALPHA | Glowing red triangle icon. |
rect | pygame.Rect | Centred at (x, y) | Collision and positioning rect. |
__init__(x, y, enemy_type)
Horizontal spawn position. Can be any float; the rect is centred on this value.
Vertical spawn position.
Reserved for future enemy variants. Currently only
"virus" is used.(255, 50, 50) is drawn as a 2-px-stroke polygon with vertices at (12, 0), (0, 24), (24, 24). A darker red (100, 0, 0) solid inner triangle is inset by 4 px to create a glowing-border effect.
update(player_pos)
Moves the enemy toward the player at self.speed pixels per frame.
The current world-space position of the player. Passed by the main loop as
player.pos.self.speed px/frame regardless of distance. When the enemy collides with a wall, the main loop pushes it back by 2 px in the opposite direction.
Spawning behaviour
Enemies are spawned by the main loop under two concurrent conditions:- General spawner — when
len(enemies) < (4 + level * 2), there is a 2% spawn chance per frame at a random position at least 300 px from the player. This cap grows with level (Level 1: 6, Level 2: 8, Level 3: 10, Level 4: 12). - Level 1 extra spawner — while
scan_progress < 100, an additional check spawns up to 6 enemies at 8% probability, at fully random screen positions with no minimum-distance check. - Level 4 explicit cap — an additional check caps Level 4 spawns at 8 with a 5% spawn chance.