python快速编程入门飞机大战_黑马python入门(7):Python基础(简单飞机大战实战)

#!/usr/bin/env python3#-*- coding: utf-8 -*-#author:albert time:2020/9/23

importrandomimportpygame#常量

WIN_SIZE= (480, 700) #游戏窗口宽高

FPS = 60 #游戏帧数

HERO_PATH = "images/me1.png" #我方飞机图的路径

ENEMY_PATH = "images/enemy1.png" #敌机图的路径

BULLET_PATH = "images/bullet1.png" #子弹图的路径

BG_PATH = "images/background.png" #背景图的路径

CREATE_ENEMY_EVENT = pygame.USEREVENT #配合定时器定时生成敌机

CREATE_BULLET_EVENT = pygame.USEREVENT + 1 #配合定时器定时生成子弹

classHeroPlaneClass(pygame.sprite.Sprite):"""定义一个英雄飞机类 继承自pygame的精灵类

属性 image rect 定义飞机的图片来源和初始坐标和宽高

方法 update __init__(需要调用父类的init) fire() 发射子弹的方法

支持 需要pygame和 常量 WIN_SIZE"""

def __init__(self, image, **kwargs):

pygame.sprite.Sprite.__init__(self)

self.image= pygame.image.load(image) #image获取图像surface

self.rect = self.image.get_rect() #rect获取宽高

#英雄飞机初始位置位于最下面的中间

self.rect.x = int((WIN_SIZE[0] - self.rect.w)/2)

self.rect.y= WIN_SIZE[1] -self.rect.hdefupdate(self):#英雄飞机的行为:是用键盘事件上下左右键盘控制的 所以这里就不写具体行为了

pass

#负责生成子弹实例 然后子弹按照自己的行为模式运动即可

#第二个参数是用于暂时存放子弹实例的子弹精灵组

#经过测试 发现类方法传递精灵组也是地址传递 在类方法内修改一样会提现到精灵组本身

deffire(self, tmp_bullet_group):#生成一个子弹

tmp_bullet =BulletClass(BULLET_PATH, self.rect)

tmp_bullet_group.add(tmp_bullet)#添加到子弹精灵组里面

#简单的移动我机 和按键触发事件配合使用

def move(self, offset_x=0, offset_y=0):

self.rect.x+=offset_x

self.rect.y+=offset_y#避免越界

if self.rect.x <0:

self.rect.x=0elif self.rect.x > WIN_SIZE[0] -self.rect.w:

self.rect.x= WIN_SIZE[0] -self.rect.wif self.rect.y <0:

self.rect.y=0elif self.rect.y > WIN_SIZE[1] -self.rect.h:

self.rect.y= WIN_SIZE[1] -self.rect.hclassEnemyPlaneClass(pygame.sprite.Sprite):"""定义一个敌人飞机类 继承自pygame的精灵类

属性 image rect 定义飞机的图片来源和初始坐标和宽高

方法 update __init__(需要调用父类的init)

支持 需要pygame和 常量 WIN_SIZE"""

def __init__(self, image, **kwargs):

pygame.sprite.Sprite.__init__(self)

self.image= pygame.image.load(image) #image获取图像surface

self.rect = self.image.get_rect() #rect获取宽高

#敌机要求在最上一行随机位置刷新

self.rect.x = random.randint(1, WIN_SIZE[0] -self.rect.x)

self.rect.y=0def update(self, *args):#敌机的行为:是在间隔一定时间自动在最上一行随机位置产生 然后无脑向下直走 超出最下边界 就自动销毁他

#后面也可以考虑远距离开始瞄准英雄飞机抛物线撞击 后面再说

self.rect.y += 10

if self.rect.y > WIN_SIZE[1]:

self.kill()#敌机超出最下面边界了 自然是自动销毁

def __del__(self):print("<敌机销毁>")classBulletClass(pygame.sprite.Sprite):"""定义一个子弹类 继承自pygame的精灵类

属性 image rect 定义子弹的图片来源和初始坐标和宽高

方法 update __init__(需要调用父类的init)

支持 需要pygame和 常量 WIN_SIZE"""

def __init__(self, image, hero_rect):

pygame.sprite.Sprite.__init__(self)

self.image= pygame.image.load(image) #image获取图像surface

self.rect = self.image.get_rect() #rect获取宽高

#子弹的初始位置要求在英雄飞机的上部中间位置

self.rect.x = hero_rect.x + int(hero_rect.w/2)

self.rect.y=hero_rect.ydef update(self, *args):#子弹的行为:是在间隔一定时间自动在英雄飞机最上一行中间位置产生 然后无脑向上直走 超出最上边界 就自动销毁他

self.rect.y -= 10

if self.rect.y < 0 -self.rect.h:

self.kill()#子弹超出最上边界 就自动销毁他

def __del__(self):print("(子弹销毁)")classBgClass(pygame.sprite.Sprite):"""定义一个背景类 继承自pygame的精灵类

属性 image rect 定义背景的图片来源和初始坐标和宽高 初始位置是超出了游戏窗口 开始是左下和左下对齐 到头了是左上和左上对齐

方法 update __init__(需要调用父类的init)

支持 需要pygame和 常量 WIN_SIZE"""

def __init__(self, image):

pygame.sprite.Sprite.__init__(self)

self.image= pygame.image.load(image) #image获取图像surface

self.rect = self.image.get_rect() #rect获取宽高

self.rect.y = WIN_SIZE[1] - self.rect.h #设置背景的初始高度

def update(self, *args):#背景的行为:图左下和窗口左下对齐 然后慢慢的向下移动 当然了 我这里背景图片是1400高度 是2个背景图拼接在一起的

#背景图的左上对齐窗口左上或者超出 就自动回到初始位置重新来过

self.rect.y += 10

if self.rect.y >0:

self.rect.y= WIN_SIZE[1] - self.rect.h #让背景重新回到上面重新滚动

classWinClass(object):"""经过测试用get_window返回一个窗口对象可以正常的使用

这类其实就是生成一个游戏窗口对象并返回它

需要pygame库的支持"""

def __init__(self, pos):

self.x=pos[0]

self.y= pos[1]defget_window(self):returnpygame.display.set_mode((self.x, self.y))classGameGod(object):def __init__(self):#整体代码初始化 常用属性的声明

pygame.init()#窗口建立

tmp_win =WinClass(WIN_SIZE)

self.win1=tmp_win.get_window()#我机 敌机 的精灵实例和精灵组的创建 背景 子弹精灵组

self.bg1 =BgClass(BG_PATH)

self.bg_group=pygame.sprite.Group(self.bg1)

self.hero1=HeroPlaneClass(HERO_PATH)

self.hero_group=pygame.sprite.Group(self.hero1)

self.enemy_group=pygame.sprite.Group()

self.bullet_group=pygame.sprite.Group()#clock的建立和定时器定时生成敌机和生成子弹

self.clock =pygame.time.Clock()

pygame.time.set_timer(CREATE_ENEMY_EVENT,1000)

pygame.time.set_timer(CREATE_BULLET_EVENT, 100)defgame_start(self):#正式循环的开始

#循环fps 事件触发 判断碰撞 绘图 刷新

whileTrue:#1. 设置刷新帧率

self.clock.tick(FPS)#2. 事件监听

#开始遍历事件做针对处理 同时避免卡顿

for event inpygame.event.get():if event.type ==pygame.QUIT:

pygame.quit()if event.type ==CREATE_ENEMY_EVENT:#定时创建敌机

self.enemy_group.add(EnemyPlaneClass(ENEMY_PATH))if event.type ==CREATE_BULLET_EVENT:#定时开火 其实本质是定时生成子弹 子弹被生成后按照子弹类定义的行为移动

self.hero1.fire(self.bullet_group)#配合按键事件来移动我机

keys_pressed =pygame.key.get_pressed()ifkeys_pressed[pygame.K_UP]:print("向上")#hero1.rect.y -= 4

self.hero1.move(0, -4)elifkeys_pressed[pygame.K_DOWN]:print("向下")#hero1.rect.y += 4

self.hero1.move(0, 4)elifkeys_pressed[pygame.K_LEFT]:print("向左")#hero1.rect.x -= 4

self.hero1.move(-4, 0)elifkeys_pressed[pygame.K_RIGHT]:print("向右")#hero1.rect.x += 4

self.hero1.move(4, 0)#3. 碰撞检测

#子弹摧毁敌机(子弹组和敌机组的碰撞测试)

pygame.sprite.groupcollide(self.bullet_group, self.enemy_group, True, True)#敌机撞毁英雄(敌机组和英雄精英的碰撞测试)

enemies =pygame.sprite.spritecollide(self.hero1, self.enemy_group, True)#判断列表时候有内容 就是说我机被撞上了

if len(enemies) >0:#让英雄牺牲

self.hero1.kill()#结束游戏

pygame.quit()

exit()#4. 更新/绘制精灵组

self.bg_group.update() #肯定是先更新背景

self.bg_group.draw(self.win1)

self.hero_group.update()

self.hero_group.draw(self.win1)

self.enemy_group.update()

self.enemy_group.draw(self.win1)

self.bullet_group.update()

self.bullet_group.draw(self.win1)#5. 更新显示

pygame.display.update()defgame_over(self):

pygame.quit()

exit()if __name__ == '__main__':#没事可以外面加个异常处理 懒得动弹了

god1 =GameGod()

god1.game_start()

god1.game_over()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值