-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdwarf.py
307 lines (260 loc) · 16.5 KB
/
dwarf.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
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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
import pygame
import os
import time
from PIL import Image
from utils import dwarf_move_left_or_right, return_to_the_standing_position
class Dwarf:
def __init__(self, screen_height, platforms, screen_width):
self.dwarf_image = None
self.ghost_bullets = None # Пульки призрака
self.screen_width = screen_width
self.screen_height = screen_height
# Начальная позиция персонажа
self.dwarf_x = self.screen_width * 0.1 # Положение слева
self.dwarf_y = self.screen_height # Вычисляем высоту пола
self.dwarf_width = self.screen_width * 0.07
self.dwarf_height = self.screen_width * 0.1
self.dwarf_speed = 3 # Скорость перемещения персонажа
self.dwarf_is_jumping = False
self.dwarf_jump_speed = 23 # Начальная скорость прыжка
self.dwarf_bullets = [] # Список для хранения пуль
self.vertical_velocity = 0 # Вертикальная скорость
self.last_jump_time = 0 # Время последнего прыжка
self.dwarf_bullet_speed = 5 # Скорость пуль
self.gravity = 2.7 # Сила гравитации (ускорение падения)
self.max_fall_speed = 2.7 # Максимальная скорость падения
self.timer_shot = 0 # Таймер выстрела
self.jump_delay = 0.8 # Задержка между прыжками в секундах
self.breath_images = {
'worth': [
pygame.image.load("media/image_main/Стоит-на-месте.png"),
pygame.image.load("media/image_main/Стоит-на-месте-1.png"),
pygame.image.load("media/image_main/Стоит-на-месте-2.png"),
],
'goes_right': [
pygame.image.load("media/image_main/Идет-1.png"),
pygame.image.load("media/image_main/Идет-2.png"),
pygame.image.load("media/image_main/Идет-3.png"),
],
'goes_left': [
pygame.image.load("media/image_main/Идет-лево-1.png"),
pygame.image.load("media/image_main/Идет-лево-2.png"),
pygame.image.load("media/image_main/Идет-лево-3.png"),
],
'squats': [
pygame.image.load("media/image_main/Приседает.png"),
]
}
# Масштабируем изображения под нужный размер (например, 120x150)
self.dwarf_image = [pygame.transform.scale(img, (self.dwarf_width, self.dwarf_height)) for img in self.breath_images['worth']]
self.current_frame = 0
self.last_update = pygame.time.get_ticks()
# Загрузка изображения пули
self.bullet_image = pygame.image.load('media/image_main/Сфера-1-lvl.png')
self.bullet_image = pygame.transform.scale(self.bullet_image, (30, 30)) # Масштабируем изображение пули
self.dwarf_can_shoot = True # Флаг для проверки, можно ли стрелять
self.dwarf_space = True # Проверка на прыжок
self.platforms = platforms # Платформы
self.check_K_DOWN = False
def gif_dwarf(self, now):
"""Создание движения картинки"""
frame_delay = 200
if now - self.last_update > frame_delay:
self.current_frame = (self.current_frame + 1) % len(self.dwarf_image) # Переход к следующему кадру если взять последний кадр по счету
self.last_update = now # Обновляем время последнего обновления
def image(self):
if self.check_K_DOWN: # Если перс присел
dwarf_image = self.dwarf_image[0]
else:
dwarf_image = self.dwarf_image[self.current_frame]
return dwarf_image
def dwarf_screen(self, screen):
"""Вывод персонажа на экран"""
screen.blit(self.image(), (self.dwarf_x, self.dwarf_y))
def dwarf_rect(self):
"""rect dwarf"""
current_image = self.image() # Получаем текущее изображение
dwarf_rect = pygame.Rect(self.dwarf_x, self.dwarf_y, current_image.get_width(), current_image.get_height())
return dwarf_rect
def moving_the_dwarf(self, keys):
"""Перемещение гнома влево или вправо, приседа и смена изображения"""
# Сохраняем высоту персонажа до изменения
crouch_height, original_height = self.dwarf_height // 2, self.dwarf_height
if keys[pygame.K_RIGHT]:
# Возвращение в положение стоя -> return_to_the_standing_position
self.dwarf_y, self.check_K_DOWN = return_to_the_standing_position(self.check_K_DOWN, self.dwarf_y, original_height, crouch_height)
self.dwarf_x, self.dwarf_image = dwarf_move_left_or_right(
self.dwarf_x,
"R",
self.dwarf_speed,
self.check_K_DOWN,
self.breath_images['goes_right'],
original_height)
elif keys[pygame.K_LEFT]:
# Возвращение в положение стоя -> return_to_the_standing_position
self.dwarf_y, self.check_K_DOWN = return_to_the_standing_position(self.check_K_DOWN, self.dwarf_y, original_height, crouch_height)
self.dwarf_x, self.dwarf_image = dwarf_move_left_or_right(
self.dwarf_x,
"L",
self.dwarf_speed,
self.check_K_DOWN,
self.breath_images['goes_left'],
original_height)
elif keys[pygame.K_LCTRL]: # Приседание
self.dwarf_image = [pygame.transform.scale(img, (self.dwarf_width, crouch_height)) for img in self.breath_images['squats']]
if not self.check_K_DOWN: # Проверяем, чтобы не корректировать позицию несколько раз
self.dwarf_y += (original_height - crouch_height) # Поднимаем персонажа, чтобы компенсировать уменьшение высоты
self.check_K_DOWN = True # Флаг, что персонаж присел
else:
# Возвращение в положение стоя -> return_to_the_standing_position
self.dwarf_y, self.check_K_DOWN = return_to_the_standing_position(self.check_K_DOWN, self.dwarf_y, original_height, crouch_height)
self.dwarf_image = [pygame.transform.scale(img, (self.dwarf_width, original_height)) for img in self.breath_images['worth']]
def dwarf_is_jumping_K_UP(self, keys):
"""Проверка на прыжок: можно прыгать только после задержки"""
current_time = time.time()
if keys[pygame.K_UP] and not self.dwarf_is_jumping and (current_time - self.last_jump_time > self.jump_delay):
self.dwarf_is_jumping = True # Устанавливаем флаг прыжка
self.vertical_velocity -= self.dwarf_jump_speed # Начальная вертикальная скорость при прыжке
self.dwarf_space = True # Флаг пространства для прыжка
self.last_jump_time = current_time # Обновляем время последнего прыжка
def contact_trap_update_x_or_y(self, update_dwarf_x, update_dwarf_y):
"""Функция для смены положения персонажа при соприкосновении с stone trap"""
if self.dwarf_x > update_dwarf_x:
self.dwarf_x -= 3
self.dwarf_y -= 3
elif self.dwarf_x < update_dwarf_x:
self.dwarf_x += 3
self.dwarf_y -= 3
def dwarf_apply_gravity(self, floor_y, current_location, platforms):
"""Применение гравитации и обновление положения персонажа"""
if self.dwarf_is_jumping:
self.dwarf_y += self.vertical_velocity # Обновляем положение по Y с учётом скорости
self.vertical_velocity += self.gravity # Применяем гравитацию (ускорение)
# Ограничиваем скорость падения
if self.vertical_velocity > self.max_fall_speed:
self.vertical_velocity = self.max_fall_speed
# Проверяем коллизии с платформами и полом
if self.dwarf_image:
character_rect = self.dwarf_rect()
# Проверяем столкновение с платформами
for platform in platforms[current_location]:
if (character_rect.colliderect(platform)) and \
(self.vertical_velocity >= 0) and \
(character_rect.bottom <= platform.top + 10) and \
(platform.bottom > character_rect.bottom) and \
(character_rect.bottom > platform.top): # Проверка, что персонаж сверху платформы
self.dwarf_y = platform.top - self.image().get_height() # Корректируем положение на платформе
self.dwarf_is_jumping = False # Завершаем прыжок
self.vertical_velocity = 0 # Останавливаем вертикальную скорость
break
else:
if self.dwarf_y < floor_y - self.image().get_height():
self.dwarf_is_jumping = True # Продолжаем прыжок, если ещё не на земле
else:
self.dwarf_y = floor_y - self.image().get_height() # Останавливаем на земле
self.dwarf_is_jumping = False # Завершаем прыжок
self.vertical_velocity = 0 # Обнуляем скорость
self.dwarf_space = False # Персонаж на земле
def dwarf_check_boundaries(self, size, current_location):
"""Проверка выхода за границы экрана и смена уровня"""
# if self.dwarf_image:
# if dwarf_x >= size[0] - self.dwarf_image.get_width() and current_location == 0:
# current_location += 1 # Переход на следующую локацию
# dwarf_x = 0 # Персонаж перемещается в начало экрана
#
# elif dwarf_x <= 0 and current_location == 1:
# evil_dwarf_bullets = [] # Очищаем пули злодея
# dwarf_bullets = [] # Очищаем пули
# current_location = 0 # Возвращаемся на предыдущую локацию
# dwarf_x = size[0] - 50 # Персонаж в конец экрана
# Ограничиваем движение персонажа в пределах экрана
self.dwarf_x = max(0, min(self.dwarf_x, size[0] - self.image().get_width()))
return self.dwarf_x, current_location
def move_ladders(self, ladders, keys, current_location):
"""Движение по лестнице"""
rect = self.dwarf_rect()
for ladder in ladders[current_location]:
if rect.colliderect(ladder):
self.vertical_velocity = 0 # Останавливаем вертикальное движение
if keys[pygame.K_DOWN]: # Спуск вниз
self.dwarf_y += 5
elif keys[pygame.K_UP]: # Подъем вверх
self.dwarf_y -= 5
def collision_platform(self, current_location, platforms, ghost_rect):
"""Удаление пулек при попадании в платформу или врагов"""
dwarf_bullet_rects = [bullet for bullet, _ in self.dwarf_bullets]
for platform in platforms[current_location]:
collided_indices = platform.collidelistall(dwarf_bullet_rects)
if collided_indices:
for index in collided_indices: # Удаляем все столкнувшиеся пули
del self.dwarf_bullets[index]
# ________________Стрельба в GHOST главным героем______________________________
collided_indices_ghost = ghost_rect.collidelistall(dwarf_bullet_rects)
if collided_indices_ghost:
for index in collided_indices_ghost: # Удаляем все столкнувшиеся пули
del self.dwarf_bullets[index]
def shoot(self, keys, ghost_image, ghost_bullets): # СТРЕЛЬБА ГЛ. ГЕРОЯ
"""Стрельба с учетом времени задержки между выстрелами"""
current_time = time.time()
self.ghost_bullets = ghost_bullets
# Если прошла задержка, то стреляем
if current_time - self.timer_shot >= 0.2:
if keys[pygame.K_w] and keys[pygame.K_a]:
self._shoot('w-a')
elif keys[pygame.K_w] and keys[pygame.K_d]:
self._shoot('w-d')
elif keys[pygame.K_s] and keys[pygame.K_a]:
self._shoot('s-a')
elif keys[pygame.K_s] and keys[pygame.K_d]:
self._shoot('s-d')
elif keys[pygame.K_w]:
self._shoot('w')
elif keys[pygame.K_s]:
self._shoot('s')
elif keys[pygame.K_a]:
self._shoot('a')
elif keys[pygame.K_d]:
self._shoot('d')
self.timer_shot = current_time # Обновляем таймер после выстрела
# Стрельба в перса (если существует злой гном)
if ghost_image:
self._check_for_dwarf_collision()
def _shoot(self, direction): # СТРЕЛЬБА ГЛ. ГЕРОЯ
"""Создание пули и добавление ее в список"""
bullet_rect = pygame.Rect(self.dwarf_x + self.image().get_height() // 2,
self.dwarf_y + self.image().get_height() // 2,
self.bullet_image.get_width(),
self.bullet_image.get_height()) # Создаем прямоугольник для пули
self.dwarf_bullets.append((bullet_rect, direction))
def _check_for_dwarf_collision(self): # СТРЕЛЬБА В ГЛ. ГЕРОЯ
"""Проверка на столкновение с выстрелом ЗЛОДЕЕВ"""
if self.dwarf_image:
dwarf = self.dwarf_rect()
for bullet, _, _ in self.ghost_bullets:
if dwarf.colliderect(bullet):
# self.dwarf_image = None # Убираем гнома
break # Прерываем цикл после попадания
def update_bullets(self, size): # СТРЕЛЬБА ГЛ. ГЕРОЯ
"""Обновление положения пуль и удаление пуль, которые вышли за экран"""
directions = {
'w-d': (1, -1),
'w-a': (-1, -1),
's-d': (1, 1),
's-a': (-1, 1),
'w': (0, -1),
's': (0, 1),
'a': (-1, 0),
'd': (1, 0)
}
# Обновление пуль
for bullet, keyboard in self.dwarf_bullets:
dx, dy = directions.get(keyboard, (0, 0))
bullet.x += self.dwarf_bullet_speed * dx
bullet.y += self.dwarf_bullet_speed * dy
# Удаляем пули, которые вышли за экран
self.dwarf_bullets = [(bullet, keyboard) for bullet, keyboard in self.dwarf_bullets if 0 < bullet.x < size[0] and 0 < bullet.y < size[1]]
def door_next_level(self, door):
"""Переход на след уровень (Дверь)"""
dwarf_rect = self.dwarf_rect()
if dwarf_rect.colliderect(door): # ПЕРЕХОД НА СЛЕДУЮЩИЙ УРОВЕНЬ (ДВЕРЬ)
pass