控制英雄精灵移动
项目准备
安装准备
这里我们要用到pygame模块,pygame模块是python中针对电子游戏开发的模块,功能十分完善,安装pygame模块的方法(针对windows用户):直接在终端输入 pip install pygame,如果运行失败可以用镜像源 pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple
安装成功后会显示successfully,也可以输入pip list 进行查看
绘制窗口
初始化和退出
这里我们需要使用到pygame提供的init方法进行初始化,quit来退出
创建游戏主窗口
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 650))
while True:
pass
pygame.quit()
#修改游戏名称
pygame.display.set_caption('飞机大战')
#修改游戏图标
icon = pygame.image.load("image/icon72x72.png")
pygame.display.set_icon(icon)
创建游戏窗口用set_mode方法,取决于背景图片的大小,里面第一个参数是(width,height),是一个元组一定要用() 括起来,这里设置的是宽480,高650。
pygame.image.load()加载图像数据
绘制图像
# 加载图像数据,括号里面是图片地址
background = pygame.image.load('image/background.png')
# blit绘制图像,(0,0)是将背景图的左上角绘制到游戏窗口的左上角
screen.blit(background, (0, 0))
# update 更新屏幕显示
pygame.display.update()
使用pygame.image.load()加载图像的数据
调用pygame.display.update()方法更新整个屏幕的显示,可以在所有图像绘制完之后调用update
pygame.diaplay.update()来更新整个屏幕的显示
定义图片切换索引
hero_imgindex=0
时钟对象
# 设置时钟对象
clock = pygame.time.Clock()
while True:
# 设置游戏频率,可以指定循环内部的代码执行的频率,60表示每秒执行60次
clock.tick(60)
上面的游戏窗口已经把游戏窗口和背景都已经设置好,而这里我们可以设置每秒刷新60次
在规定的时间内执行多少次,可以理解为每秒执行多少次,即刷新帧率,pygame专门提供一个类pygame.time.Clock()可以非常方便的设置屏幕绘制速度,即刷新帧率
绘制英雄机
hero_img1 = pygame.image.load("image/me1.png")
英雄机的移动
# 设置时钟对象
clock = pygame.time.Clock()
# 定义rect记录飞机的初始位置
hero_rect = pygame.Rect(190,525,100,124)
while True:
# 60表示每秒执行60次
clock.tick(60)
# 修改飞机的位置
hero_rect.y -= 1
# 调用blit方法绘制图像,每次循环完用背景图覆盖一次,不然会造成每次循环的飞机重叠
screen.blit(background, (0, 0))
screen.blit(hero, hero_rect)
# 更新屏幕显示
pygame.display.update()
定义飞机的位置,然后在每次循环内对飞机的坐标进行更改,然后每次循环结束前在对屏幕进行更新
注:在每次循环内我们需要覆盖掉上一次战机,即用背景图进行覆盖,不然会造成每次循环的战机都留在屏幕上,所以我们在每次循环绘制战机之前,先对上一次循环的战机进行覆盖
将英雄的飞机绘制到窗口上
if shitindex == 0:
screen.blit(hero_img1, (hero_PlaneX, hero_PlaneY))
shitindex = 1
else:
screen.blit(hero_img2, (hero_PlaneX, hero_PlaneY))
shitindex = 0
更改英雄机精灵坐标位置
英雄精灵自动移动
# 飞机从底部飞出
if hero_PlaneY<0:
hero_PlaneY=750
就是当战机移动到顶部的时候,会从底部钻出来,这样会使战机移动更连续
事件监听
首先获取所有事件
# 对事件进行监听 获取所有事件
event_list = pygame.event.get()
#捕捉窗口退出事件
for event in event_list:
if event.type == pygame.QUIT: # 加上这个模块就不卡了
print("游戏结束了.......")
pygame.quit() # 卸载模块
exit(0) # 终止Python程序, exit(0)表示正常退出 exit(1)表示异常退出
控制英雄精灵移动
# 控制英雄精灵移动
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
hero_PlaneX = hero_PlaneX - 5 if hero_PlaneX >= 5 else 0
elif event.key == pygame.K_RIGHT:
hero_PlaneX = hero_PlaneX + 5 if hero_PlaneX <= 375 else 380
elif event.key == pygame.K_DOWN:
hero_PlaneY = hero_PlaneY + 5 if hero_PlaneY <= 521 else 526
elif event.key == pygame.K_UP:
hero_PlaneY = hero_PlaneY - 5 if hero_PlaneY >= 5 else 0
设置灵敏度
pygame.key.set_repeat(20,30)
绘制敌机
加载敌机
enemy_img=pygame.image.load('image/enemy2.png')
enemy_img2=pygame.image.load("image/enemy2_hit.png")
定义敌机位置
enemy_rect=pygame.rect.Rect(158,0,69,99) #(480-69)/2
enemyPlaneX=enemy_rect.x
enemyPlaneY=enemy_rect.y
绘制敌机
screen.blit(enemy_img,(enemyPlaneX,enemyPlaneY))
控制敌机精灵移动
if direct =='left':
enemyPlaneX-=5
if enemyPlaneX<=0:
direct='right'
elif direct=='right':
enemyPlaneX=enemyPlaneX + 5
if enemyPlaneX >=480-165:
direct='left'
绘制精灵子弹
用类的方法
英雄机子弹
class HeroBullet:
def __init__(self,x,y,screen):
self.x=x
self.y=y
self.screen=screen
self.pic=pygame.image.load('image/bullet1.png')
#画子弹
def draw(self):
self.screen.blit(self.pic,(self.x,self.y))
self.move()
#子弹移动方法
def move(self):
self.y-=5
#英雄机子弹列表
hero_Bulletlist=[]
敌机子弹
class EnemyBullet:
def __init__(self, x, y, screen):
self.x = x
self.y = y
self.screen = screen
self.pic = pygame.image.load('image/bullet2.png')
# 画子弹
def draw(self):
self.screen.blit(self.pic, (self.x, self.y))
self.move()
# 子弹移动方法
def move(self):
self.y+=5
#敌机子弹列表
enemy_list=[]
画出敌机子弹
x=random.randint(1,100)
if x==5 or x==78 :
#绘制敌机子弹
enemybullet=EnemyBullet(enemyPlaneX+69/2-5/2,enemyPlaneY+99,screen)
enemy_list.append(enemybullet)
for bullet2 in enemy_list:
bullet2.draw()
随机我们就应该要想到random模块,使用random来让敌机出现的位置随机,我们先在文件中导入random模块,然后在敌机精灵类中的初始化方法中进行操作 绘制精灵爆炸
绘制敌机爆炸
#敌机爆炸条件
enemy_bomb=False
#敌机爆炸索引
enemy_bomb_index=0
for bullet in hero_Bulletlist:
bullet.draw()
#让子弹到最上面的时候消失
hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
# 定义英雄子弹rect
hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
# 碰撞检测
flag = hero_bullet_rect.colliderect(enemy_rect)
if flag:
print("敌机爆炸")
enemy_bomb = True
hero_Bulletlist.remove(bullet)
爆炸图片
enemy_bomb_imgs=["image/enemy2_down1.png",
"image/enemy2_down2.png", "image/enemy2_down3.png", "image/enemy2_down4.png"]
for bullet in hero_Bulletlist:
bullet.draw()
#让子弹到最上面的时候消失
hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
# 定义英雄子弹rect
hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
# 碰撞检测
flag = hero_bullet_rect.colliderect(enemy_rect)
if flag:
print("敌机爆炸")
enemy_bomb = True
hero_Bulletlist.remove(bullet)
if enemy_bomb == False:
#切换图片, # 绘制敌机图片
if enemy_bomb_index == 0:
screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))
enemy_bomb_index = 1
else:
screen.blit(enemy_img2, (enemyPlaneX, enemyPlaneY))
enemy_bomb_index = 0
else:
if enemy_bomb_index == len(enemy_bomb_imgs):
# 当敌机爆炸索引与图片总数相同时,退出游戏
time.sleep(0.2)
exit(0)
enemy_bomb_img = pygame.image.load(enemy_bomb_imgs[enemy_bomb_index])
screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY)) # 绘制爆炸图片
enemy_bomb_index += 1
time.sleep(0.2)
绘制英雄机爆炸
#英雄机爆炸
hero_bomb=False
#英雄机爆炸索引
hero_bomb_index=0
for bullet in hero_Bulletlist:
bullet.draw()
#让子弹到最上面的时候消失
hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
# 定义英雄子弹rect
hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
# 碰撞检测
flag = hero_bullet_rect.colliderect(enemy_rect)
if flag:
print("敌机爆炸")
enemy_bomb = True
hero_Bulletlist.remove(bullet)
if enemy_bomb == False:
#切换图片, # 绘制敌机图片
if enemy_bomb_index == 0:
screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))
enemy_bomb_index = 1
else:
screen.blit(enemy_img2, (enemyPlaneX, enemyPlaneY))
enemy_bomb_index = 0
else:
if enemy_bomb_index == len(enemy_bomb_imgs):
# 当敌机爆炸索引与图片总数相同时,退出游戏
time.sleep(0.2)
exit(0)
enemy_bomb_img = pygame.image.load(enemy_bomb_imgs[enemy_bomb_index])
screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY)) # 绘制爆炸图片
enemy_bomb_index += 1
time.sleep(0.2)
全部代码
import random
import pygame
import time
pygame.init()
#创建窗口
screen=pygame.display.set_mode((480,650))#480为宽,500为高
#修改游戏名称
pygame.display.set_caption('飞机大战')
#修改游戏图标
icon = pygame.image.load("image/icon72x72.png")
pygame.display.set_icon(icon)
# 加载背景
bg_img = pygame.image.load('image/background.png')
#加载精灵图片
hero_img1 = pygame.image.load("image/me1.png")
hero_img2 = pygame.image.load("image/me2.png")
#加载战机战损
hero_bomb_imgs=["image/me_destroy_1.png",
"image/me_destroy_2.png", "image/me_destroy_3.png", "image/me_destroy_4.png"]
#作为切换的索引值
shitindex=0
#定义英雄机位置
hero_rect=pygame.rect.Rect(190,525,100,124)
#设置精灵XY轴
hero_PlaneX=hero_rect.x
hero_PlaneY=hero_rect.y
#加载敌机图片
enemy_img=pygame.image.load('image/enemy2.png')
enemy_img2=pygame.image.load("image/enemy2_hit.png")
#加载敌机战损
enemy_bomb_imgs=["image/enemy2_down1.png",
"image/enemy2_down2.png", "image/enemy2_down3.png", "image/enemy2_down4.png"]
#定义敌机位置
enemy_rect=pygame.rect.Rect(158,0,69,99) #(480-69)/2
enemyPlaneX=enemy_rect.x
enemyPlaneY=enemy_rect.y
#设置灵敏度
pygame.key.set_repeat(20,30)
#定义时钟
clock=pygame.time.Clock()
#定义图片切换索引
hero_imgindex=0
#定义敌机初始移动方向
direct='left'
#定义英雄机子弹 子弹类
class HeroBullet:
def __init__(self,x,y,screen):
self.x=x
self.y=y
self.screen=screen
self.pic=pygame.image.load('image/bullet1.png')
#画子弹
def draw(self):
self.screen.blit(self.pic,(self.x,self.y))
self.move()
#子弹移动方法
def move(self):
self.y-=5
#英雄机子弹列表
hero_Bulletlist=[]
#定义敌机子弹
class EnemyBullet:
def __init__(self, x, y, screen):
self.x = x
self.y = y
self.screen = screen
self.pic = pygame.image.load('image/bullet2.png')
# 画子弹
def draw(self):
self.screen.blit(self.pic, (self.x, self.y))
self.move()
# 子弹移动方法
def move(self):
self.y+=5
#敌机子弹列表
enemy_list=[]
#英雄机爆炸
hero_bomb=False
#英雄机爆炸索引
hero_bomb_index=0
#敌机爆炸条件
enemy_bomb=False
#敌机爆炸索引
enemy_bomb_index=0
#游戏循环
while True:
clock.tick(60)#60表示每秒刷新60
# 图片背景
screen.blit(bg_img, (0, 0))
# 修改飞机y值,实现自动飞行
hero_PlaneY -=1
# 飞机从底部飞出
if hero_PlaneY<0:
hero_PlaneY=750
#绘制敌机
screen.blit(enemy_img,(enemyPlaneX,enemyPlaneY))
# 控制敌机移动
if direct =='left':
enemyPlaneX-=5
if enemyPlaneX<=0:
direct='right'
elif direct=='right':
enemyPlaneX=enemyPlaneX + 5
if enemyPlaneX >=480-165:
direct='left'
x=random.randint(1,100)
if x==5 or x==78 :
#绘制敌机子弹
enemybullet=EnemyBullet(enemyPlaneX+69/2-5/2,enemyPlaneY+99,screen)
enemy_list.append(enemybullet)
for bullet2 in enemy_list:
bullet2.draw()
enemy_bullet_rect = pygame.rect.Rect(bullet2.x, bullet2.y, 5, 11)
flag2 = enemy_bullet_rect.colliderect(hero_rect)
if flag2:
print("战机爆炸")
hero_bomb = True
enemy_list.remove(bullet2)
if hero_bomb == False:
# 英雄机绘制到窗口
if shitindex == 0:
screen.blit(hero_img1, (hero_PlaneX, hero_PlaneY))
shitindex = 1
else:
screen.blit(hero_img2, (hero_PlaneX, hero_PlaneY))
shitindex = 0
else:
if hero_bomb_index == len(hero_bomb_imgs):
time.sleep(0.3)
exit()
hero_bomb_img = pygame.image.load(hero_bomb_imgs[hero_bomb_index])
screen.blit(hero_bomb_img, (hero_PlaneX, hero_PlaneY)) # 绘制爆炸图片
hero_bomb_index += 1
time.sleep(0.07)
# 对事件进行监听 获取所有事件
event_list = pygame.event.get()
#捕捉窗口退出事件
for event in event_list:
if event.type == pygame.QUIT: # 加上这个模块就不卡了
print("游戏结束了.......")
pygame.quit() # 卸载模块
exit(0) # 终止Python程序, exit(0)表示正常退出 exit(1)表示异常退出
# 控制英雄精灵移动
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
hero_PlaneX = hero_PlaneX - 5 if hero_PlaneX >= 5 else 0
elif event.key == pygame.K_RIGHT:
hero_PlaneX = hero_PlaneX + 5 if hero_PlaneX <= 375 else 380
elif event.key == pygame.K_DOWN:
hero_PlaneY = hero_PlaneY + 5 if hero_PlaneY <= 521 else 526
elif event.key == pygame.K_UP:
hero_PlaneY = hero_PlaneY - 5 if hero_PlaneY >= 5 else 0
elif event.key == pygame.K_SPACE:
#调用子弹的方法属性
hero_bullet=HeroBullet(hero_PlaneX+50,hero_PlaneY-11,screen)
#把子弹放入列表中 子弹是多个 我们将多个实例化的子弹放表中
hero_Bulletlist.append(hero_bullet)
for bullet in hero_Bulletlist:
bullet.draw()
#让子弹到最上面的时候消失
hero_Bulletlist.remove(bullet) if bullet.y < 0 else ''
# 定义英雄子弹rect
hero_bullet_rect = pygame.rect.Rect(bullet.x, bullet.y, 5, 11)
# 碰撞检测
flag = hero_bullet_rect.colliderect(enemy_rect)
if flag:
print("敌机爆炸")
enemy_bomb = True
hero_Bulletlist.remove(bullet)
if enemy_bomb == False:
#切换图片, # 绘制敌机图片
if enemy_bomb_index == 0:
screen.blit(enemy_img, (enemyPlaneX, enemyPlaneY))
enemy_bomb_index = 1
else:
screen.blit(enemy_img2, (enemyPlaneX, enemyPlaneY))
enemy_bomb_index = 0
else:
if enemy_bomb_index == len(enemy_bomb_imgs):
# 当敌机爆炸索引与图片总数相同时,退出游戏
time.sleep(0.2)
exit(0)
enemy_bomb_img = pygame.image.load(enemy_bomb_imgs[enemy_bomb_index])
screen.blit(enemy_bomb_img, (enemyPlaneX, enemyPlaneY)) # 绘制爆炸图片
enemy_bomb_index += 1
time.sleep(0.2)
# 图片更新
pygame.display.update()