本帖最后由 周易航 于 2025-7-17 11:05 编辑
[Python] 纯文本查看 复制代码 import pygame
import random
import math
import sys
# 初始化pygame
pygame.init()
# 确保中文显示正常
pygame.font.init()
font_path = pygame.font.match_font(
'simsun') or pygame.font.match_font('simhei')
if not font_path:
# 如果没有找到中文字体,使用默认字体
font_path = pygame.font.get_default_font()
game_font = pygame.font.Font(font_path, 24)
small_font = pygame.font.Font(font_path, 16)
# 游戏窗口设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("像素枪战")
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 50, 255)
YELLOW = (255, 255, 0)
GRAY = (150, 150, 150)
# 游戏参数
FPS = 60
PLAYER_SPEED = 50
ENEMY_SPEED = 2
BULLET_SPEED = 50
ENEMY_SPAWN_RATE = 3000 # 毫秒
BULLET_COOLDOWN = 300 # 毫秒
MAX_ENEMIES = 10
ENEMY_HEALTH = 0
PLAYER_HEALTH = 114514
SCORE_PER_KILL = 10
# 精灵类
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((30, 30))
self.image.fill(BLUE)
self.rect = self.image.get_rect()
self.rect.centerx = SCREEN_WIDTH // 2
self.rect.centery = SCREEN_HEIGHT // 2
self.speed_x = 0
self.speed_y = 0
self.health = PLAYER_HEALTH
self.last_shot = pygame.time.get_ticks()
def update(self):
self.speed_x = 0
self.speed_y = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT] or keystate[pygame.K_a]:
self.speed_x = -PLAYER_SPEED
if keystate[pygame.K_RIGHT] or keystate[pygame.K_d]:
self.speed_x = PLAYER_SPEED
if keystate[pygame.K_UP] or keystate[pygame.K_w]:
self.speed_y = -PLAYER_SPEED
if keystate[pygame.K_DOWN] or keystate[pygame.K_s]:
self.speed_y = PLAYER_SPEED
# 移动玩家
self.rect.x += self.speed_x
self.rect.y += self.speed_y
# 保持玩家在屏幕内
if self.rect.right > SCREEN_WIDTH:
self.rect.right = SCREEN_WIDTH
if self.rect.left < 0:
self.rect.left = 0
if self.rect.bottom > SCREEN_HEIGHT:
self.rect.bottom = SCREEN_HEIGHT
if self.rect.top < 0:
self.rect.top = 0
def shoot(self):
now = pygame.time.get_ticks()
if now - self.last_shot > BULLET_COOLDOWN:
self.last_shot = now
mouse_x, mouse_y = pygame.mouse.get_pos()
bullet = Bullet(self.rect.centerx,
self.rect.centery, mouse_x, mouse_y)
all_sprites.add(bullet)
bullets.add(bullet)
return True
return False
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((25, 25))
self.image.fill(RED)
self.rect = self.image.get_rect()
# 随机在屏幕边缘生成敌人
side = random.randint(1, 4)
if side == 1: # 上边
self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = -self.rect.height
elif side == 2: # 右边
self.rect.x = SCREEN_WIDTH
self.rect.y = random.randint(0, SCREEN_HEIGHT - self.rect.height)
elif side == 3: # 下边
self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
self.rect.y = SCREEN_HEIGHT
else: # 左边
self.rect.x = -self.rect.width
self.rect.y = random.randint(0, SCREEN_HEIGHT - self.rect.height)
self.speed = random.randint(1, ENEMY_SPEED)
self.health = ENEMY_HEALTH
def update(self):
# 向玩家移动
dx = player.rect.centerx - self.rect.centerx
dy = player.rect.centery - self.rect.centery
distance = max(1, math.sqrt(dx*dx + dy*dy)) # 避免除以零
self.rect.x += (dx / distance) * self.speed
self.rect.y += (dy / distance) * self.speed
# 保持敌人在屏幕内
if self.rect.right > SCREEN_WIDTH:
self.rect.right = SCREEN_WIDTH
if self.rect.left < 0:
self.rect.left = 0
if self.rect.bottom > SCREEN_HEIGHT:
self.rect.bottom = SCREEN_HEIGHT
if self.rect.top < 0:
self.rect.top = 0
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, target_x, target_y):
super().__init__()
self.image = pygame.Surface((8, 8))
self.image.fill(YELLOW)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.centery = y
# 计算子弹方向
dx = target_x - x
dy = target_y - y
distance = max(1, math.sqrt(dx*dx + dy*dy)) # 避免除以零
self.speed_x = (dx / distance) * BULLET_SPEED
self.speed_y = (dy / distance) * BULLET_SPEED
def update(self):
self.rect.x += self.speed_x
self.rect.y += self.speed_y
# 如果子弹超出屏幕,删除它
if (self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT or
self.rect.right < 0 or self.rect.left > SCREEN_WIDTH):
self.kill()
class Explosion(pygame.sprite.Sprite):
def __init__(self, center):
super().__init__()
self.size = random.randint(15, 30)
self.image = pygame.Surface((self.size, self.size))
self.image.fill(YELLOW)
self.rect = self.image.get_rect()
self.rect.center = center
self.lifetime = 10
self.frame = 0
def update(self):
self.frame += 1
if self.frame >= self.lifetime:
self.kill()
else:
# 爆炸效果逐渐消失
alpha = 255 - (self.frame * 255 // self.lifetime)
self.image.set_alpha(alpha)
# 创建精灵组
all_sprites = pygame.sprite.Group()
enemies = pygame.sprite.Group()
bullets = pygame.sprite.Group()
# 创建玩家
player = Player()
all_sprites.add(player)
# 游戏变量
score = 0
last_enemy_spawn = pygame.time.get_ticks()
game_over = False
show_menu = True
clock = pygame.time.Clock()
# 游戏循环
running = True
while running:
clock.tick(FPS)
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN and not game_over and not show_menu:
if event.button == 1: # 左键点击
player.shoot()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE and (game_over or show_menu):
# 重置游戏
game_over = False
show_menu = False
score = 0
player.health = PLAYER_HEALTH
# 清空精灵组
for sprite in all_sprites:
if sprite != player:
sprite.kill()
enemies.empty()
bullets.empty()
# 重新添加玩家
if player not in all_sprites:
all_sprites.add(player)
elif event.key == pygame.K_ESCAPE:
running = False
# 游戏逻辑
if not game_over and not show_menu:
# 生成敌人
now = pygame.time.get_ticks()
if now - last_enemy_spawn > ENEMY_SPAWN_RATE and len(enemies) < MAX_ENEMIES:
last_enemy_spawn = now
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
|