# 导包 import time import pygame import random # 初始化游戏 pygame.init() # 显示窗口 screen = pygame.display.set_mode((480, 650)) # 修改游戏图标 icon = pygame.image.load("img/icon.png") pygame.display.set_icon(icon) # 加载背景 bg_img = pygame.image.load("img/background.png") # 加载战机 hero_img1 = pygame.image.load("img/me1.png") hero_img2 = pygame.image.load("img/me2.png") # 定义战机 hero_rect = pygame.rect.Rect(189, 524, 102, 126) heroPlaneX = hero_rect.x heroPlaneY = hero_rect.y pygame.key.set_repeat(20, 30) # 显示战机要用参数 a = "单发" # 定义英雄子弹 class HeroBullet: def __init__(self, x, y, screen): self.x = x self.y = y self.show = screen self.pic = pygame.image.load("img/bullet1.png") # 画子弹 def draw(self): self.show.blit(self.pic,(self.x,self.y)) self.move() # 子弹移动 def move(self): self.y -= 5 # 战机子弹列表 hero_Bulletlist = [] # 战机爆炸条件 hero_bomb = False # 战机爆炸索引 hero_bomb_index = 0 # 战机爆炸图片 hero_bomb_list = ["img/enemy1_down1.png", "img/enemy1_down2.png", "img/enemy1_down3.png", "img/enemy1_down4.png"] # 加载敌机 di_img = pygame.image.load("img/enemy2.png") # 定义敌机 di_rect = pygame.rect.Rect(189, 0, 69, 99) diPlaneX = di_rect.x diPlaneY = di_rect.y # 敌机移动要用的参数 b = 'left' # 敌机子弹 class DiBullet: def __init__(self,x,y,screen): self.x = x self.y = y self.show = screen self.pic = pygame.image.load("img/bullet2.png") # 画子弹 def draw(self): self.show.blit(self.pic,(self.x,self.y)) self.move() # 子弹移动 def move(self): self.y += 5 # 敌机子弹列表 di_Bulletlist = [] # 敌机爆炸条件 is_bomb = False # 敌机爆炸索引 di_bomb_index = 0 # 敌机爆炸图片 di_bomb_list = ["img/enemy1_down1.png", "img/enemy1_down2.png", "img/enemy1_down3.png", "img/enemy1_down4.png"] clock = pygame.time.Clock() while True: clock.tick(120) # 显示背景 screen.blit(bg_img, (0, 0)) # 战机底部飞入 heroPlaneY -= 1 if heroPlaneY <= 0: heroPlaneY = 500 # 获取所有监听事件 event_list = pygame.event.get() # 获取窗口退出事件 for event in event_list: if event.type == pygame.QUIT: print("游戏结束了") # 卸载模块 pygame.quit() exit(0) # 战机移动 if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: heroPlaneX = heroPlaneX-10 if heroPlaneX >= 5 else 0 elif event.key == pygame.K_RIGHT: heroPlaneX = heroPlaneX+10 if heroPlaneX <=370 else 380 elif event.key == pygame.K_UP: heroPlaneY = heroPlaneY-10 if heroPlaneY >=5 else 0 elif event.key == pygame.K_DOWN: heroPlaneY = heroPlaneY+20 if heroPlaneY <=521 else 526 elif event.key == pygame.K_SPACE: hero_bullet = HeroBullet(heroPlaneX+40+10, heroPlaneY-11,screen) hero_Bulletlist.append(hero_bullet) # 调用函数画出战机子弹 for bullet in hero_Bulletlist: bullet.draw() # 定义战机子弹的rect hero_bullet_rect = pygame.rect.Rect(bullet.x,bullet.y,5,11) # 检测敌机和子弹矩形是否相交 flag = hero_bullet_rect.colliderect(di_rect) # 如果相交 if flag: print("敌机爆炸") is_bomb = True hero_Bulletlist.remove(bullet) # 绘制敌机爆炸图片 if is_bomb == False: # screen.blit(di_img,(diPlaneX,diPlaneY)) else: # if di_bomb_index == len(di_bomb_list): time.sleep(0.2) exit(0) di_bomb_img = pygame.image.load(di_bomb_list[di_bomb_index]) screen.blit(di_bomb_img,(diPlaneX,diPlaneY)) di_bomb_index += 1 time.sleep(0.2) # 显示敌机 # screen.blit(di_img,(diPlaneX,diPlaneY)) # 敌机移动 if b == 'left': diPlaneX = diPlaneX-3 if diPlaneX <= 0: b = 'right' elif b == 'right': diPlaneX = diPlaneX+3 if diPlaneX >= 480-60: b = 'left' # 定义敌机子弹 x = random.randint(1, 100) if x == 5 or x == 78: enemybullet = DiBullet(diPlaneX+(69+5)/2, diPlaneY+99, screen) di_Bulletlist.append(enemybullet) for bullet1 in di_Bulletlist: bullet1.draw() di_bullet_rect = pygame.rect.Rect(bullet1.x,bullet1.y,9,21) flag = di_bullet_rect.colliderect(hero_rect) if flag: print("战机爆炸") hero_bomb = True di_Bulletlist.remove(bullet1) if hero_bomb == False: # 显示战机 if a == "连发": screen.blit(hero_img1, (heroPlaneX, heroPlaneY)) a = "连发" else: screen.blit(hero_img2, (heroPlaneX, heroPlaneY)) a = "单发" else: if hero_bomb_index == len(hero_bomb_list): time.sleep(0.5) exit() hero_bomb_img = pygame.image.load(hero_bomb_list[hero_bomb_index]) screen.blit(hero_bomb_img,(heroPlaneX, heroPlaneY)) hero_bomb_index += 1 time.sleep(0.5) # 循环显示所有图片 pygame.display.update()
分段解析
1.导包和初始化
import time import pygame import random
导入必要的Python模块:time用于处理时间相关的功能,pygame是用于游戏开发的库,random用于生成随机数。
pygame.init()
初始化Pygame库,这是使用Pygame之前必须做的。
2. 设置窗口和图标
screen = pygame.display.set_mode((480, 650))
创建一个游戏窗口,大小为480x650像素。
icon = pygame.image.load("img/icon.png") pygame.display.set_icon(icon)
加载游戏图标并设置到游戏窗口。
3. 加载游戏资源
bg_img = pygame.image.load("img/background.png")
加载背景图片。
hero_img1 = pygame.image.load("img/me1.png") hero_img2 = pygame.image.load("img/me2.png")
加载英雄战机的两种不同状态图片。
4.定义英雄飞机和敌机的基本属性
hero_rect = pygame.rect.Rect(189,524,102,126) heroPlaneX = hero_rect.x heroPlaneY = hero_rect.y pygame.key.set_repeat(20,30)
创建英雄战机的矩形区域,并设置初始位置。pygame.key.set_repeat用于设置按键重复的延迟和间隔。
5.英雄飞机子弹类
a = "单发"
一个变量,用于控制英雄战机的图片切换。
class HeroBullet: def __init__(self,x,y,screen): self.x = x self.y = y self.show = screen self.pic = pygame.image.load("img/bullet1.png") # 画子弹 def draw(self): self.show.blit(self.pic,(self.x,self.y)) self.move() # 子弹移动 def move(self): self.y -= 5 # 战机子弹列表 hero_Bulletlist = [] # 战机爆炸条件 hero_bomb = False # 战机爆炸索引 hero_bomb_index = 0 # 战机爆炸图片 hero_bomb_list = ["img/enemy1_down1.png", "img/enemy1_down2.png", "img/enemy1_down3.png", "img/enemy1_down4.png"] # 加载敌机 di_img = pygame.image.load("img/enemy2.png") # 定义敌机 di_rect = pygame.rect.Rect(189, 0, 69, 99) diPlaneX = di_rect.x diPlaneY = di_rect.y # 敌机移动要用的参数 b = 'left' # 敌机子弹 class DiBullet: def __init__(self,x,y,screen): self.x = x self.y = y self.show = screen self.pic = pygame.image.load("img/bullet2.png") # 画子弹 def draw(self): self.show.blit(self.pic,(self.x,self.y)) self.move() # 子弹移动 def move(self): self.y += 5 # 敌机子弹列表 di_Bulletlist = [] # 敌机爆炸条件 is_bomb = False # 敌机爆炸索引 di_bomb_index = 0 # 敌机爆炸图片 di_bomb_list = ["img/enemy1_down1.png", "img/enemy1_down2.png", "img/enemy1_down3.png", "img/enemy1_down4.png"]
这段代码定义了两个类 HeroBullet 和 DiBullet,分别用于创建和渲染英雄战机和敌机的子弹。同时,它还初始化了一些用于控制游戏逻辑的变量。
HeroBullet 类
这个类用于创建英雄战机的子弹。每个子弹对象都有以下属性和方法:
x 和 y:子弹在屏幕上的坐标。
show:游戏屏幕的表面对象,用于在屏幕上绘制子弹。
pic:子弹的图像,通过 pygame.image.load 加载。
draw() 方法:在屏幕上绘制子弹,并调用 move() 方法来更新子弹的位置。
move() 方法:将子弹的 y 坐标减少 5,使子弹向上移动。
DiBullet 类
这个类用于创建敌机的子弹。它的结构和工作方式与 HeroBullet 类似,但是子弹的移动方向相反:子弹的 y 坐标增加 5,使子弹向下移动。
游戏逻辑变量
hero_Bulletlist 和 di_Bulletlist:这两个列表分别存储英雄战机和敌机的子弹对象。
hero_bomb 和 is_bomb:这两个布尔变量用于判断战机是否应该爆炸。
hero_bomb_index 和 di_bomb_index:这两个整型变量用于跟踪爆炸动画的当前帧。
hero_bomb_list 和 di_bomb_list:这两个列表包含战机爆炸动画的帧图像文件路径。
敌机初始化
di_img:加载敌机的图像。
di_rect:定义敌机的矩形区域,用于碰撞检测。
diPlaneX 和 diPlaneY:存储敌机的当前位置。
b:控制敌机移动方向的变量,初始值为 'left'。
敌机移动逻辑
敌机的移动逻辑在主游戏循环中实现,根据变量 b 的值,敌机在屏幕上左右移动。当敌机到达屏幕边缘时,改变移动方向。
爆炸逻辑
当战机被子弹击中时,相应的爆炸条件变量 (hero_bomb 或 is_bomb) 设置为 True,并在游戏循环中触发爆炸动画。动画通过遍历爆炸图像列表来实现,每次循环显示一张图像,直到列表中的所有图像都被显示一遍。
这段代码是游戏的一部分,它需要与游戏的主循环和事件处理逻辑结合使用。在主循环中,将创建子弹对象,更新它们的位置,检测碰撞,并绘制到屏幕上。当战机或敌机被击中时,将触发爆炸动画,最终可能结束游戏或进行其他游戏逻辑的处理。
clock = pygame.time.Clock()
创建一个时钟对象,用于控制游戏的帧率。
6.游戏循环和事件处理
while True: clock.tick(120)
游戏的主循环,所有游戏逻辑都在这个循环中处理。
游戏循环开始,clock.tick(120) 设置每秒钟最多执行120次循环,即游戏的帧率为120FPS。
screen.blit(bg_img, (0, 0))
在屏幕上绘制背景图像,位于屏幕的左上角。
heroPlaneY -= 1 if heroPlaneY <= 0: heroPlaneY = 500
英雄战机的Y坐标每帧减少1,模拟战机移动。如果战机移动到屏幕顶部之外,将其重新设置到屏幕底部。
event_list = pygame.event.get()
获取所有pygame事件。
for event in event_list: if event.type == pygame.QUIT: print("游戏结束了") pygame.quit() exit(0)
遍历事件列表,如果检测到QUIT事件(通常是用户关闭窗口),则打印游戏结束信息,卸载pygame模块,并退出程序。
if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: heroPlaneX = heroPlaneX-10 if heroPlaneX >= 5 else 0 elif event.key == pygame.K_RIGHT: heroPlaneX = heroPlaneX+10 if heroPlaneX <=370 else 380 elif event.key == pygame.K_UP: heroPlaneY = heroPlaneY-10 if heroPlaneY >=5 else 0 elif event.key == pygame.K_DOWN: heroPlaneY = heroPlaneY+20 if heroPlaneY <=521 else 526 elif event.key == pygame.K_SPACE: hero_bullet = HeroBullet(heroPlaneX+40+10, heroPlaneY-11,screen) hero_Bulletlist.append(hero_bullet)
如果检测到KEYDOWN事件(键盘按键按下),则根据按下的键来移动战机或发射子弹。
for bullet in hero_Bulletlist: bullet.draw() # 定义战机子弹的rect hero_bullet_rect = pygame.rect.Rect(bullet.x,bullet.y,5,11) # 检测敌机和子弹矩形是否相交 flag = hero_bullet_rect.colliderect(di_rect) # 如果相交 if flag: print("敌机爆炸") is_bomb = True hero_Bulletlist.remove(bullet) for bullet in hero_Bulletlist: bullet.draw()
遍历英雄战机的子弹列表,调用每个子弹的draw方法来绘制它们,并检测子弹是否与敌机碰撞。
for bullet in hero_Bulletlist: bullet.draw() # 定义战机子弹的rect hero_bullet_rect = pygame.rect.Rect(bullet.x,bullet.y,5,11) # 检测敌机和子弹矩形是否相交 flag = hero_bullet_rect.colliderect(di_rect) # 如果相交 if flag: print("敌机爆炸") is_bomb = True hero_Bulletlist.remove(bullet)
如果敌机没有被击中(is_bomb为False),则绘制敌机。否则,播放敌机爆炸动画。
for bullet1 in di_Bulletlist: bullet1.draw() di_bullet_rect = pygame.rect.Rect(bullet1.x,bullet1.y,9,21) flag = di_bullet_rect.colliderect(hero_rect) if flag: print("战机爆炸") hero_bomb = True di_Bulletlist.remove(bullet1)
遍历敌机的子弹列表,调用每个子弹的draw方法来绘制它们,并检测子弹是否与英雄战机碰撞。
if is_bomb == False: # screen.blit(di_img,(diPlaneX,diPlaneY)) else: # if di_bomb_index == len(di_bomb_list): time.sleep(0.2) exit(0) di_bomb_img = pygame.image.load(di_bomb_list[di_bomb_index]) screen.blit(di_bomb_img,(diPlaneX,diPlaneY)) di_bomb_index += 1 time.sleep(0.2)
如果英雄战机没有被击中(hero_bomb为False),则绘制战机。否则,播放战机爆炸动画。
7.游戏结束条件
pygame.display.update()
更新整个屏幕的显示,这是游戏循环的最后一部分。
总结分析:
1.游戏初始化:
1.1导入所需的模块:time, pygame, random。
1.2初始化游戏窗口,设置窗口大小为480x650像素。
1.3加载游戏图标和背景图片。
1.4加载英雄机和敌机的图片,并定义它们的矩形区域。
1.5设置键盘重复事件,以便在按下键时能够连续移动英雄机。
2.英雄机控制:
2.1英雄机在窗口中上下移动,并且当到达窗口底部时会重新出现在顶部。
2.2英雄机可以通过键盘的左右键来移动。
2.3按下空格键时,英雄机会发射子弹。
3.子弹和敌机:
3.1英雄机的子弹是一个单独的类 HeroBullet,它有绘制和移动子弹的方法。
3.2敌机也是一个单独的类 DiBullet,它有绘制和移动敌机子弹的方法。
3.3敌机子弹列表 enemy_Bulletlist 和英雄机子弹列表 hero_Bulletlist 用于存储所有子弹对象。
4.碰撞检测:
4.1使用 colliderect 函数来检测英雄子弹和敌机,以及敌机子弹和英雄机之间的碰撞。
4.2当发生碰撞时,相应的子弹会被移除,并且敌机或英雄机会触发爆炸效果。
5.爆炸效果:
5.1爆炸条件 is_bomb 和 hero_bomb 用于指示敌机和英雄机是否发生了爆炸。
5.2爆炸图片列表 enemy_bomb_list 和 hero_bomb_list 包含了用于显示爆炸的图片。
5.3当爆炸条件为真时,会循环显示爆炸图片,直到图片索引到达列表的末尾,然后结束游戏或重新开始。
6.游戏循环:
6.1游戏循环不断运行,处理事件、更新游戏状态、绘制图像,并更新窗口显示。
6.2循环中使用了 pygame.display.update() 来刷新屏幕显示。
7.游戏结束:
7.1游戏中设置了退出事件,当用户关闭窗口或按下退出键时,游戏会打印“游戏结束了”,并退出程序。