#v1.01 开发日志 :
原理:和动画原理相同,快速切换图片,为了避免上一次贴图,每次刷新前,重贴所有图片
分级实现: 对应下图work项目文件图 文件后缀编号
V1 搭建整体框架
V2 设计主逻辑
V3 主逻辑事件检测
V4 我方坦克分析
V5 创建我方坦克 并且加载贴图
V6 实现我方坦克 移动
整体实现: 实现键盘控制我方坦克上下左右移动 2020-05-13
分析.txt 部分截图 序号为程序编写步骤 对比py文件 比如#v5.1# v5.2# v5.4
1.pip 安装
2.pycharm中安装
3.下载好安装包之后直接安装
使用 pip list 查看是否有pygame
开始项目的时候先搭建整体框架
实现框架的搭建(类的设计)
主逻辑类
基本坦克类
我方坦克类
敌方坦克类
子弹类
墙壁类
爆炸类
# 主逻辑类
class MainGame:
def start(self):
"""开始游戏"""
pass
def game_over(self):
"""结束游戏"""
pass
# 基本坦克类
class BaseTank:
pass
# 我方坦克类
class HeroTank:
pass
# 敌方坦克类
class EnemyTank:
pass
# 子弹类
class Bullet:
pass
# 墙壁类
class wall:
pass
v2
主逻辑类
属性:游戏窗口
方法:开始游戏 start()
- 窗口初始化
- 设置窗口
- 设置标题(坦克大战v_1.0)
- 窗口背景
- 游戏应该在无限循环
"""
项目:坦克大战
时间:2020-05-13
作者:稳稳
使用软件及版本:Pycharm python3.6 pygame1.9
"""
# 主逻辑类
"""
主逻辑类
属性:游戏窗口
方法:开始游戏 start()
- 窗口初始化
- 设置窗口
- 设置标题(坦克大战v_1.0)
- 窗口背景
- 游戏应该在无限循环
"""
import pygame
class MainGame:
# 游戏主窗口
window = None
def start(self):
"""开始游戏"""
# 调用窗口初始化
pygame.display.init()
# 创建窗口 set_mode("窗口宽,窗口高")
MainGame.window = pygame.display.set_mode((900,500))
# 设置窗口标题
pygame.display.set_caption("坦克大战v_1.0")
while True :
# 设置窗口背景 fill() 设置颜色 RGB 这里设置黑色
MainGame.window.fill((0,0,0))
# 刷新显示
pygame.display.update()
def game_over(self):
"""结束游戏"""
pass
# 基本坦克类
class BaseTank:
pass
# 我方坦克类
class HeroTank:
pass
# 敌方坦克类
class EnemyTank:
pass
# 子弹类
class Bullet:
pass
# 墙壁类
class wall:
pass
# 创建对象
start = MainGame()
# 对象开始游戏
start.start()
v3
添加内容:主逻辑内进行事件检测
主逻辑类
效果:鼠标放到窗口 反馈数据
属性:游戏窗口
方法:开始游戏 start()
事件检测 deal_event()
"""
项目:坦克大战
时间:2020-05-13
作者:稳稳
使用软件及版本:Pycharm python3.6 pygame1.9
"""
# 主逻辑类
"""
主逻辑类
属性:游戏窗口
方法:开始游戏 start()
- 窗口初始化
- 设置窗口
- 设置标题(坦克大战v_1.0)
- 窗口背景
- 游戏应该在无限循环
"""
import pygame
import sys
class MainGame:
# 游戏主窗口
window = None
def start(self):
"""开始游戏"""
# 调用窗口初始化
pygame.display.init()
# 创建窗口 set_mode("窗口宽,窗口高")
MainGame.window = pygame.display.set_mode((900,500))
# 设置窗口标题
pygame.display.set_caption("坦克大战v_1.0")
while True :
# 设置窗口背景 fill() 设置颜色 RGB 这里设置黑色
MainGame.window.fill((0,0,0))
# 调用时间检测事件
self.deal_event()
# 刷新显示
pygame.display.update()
def deal_event(self):
"""事件检测"""
# 鼠标放上窗口和敲击键盘可以观察到位置信息反馈
# print(pygame.event.get())
# 获取新事件
for event in pygame.event.get():
# 1. 鼠标点击关闭窗口事件
if event.type == pygame.QUIT:
print("点击关闭窗口按钮")
sys.exit() # 关闭程序
# 2. 按下键盘检测
elif event.type == pygame.KEYDOWN:
# 按下键盘反馈数据
# print("按下键盘")
if event.key == pygame.K_LEFT:
print("左移动")
elif event.key == pygame.K_RIGHT:
print("右移动")
# 3. 鼠标点击检测
elif event.type == pygame.MOUSEBUTTONDOWN:
print("鼠标点击事件")
def game_over(self):
"""结束游戏"""
pass
# 基本坦克类
class BaseTank:
pass
# 我方坦克类
class HeroTank:
pass
# 敌方坦克类
class EnemyTank:
pass
# 子弹类
class Bullet:
pass
# 墙壁类
class wall:
pass
# 创建对象
start = MainGame()
# 对象开始游戏
start.start()
鼠标放到游戏窗口,键盘左右按下,可以看到反馈,其实这个可以注释掉,只能留下关闭窗口检测
v4
我方坦克分析
由于我方坦克和敌方坦克有相识属性和方法,所以可以先写基本坦克类
让我方坦克和敌方坦克继承基本坦克类
基本坦克类:BaseTank
属性:图片、方向、图片矩形区域、坦克位置、移动速度、是否活着
方法:移动、贴图
参考代码以及步骤(定义基本坦克类,让我方坦克继承)
1.加载坦克图片 存于字典中
2.初始化坦克方向
3.根据坦克方向获取坦克图片
4.获取图片矩形区域
5.根据传入的参数,决定坦克的位置
6.移动速度
7.是否活着
坦克贴图方法display_tank()
8.先获取坦克图片
9.贴坦克图片
我方坦克类HeroTank(BaseTank)
10.继承基本坦克类
"""
项目:坦克大战
时间:2020-05-13
作者:稳稳
使用软件及版本:Pycharm python3.6 pygame1.9
"""
# 主逻辑类
"""
主逻辑类
属性:游戏窗口
方法:开始游戏 start()
- 窗口初始化
- 设置窗口
- 设置标题(坦克大战v_1.0)
- 窗口背景
- 游戏应该在无限循环
"""
import pygame
import sys
class MainGame:
# 游戏主窗口
window = None
def start(self): # V2
"""开始游戏"""
# 调用窗口初始化
pygame.display.init()
# 创建窗口 set_mode("窗口宽,窗口高")
MainGame.window = pygame.display.set_mode((900,500))
# 设置窗口标题
pygame.display.set_caption("坦克大战v_1.0")
while True :
# 设置窗口背景 fill() 设置颜色 RGB 这里设置黑色
MainGame.window.fill((0,0,0))
# 调用时间检测事件
self.deal_event()
# 刷新显示
pygame.display.update()
def deal_event(self): # V3
"""事件检测"""
# 鼠标放上窗口和敲击键盘可以观察到位置信息反馈
# print(pygame.event.get())
# 获取新事件
for event in pygame.event.get():
# 1. 鼠标点击关闭窗口事件
if event.type == pygame.QUIT:
print("点击关闭窗口按钮")
sys.exit() # 关闭程序
# 2. 按下键盘检测
elif event.type == pygame.KEYDOWN:
# 按下键盘反馈数据
# print("按下键盘")
if event.key == pygame.K_LEFT:
print("左移动")
elif event.key == pygame.K_RIGHT:
print("右移动")
# 3. 鼠标点击检测
elif event.type == pygame.MOUSEBUTTONDOWN:
print("鼠标点击事件")
def game_over(self):
"""结束游戏"""
pass
# 基本坦克类
class BaseTank: # V4
def __init__(self,x,y):
"""
基本坦克类的属性
x,y:坦克初始在游戏窗口的位置
"""
# 1.加载图片文件,返回图片对象
# 1.将坦克图片存储在字典中
self.images = {
"U":pygame.image.load("tank_img/p1tankU.gif"),
"D":pygame.image.load("tank_img/p1tankU.gif"),
"L":pygame.image.load("tank_img/p1tankU.gif"),
"R":pygame.image.load("tank_img/p1tankU.gif"),
}
# 2.给初始化坦克一个方向
self.direction = "U"
# 3.根据坦克方向获取坦克图片
self.image = self.images[self.direction]
# 4.获取图片矩形区域
self.rect = self.image.get_rect()
# 5.根据传入的参数,决定坦克的位置
self.rect.x = x # 坦克的x坐标
self.rect.y = y # 坦克的y坐标
# 6.移动速度
self.speed = 3
# 7.是否活着
self.live = True
def display_tank(self):
"""坦克图片的贴图方法"""
# 8.先获取坦克图片
self.image = self.images[self.direction]
# 9.贴坦克图片
MainGame.window.blit(self.image,self.rect)
# 我方坦克类
class HeroTank(BaseTank):
# 10.继承基本坦克类
def __init__(self):
super(HeroTank,self).__init__(x,y)
self.speed = 2
# 敌方坦克类
class EnemyTank:
pass
# 子弹类
class Bullet:
pass
# 墙壁类
class wall:
pass
# 创建对象
start = MainGame()
# 对象开始游戏
start.start()
v5
创建我方坦克 并加载图片
在主逻辑中,一开始就在我方坦克,定义P类属性记录
先定义创建我方坦克的方法 create_hero_tank,
在定义加载坦克图片方法 load_hero_tank
在开始游戏时,调用创建坦克对象的方法,在循环中加载坦克图片
1.记录我方坦克
2.在MainGame 创建坦克方法 create_tank()
3.加载我方坦克 load_heor_tank()
4.调用坦克创建的方法
5.调用坦克贴图方法
并不能移动!!!!!!!!!!!!!!!!!!!!
"""
项目:坦克大战
时间:2020-05-13
作者:稳稳
使用软件及版本:Pycharm python3.6 pygame1.9
"""
import pygame
import sys
# 主逻辑类
class MainGame:
# V2游戏主窗口
window = None
# V5.1记录我方坦克
P1 = None
def create_tank(self): #V5.2
"""创建我方坦克"""
# v5.2判断我方坦克是否创建
if not MainGame.P1:
MainGame.P1 = HeroTank(500,400) # 坦克初始位置
def load_heor_tank(self): #v5.3
"""加载我方坦克"""
# v5.3如果坦克就调用坦克贴图的方法
if MainGame.P1 and MainGame.P1.live:
MainGame.P1.display_tank()
else:
# v5.3如果坦克死了,删除坦克对象,删除贴图
del MainGame.P1
MainGame.P1 = None # v5.3恢复坦克初始化设置
def start(self): # V2
"""开始游戏"""
# V2调用窗口初始化
pygame.display.init()
# V2创建窗口 set_mode("窗口宽,窗口高")
MainGame.window = pygame.display.set_mode((900,500))
# V2设置窗口标题
pygame.display.set_caption("坦克大战v_1.0")
# v5.4 调用坦克创建的方法
self.create_tank()
while True :
# V2设置窗口背景 fill() 设置颜色 RGB 这里设置黑色
MainGame.window.fill((0,0,0))
# V2调用时间检测事件
self.deal_event()
# v5.5调用坦克贴图方法
self.load_heor_tank()
# V2刷新显示
pygame.display.update()
def deal_event(self): # V3
"""事件检测"""
# V3鼠标放上窗口和敲击键盘可以观察到位置信息反馈
# print(pygame.event.get())
# V3获取新事件
for event in pygame.event.get():
# V3.1 鼠标点击关闭窗口事件
if event.type == pygame.QUIT:
print("点击关闭窗口按钮")
sys.exit() # 关闭程序
# V3.2 按下键盘检测
elif event.type == pygame.KEYDOWN:
# print("按下键盘")
# V3.2按下键盘反馈数据
if event.key == pygame.K_LEFT:
print("左移动")
elif event.key == pygame.K_RIGHT:
print("右移动")
# 3. 鼠标点击检测
elif event.type == pygame.MOUSEBUTTONDOWN:
print("鼠标点击事件")
def game_over(self):
"""结束游戏"""
pass
# 基本坦克类
class BaseTank: # V4
def __init__(self,x,y):
self.x = x
self.y = y
"""
基本坦克类的属性
x,y:坦克初始在游戏窗口的位置
"""
# V4.1.加载图片文件,返回图片对象
# V4.1.将坦克图片存储在字典中
self.images = {
"U":pygame.image.load("tank_img/p1tankU.gif"),
"D":pygame.image.load("tank_img/p1tankU.gif"),
"L":pygame.image.load("tank_img/p1tankU.gif"),
"R":pygame.image.load("tank_img/p1tankU.gif"),
}
# V4.2.给初始化坦克一个方向
self.direction = "U"
# V4.3.根据坦克方向获取坦克图片
self.image = self.images[self.direction]
# V4.4.获取图片矩形区域
self.rect = self.image.get_rect()
# V4.5.根据传入的参数,决定坦克的位置
self.rect.x = x # 坦克的x坐标
self.rect.y = y # 坦克的y坐标
# V4.6.移动速度
self.speed = 3
# V4.7.是否活着
self.live = True
def display_tank(self):
"""坦克图片的贴图方法"""
# V4.8.先获取坦克图片
self.image = self.images[self.direction]
# V4.9.贴坦克图片
MainGame.window.blit(self.image,self.rect)
# 我方坦克类
class HeroTank(BaseTank):
# V4.10.继承基本坦克类
def __init__(self,x,y):
super(HeroTank,self).__init__(x,y)
self.speed = 2
# 敌方坦克类
class EnemyTank:
pass
# 子弹类
class Bullet:
pass
# 墙壁类
class wall:
pass
# 创建对象
start = MainGame()
# 对象开始游戏
start.start()
v6
实现我方坦克移动的方法
BaseTank 中 创建 move()
在基本坦克类中添加坦克移动方法
判断坦克的方向,是哪个方向就向哪个方向移动 PS:参考位置图
- 移动方式:
- 初始化位置设为全局变量
代码执行:
1.坦克方向判断
2.边界判断
3.修改全局变量 SCREEN_HEIGHT,SCREEN_WIDTH
4.修改判断边界
5.我方坦克重写父类move()
6.判断键盘状态
7.键盘被按下执行移动
"""
项目:坦克大战
时间:2020-05-13
作者:稳稳
使用软件及版本:Pycharm python3.6 pygame1.9
"""
import pygame
import sys
import time
# V6.3 全局判断
SCREEN_HEIGHT = 500
SCREEN_WIDTH = 900
# 主逻辑类
class MainGame:
# V2游戏主窗口
window = None
# V5.1记录我方坦克
P1 = None
def create_tank(self): # V5.2
"""创建我方坦克"""
# v5.2判断我方坦克是否创建
if not MainGame.P1:
MainGame.P1 = HeroTank(500,400) # 坦克初始位置
def load_heor_tank(self): # v5.3
"""加载我方坦克"""
# v5.3如果坦克就调用坦克贴图的方法
if MainGame.P1 and MainGame.P1.live:
MainGame.P1.display_tank()
MainGame.P1.move()
else:
# v5.3如果坦克死了,删除坦克对象,删除贴图
del MainGame.P1
MainGame.P1 = None # v5.3恢复坦克初始化设置
def start(self): # V2
"""开始游戏"""
# V2调用窗口初始化
pygame.display.init()
# V2创建窗口 set_mode("窗口宽,窗口高") # V6.3
MainGame.window = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
# V2设置窗口标题
pygame.display.set_caption("坦克大战v_1.0")
# v5.4 调用坦克创建的方法
self.create_tank()
while True :
# V2设置窗口背景 fill() 设置颜色 RGB 这里设置黑色
MainGame.window.fill((0,0,0))
# V2调用时间检测事件
self.deal_event()
# v5.5调用坦克贴图方法
self.load_heor_tank()
# V2刷新显示
pygame.display.update()
time.sleep(0.02)
def deal_event(self): # V3
"""事件检测"""
# V3鼠标放上窗口和敲击键盘可以观察到位置信息反馈
# print(pygame.event.get())
# V3获取新事件
for event in pygame.event.get():
# V3.1 鼠标点击关闭窗口事件
if event.type == pygame.QUIT:
print("点击关闭窗口按钮")
sys.exit() # 关闭程序
# V3.2 按下键盘检测
elif event.type == pygame.KEYDOWN:
# print("按下键盘")
# V3.2按下键盘反馈数据
if event.key == pygame.K_LEFT:
print("左移动")
elif event.key == pygame.K_RIGHT:
print("右移动")
elif event.key == pygame.K_SPACE:
print("空格发射子弹")
# 3. 鼠标点击检测
elif event.type == pygame.MOUSEBUTTONDOWN:
print("鼠标点击事件")
def game_over(self):
"""结束游戏"""
# 基本坦克类
class BaseTank: # V4
def __init__(self,x,y):
self.x = x
self.y = y
"""
基本坦克类的属性
x,y:坦克初始在游戏窗口的位置
"""
# V4.1.加载图片文件,返回图片对象
# V4.1.将坦克图片存储在字典中
self.images = {
"U":pygame.image.load("tank_img/p1tankU.gif"),
"D":pygame.image.load("tank_img/p1tankD.gif"),
"L":pygame.image.load("tank_img/p1tankL.gif"),
"R":pygame.image.load("tank_img/p1tankR.gif"),
}
# V4.2.给初始化坦克一个方向
self.direction = "U"
# V4.3.根据坦克方向获取坦克图片
self.image = self.images[self.direction]
# V4.4.获取图片矩形区域
self.rect = self.image.get_rect()
# V4.5.根据传入的参数,决定坦克的位置
self.rect.x = x # 坦克的x坐标
self.rect.y = y # 坦克的y坐标
# V4.6.移动速度
self.speed = 3
# V4.7.是否活着
self.live = True
def display_tank(self):
"""坦克图片的贴图方法"""
# V4.8.先获取坦克图片
self.image = self.images[self.direction]
# V4.9.贴坦克图片
MainGame.window.blit(self.image,self.rect)
def move(self):
"""坦克移动的方法"""
# v6.1 判断坦克的方向 是否向上 向上处理
if self.direction == "U":
# v6.2 边界判断
if self.rect.y > 0 :
self.rect.y -= self.speed
elif self.direction == "D":
# v6.2 边界判断 #v6.4
if self.rect.y<SCREEN_HEIGHT-self.rect.height :
self.rect.y += self.speed
elif self.direction == "L":
# v6.2 边界判断
if self.rect.x > 0 :
self.rect.x -= self.speed
elif self.direction == "R":
# v6.2 边界判断 #v6.4
if self.rect.x<SCREEN_WIDTH-self.rect.width :
self.rect.x += self.speed
# 在加载我方坦克调用坦克移动放马 MainGame.P1.move()
# 此时坦克只能向上移动
# 我方坦克类
class HeroTank(BaseTank):
# V4.10.继承基本坦克类
def __init__(self,x,y):
super(HeroTank,self).__init__(x,y)
self.speed = 2
# v6.5 创建我方坦克方法 重写父类
def move(self):
"""我方坦克移动方法"""
# #v6.6 键盘长按事件 获取键盘上所有按键状态 按下1 没按0
keys_status = pygame.key.get_pressed()
# print(keys_status)
# v6.7如果被按下
if keys_status[pygame.K_UP]:
# 改变移动的方向 重新赋值
self.direction = "U"
# 调用父类移动方式
super(HeroTank, self).move()
elif keys_status[pygame.K_DOWN]:
# 改变移动的方向 重新赋值
self.direction = "D"
# 调用父类移动方式
super(HeroTank, self).move()
elif keys_status[pygame.K_LEFT]:
# 改变移动的方向 重新赋值
self.direction = "L"
# 调用父类移动方式
super(HeroTank, self).move()
elif keys_status[pygame.K_RIGHT]:
# 改变移动的方向 重新赋值
self.direction = "R"
# 调用父类移动方式
super(HeroTank, self).move()
# 敌方坦克类
class EnemyTank:
pass
# 子弹类
class Bullet:
pass
# 墙壁类
class wall:
pass
# 创建对象
start = MainGame()
# 对象开始游戏
start.start()
游戏_API文档.py
import pygame # 导入pygame
# 初始化pygame库,让计算机硬件准备
pygame.init()
# --------窗口相关操作----------
# 创建窗口
window = pygame.display.set_mode((窗口宽,窗口高))
#窗口填充颜色
window.fill((0,0,0))
# 刷新界面 不刷新不会更新显示的内容
pygame.display.update()
# 设置窗口标题
pygame.display.set_caption("窗口标题")
# 设置窗口图标
image = pygame.image.load("res/game.ico")
pygame.display.set_icon(image)
# --------图像相关操作-----------
# 加载图片文件,返回图片对象
image = pygame.image.load("图片路径")
# 贴图(指定坐标,将图片绘制到窗口)
window.blit(image, (0, 0))
# 判断两个矩形是否相交,相交返回True, 否则返回False
flag = pygame.Rect.colliderect(rect1, rect2)
# 进行一对一的冲突检测
pygame.sprite.collide_rect(obj1,obj2)
# 获得图片矩形对象 -> Rect(x, y, width, height) x,y默认都是左上角(0,0)
rect = image.get_rect()
# 获取图片的宽高
print(rect.width)
# 在原位置基础上,移动指定的偏移量 (x, y 增加)
rect.move_ip(num1, num2)
# 将图片对象按指定宽高缩放,返回新的图片对象
trans_image = pygame.transform.scale(image, (WINDOWWIDTH, WINDOWHEIGHT))
# --------事件相关操作-----------
# 获取新事件
for event in pygame.event.get():
# 1. 鼠标点击关闭窗口事件
if event.type == pygame.QUIT:
print("点击关闭窗口按钮")
sys.exit() # 关闭程序
pygame.quit() # 退出pygame,清理pygame占用资源
# 2. 键盘按下事件
if event.type == pygame.KEYDOWN:
# 判断用户按键
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
print("left")
if event.key == pygame.K_RIGHT or event.key == pygame.K_d:
print("right")
if event.key == pygame.K_SPACE:
print("space")
# 3. 键盘长按事件
# 获取当前键盘所有按键的状态(按下/没有按下),返回bool元组 (0, 0, 0, 0, 1, 0, 0, 0, 0)
pressed_keys = pygame.key.get_pressed()
if pressed_keys[pygame.K_a] or pressed_keys[pygame.K_LEFT]:
print("left")
if pressed_keys[pygame.K_d] or pressed_keys[pygame.K_RIGHT]:
print("right")
# ----------文本相关操作-------------
# 加载系统字体,返回字体对象
font_obj = pygame.font.SysFont('SimHei', 42)
# 加载自定义字体,返回字体对象
font_obj = pygame.font.Font("res/SIMHEI.TTF", 42)
三基色: Red Green Blue
0 - 255
# 设置文本,返回文本对象 render(文本内容, 抗锯齿,颜色)
text_obj = font.render("飞机大战", 1, (255, 255, 255))
# 设置文本的位置和尺寸 获取文本的Rect并修改Rect的中心点为 (300,300)
text_rect = text_obj.get_rect(centerx=300, centery=300)
# 在指定位置和尺寸绘制指定文字对象
window.blit(text_obj, text_rect)
# ---------音效相关操作------------
# 加载背景音乐
pygame.mixer.music.load("./res/bg2.ogg")
# 循环播放背景音乐
pygame.mixer.music.play(-1)
# 停止背景音乐
pygame.mixer.music.stop()
# 生成音效对象
boom_sound = pygame.mixer.Sound("./res/baozha.ogg")
# 播放音效
boom_sound.play()
# 停止音效
boom_sound.stop()