Browse Source

Инструкция к игре, счет, уничтожение пушек

master
Lev 3 years ago
parent
commit
a6af82c7a6
  1. BIN
      lab5/IntroRust.otf
  2. BIN
      lab5/ProximaNova.otf
  3. 59
      lab5/gun.py

BIN
lab5/IntroRust.otf

Binary file not shown.

BIN
lab5/ProximaNova.otf

Binary file not shown.

59
lab5/gun.py

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
import math import math
from copy import deepcopy from copy import deepcopy
import time
from random import choice, uniform, randrange as rnd from random import choice, uniform, randrange as rnd
from dataclasses import dataclass, field from dataclasses import dataclass, field
@ -23,6 +24,9 @@ GAME_COLORS = [RED, BLUE, YELLOW, GREEN, MAGENTA, CYAN]
WIDTH = 800 WIDTH = 800
HEIGHT = 600 HEIGHT = 600
pygame.init()
font = pygame.font.Font('IntroRust.otf', 25)
font2 = pygame.font.Font('IntroRust.otf', 16)
@dataclass @dataclass
@ -33,6 +37,7 @@ class Ball:
color: int = field(default_factory=lambda: choice(GAME_COLORS)) color: int = field(default_factory=lambda: choice(GAME_COLORS))
time_to_split: typing.Optional[int] = field(default_factory=lambda: choice([None, rnd(5, 25)])) time_to_split: typing.Optional[int] = field(default_factory=lambda: choice([None, rnd(5, 25)]))
live: int = 30 live: int = 30
source: int = 0
def move(self): def move(self):
"""Переместить мяч по прошествии единицы времени. """Переместить мяч по прошествии единицы времени.
@ -92,6 +97,7 @@ class Ball:
@dataclass @dataclass
class Gun: class Gun:
gun_id: int = field(default_factory=lambda: rnd(1, 1000000))
bullet: bool = 0 bullet: bool = 0
f2_power: int = 10 f2_power: int = 10
f2_on: bool = 0 f2_on: bool = 0
@ -118,14 +124,15 @@ class Gun:
new_ball.r += 5 new_ball.r += 5
new_ball.v[0] = self.f2_power * math.cos(self.an) new_ball.v[0] = self.f2_power * math.cos(self.an)
new_ball.v[1] = - self.f2_power * math.sin(self.an) new_ball.v[1] = - self.f2_power * math.sin(self.an)
new_ball.source = self.gun_id
game.balls.append(new_ball) game.balls.append(new_ball)
self.f2_on = False self.f2_on = False
self.f2_power = 10 self.f2_power = 10
def targetting(self, event): def targetting(self, event):
"""Прицеливание. Зависит от положения мыши.""" """Прицеливание. Зависит от положения мыши."""
if event and event.pos[0] != 20: if event and event.pos[0] != self.x0:
self.an = math.atan((event.pos[1] - self.y0) / (event.pos[0] - self.x0)) self.an = math.atan2((event.pos[1] - self.y0), (event.pos[0] - self.x0))
if self.f2_on: if self.f2_on:
self.color = RED self.color = RED
else: else:
@ -179,6 +186,13 @@ class Gun:
else: else:
self.color = GREY self.color = GREY
def hittest(self, obj):
if self.x0 - 50 - obj.r < obj.position[0] < self.x0 + 50 + obj.r \
and self.y0 - obj.r < obj.position[1] < self.y0 + 35 + obj.r \
and hasattr(obj, 'source') and obj.source != self.gun_id:
return True
return False
@dataclass @dataclass
class Target: class Target:
@ -188,7 +202,6 @@ class Target:
vx: float = field(default_factory=lambda: rnd(-4, 6)) vx: float = field(default_factory=lambda: rnd(-4, 6))
vy: float = field(default_factory=lambda: rnd(-4, 6)) vy: float = field(default_factory=lambda: rnd(-4, 6))
color: int = RED color: int = RED
points: int = 0
live: int = 1 live: int = 1
ax: float = 0 ax: float = 0
ay: float = 0 ay: float = 0
@ -197,9 +210,9 @@ class Target:
oscillation_ampl: float = field(default_factory=lambda: rnd(0, 6) * choice([0, 0, 1])) oscillation_ampl: float = field(default_factory=lambda: rnd(0, 6) * choice([0, 0, 1]))
oscillation_phase: float = field(default_factory=lambda: uniform(0, 2 * np.pi)) oscillation_phase: float = field(default_factory=lambda: uniform(0, 2 * np.pi))
def hit(self, points=1): def hit(self, game: Game, points=1):
"""Попадание шарика в цель.""" """Попадание шарика в цель."""
self.points += points game.points += points
def draw(self, screen): def draw(self, screen):
pygame.draw.circle( pygame.draw.circle(
@ -264,6 +277,8 @@ class Game:
finished: bool = False finished: bool = False
clock: pygame.time.Clock = field(default_factory=pygame.time.Clock) clock: pygame.time.Clock = field(default_factory=pygame.time.Clock)
fps: int = FPS fps: int = FPS
points: int = 0
screen: pygame.Surface = field(default_factory=lambda: pygame.display.set_mode((WIDTH, HEIGHT)))
def move(self): def move(self):
for target in self.targets: for target in self.targets:
@ -276,11 +291,14 @@ class Game:
ball1, ball2 = ball.get_split() ball1, ball2 = ball.get_split()
self.balls.pop([i for i in range(len(self.balls)) if self.balls[i].position is ball.position][0]) self.balls.pop([i for i in range(len(self.balls)) if self.balls[i].position is ball.position][0])
self.balls.extend([ball1, ball2]) self.balls.extend([ball1, ball2])
for gun in self.guns:
if gun.hittest(ball):
self.guns.remove(gun)
for target in self.targets: for target in self.targets:
if ball.hittest(target) and target.live: if ball.hittest(target) and target.live:
target.live = 0 target.live = 0
ball.live = -1 ball.live = -1
target.hit() target.hit(self)
self.targets.remove(target) self.targets.remove(target)
self.targets.append(Target()) self.targets.append(Target())
for gun in self.guns: for gun in self.guns:
@ -294,6 +312,8 @@ class Game:
target.draw(screen) target.draw(screen)
for ball in self.balls: for ball in self.balls:
ball.draw(screen) ball.draw(screen)
score_text = font.render(str(self.points), 1, BLACK)
screen.blit(score_text, (10, 10))
pygame.display.update() pygame.display.update()
def process_event(self, event): def process_event(self, event):
@ -307,9 +327,8 @@ class Game:
gun.handle_event(event, self) gun.handle_event(event, self)
def main_loop(self): def main_loop(self):
screen = pygame.display.set_mode((WIDTH, HEIGHT))
while not self.finished: while not self.finished:
self.draw(screen) self.draw(self.screen)
self.clock.tick(self.fps) self.clock.tick(self.fps)
for event in pygame.event.get(): for event in pygame.event.get():
self.process_event(event) self.process_event(event)
@ -317,6 +336,28 @@ class Game:
pygame.quit() pygame.quit()
pygame.init() rules_text = '''
Управление левой пушкой:
a - влево, d - вправо, qe - наведение, s - стрелять
Управление правой:
jl - движение, uo - наведение, k - стрелять
Некоторые снаряды разрывные - разбиваются на 2.
Цели бывают обычные (те, которые полностью красные) - они
движутся, просто отражаясь от стенок, -
а также те, которые движутся случайно, и те, которые вращаются
Кликните, чтобы начать
'''
game = Game() game = Game()
y = 100
game.screen.fill(0x2e2646)
for line in rules_text.split('\n'):
surface = font2.render(line, True, WHITE)
game.screen.blit(surface, (WIDTH / 2 - surface.get_width() / 2, y))
y += 5 + surface.get_height()
rules_surface = font2.render(rules_text, True, WHITE)
pygame.display.update()
while not any(ev.type == pygame.MOUSEBUTTONUP or ev.type == pygame.QUIT for ev in pygame.event.get()):
pass
game.main_loop() game.main_loop()

Loading…
Cancel
Save