python入门笔记——飞机大战(极简版、未进行继承优化)
import random
import pygame# 引用pygame里的模块
from pygame.locals import *# *意思为导入该包内所有的内容
class PlaneFly:
'''
飞机类(关于飞机的操作及行为等,具体为移动,发射子弹和显示功能)
注:
在这里最要注意的事情是,飞机移动需要设置边界
以及这里的y轴是箭头朝下的,意思是数值往下渐增
'''
def __init__(self,screen):# 将screen参数传入,便于进行与飞机对象的联动
# 设置默认位置,使飞机初始默认位置居于屏幕下方中央
self.x = 150
self.y = 450
self.screen = screen
self.bulletList = []# 存放子弹的列表
# 生成飞机的图片,这里.指的是当前目录下
self.image = pygame.image.load('./feiji/hero.png')
pass
def moveleft(self):# 飞机左移
if self.x > 0:
self.x -= 5
pass
pass
def moveright(self):# 飞机右移
if self.x < 350 - 40:# 注:这里的40和下面下移的50都是飞机自己占的像素数目
self.x += 5
pass
pass
def moveup(self):# 飞机上移
if self.y > 0:
self.y -= 5
pass
pass
def movedown(self):# 飞机下移
if self.y < 500 - 50:
self.y += 5
pass
pass
def display(self):# 显示飞机
self.screen.blit(self.image,(self.x,self.y))
'''
下面为完善子弹运作逻辑的代码
这里注意,必须要删除掉越界的子弹,否则会导致程序越来越卡
'''
bulletDelList = []# 因越界需要删除的子弹列表
for item in self.bulletList:
if item.judge():# 将判断越界的子弹传入需要删除的子弹列表中
bulletDelList.append(item)
pass
pass
# 再次遍历并删除列表里越界的子弹(因极不建议在上面的循环里的if中删除,故需要在此遍历删除比较好)
for item in bulletDelList:
self.bulletList.remove(item)
pass
# 对于未越界的子弹,对于列表进行遍历操作,显示当前位置,并进行移动
# 即可在main函数里的while循环的 下一次显示移动后的位置
for item in self.bulletList:
item.display()# 显示子弹的位置
item.move()# 子弹发生移动
pass
def fire_Bullet(self):# 发射子弹
# 创建一个子弹对象
new_bullet = Bullet(self.screen,self.x,self.y)
# 将每次创建的子弹对象加入bulletList列表中
self.bulletList.append(new_bullet)
pass
pass
class Bullet:
'''
我方飞机的子弹类
'''
def __init__(self,screen,x,y):
self.x = x + 13# 这里的13是为了居于飞机的中央发射,下面的20也是为了外观设计,可以根据实际情况更改
self.y = y - 20
self.screen = screen
self.image = pygame.image.load('./feiji/bullet.png')
pass
def display(self):# 显示子弹图像
self.screen.blit(self.image,(self.x,self.y))
pass
def move(self):# 子弹移动
self.y -= 3# 这里的数值代表子弹飞行的速度,可以适当调整
pass
def judge(self):# 判断子弹是否越界的函数
if self.y <= 0:
return True
else:
return False
pass
pass
class EnemyFly:
def __init__(self,screen):
self.x = 10# 设置敌机的初始默认位置
self.y = 10
self.screen = screen
self.image = pygame.image.load('./feiji/enemy0.png')
self.bulletList = []
self.flag = 0
pass
def display(self):
self.screen.blit(self.image,(self.x,self.y))
'''
敌机的完善子弹运作的逻辑
'''
bulletDelList = [] # 因越界需要删除的子弹列表
for item in self.bulletList:
if item.judge(): # 将判断越界的子弹传入需要删除的子弹列表中
bulletDelList.append(item)
pass
pass
# 再次遍历并删除列表里越界的子弹(因极不建议在上面的循环里的if中删除,故需要在此遍历删除比较好)
for item in bulletDelList:
self.bulletList.remove(item)
pass
# 对于未越界的子弹,对于列表进行遍历操作,显示当前位置,并进行移动
# 即可在main函数里的while循环的 下一次显示移动后的位置
for item in self.bulletList:
item.display() # 显示子弹的位置
item.move() # 子弹发生移动
pass
pass
def fire_Bullet(self):
'''
这里敌机发射的子弹是随机的,所以注意一下需要在上面import random
以及在这里更改成随机发射的代码
:return:
'''
num = random.randint(1,200)
# 随机得num等于10时候,敌机发射子弹
if num == 2:
newBullet = Enemy_Bullet(self.screen,self.x,self.y)
# 将敌机随机发射的子弹对象加入bulletList列表中
self.bulletList.append(newBullet)
pass
pass
def random_mov(self):
if self.flag == 0:
self.x += 1
pass
elif self.flag == 1:
self.x -= 1
pass
if self.x >= 350 - 20:
self.flag = 1
pass
elif self.x <= 0:
self.flag = 0
pass
pass
pass
class Enemy_Bullet:
'''
敌机的子弹类
'''
def __init__(self,screen,x,y):
self.x = x# 敌机的子弹位置根据实际情况进行了相应更改
self.y = y + 10
self.screen = screen
self.image = pygame.image.load('./feiji/bullet1.png')
pass
def display(self):# 显示敌机的子弹图像
self.screen.blit(self.image,(self.x,self.y))
pass
def move(self):# 敌机子弹移动
self.y += 1# 注意这里,敌机子弹是往下飞的,所以需改成+
pass
def judge(self):# 判断子弹是否越界的函数
if self.y >= 500:
return True
else:
return False
pass
pass
def key_control(planeObj):
'''
键盘控制函数
:param planeObj:该传入的参数为main函数里创建的飞机对象
:return:
'''
eventList = pygame.event.get()
for item in eventList:
if item.type == QUIT:
print('退出')
exit()
elif item.type == KEYDOWN: # 如果按下了某个按键的话:
pygame.key.set_repeat()
if item.key == K_a or item.key == K_LEFT: # 如果按下的是左键
# 这里的set_repeat函数使得可以按住一个键使其重复所需的操作
pygame.key.set_repeat(1,50)
# print('left')
planeObj.moveleft()
pass
elif item.key == K_d or item.key == K_RIGHT: # 如果按下的是右键
pygame.key.set_repeat(1, 50)
# print('right')
planeObj.moveright()
pass
elif item.key == K_w or item.key == K_UP:
pygame.key.set_repeat(1, 50)
# print('up')
planeObj.moveup()
pass
elif item.key == K_s or item.key == K_DOWN:
pygame.key.set_repeat(1, 50)
# print('down')
planeObj.movedown()
pass
# 以下为非方向键的按键操作
elif item.key == K_SPACE: # 如果按下的是空格键
pygame.key.set_repeat(1, 200)
# print('space')
planeObj.fire_Bullet()
pass
elif item.key == K_ESCAPE:
print('退出')
exit()
pass
pass
pass
pass
def main():
'''
main函数
:return:
'''
# 先创建一个窗口,用来显示所有的内容
screen = pygame.display.set_mode((350,500),depth=32)# 设置该窗口的宽和高,这里只是仿照老师的设计
# 接下来设置一个和设定窗口差不多的图片用来充当背景
background = pygame.image.load('./feiji/background.png')
# 下面的语句是用来设置一个窗口标题
pygame.display.set_caption('简易飞机游戏')
# 添加背景音乐
pygame.mixer.init()# pygame里的mixer函数用来加载和播放声音,init用来初始化混音模块
pygame.mixer.music.load('./feiji/background.mp3')# 把文件夹中的音乐加载进来
pygame.mixer.music.set_volume(0.2)# 设置音乐的音量,该值应处于0.0到1.0之间
pygame.mixer.music.play(-1)# 开始播放音乐,该括号中有三个参数,loop、start以及fade_ms,默认都为0
# 这里填入-1即将loop的值改为了-1,意味着将无限重复循环
# 创建一个飞机对象
plane = PlaneFly(screen)
# 创建一个敌机对象
enemyplane = EnemyFly(screen)
while True:# 如果没有加这个循环的话,图片会一闪而过
# 设置需要显示的图片,(0,0)的意思是居中显示
screen.blit(background,(0,0))# 这个如果不放在循环里,则会留下飞机每次移动前的图像
# 调用display函数来显示我方飞机
plane.display()
# 调用display函数来显示敌机,紧接着敌机进行移动以及发射子弹
enemyplane.display()
enemyplane.random_mov()
enemyplane.fire_Bullet()
# 用键盘控制飞机的移动
key_control(plane)
# 更新需要显示的内容
pygame.display.update()
pass
if __name__ == '__main__':# 这种写的方式是有相应好处的,在后续内容中说明
main()
pass
结果截图:
进行继承优化后的代码(无实际内容增加)