|
|
import pygame
import sys
import random
import math
from pygame import mixer
# 初始化pygame
pygame.init()
mixer.init()
# 游戏参数
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
# 颜色定义
BACKGROUND = (20, 30, 50)
PLAYER_COLOR = (70, 130, 180)
ENEMY_COLOR = (220, 60, 80)
BULLET_COLOR = (255, 215, 0)
TEXT_COLOR = (220, 220, 220)
AMMO_BAR_BG = (50, 50, 70)
AMMO_BAR_FG = (0, 200, 255)
HEALTH_BAR_BG = (70, 50, 50)
HEALTH_BAR_FG = (0, 200, 100)
# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("打枪射击游戏")
clock = pygame.time.Clock()
# 加载字体
font = pygame.font.SysFont(None, 36)
small_font = pygame.font.SysFont(None, 24)
# 加载音效
try:
shoot_sound = mixer.Sound("shoot.wav") # 需要提供音效文件
enemy_hit_sound = mixer.Sound("hit.wav") # 需要提供音效文件
except:
# 如果没有音效文件,创建虚拟音效
shoot_sound = mixer.Sound(pygame.sndarray.array([0]))
enemy_hit_sound = mixer.Sound(pygame.sndarray.array([0]))
class Player:
def __init__(self):
self.x = SCREEN_WIDTH // 2
self.y = SCREEN_HEIGHT // 2
self.radius = 20
self.speed = 5
self.health = 1000
self.max_health = 1000
self.ammo = 30000000000000000000000000
self.max_ammo =100000000000000000000000000000
self.reload_time = 0
self.score = 0
self.kills = 0
self.last_shot = 0
self.shoot_delay = 150 # 射击延迟(毫秒)
def move(self, dx, dy):
# 移动玩家并确保不会超出屏幕边界
self.x = max(self.radius, min(SCREEN_WIDTH - self.radius, self.x + dx * self.speed))
self.y = max(self.radius, min(SCREEN_HEIGHT - self.radius, self.y + dy * self.speed))
def shoot(self, mouse_pos):
current_time = pygame.time.get_ticks()
if current_time - self.last_shot > self.shoot_delay and self.ammo > 0:
self.last_shot = current_time
self.ammo -= 1
shoot_sound.play()
# 计算子弹方向
angle = math.atan2(mouse_pos[1] - self.y, mouse_pos[0] - self.x)
return Bullet(self.x, self.y, angle)
return None
def reload(self):
if self.ammo < self.max_ammo and self.reload_time == 0:
self.reload_time = 1000 # 1.5秒装弹时间
def update(self):
# 更新装弹状态
if self.reload_time > 0:
self.reload_time = max(0, self.reload_time - clock.get_time())
if self.reload_time == 0:
self.ammo = self.max_ammo
def draw(self, surface):
# 绘制玩家
pygame.draw.circle(surface, PLAYER_COLOR, (self.x, self.y), self.radius)
# 绘制枪管
mouse_x, mouse_y = pygame.mouse.get_pos()
angle = math.atan2(mouse_y - self.y, mouse_x - self.x)
gun_length = self.radius + 25
gun_end_x = self.x + math.cos(angle) * gun_length
gun_end_y = self.y + math.sin(angle) * gun_length
pygame.draw.line(surface, (40, 40, 50), (self.x, self.y), (gun_end_x, gun_end_y), 8)
# 绘制玩家方向指示器
pygame.draw.circle(surface, (50, 50, 70), (self.x, self.y), self.radius + 5, 2)
# 绘制生命条
pygame.draw.rect(surface, HEALTH_BAR_BG, (self.x - 30, self.y - self.radius - 15, 60, 10))
pygame.draw.rect(surface, HEALTH_BAR_FG, (self.x - 30, self.y - self.radius - 15, 60 * (self.health / self.max_health), 10))
# 绘制弹药指示器
pygame.draw.rect(surface, AMMO_BAR_BG, (self.x - 30, self.y + self.radius + 5, 60, 8))
pygame.draw.rect(surface, AMMO_BAR_FG, (self.x - 30, self.y + self.radius + 5, 60 * (self.ammo / self.max_ammo), 8))
class Enemy:
def __init__(self):
# 从屏幕边缘生成敌人
side = random.choice(['left', 'right', 'top', 'bottom'])
if side == 'left':
self.x = -20
self.y = random.randint(0, SCREEN_HEIGHT)
elif side == 'right':
self.x = SCREEN_WIDTH + 20
self.y = random.randint(0, SCREEN_HEIGHT)
elif side == 'top':
self.x = random.randint(0, SCREEN_WIDTH)
self.y = -20
else: # bottom
self.x = random.randint(0, SCREEN_WIDTH)
self.y = SCREEN_HEIGHT + 20
self.radius = 15
self.speed = random.uniform(1.0, 3.0)
self.health = 30
self.color = ENEMY_COLOR
self.move_timer = 0
self.move_direction = random.uniform(0, 2 * math.pi)
self.change_direction_time = random.randint(1000, 3000)
self.shoot_cooldown = random.randint(1000, 3000)
self.last_shot = pygame.time.get_ticks()
def update(self, player):
# 计算到玩家的向量
dx = player.x - self.x
dy = player.y - self.y
distance = math.sqrt(dx ** 2 + dy ** 2)
# 更新移动方向
self.move_timer += clock.get_time()
if self.move_timer > self.change_direction_time:
self.move_timer = 0
self.change_direction_time = random.randint(1000, 3000)
# 30%概率直接朝玩家移动,70%概率随机移动
if random.random() < 0.3:
# 朝玩家移动
angle = math.atan2(dy, dx)
self.move_direction = angle
else:
# 随机移动
self.move_direction = random.uniform(0, 50 * math.pi)
# 移动敌人
self.x += math.cos(self.move_direction) * self.speed
self.y += math.sin(self.move_direction) * self.speed
# 确保敌人不会离开屏幕太远
self.x = max(-50, min(SCREEN_WIDTH + 50, self.x))
self.y = max(-50, min(SCREEN_HEIGHT + 50, self.y))
# 射击逻辑
current_time = pygame.time.get_ticks()
if distance < 400 and current_time - self.last_shot > self.shoot_cooldown:
self.last_shot = current_time
self.shoot_cooldown = random.randint(1000, 3000)
angle = math.atan2(player.y - self.y, player.x - self.x)
return Bullet(self.x, self.y, angle, enemy_bullet=True)
return None
def draw(self, surface):
pygame.draw.circle(surface, self.color, (self.x, self.y), self.radius)
# 绘制敌人眼睛
eye_offset = self.radius * 0.4
pygame.draw.circle(surface, (255, 255, 255), (self.x - eye_offset, self.y - eye_offset), self.radius * 0.3)
pygame.draw.circle(surface, (255, 255, 255), (self.x + eye_offset, self.y - eye_offset), self.radius * 0.3)
pygame.draw.circle(surface, (0, 0, 0), (self.x - eye_offset, self.y - eye_offset), self.radius * 0.1)
pygame.draw.circle(surface, (0, 0, 0), (self.x + eye_offset, self.y - eye_offset), self.radius * 0.1)
# 绘制生命条
pygame.draw.rect(surface, HEALTH_BAR_BG, (self.x - self.radius, self.y - self.radius - 10, self.radius * 2, 5))
pygame.draw.rect(surface, HEALTH_BAR_FG, (self.x - self.radius, self.y - self.radius - 10, self.radius * 2 * (self.health / 30), 5))
class Bullet:
def __init__(self, x, y, angle, enemy_bullet=False):
self.x = x
self.y = y
self.radius = 4
self.speed = 7
self.angle = angle
self.enemy_bullet = enemy_bullet
self.creation_time = pygame.time.get_ticks()
|
|