Python入门课程系列:
- Python学习 day1:认识Python
- Python学习 day2:判断语句与循环控制
- Python学习 day3:高级数据类型
- Python学习 day4:函数基础
- Python学习 day5:函数
- Python学习 day6:内置函数
- Python学习 day7:面向对象基础·上
- Python学习 day8:面向对象基础·中
- Python学习 day9:面向对象基础·下
1. Pygame
Pygame介绍:Pygame是一个利用SDL库写的游戏库,SDL库全名Simple DirectMedia Layer,是用C写的,不过也可以用C++进行开发,Pygame就是Python中使用它的一个库
官网教程:http://www.pygame.org/docs/
官网安装指南:https://www.pygame.org/wiki/GettingStarted#Pygame%20Installation
Pygame模块一览表:
模块名 | 功能 | 模块名 | 功能 |
---|---|---|---|
pygame.cdrom | 访问光驱 | pygame.movie | 播放视频 |
pygame.cursors | 加载光标 | pygame.music | 播放音频 |
pygame.display | 访问显示设备 | pygame.overlay | 访问高级视频叠加 |
pygame.draw | 绘制形状、线和点 | pygame | 就是我们在学的这个东西了…… |
pygame.event | 管理事件 | pygame.rect | 管理矩形区域 |
pygame.font | 使用字体 | pygame.sndarray | 操作声音数据 |
pygame.image | 加载和存储图片 | pygame.sprite | 操作移动图像 |
pygame.joystick | 使用游戏手柄或者类似的东西 | pygame.surface | 管理图像和屏幕 |
pygame.key | 读取键盘按键 | pygame.surfarray | 管理点阵图像数据 |
pygame.mixer | 声音 | pygame.time | 管理时间和帧信息 |
pygame.mouse | 鼠标 | pygame.transform | 缩放和移动图像 |
在电脑安装好pygame后,打开pycharm安装pygame模块
如果在pycharm中安装不成功,出现Command "python setup.py egg_info" failed with code 1 in xxx\xxx\xxx的报错,说明pycharm和pygame版本不同步,处理方法:1. 确保在系统层面的python环境里面已经安装了pygame(pip install pygame);2. 可以把已经安装好的pygame模块的文件夹拷贝到pycharm所创建项目中venv虚拟环境里面。
2. 思路
需求的描述:
存在4个对象:
我方飞机、敌方飞机、我方子弹、敌方子弹。
功能:
背景音乐的添加
我方飞机可以移动【根据按键来控制的】
敌方飞机也可以移动【随机的自动移动】
双方飞机都可以发射子弹
步骤:
1.创建一个窗口
2.创建一个我方飞机 根据方向键左右的移动
3.给我方飞机添加发射子弹的功能【按下空格键发射】
4.创建一个敌机
5.敌机可以自由移动
6.敌机可以发射子弹
准备背景音乐和素材图片(战机、敌机、战机子弹、敌机子弹)
控制玩具飞机-面向对象⚠️
实现步骤与原理:
实现步骤原理跟面向过程是一样的,不同的是代码的组织方式不一样:
1)创建一个飞机类,实现左移、右移、显示三个功能
2)创建一个键盘控制函数,实现键盘的左、右、空格键的功能
3)创建主函数,实现创建窗口、背景图片、背景音乐、并实现所有的逻辑
玩家飞机发射子弹⚠️
实现原理
1)每次按回车键就会有一颗子弹射出,起始位置就是从飞机的停靠位置
2)子弹超出窗口就会消失,并且删除掉子弹(否则子弹越来越多,界面会越来越卡)
3)每一颗子弹就代表一张图片
4)子弹从发射开始 ,慢慢往上移动直到消失。
import pygame #引用第三方模块
import random
import time
from pygame.locals import * #*表示要导入这个包所有的内容
'''
1. 实现飞机的显示,并且可以控制飞机的移动【面向对象】
'''
class HeroPlane(object):
def __init__(self,screen):
'''
初始化函数
:param screen: 主窗体对象
'''
#设定飞机的默认位置
self.x=175
self.y=615
#设置要显示内容的窗口
self.screen=screen
#生成飞机的图片对象
self.imageName='./雷霆战机/images/hero/hero04.png'
self.image=pygame.image.load(self.imageName)
#用来存放子弹的列表
self.bulletList=[]
pass
def moveleft(self):
'''
左移
:return:
'''
if self.x>0:
self.x-=10
pass
def moveright(self,):
'''
右移
:return:
'''
if self.x<490:
self.x+=10
pass
def display(self):
'''
飞机在主窗口中的显示
:return:
'''
self.screen.blit(self.image,(self.x,self.y))
#完善子弹的显示逻辑
needDelItemList=[]
for item in self.bulletList:
if item.judge():
needDelItemList.append(item)
pass
pass
#重新遍历一下
for i in needDelItemList:
self.bulletList.remove(i)
pass
for bullet in self.bulletList:
bullet.display() #显示子弹的位置
bullet.move() #让这个子弹进行移动 下次再显示的时候就会看到子弹在修改后的位置
pass
#发射子弹
def sheBullet(self):
#创建一个新的子弹对象
newBullet=Bullet(self.x,self.y,self.screen)
self.bulletList.append(newBullet)
pass
pass
#创建子弹类对象
class Bullet(object):
def __init__(self,x,y,screen):
'''
:param x:
:param y:
:param screen:
'''
self.x=x+50
self.y=y-10
self.screen=screen
self.image=pygame.image.load('./雷霆战机/images/bullet/img_bullet.png')
pass
def display(self):
self.screen.blit(self.image,(self.x,self.y))
pass
def move(self):
self.y-=5
pass
def judge(self):
'''
判断子弹是否越界
:return:
'''
if self.y<0:
return True
else:
return False
pass
#创建敌机类
class EnemyPlane:
def __init__(self,screen):
#默认设置一个方向
self.direction='right'
# 设定飞机的默认位置
self.x = 0
self.y = 0
# 设置要显示内容的窗口
self.screen = screen
self.bulletList=[]
# 生成飞机的图片对象
self.imageName = './雷霆战机/images/enemy/boss.png'
self.image = pygame.image.load(self.imageName)
pass
def display(self):
'''
显示敌机以及子弹位置信息
:return:
'''
self.screen.blit(self.image,(self.x,self.y))
# 完善子弹的显示逻辑
needDelItemList = []
for item in self.bulletList:
if item.judge():
needDelItemList.append(item)
pass
pass
# 重新遍历一下
for i in needDelItemList:
self.bulletList.remove(i)
pass
for bullet in self.bulletList:
bullet.display() # 显示子弹的位置
bullet.move() # 让这个子弹进行移动 下次再显示的时候就会看到子弹在修改后的位置
pass
pass
def sheBullet(self):
'''
敌机随机发射子弹
:return:
'''
num=random.randint(1,100)
if num==3:
newBullet=EnemyBullet(self.x,self.y,self.screen)
self.bulletList.append(newBullet)
pass
def move(self):
'''
敌机移动,随机进行
:return:
'''
if self.direction=='right':
self.x+=1
pass
elif self.direction=='left':
self.x-=1
pass
if self.x>260:
self.direction='left'
pass
elif self.x<0:
self.direction='right'
pass
#敌机子弹类
class EnemyBullet(object):
def __init__(self,x,y,screen):
'''
:param x:
:param y:
:param screen:
'''
self.x=x+90
self.y=y+90
self.screen=screen
self.image=pygame.image.load('./雷霆战机/images/bullet/enemy_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):
'''
判断子弹是否越界
:return:
'''
if self.y>700:
return True
else:
return False
pass
def key_control(HeroObj):
'''
定义普通函数 用来实现键盘的检测
:param HeroObj: 可控制检测的对象
:return:
'''
# 获取键盘事件
eventlist = pygame.event.get()
for event in eventlist:
if event.type == QUIT:
print('退出')
exit()
pass
elif event.type == KEYDOWN:
if event.type == K_a or event.key == K_LEFT:
print('left')
HeroObj.moveleft() #调用函数实现左移
elif event.type == K_d or event.key == K_RIGHT:
print('right')
HeroObj.moveright() #调用函数实现右移
elif event.key == K_SPACE:
print('K_SPACE')
HeroObj.sheBullet()
pass
def main():
# 首先创建窗口对象
screen=pygame.display.set_mode((450,700))
#创建一个背景图片对象
background=pygame.image.load('./雷霆战机/images/bg/bg1.jpg')
#设置一个title
pygame.display.set_caption('huihui飞机大战')
#添加背景音乐
pygame.mixer.init() #初始化这个函数
pygame.mixer.music.load('./PlaneWar/sound/game_music.ogg')
pygame.mixer.music.set_volume((0.2))
pygame.mixer.music.play(-1) #表示无限循环
#创建一个飞机对象
hero=HeroPlane(screen)
#创建一个敌机对象
enemyplane=EnemyPlane(screen)
#设定需要显示的内容
while True:
screen.blit(background,(0,0))
# 显示玩家飞机图片
hero.display()
enemyplane.display() #显示敌机
enemyplane.move() #敌机移动
enemyplane.sheBullet() #敌机随机发射子弹
#获取键盘事件
key_control((hero))
#更新显示内容
pygame.display.update()
# time.sleep(1) #休眠一秒钟
pygame.time.Clock().tick(20) #一秒钟运行20次
pass
if __name__=='__main__':
main()
抽象基类⚠️
import pygame #引用第三方模块
import random
import time
from pygame.locals import * #*表示要导入这个包所有的内容
'''
1. 实现飞机的显示,并且可以控制飞机的移动【面向对象】
'''
'''
1:实现飞机的显示 并且可以控制飞机的移动【面向对象】
'''
#抽象一个飞机的基类
class BasePlane(object):
def __init__(self,screen,imageName):
'''
初始化基类函数
:param screen:主窗体对象
:param imageName:加载的图片
'''
self.screen=screen
self.image=pygame.image.load(imageName)
self.bulletList=[] #存储所有的子弹
pass
def display(self):
self.screen.blit(self.image, (self.x, self.y))
# 完善子弹的显示逻辑
needDelItemList = []
for item in self.bulletList:
if item.judge():
needDelItemList.append(item)
pass
pass
# 重新遍历一下
for i in needDelItemList:
self.bulletList.remove(i)
pass
for bullet in self.bulletList:
bullet.display() # 显示子弹的位置
bullet.move() # 让这个子弹进行移动 下次再显示的时候就会看到子弹在修改后的位置
pass
pass
class CommonBullet(object):
'''
公共的子弹类
'''
def __init__(self,x,y,screen,bulletTYpe):
self.type=bulletTYpe
self.screen=screen
if self.type=='hero':
self.x=x+50
self.y=y-10
self.imagePath='./雷霆战机/images/bullet/img_bullet.png'
elif self.type=='enemy':
self.x=x+90
self.y=y+90
self.imagePath='./雷霆战机/images/bullet/enemy_bullet.png'
pass
self.image=pygame.image.load(self.imagePath)
pass
def move(self):
'''
子弹的移动
:return:
'''
if self.type=='hero':
self.y-=5
elif self.type=='enemy':
self.y+=3
pass
pass
def display(self):
self.screen.blit(self.image,(self.x,self.y))
pass
def judge(self):
'''
判断子弹是否越界
:return:
'''
if self.y>700 or self.x<0:
return True
else:
return False
pass
pass
class HeroPlane(BasePlane):
def __init__(self,screen):
'''
初始化函数
:param screen: 主窗体对象
'''
super().__init__(screen,'./雷霆战机/images/hero/hero04.png')
#设定飞机的默认位置
self.x=175
self.y=615
pass
def moveleft(self):
'''
左移
:return:
'''
if self.x>0:
self.x-=10
pass
def moveright(self,):
'''
右移
:return:
'''
if self.x<490:
self.x+=10
pass
#发射子弹
def sheBullet(self):
#创建一个新的子弹对象
newBullet=CommonBullet(self.x,self.y,self.screen,'hero')
self.bulletList.append(newBullet)
pass
pass
#创建敌机类
class EnemyPlane(BasePlane):
def __init__(self,screen):
super.__init__(screen,'./雷霆战机/images/enemy/boss.png')
#默认设置一个方向
self.direction='right'
# 设定飞机的默认位置
self.x = 0
self.y = 0
pass
def sheBullet(self):
'''
敌机随机发射子弹
:return:
'''
num=random.randint(1,100)
if num==3:
newBullet=CommonBullet(self.x,self.y,self.screen,'enemy')
self.bulletList.append(newBullet)
pass
def move(self):
'''
敌机移动,随机进行
:return:
'''
if self.direction=='right':
self.x+=1
pass
elif self.direction=='left':
self.x-=1
pass
if self.x>260:
self.direction='left'
pass
elif self.x<0:
self.direction='right'
pass
def key_control(HeroObj):
'''
定义普通函数 用来实现键盘的检测
:param HeroObj: 可控制检测的对象
:return:
'''
# 获取键盘事件
eventlist = pygame.event.get()
for event in eventlist:
if event.type == QUIT:
print('退出')
exit()
pass
elif event.type == KEYDOWN:
if event.type == K_a or event.key == K_LEFT:
print('left')
HeroObj.moveleft() #调用函数实现左移
elif event.type == K_d or event.key == K_RIGHT:
print('right')
HeroObj.moveright() #调用函数实现右移
elif event.key == K_SPACE:
print('K_SPACE')
HeroObj.sheBullet()
pass
def main():
# 首先创建窗口对象
screen=pygame.display.set_mode((450,700))
#创建一个背景图片对象
background=pygame.image.load('./雷霆战机/images/bg/bg1.jpg')
#设置一个title
pygame.display.set_caption('huihui飞机大战')
#添加背景音乐
pygame.mixer.init() #初始化这个函数
pygame.mixer.music.load('./PlaneWar/sound/game_music.ogg')
pygame.mixer.music.set_volume((0.2))
pygame.mixer.music.play(-1) #表示无限循环
#创建一个飞机对象
hero=HeroPlane(screen)
#创建一个敌机对象
enemyplane=EnemyPlane(screen)
#设定需要显示的内容
while True:
screen.blit(background,(0,0))
# 显示玩家飞机图片
hero.display()
enemyplane.display() #显示敌机
enemyplane.move() #敌机移动
enemyplane.sheBullet() #敌机随机发射子弹
#获取键盘事件
key_control((hero))
#更新显示内容
pygame.display.update()
# time.sleep(1) #休眠一秒钟
pygame.time.Clock().tick(20) #一秒钟运行20次
pass
if __name__=='__main__':
main()