找回密码
 中文实名注册
搜索
查看: 60|回复: 0

射击

[复制链接]

29

主题

97

回帖

1132

积分

金牌会员

积分
1132
发表于 2025-10-2 10:52:58 | 显示全部楼层 |阅读模式
import pygame
import sys
import random
import math
from pygame import mixer


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 = 100000000000000000000000000
        self.max_health = 100000000000000000000000
        self.ammo = 300000000000000000000000000000000000
        self.max_ammo = 30000000000000000000000000
        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 = 1500  # 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)

            
            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()
        self.max_lifetime = 2000  # 子弹存在的最长时间(毫秒)

    def update(self):
        
        self.x += math.cos(self.angle) * self.speed
        self.y += math.sin(self.angle) * self.speed

        
        current_time = pygame.time.get_ticks()
        if (self.x < -50 or self.x > SCREEN_WIDTH + 50 or
            self.y < -50 or self.y > SCREEN_HEIGHT + 50 or
            current_time - self.creation_time > self.max_lifetime):
            return False
        return True

    def draw(self, surface):
        color = (255, 150, 0) if self.enemy_bullet else BULLET_COLOR
        pygame.draw.circle(surface, color, (int(self.x), int(self.y)), self.radius)

        
        for i in range(1, 4):
            trail_x = self.x - math.cos(self.angle) * i * 3
            trail_y = self.y - math.sin(self.angle) * i * 3
            pygame.draw.circle(surface, (*color[:3], 150 - i*50), (int(trail_x), int(trail_y)), self.radius - i)

class Particle:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.size = random.randint(2, 6)
        self.speed_x = random.uniform(-3, 3)
        self.speed_y = random.uniform(-3, 3)
        self.lifetime = random.randint(20, 40)

    def update(self):
        self.x += self.speed_x
        self.y += self.speed_y
        self.lifetime -= 1
        self.size = max(0, self.size - 0.1)
        return self.lifetime > 0

    def draw(self, surface):
        pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), int(self.size))

def draw_hud(surface, player, wave, enemies_left):
    # 绘制分数
    score_text = font.render(f"分数: {player.score}", True, TEXT_COLOR)
    surface.blit(score_text, (10, 10))

   
    kills_text = font.render(f"击杀: {player.kills}", True, TEXT_COLOR)
    surface.blit(kills_text, (10, 50))

   
    wave_text = font.render(f"波数: {wave}", True, TEXT_COLOR)
    surface.blit(wave_text, (SCREEN_WIDTH - wave_text.get_width() - 10, 10))

   
    enemies_text = font.render(f"敌人: {enemies_left}", True, TEXT_COLOR)
    surface.blit(enemies_text, (SCREEN_WIDTH - enemies_text.get_width() - 10, 50))

   
    ammo_text = font.render(f"弹药: {player.ammo}/{player.max_ammo}", True, TEXT_COLOR)
    surface.blit(ammo_text, (SCREEN_WIDTH // 2 - ammo_text.get_width() // 2, SCREEN_HEIGHT - 40))

   
    if player.reload_time > 0:
        reload_text = font.render("装弹中...", True, (255, 150, 50))
        surface.blit(reload_text, (SCREEN_WIDTH // 2 - reload_text.get_width() // 2, SCREEN_HEIGHT - 80))

def draw_game_over(surface, player):
    overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表