-
Notifications
You must be signed in to change notification settings - Fork 0
/
plan_view.py
155 lines (125 loc) · 4.68 KB
/
plan_view.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python3
"""
plan_view.py
Copyright 2023 Steve Palmer
"""
import pyglet
import numpy as np
from utils import traced_methods, do_not_trace
from game_controller import GameView
@traced_methods
class RoomSprite(pyglet.sprite.Sprite):
def __init__(self, planview, position: np.ndarray, room, *args, **kwargs):
self.planview = planview
self.room_position = position
super().__init__(planview.room_image(room.walls), *args, **kwargs)
self.view_update()
room.attach(self)
def view_update(self):
self.planview.switch_to()
self.scale = self.planview.sprite_scale
self.position = self.planview.position2xy(self.room_position)
def walls_update(self, _, walls):
self.planview.switch_to()
self.image = self.planview.room_image(walls)
@traced_methods
class PlayerSprite(pyglet.sprite.Sprite):
def __init__(self, planview, player, *args, **kwargs):
self.planview = planview
self.player = player
super().__init__(
planview.player_image(player.direction.right_angle_bearing()),
*args,
**kwargs
)
self.view_update()
def view_update(self):
self.planview.switch_to()
self.scale = self.planview.sprite_scale
self.direction_update()
self.position_update()
def direction_update(self):
self.planview.switch_to()
self.image = self.planview.player_image(
self.player.direction.right_angle_bearing()
)
def position_update(self):
self.planview.switch_to()
self.position = self.planview.position2xy(self.player.position)
@traced_methods
class PlanView(GameView):
def __init__(self, game_controller, label: str = None):
super().__init__(game_controller, label or "Plan View")
# Maze Image Stuff
room_atlas_img = pyglet.image.load("rooms_atlas.png")
self._tile_size = room_atlas_img.height
self._room_atlas = pyglet.image.ImageGrid(
room_atlas_img, 1, 16, column_padding=2
)
assert self._room_atlas[0].width == self._tile_size
# Player Image Stuff
player_atlas_img = pyglet.image.load("player_atlas.png")
assert self._tile_size == player_atlas_img.height
assert player_atlas_img.width / self._tile_size == 4
self._player_atlas = pyglet.image.ImageGrid(player_atlas_img, 1, 4)
# Scaling stuff
self.update_scaling()
# Build the picture
self.batch = pyglet.graphics.Batch()
background = pyglet.graphics.OrderedGroup(0)
self.rooms = []
for position, room in game_controller.maze.items():
self.rooms.append(
RoomSprite(self, position, room, batch=self.batch, group=background)
)
self.player_sprite = None
def room_image(self, i: int):
return self._room_atlas[i]
def player_image(self, i: int):
return self._player_atlas[i]
def update_scaling(self):
window_shape = np.array([self.width, self.height])
maze_shape = self.game_controller.maze.shape
self.sprite_scale = max(
int((window_shape / maze_shape).min() / self._tile_size), 1
)
self.scale = self.sprite_scale * self._tile_size
self.offset = (window_shape - maze_shape * self.scale) // 2
def position2xy(self, position: np.ndarray):
return tuple((position * self.scale) + self.offset)
def add_player(self, player):
super().add_player(player)
self.switch_to()
assert self.player_sprite is None
foreground = pyglet.graphics.OrderedGroup(1)
self.player_sprite = PlayerSprite(
self, player, batch=self.batch, group=foreground
)
def entry(self):
super().entry()
self.display_update()
def on_direction_update(self):
assert self.player_sprite is not None
self.player_sprite.direction_update()
def on_position_update(self):
assert self.player_sprite is not None
self.player_sprite.position_update()
def display_update(self):
if self.player_sprite is not None:
self.player_sprite.view_update()
@do_not_trace
def on_draw(self):
if self.active:
self.switch_to()
self.clear()
self.batch.draw()
def on_resize(self, width: int, height: int):
if self.active:
self.switch_to()
super().on_resize(width, height)
self.update_scaling()
for room in self.rooms:
room.view_update()
if self.player_sprite is not None:
self.player_sprite.view_update()
__all__ = "PlanView"