REFACTOR: moved render components into seperate module

ADD: Health bar
This commit is contained in:
2025-03-19 19:03:37 +01:00
parent e168e413e0
commit 45abd430dc
7 changed files with 60 additions and 43 deletions

View File

@@ -8,7 +8,8 @@ def main():
demo_parser = demoparser2.DemoParser("demo.dem") demo_parser = demoparser2.DemoParser("demo.dem")
game_info = demo_parser.parse_ticks(["X", "Y", "Z", "pitch", "yaw", "is_alive", "team", "player_steamid", game_info = demo_parser.parse_ticks(["X", "Y", "Z", "pitch", "yaw", "is_alive", "team", "player_steamid",
"team_rounds_total", "team_num", "total_rounds_played", "shots_fired"]) "team_rounds_total", "team_num", "total_rounds_played", "shots_fired",
"health"])
header_info = demo_parser.parse_header() header_info = demo_parser.parse_header()
map_name = header_info['map_name'] map_name = header_info['map_name']
players = demo_parser.parse_player_info() players = demo_parser.parse_player_info()
@@ -17,7 +18,6 @@ def main():
team_1.set_ct() team_1.set_ct()
team_2 = Team() team_2 = Team()
m = Match(map_name, game_info, team_1, team_2) m = Match(map_name, game_info, team_1, team_2)
m.tick = 1800
for index, row in players.iterrows(): for index, row in players.iterrows():
if row["team_number"] == 2: if row["team_number"] == 2:
team_1.add_player(Player(row["name"], row["steamid"])) team_1.add_player(Player(row["name"], row["steamid"]))

View File

@@ -2,7 +2,7 @@ import pygame
from models.match import Match from models.match import Match
from models.player import Player from models.player import Player
from models.team import Team from models.team import Team
from models.renderer import Renderer from render.renderer import Renderer
WIDTH, HEIGHT = 700,700 WIDTH, HEIGHT = 700,700
FPS = 60 FPS = 60

View File

@@ -32,6 +32,7 @@ class Match:
player.yaw = self.current_tick[self.current_tick["player_steamid"] == player.steam_id]["yaw"].values[0] player.yaw = self.current_tick[self.current_tick["player_steamid"] == player.steam_id]["yaw"].values[0]
player.dead = self.current_tick[self.current_tick["player_steamid"] == player.steam_id]["is_alive"].values[0] == 0 player.dead = self.current_tick[self.current_tick["player_steamid"] == player.steam_id]["is_alive"].values[0] == 0
player.is_shooting = self.current_tick[self.current_tick["player_steamid"] == player.steam_id]["shots_fired"].values[0] player.is_shooting = self.current_tick[self.current_tick["player_steamid"] == player.steam_id]["shots_fired"].values[0]
player.health = int(self.current_tick[self.current_tick["player_steamid"] == player.steam_id]["health"].values[0])
def _update_round(self) -> None: def _update_round(self) -> None:
if self.current_tick.empty: if self.current_tick.empty:

View File

@@ -5,9 +5,10 @@ class Player:
self.x = x self.x = x
self.y = y self.y = y
self.z = z self.z = z
self.pitch = pitch self.pitch = pitch
self.yaw = yaw # Probably only need this if top-down self.yaw = yaw # Probably only need this if top-down
self.health = 100
self.dead = False self.dead = False
self.is_shooting = False self.is_shooting = False

0
render/__init__.py Normal file
View File

49
render/player_render.py Normal file
View File

@@ -0,0 +1,49 @@
import pygame, math
from models.match import Match
from utils.utils import mapped_value
class PlayerRender:
def __init__(self, screen, match: Match, map_coord_controller, player_font):
self.screen = screen
self.match = match
self.map_coord_controller = map_coord_controller
self.player_font = player_font
self.player_radius = 5
self.health_bar_foreground = (0, 255, 0)
self.health_bar_background = (255, 0, 0)
def _render_circle(self, player, team):
x, y = self.map_coord_controller.map_to_screen(player.x, player.y)
pygame.draw.circle(self.screen, team.colour, (x, y), self.player_radius)
def _render_text(self, player):
x, y = self.map_coord_controller.map_to_screen(player.x, player.y)
text = self.player_font.render(player.name, True, (255, 255, 255))
self.screen.blit(text, (x-(text.get_width()/2), y+5))
def _render_yaw(self, player, team):
if player.is_shooting:
mapped_x, mapped_y = self.map_coord_controller.map_to_screen(player.x, player.y)
player_yaw = math.radians(player.yaw)
end_x = mapped_x + (100 * math.cos(player_yaw))
end_y = mapped_y - (100 * math.sin(player_yaw))
pygame.draw.line(self.screen, team.colour, (mapped_x, mapped_y), (end_x, end_y), 2)
def _render_health(self, player):
x, y = self.map_coord_controller.map_to_screen(player.x, player.y)
pygame.draw.rect(self.screen, self.health_bar_background, (x-10, y-10, 20, 5))
pygame.draw.rect(self.screen, self.health_bar_foreground, (x-10, y-10, mapped_value(player.health, 0, 100, 0, 20), 5))
def render(self):
for team in self.match.get_teams():
for player in team.players:
if player.dead:
continue
self._render_circle(player, team)
self._render_text(player)
self._render_yaw(player, team)
self._render_health(player)

View File

@@ -1,11 +1,8 @@
import math
import pygame import pygame
from widgets.slider import HorizontalSlider from widgets.slider import HorizontalSlider
from pygame_widgets.slider import Slider
from models.match import Match from models.match import Match
from models.player import Player
from models.team import Team
from controllers.map_coord_controller import MapCoordController from controllers.map_coord_controller import MapCoordController
from render.player_render import PlayerRender
from utils.json_object import JSONObject from utils.json_object import JSONObject
class Renderer: class Renderer:
@@ -42,25 +39,8 @@ class Renderer:
self.top_left_x, self.bottom_right_x, self.top_left_y, self.bottom_right_y) self.top_left_x, self.bottom_right_x, self.top_left_y, self.bottom_right_y)
self.slider = HorizontalSlider(self.screen, 50, 650, self.screen.get_width()-100, 20, 1, self.match.max_tick) self.slider = HorizontalSlider(self.screen, 50, 650, self.screen.get_width()-100, 20, 1, self.match.max_tick)
#self.slider.fill = True
def render_players(self):
"""Draws everything on screen."""
# Update screen size if it has changed
self.map_coord_controller.update_screen_size(self.screen.get_width(), self.screen.get_height())
# loop through the teams and each of their players
for team in self.match.get_teams():
for player in team.players:
# Draw player if they are alive
if player.dead:
continue
self._render_player(player, team)
self._render_player_yaw(player, team)
#def render_player_path(self):
self.player_render = PlayerRender(self.screen, self.match, self.map_coord_controller, self.small_font)
def render_text(self): def render_text(self):
# Draw current tick # Draw current tick
@@ -88,24 +68,10 @@ class Renderer:
self.slider.set_value(self.match.tick) self.slider.set_value(self.match.tick)
self.slider.draw() self.slider.draw()
def _render_player(self, player: Player, team: Team):
mapped_x, mapped_y = self.map_coord_controller.map_to_screen(player.x, player.y)
pygame.draw.circle(self.screen, team.colour, (mapped_x, mapped_y), 5)
text = self.small_font.render(player.name, True, (255, 255, 255))
self.screen.blit(text, (mapped_x-10, mapped_y-15))
def _render_player_yaw(self, player: Player, team: Team):
if player.is_shooting:
mapped_x, mapped_y = self.map_coord_controller.map_to_screen(player.x, player.y)
player_yaw = math.radians(player.yaw)
end_x = mapped_x + (100 * math.cos(player_yaw))
end_y = mapped_y - (100 * math.sin(player_yaw))
pygame.draw.line(self.screen, team.colour, (mapped_x, mapped_y), (end_x, end_y), 2)
def render(self): def render(self):
self.screen.fill((30, 30, 30)) # Clear screen self.screen.fill((30, 30, 30)) # Clear screen
self.map_coord_controller.update_screen_size(self.screen.get_width(), self.screen.get_height())
self.render_slider()
self.render_map() self.render_map()
self.render_text() self.render_text()
self.render_players() self.player_render.render()
self.render_slider()