|
|
|
@ -90,20 +90,24 @@ class Ball:
|
|
|
|
|
return ball1, ball2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass |
|
|
|
|
class Gun: |
|
|
|
|
def __init__(self): |
|
|
|
|
self.bullet = 0 |
|
|
|
|
self.f2_power = 10 |
|
|
|
|
self.f2_on = 0 |
|
|
|
|
self.an = 1 |
|
|
|
|
self.color = GREY |
|
|
|
|
self.x0 = 40 |
|
|
|
|
self.y0 = 450 |
|
|
|
|
bullet: bool = 0 |
|
|
|
|
f2_power: int = 10 |
|
|
|
|
f2_on: bool = 0 |
|
|
|
|
an: float = 1 |
|
|
|
|
color: int = GREY |
|
|
|
|
x0: int = 40 |
|
|
|
|
y0: int = 350 |
|
|
|
|
bg_color: int = BLUE |
|
|
|
|
keymap: typing.List[int] = field( |
|
|
|
|
default_factory=lambda: [pygame.K_a, pygame.K_s, pygame.K_d, pygame.K_q, pygame.K_e] |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
def fire2_start(self, _event): |
|
|
|
|
self.f2_on = 1 |
|
|
|
|
self.f2_on = True |
|
|
|
|
|
|
|
|
|
def fire2_end(self, event, game: Game): |
|
|
|
|
def fire2_end(self, game: Game): |
|
|
|
|
"""Выстрел мячом. |
|
|
|
|
|
|
|
|
|
Происходит при отпускании кнопки мыши. |
|
|
|
@ -112,22 +116,31 @@ class Gun:
|
|
|
|
|
self.bullet += 1 |
|
|
|
|
new_ball = Ball(position=np.array([self.x0 + self.deltas()[0], self.y0 + self.deltas()[1]])) |
|
|
|
|
new_ball.r += 5 |
|
|
|
|
self.an = math.atan2((event.pos[1] - new_ball.position[1]), (event.pos[0] - new_ball.position[0])) |
|
|
|
|
new_ball.v[0] = self.f2_power * math.cos(self.an) |
|
|
|
|
new_ball.v[1] = - self.f2_power * math.sin(self.an) |
|
|
|
|
game.balls.append(new_ball) |
|
|
|
|
self.f2_on = 0 |
|
|
|
|
self.f2_on = False |
|
|
|
|
self.f2_power = 10 |
|
|
|
|
|
|
|
|
|
def targetting(self, event): |
|
|
|
|
"""Прицеливание. Зависит от положения мыши.""" |
|
|
|
|
if event and event.pos[0] != 20: |
|
|
|
|
self.an = math.atan((event.pos[1] - 450) / (event.pos[0] - 20)) |
|
|
|
|
self.an = math.atan((event.pos[1] - self.y0) / (event.pos[0] - self.x0)) |
|
|
|
|
if self.f2_on: |
|
|
|
|
self.color = RED |
|
|
|
|
else: |
|
|
|
|
self.color = GREY |
|
|
|
|
|
|
|
|
|
def handle_event(self, event, game: Game): |
|
|
|
|
if event.type == pygame.MOUSEMOTION: |
|
|
|
|
self.targetting(event) |
|
|
|
|
if event.type == pygame.KEYDOWN and event.key == self.keymap[1]: |
|
|
|
|
self.fire2_start(event) |
|
|
|
|
if event.type == pygame.KEYUP and event.key == self.keymap[1]: |
|
|
|
|
self.fire2_end(game) |
|
|
|
|
elif event.type == pygame.MOUSEBUTTONDOWN: |
|
|
|
|
self.fire2_start(event) |
|
|
|
|
|
|
|
|
|
def deltas(self) -> typing.Tuple[float, float]: |
|
|
|
|
length = 50 + self.f2_power |
|
|
|
|
return length * math.cos(self.an), length * math.sin(self.an) |
|
|
|
@ -140,6 +153,23 @@ class Gun:
|
|
|
|
|
(self.x0 + dx, self.y0 + dy), (self.x0 - dx, self.y0 - dy), |
|
|
|
|
(self.x0 + delta_x - dx, self.y0 + delta_y - dy), (self.x0 + delta_x + dx, self.y0 + delta_y + dy)] |
|
|
|
|
pygame.draw.polygon(screen, self.color, points) |
|
|
|
|
pygame.draw.polygon(screen, self.bg_color, |
|
|
|
|
[(self.x0 - 50, self.y0), (self.x0 + 50, self.y0), (self.x0 + 50, self.y0 + 35), |
|
|
|
|
(self.x0 - 50, self.y0 + 35)]) |
|
|
|
|
pygame.draw.polygon(screen, self.bg_color, |
|
|
|
|
[(self.x0 - 15, self.y0 - 10), (self.x0 + 15, self.y0 - 10), (self.x0 + 15, self.y0 + 3), |
|
|
|
|
(self.x0 - 15, self.y0 + 3)]) |
|
|
|
|
|
|
|
|
|
def move(self, _game): |
|
|
|
|
if pygame.key.get_pressed()[self.keymap[2]]: |
|
|
|
|
self.x0 += 5 |
|
|
|
|
if pygame.key.get_pressed()[self.keymap[0]]: |
|
|
|
|
self.x0 -= 5 |
|
|
|
|
if pygame.key.get_pressed()[self.keymap[3]]: |
|
|
|
|
self.an -= 0.05 |
|
|
|
|
if pygame.key.get_pressed()[self.keymap[4]]: |
|
|
|
|
self.an += 0.05 |
|
|
|
|
self.power_up() |
|
|
|
|
|
|
|
|
|
def power_up(self): |
|
|
|
|
if self.f2_on: |
|
|
|
@ -228,7 +258,9 @@ class Target:
|
|
|
|
|
class Game: |
|
|
|
|
balls: typing.List[Ball] = field(default_factory=list) |
|
|
|
|
targets: typing.List[Target] = field(default_factory=lambda: [Target(), Target()]) |
|
|
|
|
gun: Gun = field(default_factory=Gun) |
|
|
|
|
guns: typing.List[Gun] = field(default_factory=lambda: [ |
|
|
|
|
Gun(), Gun(x0=300, keymap=[pygame.K_j, pygame.K_k, pygame.K_l, pygame.K_u, pygame.K_o], bg_color=GREEN) |
|
|
|
|
]) |
|
|
|
|
finished: bool = False |
|
|
|
|
clock: pygame.time.Clock = field(default_factory=pygame.time.Clock) |
|
|
|
|
fps: int = FPS |
|
|
|
@ -251,11 +283,13 @@ class Game:
|
|
|
|
|
target.hit() |
|
|
|
|
self.targets.remove(target) |
|
|
|
|
self.targets.append(Target()) |
|
|
|
|
self.gun.power_up() |
|
|
|
|
for gun in self.guns: |
|
|
|
|
gun.move(self) |
|
|
|
|
|
|
|
|
|
def draw(self, screen): |
|
|
|
|
screen.fill(WHITE) |
|
|
|
|
self.gun.draw(screen) |
|
|
|
|
for gun in self.guns: |
|
|
|
|
gun.draw(screen) |
|
|
|
|
for target in self.targets: |
|
|
|
|
target.draw(screen) |
|
|
|
|
for ball in self.balls: |
|
|
|
@ -265,12 +299,12 @@ class Game:
|
|
|
|
|
def process_event(self, event): |
|
|
|
|
if event.type == pygame.QUIT: |
|
|
|
|
self.finished = True |
|
|
|
|
elif event.type == pygame.MOUSEBUTTONDOWN: |
|
|
|
|
self.gun.fire2_start(event) |
|
|
|
|
elif event.type == pygame.MOUSEBUTTONUP: |
|
|
|
|
self.gun.fire2_end(event, self) |
|
|
|
|
elif event.type == pygame.MOUSEMOTION: |
|
|
|
|
self.gun.targetting(event) |
|
|
|
|
for gun in self.guns: |
|
|
|
|
gun.targetting(event) |
|
|
|
|
gun.fire2_end(self) |
|
|
|
|
for gun in self.guns: |
|
|
|
|
gun.handle_event(event, self) |
|
|
|
|
|
|
|
|
|
def main_loop(self): |
|
|
|
|
screen = pygame.display.set_mode((WIDTH, HEIGHT)) |
|
|
|
|