先展示一下效果
搓搓小手手,坦克大战即将开始……https://www.zhihu.com/video/1140743290784817152一、游戏引擎的安装
安装方式有两种:1.pip安装
windows + R --> cmd --> pip install pygame
2.pycharm安装
File -->setting -->project -->prioect Interpreter -->右侧 + install --> 搜索输入pygame -->左下方installpackage
验证pygame安装是否成功
import pygame运行结果:
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
二.项目的需求(基于面向对象的分析):
有哪些类,不同的类具有的功能
1.主逻辑类
开始游戏
结束游戏
2.坦克类(1.我方坦克 2.敌方坦克)
移动
射击
展示
3.子弹类
移动
展示
4.爆炸效果类
展示爆炸效果
5.墙壁类
属性:坦克和子弹是否可以通过
6.音效类
播放背景音乐,射击音效,爆炸音效
三.坦克大战项目框架的搭建
涉及到的类,用代码简单的实现
import pygameclass MainGame:"""主游戏类"""def __init__(self):passdef startGame(self):"""开始游戏"""passdef endGame(self):"""结束游戏"""passclass Tank:"""坦克类"""def __init__(self):passdef move(self):"""坦克的移动"""passdef shot(self):"""坦克的射击"""passdef displayTank(self):"""展示坦克"""passclass MyTank(Tank):"""我方坦克类"""def __init__(self):passclass EnemyTank(Tank):"""敌方坦克类"""def __init__(self):passclass Bullet:"""子弹类"""def __init__(self):passdef move(self):"""子弹的移动"""passdef displayBullet(self):"""展示子弹"""passclass Explode:"""爆炸效果类"""def __init__(self):passdef displayExplode(self):"""展示爆炸效果"""passclass Wall:"""墙壁类"""def __init__(self):passdef dispalyWall(self):"""展示墙壁"""passclass Music:"""音效类"""def __init__(self):passdef play(self):"""开始播放音乐"""pass
四.项目开始:
1.创建游戏窗口
用到游戏引擎中的功能模块:
查看官方开发文档 http://www.pygame.org/docs/
import pygame_display = pygame.display
COLOR_BLACK = pygame.Color(0,0,0)#窗口颜色class MainGame:"""主游戏类"""window = None # 游戏主窗口SCREEN_HEIGHT = 500 # 窗口的高度SCREEN_WIDTH = 800 # 窗口的宽度def __init__(self):passdef startGame(self):"""开始游戏"""_display.init() # 初始化窗口MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH,MainGame.SCREEN_HEIGHT]) # 创建窗口并加载窗口(借鉴官方文档)_display.set_caption("坦克大战v1.03") # 设置游戏的标题while True:#让窗口持续刷新MainGame.window.fill(COLOR_BLACK)#给窗口完成一个填充颜色_display.update()#窗口的刷新def endGame(self):"""结束游戏"""print("谢谢使用")exit() # 结束python解释器class Tank:"""坦克类"""def __init__(self):passdef move(self):"""坦克的移动"""passdef shot(self):"""坦克的射击"""passdef displayTank(self):"""展示坦克"""passclass MyTank(Tank):"""我方坦克类"""def __init__(self):passclass EnemyTank(Tank):"""敌方坦克类"""def __init__(self):passclass Bullet:"""子弹类"""def __init__(self):passdef move(self):"""子弹的移动"""passdef displayBullet(self):"""展示子弹"""passclass Explode:"""爆炸效果类"""def __init__(self):passdef displayExplode(self):"""展示爆炸效果"""passclass Wall:"""墙壁类"""def __init__(self):passdef dispalyWall(self):"""展示墙壁"""passclass Music:"""音效类"""def __init__(self):passdef play(self):"""开始播放音乐"""passMainGame().startGame()
运行结果:
2.事件处理
- 点击关闭按钮,退出程序
- 方向控制,子弹发射
import pygame_display = pygame.display
COLOR_BLACK = pygame.Color(0, 0, 0) # 窗口颜色class MainGame:"""主游戏类"""window = None # 游戏主窗口SCREEN_HEIGHT = 500 # 窗口的高度SCREEN_WIDTH = 800 # 窗口的宽度def __init__(self):passdef startGame(self):"""开始游戏"""_display.init() # 初始化窗口MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH,MainGame.SCREEN_HEIGHT]) # 创建窗口并加载窗口(借鉴官方文档)_display.set_caption("坦克大战v1.04") # 设置游戏的标题# 让窗口持续刷新while True:MainGame.window.fill(COLOR_BLACK) # 给窗口完成一个填充颜色self.getEvent() # 在循环中持续完成事件的获取_display.update() # 窗口的刷新def getEvent(self):"""获取程序运行期间所有的鼠标和键盘事件"""eventList = pygame.event.get() # 获取所有的事件for event in eventList: # 对事件进行判断处理(1.点击鼠标关闭按钮 2.按下键盘上的某个按键)if event.type == pygame.QUIT: # 判断event.type是否为QUIT,如果是,直接调用程序结束方法self.endGame()# 判断事件是否为键盘按键操作,如果是,继续判断按键是哪一个按键,并进行对应的处理if event.type == pygame.KEYDOWN:# 具体是哪个按键的处理if event.key == pygame.K_LEFT:print("坦克向左调头,移动")elif event.key == pygame.K_RIGHT:print("坦克向右调头,移动")elif event.key == pygame.K_UP:print("坦克向上调头,移动")elif event.key == pygame.K_DOWN:print("坦克向下调头,移动")elif event.key == pygame.K_SPACE:print("发射子弹")def endGame(self):"""结束游戏"""print("谢谢使用")exit() # 结束python解释器class Tank:"""坦克类"""def __init__(self):passdef move(self):"""坦克的移动"""passdef shot(self):"""坦克的射击"""passdef displayTank(self):"""展示坦克"""passclass MyTank(Tank):"""我方坦克类"""def __init__(self):passclass EnemyTank(Tank):"""敌方坦克类"""def __init__(self):passclass Bullet:"""子弹类"""def __init__(self):passdef move(self):"""子弹的移动"""passdef displayBullet(self):"""展示子弹"""passclass Explode:"""爆炸效果类"""def __init__(self):passdef displayExplode(self):"""展示爆炸效果"""passclass Wall:"""墙壁类"""def __init__(self):passdef dispalyWall(self):"""展示墙壁"""passclass Music:"""音效类"""def __init__(self):passdef play(self):"""开始播放音乐"""passMainGame().startGame()
运行结果:
3.实现左上角文字提示内容
模块:font
import pygame_display = pygame.display
COLOR_BLACK = pygame.Color(0, 0, 0) # 窗口颜色
COLOR_RED = pygame.Color(255, 0, 0) # 窗口左上角文字颜色class MainGame:"""主游戏类"""window = None # 游戏主窗口SCREEN_HEIGHT = 500 # 窗口的高度SCREEN_WIDTH = 800 # 窗口的宽度def __init__(self):passdef startGame(self):"""开始游戏"""_display.init() # 初始化窗口# 创建窗口并加载窗口(借鉴官方文档)MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH, MainGame.SCREEN_HEIGHT])_display.set_caption("坦克大战v1.05") # 设置游戏的标题# 让窗口持续刷新while True:MainGame.window.fill(COLOR_BLACK) # 给窗口完成一个填充颜色# 将绘制文字的小画布粘贴到窗口中MainGame.window.blit(self.getTextSurface("剩余敌方坦克{}辆".format(5)), (5, 5))self.getEvent() # 在循环中持续完成事件的获取_display.update() # 窗口的刷新def getEvent(self):"""获取程序运行期间所有的鼠标和键盘事件"""eventList = pygame.event.get() # 获取所有的事件# 对事件进行判断处理(1.点击鼠标关闭按钮 2.按下键盘上的某个按键)for event in eventList:# 判断event.type是否为QUIT,如果是,直接调用程序结束方法if event.type == pygame.QUIT:self.endGame()# 判断事件是否为键盘按键操作,如果是,继续判断按键是哪一个按键,并进行对应的处理if event.type == pygame.KEYDOWN:# 具体是哪个按键的处理if event.key == pygame.K_LEFT:print("坦克向左调头,移动")elif event.key == pygame.K_RIGHT:print("坦克向右调头,移动")elif event.key == pygame.K_UP:print("坦克向上调头,移动")elif event.key == pygame.K_DOWN:print("坦克向下调头,移动")elif event.key == pygame.K_SPACE:print("发射子弹")def getTextSurface(self, text):pygame.font.init() # 初始化字体模块# fontList = pygame.font.get_fonts() # 查看系统支持的所有字体# print(fontList)font = pygame.font.SysFont('kaiti', 20) # 选一个合适的字体textSurface = font.render(text, True, COLOR_RED) # 使用对应的字符完成相关内容的绘制return textSurfacedef endGame(self):"""结束游戏"""print("谢谢使用")exit() # 结束python解释器class Tank:"""坦克类"""def __init__(self):passdef move(self):"""坦克的移动"""passdef shot(self):"""坦克的射击"""passdef displayTank(self):"""展示坦克"""passclass MyTank(Tank):"""我方坦克类"""def __init__(self):passclass EnemyTank(Tank):"""敌方坦克类"""def __init__(self):passclass Bullet:"""子弹类"""def __init__(self):passdef move(self):"""子弹的移动"""passdef displayBullet(self):"""展示子弹"""passclass Explode:"""爆炸效果类"""def __init__(self):passdef displayExplode(self):"""展示爆炸效果"""passclass Wall:"""墙壁类"""def __init__(self):passdef dispalyWall(self):"""展示墙壁"""passclass Music:"""音效类"""def __init__(self):passdef play(self):"""开始播放音乐"""passMainGame().startGame()
运行结果:
4.加载我方坦克
素材:
import pygame_display = pygame.display
COLOR_BLACK = pygame.Color(0, 0, 0) # 窗口颜色
COLOR_RED = pygame.Color(255, 0, 0) # 窗口左上角文字颜色class MainGame:"""主游戏类"""window = None # 游戏主窗口SCREEN_WIDTH = 800 # 窗口的宽度SCREEN_HEIGHT = 500 # 窗口的高度TANK_P1 = None # 我方坦克def __init__(self):passdef startGame(self):"""开始游戏"""_display.init() # 初始化窗口# 创建窗口并加载窗口(借鉴官方文档)MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH, MainGame.SCREEN_HEIGHT])MainGame.TANK_P1 = Tank(MainGame.SCREEN_WIDTH // 2, MainGame.SCREEN_HEIGHT - 70) # 创建我方坦克_display.set_caption("坦克大战v1.06") # 设置游戏的标题# 让窗口持续刷新while True:MainGame.window.fill(COLOR_BLACK) # 给窗口完成一个填充颜色# 将绘制文字的小画布粘贴到窗口中MainGame.window.blit(self.getTextSurface("剩余敌方坦克{}辆".format(5)), (5, 5))# 将我方坦克加入到窗口中MainGame.TANK_P1.displayTank()self.getEvent() # 在循环中持续完成事件的获取_display.update() # 窗口的刷新def getEvent(self):"""获取程序运行期间所有的鼠标和键盘事件"""eventList = pygame.event.get() # 获取所有的事件# 对事件进行判断处理(1.点击鼠标关闭按钮 2.按下键盘上的某个按键)for event in eventList:# 判断event.type是否为QUIT,如果是,直接调用程序结束方法if event.type == pygame.QUIT:self.endGame()# 判断事件是否为键盘按键操作,如果是,继续判断按键是哪一个按键,并进行对应的处理if event.type == pygame.KEYDOWN:# 具体是哪个按键的处理if event.key == pygame.K_LEFT:print("坦克向左调头,移动")elif event.key == pygame.K_RIGHT:print("坦克向右调头,移动")elif event.key == pygame.K_UP:print("坦克向上调头,移动")elif event.key == pygame.K_DOWN:print("坦克向下调头,移动")elif event.key == pygame.K_SPACE:print("发射子弹")def getTextSurface(self, text):pygame.font.init() # 初始化字体模块# fontList = pygame.font.get_fonts() # 查看系统支持的所有字体# print(fontList)font = pygame.font.SysFont('kaiti', 20) # 选一个合适的字体textSurface = font.render(text, True, COLOR_RED) # 使用对应的字符完成相关内容的绘制return textSurfacedef endGame(self):"""结束游戏"""print("谢谢使用")exit() # 结束python解释器class Tank:"""坦克类"""def __init__(self, left, top):self.images = {'D': pygame.image.load('img/tank_1_D.jpg'),'U': pygame.image.load('img/tank_1_U.jpg'),'L': pygame.image.load('img/tank_1_L.jpg'),'R': pygame.image.load('img/tank_1_R.jpg'),} # 四个方向,四个图片self.direction = 'U' # 初始方向为上self.image = self.images[self.direction] # 根据方向选择对应的图片# 坦克所在的区域 Rect-->self.rect = self.image.get_rect()# 指定坦克初始化位置分别距x,y轴的位置self.rect.left = leftself.rect.top = topdef move(self):"""坦克的移动"""passdef shot(self):"""坦克的射击"""passdef displayTank(self):"""展示坦克(将坦克绘制到窗口中,使用blit())"""# 重新设置坦克的图片self.image = self.images[self.direction]# 将坦克加载到窗口中MainGame.window.blit(self.image, self.rect)class MyTank(Tank):"""我方坦克类"""def __init__(self):passclass EnemyTank(Tank):"""敌方坦克类"""def __init__(self):passclass Bullet:"""子弹类"""def __init__(self):passdef move(self):"""子弹的移动"""passdef displayBullet(self):"""展示子弹"""passclass Explode:"""爆炸效果类"""def __init__(self):passdef displayExplode(self):"""展示爆炸效果"""passclass Wall:"""墙壁类"""def __init__(self):passdef dispalyWall(self):"""展示墙壁"""passclass Music:"""音效类"""def __init__(self):passdef play(self):"""开始播放音乐"""passMainGame().startGame()
运行结果:
5.坦克类新增speed属性,用来控制坦克移动快慢
6.事件处理:
- 改变坦克方向
- 修改坦克的位置(left,top):取决于坦克的速度
import pygame_display = pygame.display
COLOR_BLACK = pygame.Color(0, 0, 0) # 窗口颜色
COLOR_RED = pygame.Color(255, 0, 0) # 窗口左上角文字颜色class MainGame:"""主游戏类"""window = None # 游戏主窗口SCREEN_WIDTH = 800 # 窗口的宽度SCREEN_HEIGHT = 500 # 窗口的高度TANK_P1 = None # 我方坦克def __init__(self):passdef startGame(self):"""开始游戏"""_display.init() # 初始化窗口# 创建窗口并加载窗口(借鉴官方文档)MainGame.window = _display.set_mode([MainGame.SCREEN_WIDTH, MainGame.SCREEN_HEIGHT])MainGame.TANK_P1 = Tank(MainGame.SCREEN_WIDTH // 2, MainGame.SCREEN_HEIGHT - 70) # 创建我方坦克_display.set_caption("坦克大战v1.07") # 设置游戏的标题# 让窗口持续刷新while True:MainGame.window.fill(COLOR_BLACK) # 给窗口完成一个填充颜色# 将绘制文字的小画布粘贴到窗口中MainGame.window.blit(self.getTextSurface("剩余敌方坦克{}辆".format(5)), (5, 5))# 将我方坦克加入到窗口中MainGame.TANK_P1.displayTank()self.getEvent() # 在循环中持续完成事件的获取_display.update() # 窗口的刷新def getEvent(self):"""获取程序运行期间所有的鼠标和键盘事件"""eventList = pygame.event.get() # 获取所有的事件# 对事件进行判断处理(1.点击鼠标关闭按钮 2.按下键盘上的某个按键)for event in eventList:# 判断event.type是否为QUIT,如果是,直接调用程序结束方法if event.type == pygame.QUIT:self.endGame()# 判断事件是否为键盘按键操作,如果是,继续判断按键是哪一个按键,并进行对应的处理if event.type == pygame.KEYDOWN:# 具体是哪个按键的处理if event.key == pygame.K_LEFT:print("坦克向左调头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'L'# 完成移动操作(调用坦克的移动方法)MainGame.TANK_P1.move()elif event.key == pygame.K_RIGHT:print("坦克向右调头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'R'# 完成移动操作(调用坦克的移动方法)MainGame.TANK_P1.move()elif event.key == pygame.K_UP:print("坦克向上调头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'U'# 完成移动操作(调用坦克的移动方法)MainGame.TANK_P1.move()elif event.key == pygame.K_DOWN:print("坦克向下调头,移动")# 修改坦克方向MainGame.TANK_P1.direction = 'D'# 完成移动操作(调用坦克的移动方法)MainGame.TANK_P1.move()elif event.key == pygame.K_SPACE:print("发射子弹")def getTextSurface(self, text):pygame.font.init() # 初始化字体模块# fontList = pygame.font.get_fonts() # 查看系统支持的所有字体# print(fontList)font = pygame.font.SysFont('kaiti', 20) # 选一个合适的字体textSurface = font.render(text, True, COLOR_RED) # 使用对应的字符完成相关内容的绘制return textSurfacedef endGame(self):"""结束游戏"""print("谢谢使用")exit() # 结束python解释器class Tank:"""坦克类"""def __init__(self, left, top):self.images = {'D': pygame.image.load('img/tank_1_D.jpg'),'U': pygame.image.load('img/tank_1_U.jpg'),'L': pygame.image.load('img/tank_1_L.jpg'),'R': pygame.image.load('img/tank_1_R.jpg'),} # 四个方向,四个图片self.direction = 'U' # 初始方向为上self.image = self.images[self.direction] # 根据方向选择对应的图片# 坦克所在的区域 Rect-->self.rect = self.image.get_rect()# 指定坦克初始化位置分别距x,y轴的位置self.rect.left = leftself.rect.top = topself.speed = 5def move(self):"""坦克的移动"""if self.direction == 'L':self.rect.left -= self.speedelif self.direction == 'R':self.rect.left += self.speedelif self.direction == 'U':self.rect.top -= self.speedelif self.direction == 'D':self.rect.top += self.speeddef shot(self):"""坦克的射击"""passdef displayTank(self):"""展示坦克(将坦克绘制到窗口中,使用blit())"""# 重新设置坦克的图片self.image = self.images[self.direction]# 将坦克加载到窗口中MainGame.window.blit(self.image, self.rect)class MyTank(Tank):"""我方坦克类"""def __init__(self):passclass EnemyTank(Tank):"""敌方坦克类"""def __init__(self):passclass Bullet:"""子弹类"""def __init__(self):passdef move(self):"""子弹的移动"""passdef displayBullet(self):"""展示子弹"""passclass Explode:"""爆炸效果类"""def __init__(self):passdef displayExplode(self):"""展示爆炸效果"""passclass Wall:"""墙壁类"""def __init__(self):passdef dispalyWall(self):"""展示墙壁"""passclass Music:"""音效类"""def __init__(self):passdef play(self):"""开始播放音乐"""passMainGame().startGame()
运行结果:
可以朝各个方向移动了https://www.zhihu.com/video/1141070523843960832字数上限,新开一篇……
Life is short,you need Python——Python实现坦克大战(二)
皮卡丘比特:Life is short,you need Python——Python实现坦克大战(二)zhuanlan.zhihu.com