Загрузка данных
import pygame
import random
import math
pygame.init()
WIDTH = 800
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Cyber Void: Star Defender DX")
clock = pygame.time.Clock()
FPS = 60
# Цвета
BLACK = (10, 10, 20)
WHITE = (255, 255, 255)
CYAN = (0, 255, 255)
RED = (255, 60, 60)
ORANGE = (255, 160, 20)
YELLOW = (255, 230, 80)
GREEN = (50, 255, 100)
BLUE = (80, 150, 255)
PURPLE = (180, 50, 255)
font = pygame.font.Font(None, 28)
big_font = pygame.font.Font(None, 60)
class Player:
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT - 70
self.speed = 7
self.size = 20
self.cooldown = 0
self.shield = 0
self.triple_shot_timer = 0
def update(self, keys):
if (keys[pygame.K_LEFT] or keys[pygame.K_a]) and self.x > self.size:
self.x -= self.speed
if (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and self.x < WIDTH - self.size:
self.x += self.speed
if (keys[pygame.K_UP] or keys[pygame.K_w]) and self.y > self.size:
self.y -= self.speed
if (keys[pygame.K_DOWN] or keys[pygame.K_s]) and self.y < HEIGHT - self.size:
self.y += self.speed
if self.cooldown > 0:
self.cooldown -= 1
if self.triple_shot_timer > 0:
self.triple_shot_timer -= 1
def draw(self, surface):
points = [
(self.x, self.y - self.size),
(self.x - self.size, self.y + self.size),
(self.x, self.y + self.size // 2),
(self.x + self.size, self.y + self.size)
]
pygame.draw.polygon(surface, CYAN, points)
pygame.draw.circle(surface, WHITE, (int(self.x), int(self.y)), 4)
if self.shield > 0:
pygame.draw.circle(surface, BLUE, (int(self.x), int(self.y)), self.size + 10, 2)
class Laser:
def __init__(self, x, y, dx=0, dy=-12, color=YELLOW):
self.x = x
self.y = y
self.dx = dx
self.dy = dy
self.radius = 4
self.color = color
def update(self):
self.x += self.dx
self.y += self.dy
def draw(self, surface):
pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius)
class PowerUp:
def __init__(self, x, y):
self.x = x
self.y = y
self.type = random.choice(["triple", "shield"])
self.color = GREEN if self.type == "triple" else BLUE
self.speed = 2
self.radius = 10
def update(self):
self.y += self.speed
def draw(self, surface):
pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius)
pygame.draw.circle(surface, WHITE, (int(self.x), int(self.y)), self.radius, 2)
class Boss:
def __init__(self):
self.x = WIDTH // 2
self.y = -100
self.target_y = 120
self.max_hp = 60
self.hp = self.max_hp
self.radius = 45
self.shoot_timer = 0
self.dx = 3
def update(self, boss_bullets):
if self.y < self.target_y:
self.y += 2
else:
self.x += self.dx
if self.x < self.radius + 20 or self.x > WIDTH - self.radius - 20:
self.dx = -self.dx
self.shoot_timer += 1
if self.shoot_timer >= 40:
self.shoot_timer = 0
for angle in [-0.5, 0, 0.5]:
bx = math.sin(angle) * 5
by = math.cos(angle) * 5
boss_bullets.append(Laser(self.x, self.y + self.radius, bx, by, PURPLE))
def draw(self, surface):
pygame.draw.circle(surface, PURPLE, (int(self.x), int(self.y)), self.radius)
pygame.draw.circle(surface, RED, (int(self.x), int(self.y)), self.radius - 8)
# HP Bar
bar_w = 120
bar_h = 10
fill = int((self.hp / self.max_hp) * bar_w)
pygame.draw.rect(surface, RED, (self.x - bar_w // 2, self.y - self.radius - 20, bar_w, bar_h))
pygame.draw.rect(surface, GREEN, (self.x - bar_w // 2, self.y - self.radius - 20, fill, bar_h))
class Enemy:
def __init__(self, speed_mult=1.0):
self.x = random.randint(30, WIDTH - 30)
self.y = random.randint(-100, -30)
self.radius = random.randint(15, 26)
self.speed = random.uniform(2.0, 4.5) * speed_mult
self.hp = 2 if self.radius > 22 else 1
def update(self):
self.y += self.speed
def draw(self, surface):
color = RED if self.hp == 1 else (255, 100, 100)
pygame.draw.circle(surface, color, (int(self.x), int(self.y)), self.radius)
pygame.draw.circle(surface, BLACK, (int(self.x), int(self.y)), self.radius - 4)
class Particle:
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
angle = random.uniform(0, math.pi * 2)
speed = random.uniform(2, 6)
self.vx = math.cos(angle) * speed
self.vy = math.sin(angle) * speed
self.life = 20
def update(self):
self.x += self.vx
self.y += self.vy
self.life -= 1
def draw(self, surface):
if self.life > 0:
pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), max(1, self.life // 4))
def main():
player = Player()
lasers = []
enemies = []
particles = []
powerups = []
boss_bullets = []
boss = None
stars = [[random.randint(0, WIDTH), random.randint(0, HEIGHT), random.randint(1, 3)] for _ in range(60)]
score = 0
next_boss_score = 150
game_over = False
spawn_timer = 0
shake_timer = 0
running = True
while running:
clock.tick(FPS)
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and game_over and event.key == pygame.K_r:
main()
return
if not game_over:
player.update(keys)
# Стрельба игрока
if (keys[pygame.K_SPACE] or keys[pygame.K_j]) and player.cooldown == 0:
if player.triple_shot_timer > 0:
lasers.append(Laser(player.x, player.y - player.size, 0, -12))
lasers.append(Laser(player.x, player.y - player.size, -3, -11))
lasers.append(Laser(player.x, player.y - player.size, 3, -11))
else:
lasers.append(Laser(player.x, player.y - player.size, 0, -12))
player.cooldown = 11
# Появление босса
if score >= next_boss_score and boss is None:
boss = Boss()
next_boss_score += 200
# Спавн обычных врагов
spawn_timer += 1
if spawn_timer >= 40 and boss is None:
enemies.append(Enemy(1.0 + score / 500))
spawn_timer = 0
# Обновление пуль
for laser in lasers[:]:
laser.update()
if laser.y < -10 or laser.x < 0 or laser.x > WIDTH:
lasers.remove(laser)
for b in boss_bullets[:]:
b.update()
if math.hypot(b.x - player.x, b.y - player.y) < player.size:
boss_bullets.remove(b)
if player.shield > 0:
player.shield -= 1
else:
game_over = True
shake_timer = 20
elif b.y > HEIGHT + 10:
boss_bullets.remove(b)
# Обновление босса
if boss:
boss.update(boss_bullets)
for laser in lasers[:]:
if math.hypot(boss.x - laser.x, boss.y - laser.y) < boss.radius:
boss.hp -= 1
lasers.remove(laser)
if boss.hp <= 0:
for _ in range(50):
particles.append(Particle(boss.x, boss.y, PURPLE))
score += 100
boss = None
shake_timer = 25
break
# Обновление бонусов
for p in powerups[:]:
p.update()
if math.hypot(p.x - player.x, p.y - player.y) < player.size + p.radius:
if p.type == "triple":
player.triple_shot_timer = 400
elif p.type == "shield":
player.shield = 1
powerups.remove(p)
elif p.y > HEIGHT:
powerups.remove(p)
# Враги и коллизии
for enemy in enemies[:]:
enemy.update()
if math.hypot(enemy.x - player.x, enemy.y - player.y) < enemy.radius + player.size - 5:
if player.shield > 0:
player.shield -= 1
enemies.remove(enemy)
shake_timer = 10
else:
game_over = True
shake_timer = 20
for laser in lasers[:]:
if math.hypot(enemy.x - laser.x, enemy.y - laser.y) < enemy.radius + laser.radius:
enemy.hp -= 1
lasers.remove(laser)
if enemy.hp <= 0:
for _ in range(16):
particles.append(Particle(enemy.x, enemy.y, ORANGE))
if random.random() < 0.25:
powerups.append(PowerUp(enemy.x, enemy.y))
enemies.remove(enemy)
score += 10
break
if enemy.y > HEIGHT + 40 and enemy in enemies:
enemies.remove(enemy)
# Тряска экрана
render_offset = [0, 0]
if shake_timer > 0:
shake_timer -= 1
render_offset = [random.randint(-4, 4), random.randint(-4, 4)]
# Фоновые звёзды и частицы
for p in particles[:]:
p.update()
if p.life <= 0:
particles.remove(p)
for s in stars:
s[1] += s[2] * 0.8
if s[1] > HEIGHT:
s[1] = 0
s[0] = random.randint(0, WIDTH)
# Отрисовка на виртуальную поверхность для тряски
canvas = pygame.Surface((WIDTH, HEIGHT))
canvas.fill(BLACK)
for s in stars:
pygame.draw.circle(canvas, (180, 180, 220), (int(s[0]), int(s[1])), s[2] // 2 + 1)
for p in particles:
p.draw(canvas)
for p in powerups:
p.draw(canvas)
for laser in lasers:
laser.draw(canvas)
for b in boss_bullets:
b.draw(canvas)
for enemy in enemies:
enemy.draw(canvas)
if boss:
boss.draw(canvas)
if not game_over:
player.draw(canvas)
else:
text_go = big_font.render("GAME OVER", True, RED)
text_restart = font.render("Press 'R' to Restart", True, WHITE)
canvas.blit(text_go, (WIDTH // 2 - text_go.get_width() // 2, HEIGHT // 2 - 40))
canvas.blit(text_restart, (WIDTH // 2 - text_restart.get_width() // 2, HEIGHT // 2 + 25))
# UI
score_surf = font.render(f"SCORE: {score}", True, CYAN)
canvas.blit(score_surf, (20, 20))
if player.triple_shot_timer > 0:
bonus_surf = font.render("TRIPLE SHOT ACTIVE!", True, GREEN)
canvas.blit(bonus_surf, (20, 50))
screen.blit(canvas, render_offset)
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()