parent
1eca700040
commit
4ee73a72b2
After Width: | Height: | Size: 1.9 MiB |
After Width: | Height: | Size: 933 KiB |
After Width: | Height: | Size: 264 KiB |
After Width: | Height: | Size: 1.0 MiB |
@ -0,0 +1,284 @@
|
||||
import pygame
|
||||
import random
|
||||
import os
|
||||
import sys
|
||||
|
||||
# 获取当前脚本的目录
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# 初始化Pygame
|
||||
pygame.init()
|
||||
|
||||
# 游戏常量设置
|
||||
SCREEN_WIDTH = 800
|
||||
SCREEN_HEIGHT = 600
|
||||
FPS = 60
|
||||
PLAYER_SPEED = 8 # 增加玩家速度
|
||||
BULLET_SPEED = 15 # 增加子弹速度
|
||||
ALIEN_COUNT = 8 # 初始外星人数量
|
||||
PLAYER_SIZE = (50, 50)
|
||||
ALIEN_SIZE = (50, 50)
|
||||
BULLET_SIZE = (20, 40)
|
||||
|
||||
# 颜色定义
|
||||
BACKGROUND_COLOR = (25, 62, 11) # 更改变量名以更好地反映其用途
|
||||
TEXT_COLOR = (255, 0, 255)
|
||||
SCORE_COLOR = (255, 0, 0)
|
||||
|
||||
# 创建游戏窗口
|
||||
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
||||
pygame.display.set_caption("外星人大战")
|
||||
|
||||
|
||||
# 字体设置 - 改进中文字体加载
|
||||
def load_chinese_font(size=48):
|
||||
"""尝试多种方式加载中文字体"""
|
||||
# 常见的中文字体文件路径
|
||||
font_paths = [
|
||||
"c:/Windows/Fonts/simhei.ttf", # Windows 黑体
|
||||
"c:/Windows/Fonts/msyh.ttc", # Windows 微软雅黑
|
||||
"c:/Windows/Fonts/simsun.ttc", # Windows 宋体
|
||||
"/System/Library/Fonts/PingFang.ttc", # macOS
|
||||
"/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf", # Linux
|
||||
]
|
||||
|
||||
# 尝试从文件加载字体
|
||||
for path in font_paths:
|
||||
try:
|
||||
if os.path.exists(path):
|
||||
return pygame.font.Font(path, size)
|
||||
except:
|
||||
continue
|
||||
|
||||
# 如果无法从文件加载,尝试使用系统字体
|
||||
try:
|
||||
return pygame.font.SysFont('simhei', size)
|
||||
except:
|
||||
pass
|
||||
|
||||
# 最后的备选方案:使用默认字体
|
||||
print("警告: 无法加载中文字体,将使用默认字体")
|
||||
return pygame.font.Font(None, size)
|
||||
|
||||
|
||||
# 加载字体 - 为所有文本使用同一个中文字体,但大小不同
|
||||
chinese_font_large = load_chinese_font(48) # 大号中文字体
|
||||
chinese_font_medium = load_chinese_font(36) # 中号中文字体
|
||||
chinese_font_small = load_chinese_font(24) # 小号中文字体
|
||||
|
||||
|
||||
# 加载图片并处理可能的错误
|
||||
def load_image(filename, size):
|
||||
"""加载并缩放图片,处理可能的错误"""
|
||||
try:
|
||||
path = os.path.join(BASE_DIR, filename)
|
||||
image = pygame.image.load(path)
|
||||
return pygame.transform.scale(image, size)
|
||||
except pygame.error as e:
|
||||
print(f"无法加载图片 {filename}: {e}")
|
||||
# 创建一个彩色占位符图像
|
||||
surface = pygame.Surface(size)
|
||||
surface.fill((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))
|
||||
return surface
|
||||
|
||||
|
||||
# 加载游戏图片
|
||||
player_img = load_image('ic.bmp', PLAYER_SIZE)
|
||||
alien_img = load_image('in.bmp', ALIEN_SIZE)
|
||||
bullet_img = load_image('ib.bmp', BULLET_SIZE)
|
||||
|
||||
|
||||
# 玩家类
|
||||
class Player(pygame.sprite.Sprite):
|
||||
def __init__(self):
|
||||
"""初始化玩家对象"""
|
||||
super().__init__()
|
||||
self.image = player_img
|
||||
self.rect = self.image.get_rect()
|
||||
self.rect.centerx = SCREEN_WIDTH // 2
|
||||
self.rect.bottom = SCREEN_HEIGHT - 10
|
||||
self.speed = PLAYER_SPEED
|
||||
self.last_shot = pygame.time.get_ticks() # 记录上次射击时间
|
||||
self.shoot_delay = 250 # 射击冷却时间(毫秒)
|
||||
|
||||
def update(self):
|
||||
"""更新玩家位置"""
|
||||
keys = pygame.key.get_pressed()
|
||||
if keys[pygame.K_LEFT] and self.rect.left > 0:
|
||||
self.rect.x -= self.speed
|
||||
if keys[pygame.K_RIGHT] and self.rect.right < SCREEN_WIDTH:
|
||||
self.rect.x += self.speed
|
||||
|
||||
# 自动射击功能
|
||||
now = pygame.time.get_ticks()
|
||||
if keys[pygame.K_SPACE] and now - self.last_shot > self.shoot_delay:
|
||||
self.shoot()
|
||||
self.last_shot = now
|
||||
|
||||
def shoot(self):
|
||||
"""创建一个新子弹"""
|
||||
bullet = Bullet(self.rect.centerx, self.rect.top)
|
||||
all_sprites.add(bullet)
|
||||
bullets.add(bullet)
|
||||
|
||||
|
||||
# 外星人类
|
||||
class Alien(pygame.sprite.Sprite):
|
||||
def __init__(self):
|
||||
"""初始化外星人对象"""
|
||||
super().__init__()
|
||||
self.image = alien_img
|
||||
self.rect = self.image.get_rect()
|
||||
self.reset_position()
|
||||
|
||||
def reset_position(self):
|
||||
"""重置外星人位置和速度"""
|
||||
self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
|
||||
self.rect.y = random.randint(-150, -40) # 增加初始高度范围,使外星人出现更分散
|
||||
self.speed = random.randint(2, 5) # 增加速度范围,使游戏更具挑战性
|
||||
|
||||
def update(self):
|
||||
"""更新外星人位置"""
|
||||
self.rect.y += self.speed
|
||||
# 如果外星人飞出屏幕底部,重置其位置
|
||||
if self.rect.top > SCREEN_HEIGHT:
|
||||
self.reset_position()
|
||||
|
||||
|
||||
# 子弹类
|
||||
class Bullet(pygame.sprite.Sprite):
|
||||
def __init__(self, x, y):
|
||||
"""初始化子弹对象"""
|
||||
super().__init__()
|
||||
self.image = bullet_img
|
||||
self.rect = self.image.get_rect()
|
||||
self.rect.centerx = x
|
||||
self.rect.bottom = y
|
||||
self.speed = BULLET_SPEED
|
||||
|
||||
def update(self):
|
||||
"""更新子弹位置"""
|
||||
self.rect.y -= self.speed
|
||||
# 如果子弹飞出屏幕顶部,删除它
|
||||
if self.rect.bottom < 0:
|
||||
self.kill()
|
||||
|
||||
|
||||
# 游戏状态类
|
||||
class GameState:
|
||||
def __init__(self):
|
||||
"""初始化游戏状态"""
|
||||
self.score = 0
|
||||
self.game_over = False
|
||||
self.reset_game()
|
||||
|
||||
def reset_game(self):
|
||||
"""重置游戏状态和精灵组"""
|
||||
global all_sprites, aliens, bullets, player
|
||||
|
||||
# 创建精灵组
|
||||
all_sprites = pygame.sprite.Group()
|
||||
aliens = pygame.sprite.Group()
|
||||
bullets = pygame.sprite.Group()
|
||||
|
||||
# 创建玩家实例并添加到精灵组
|
||||
player = Player()
|
||||
all_sprites.add(player)
|
||||
|
||||
# 创建多个外星人实例并添加到精灵组
|
||||
for i in range(ALIEN_COUNT):
|
||||
alien = Alien()
|
||||
all_sprites.add(alien)
|
||||
aliens.add(alien)
|
||||
|
||||
# 重置游戏状态
|
||||
self.score = 0
|
||||
self.game_over = False
|
||||
|
||||
|
||||
# 创建游戏状态实例
|
||||
game_state = GameState()
|
||||
|
||||
# 预渲染文本,避免在游戏循环中反复渲染
|
||||
try:
|
||||
game_over_text = chinese_font_large.render("游戏结束", True, SCORE_COLOR)
|
||||
restart_text = chinese_font_medium.render("按 R 键重新开始", True, SCORE_COLOR)
|
||||
score_label = chinese_font_medium.render("得分: ", True, SCORE_COLOR)
|
||||
except:
|
||||
# 如果中文渲染失败,使用英文替代
|
||||
game_over_text = pygame.font.Font(None, 48).render("GAME OVER", True, SCORE_COLOR)
|
||||
restart_text = pygame.font.Font(None, 36).render("Press R to Restart", True, SCORE_COLOR)
|
||||
score_label = pygame.font.Font(None, 36).render("Score: ", True, SCORE_COLOR)
|
||||
|
||||
# 游戏主循环
|
||||
clock = pygame.time.Clock()
|
||||
running = True
|
||||
|
||||
while running:
|
||||
# 处理事件
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
elif event.type == pygame.KEYDOWN:
|
||||
if event.key == pygame.K_ESCAPE: # 按ESC退出游戏
|
||||
running = False
|
||||
elif event.key == pygame.K_r and game_state.game_over: # 按R重新开始游戏
|
||||
game_state.reset_game()
|
||||
elif event.key == pygame.K_SPACE and not game_state.game_over:
|
||||
player.shoot()
|
||||
|
||||
# 更新游戏状态
|
||||
if not game_state.game_over:
|
||||
# 更新所有精灵
|
||||
all_sprites.update()
|
||||
|
||||
# 检查子弹和外星人的碰撞
|
||||
hits = pygame.sprite.groupcollide(bullets, aliens, True, True)
|
||||
for hit in hits:
|
||||
game_state.score += 10
|
||||
# 创建新的外星人
|
||||
alien = Alien()
|
||||
all_sprites.add(alien)
|
||||
aliens.add(alien)
|
||||
|
||||
# 检查玩家和外星人的碰撞
|
||||
if pygame.sprite.spritecollide(player, aliens, False):
|
||||
game_state.game_over = True
|
||||
|
||||
# 绘制
|
||||
screen.fill(BACKGROUND_COLOR)
|
||||
all_sprites.draw(screen)
|
||||
|
||||
# 显示得分 - 使用预渲染的标签和动态渲染的分数
|
||||
screen.blit(score_label, (10, 10))
|
||||
# 动态渲染分数部分
|
||||
try:
|
||||
score_value = chinese_font_medium.render(str(game_state.score), True, SCORE_COLOR)
|
||||
except:
|
||||
score_value = pygame.font.Font(None, 36).render(str(game_state.score), True, SCORE_COLOR)
|
||||
screen.blit(score_value, (10 + score_label.get_width(), 10))
|
||||
|
||||
# 游戏结束逻辑
|
||||
if game_state.game_over:
|
||||
# 绘制半透明覆盖层
|
||||
overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
|
||||
overlay.fill((0, 0, 0, 128)) # 黑色半透明
|
||||
screen.blit(overlay, (0, 0))
|
||||
|
||||
# 显示游戏结束文本
|
||||
screen.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2,
|
||||
SCREEN_HEIGHT // 2 - game_over_text.get_height() // 2))
|
||||
|
||||
# 显示重新开始提示
|
||||
screen.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2,
|
||||
SCREEN_HEIGHT // 2 + game_over_text.get_height()))
|
||||
|
||||
# 更新屏幕
|
||||
pygame.display.flip()
|
||||
|
||||
# 控制帧率
|
||||
clock.tick(FPS)
|
||||
|
||||
# 退出Pygame
|
||||
pygame.quit()
|
||||
sys.exit()
|
@ -0,0 +1,49 @@
|
||||
import pygame
|
||||
import sys
|
||||
|
||||
# 初始化 Pygame
|
||||
pygame.init()
|
||||
|
||||
# 定义窗口大小
|
||||
WIDTH, HEIGHT = 600, 400
|
||||
|
||||
# 创建窗口
|
||||
win = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||
pygame.display.set_caption("Flappy Bird Clone")
|
||||
|
||||
# 颜色定义
|
||||
BACKGROUND_COLOR = (135, 206, 250)
|
||||
BIRD_COLOR = (255, 255, 0)
|
||||
|
||||
# 初始化小鸟位置和速度
|
||||
bird_x, bird_y = WIDTH // 2, HEIGHT // 2
|
||||
# print(type(bird_x))
|
||||
bird_vel_y = 0
|
||||
|
||||
# 游戏主循环
|
||||
while True:
|
||||
# 事件处理
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
pygame.quit()
|
||||
sys.exit()
|
||||
|
||||
# 小鸟控制
|
||||
keys = pygame.key.get_pressed()
|
||||
if keys[pygame.K_SPACE]:
|
||||
bird_vel_y = -1
|
||||
|
||||
# 小鸟移动
|
||||
bird_y += bird_vel_y
|
||||
bird_vel_y += 0.02 # 添加重力
|
||||
|
||||
# 绘制背景
|
||||
win.fill(BACKGROUND_COLOR)
|
||||
|
||||
# 绘制小鸟
|
||||
print(bird_x)
|
||||
print(bird_y)
|
||||
pygame.draw.circle(win, BIRD_COLOR, (bird_x, bird_y), 10)
|
||||
|
||||
# 更新窗口
|
||||
pygame.display.update()
|
Loading…
Reference in new issue