/
graphics.py
114 lines (98 loc) · 3.62 KB
/
graphics.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from __future__ import division
import math
import pygame as pg
import vec
import constants as c
# Debug switches.
SHOW_RUDDER_FORCE = False
SHOW_INTENDED_DIRECTION = False
# Colors.
PARTICLE_COLOR = (64, 64, 64)
WALL_COLOR = (32, 32, 32)
DIRECTION_COLOR = (255, 255, 255)
THRUST_COLOR = (196, 32, 32)
BRAKE_COLOR = (16, 16, 16)
PLAYER_COLORS = [
(48, 48, 128),
(128, 128, 48),
]
class Graphics(object):
def __init__(self, display):
self.display = display
def draw(self, obj):
drawing_functions = {
'player': self.draw_player,
'particle': self.draw_particle,
'bumper': self.draw_bumper,
'wall': self.draw_wall,
}
drawing_functions[obj.graphics_type](obj)
def draw_particle(self, particle):
self.circle(PARTICLE_COLOR, particle.pos, particle.radius)
def draw_bumper(self, bumper):
self.circle(PARTICLE_COLOR, bumper.pos, bumper.radius, width=.2 * bumper.radius)
def draw_player(self, player):
# Show whether or not the player is thrusting.
if player.do_thrust:
trailing_point = vec.add(
player.pos,
vec.norm(player.direction, -1.5 * player.radius),
)
self.line(THRUST_COLOR, player.pos, trailing_point, .5 * player.radius)
if player.boost_heavy_time_remaining > 0.0:
trailing_point = vec.add(
player.pos,
vec.norm(player.direction, -2.0 * player.radius),
)
self.line(THRUST_COLOR, player.pos, trailing_point, 1.5 * player.radius)
# Show braking and boosting charge up.
if player.do_brake:
# Redden the brake color as we charge.
color = vec.add(
BRAKE_COLOR,
vec.mul(THRUST_COLOR, player.boost_charge_time / c.player_boost_ready_time)
)
# Vibrate if we are fully charged.
r = 1.2
if player.boost_charge_time == c.player_boost_ready_time:
r += 0.1 * math.sin(6 * (2*math.pi) * pg.time.get_ticks() / 1000)
self.circle(color, player.pos, r)
# Body.
self.circle(PLAYER_COLORS[player.number], player.pos, player.radius)
# Show the player pointing towards a direction.
leading_point = vec.add(
player.pos,
vec.norm(player.direction, player.radius),
)
self.line(DIRECTION_COLOR, player.pos, leading_point, .2 * player.radius)
if SHOW_RUDDER_FORCE:
point = vec.add(
player.pos,
vec.mul(player.rudder_force, .1),
)
self.line(THRUST_COLOR, player.pos, point, .1 * player.radius)
if SHOW_INTENDED_DIRECTION and hasattr(player, 'intended_direction'):
point = vec.add(
player.pos,
player.intended_direction,
)
self.line(THRUST_COLOR, player.pos, point, .1 * player.radius)
def draw_wall(self, wall):
self.line(WALL_COLOR, wall.p1, wall.p2, .25)
# Drawing utility functions.
def line(self, color, a, b, width):
pg.draw.line(
self.display.screen,
color,
self.display.to_screen(a),
self.display.to_screen(b),
max(1, int(width * self.display.pixels_per_unit)),
)
def circle(self, color, center, radius, width=0):
pg.draw.circle(
self.display.screen,
color,
self.display.to_screen(center),
int(radius * self.display.pixels_per_unit),
int(width * self.display.pixels_per_unit),
)