-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhero.py
More file actions
249 lines (181 loc) · 7.55 KB
/
Copy pathhero.py
File metadata and controls
249 lines (181 loc) · 7.55 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
key_switch_camera = 'c' # камера привязана к герою или нет
key_switch_mode = 'z' # можно проходить сквозь препятствия или нет
key_forward = 'w' # шаг вперёд (куда смотрит камера)
key_back = 's' # шаг назад
key_left = 'a' # шаг влево (вбок от камеры)
key_right = 'd' # шаг вправо
key_up = 'e' # шаг вверх
key_down = 'q' # шаг вниз
key_turn_left = 'n' # поворот камеры направо (а мира - налево)
key_turn_right = 'm' # поворот камеры налево (а мира - направо)
key_build_ground = '1' # построить блок земли перед собой
key_build_stone = '2' # построить блок камня перед собой
key_destroy = 'v' # разрушить блок перед собой
key_savemap = 'k'
key_loadmap = 'l'
class Hero():
def __init__(self, pos, land):
self.land = land
self.mode = True # режим прохождения сквозь всё
self.hero = loader.loadModel('smiley')
self.hero.setColor(1, 0.5, 0)
self.hero.setScale(0.3)
self.hero.setPos(pos)
self.hero.reparentTo(render)
self.cameraBind()
self.accept_events()
def cameraBind(self):
base.disableMouse()
base.camera.setH(180)
base.camera.reparentTo(self.hero)
base.camera.setPos(0, 0, 1.5)
self.cameraOn = True
def cameraUp(self):
pos = self.hero.getPos()
base.mouseInterfaceNode.setPos(-pos[0], -pos[1], -pos[2]-3)
base.camera.reparentTo(render)
base.enableMouse()
self.cameraOn = False
def changeView(self):
if self.cameraOn:
self.cameraUp()
else:
self.cameraBind()
def turn_left(self):
self.hero.setH((self.hero.getH() + 5) % 360)
def turn_right(self):
self.hero.setH((self.hero.getH() - 5) % 360)
def look_at(self, angle):
''' возвращает координаты, в которые переместится персонаж, стоящий в точке (x, y),
если он делает шаг в направлении angle'''
x_from = round(self.hero.getX())
y_from = round(self.hero.getY())
z_from = round(self.hero.getZ())
dx, dy = self.check_dir(angle)
x_to = x_from + dx
y_to = y_from + dy
return x_to, y_to, z_from
def just_move(self, angle):
'''перемещается в нужные координаты в любом случае'''
pos = self.look_at(angle)
self.hero.setPos(pos)
def move_to(self, angle):
if self.mode:
self.just_move(angle)
else:
self.try_move(angle)
def check_dir(self,angle):
''' возвращает округленные изменения координат X, Y,
соответствующие перемещению в сторону угла angle.
Координата Y уменьшается, если персонаж смотрит на угол 0,
и увеличивается, если смотрит на угол 180.
Координата X увеличивается, если персонаж смотрит на угол 90,
и уменьшается, если смотрит на угол 270.
угол 0 (от 0 до 20) -> Y - 1
угол 45 (от 25 до 65) -> X + 1, Y - 1
угол 90 (от 70 до 110) -> X + 1
от 115 до 155 -> X + 1, Y + 1
от 160 до 200 -> Y + 1
от 205 до 245 -> X - 1, Y + 1
от 250 до 290 -> X - 1
от 290 до 335 -> X - 1, Y - 1
от 340 -> Y - 1 '''
if angle >= 0 and angle <= 20:
return (0, -1)
elif angle <= 65:
return (1, -1)
elif angle <= 110:
return (1, 0)
elif angle <= 155:
return (1, 1)
elif angle <= 200:
return (0, 1)
elif angle <= 245:
return (-1, 1)
elif angle <= 290:
return (-1, 0)
elif angle <= 335:
return (-1, -1)
else:
return (0, -1)
def forward(self):
angle =(self.hero.getH()) % 360
self.move_to(angle)
def back(self):
angle = (self.hero.getH()+180) % 360
self.move_to(angle)
def left(self):
angle = (self.hero.getH() + 90) % 360
self.move_to(angle)
def right(self):
angle = (self.hero.getH() + 270) % 360
self.move_to(angle)
def changeMode(self):
if self.mode:
self.mode = False
else:
self.mode = True
def try_move(self, angle):
'''перемещается, если может'''
pos = self.look_at(angle)
if self.land.isEmpty(pos):
# перед нами свободно. Возможно, надо упасть вниз:
pos = self.land.findHighestEmpty(pos)
self.hero.setPos(pos)
else:
# перед нами занято. Если получится, заберёмся на этот блок:
pos = pos[0], pos[1], pos[2] + 1
if self.land.isEmpty(pos):
self.hero.setPos(pos)
# не получится забраться - стоим на месте
def up(self):
if self.mode:
self.hero.setZ(self.hero.getZ() + 1)
def down(self):
if self.mode and self.hero.getZ() > 1:
self.hero.setZ(self.hero.getZ() - 1)
def build_ground(self):
angle = self.hero.getH() % 360
pos = self.look_at(angle)
if self.mode:
self.land.addBlock(pos, 'ground.png')
else:
self.land.buildBlock(pos, 'ground.png')
def build_stone(self):
angle = self.hero.getH() % 360
pos = self.look_at(angle)
if self.mode:
self.land.addBlock(pos, 'stone.png')
else:
self.land.buildBlock(pos, 'stone.png')
def destroy(self):
angle = self.hero.getH() % 360
pos = self.look_at(angle)
if self.mode:
self.land.delBlock(pos)
else:
self.land.delBlockFrom(pos)
def accept_events(self):
base.accept(key_turn_left, self.turn_left)
base.accept(key_turn_left + '-repeat', self.turn_left)
base.accept(key_turn_right, self.turn_right)
base.accept(key_turn_right + '-repeat', self.turn_right)
base.accept(key_forward, self.forward)
base.accept(key_forward + '-repeat', self.forward)
base.accept(key_back, self.back)
base.accept(key_back + '-repeat', self.back)
base.accept(key_left, self.left)
base.accept(key_left + '-repeat', self.left)
base.accept(key_right, self.right)
base.accept(key_right + '-repeat', self.right)
base.accept(key_switch_camera, self.changeView)
base.accept(key_switch_mode, self.changeMode)
base.accept(key_up, self.up)
base.accept(key_up + '-repeat', self.up)
base.accept(key_down, self.down)
base.accept(key_down + '-repeat', self.down)
base.accept(key_build_ground, self.build_ground)
base.accept(key_build_stone, self.build_stone)
base.accept(key_destroy, self.destroy)
base.accept(key_savemap, self.land.saveMap)
base.accept(key_loadmap, self.land.loadMap)