一.Pygame相关介绍
1、Pygame是跨平台Python模块,专为电子游戏设计,包含图像、声音。允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚。Pygame常用模块 2、一个游戏循环(也可以称为主循环)就做下面这三件事: 处理事件 更新游戏状态 绘制游戏状态到屏幕上

3、安装:Pygame的安装非常简单
1)在Terminal里面执行pip install Pygame就可以。此方法较慢。
2)在Terminal里面执行pip install -i https:pypi.duban.com/simple pygame。此方法比较迅速。
Pygame安装如下:

表示安装成功!
4.Pygame简单操作介绍:
每次需要导入Pygame这个模块
import pygame
# 1). 初始化pygame
pygame.init()
# 2). 显示游戏界面
pygame.display.set_mode((600, 600)) #设置画布的规格
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("游戏结束......")
exit(0)
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
print("UP")
elif event.key == pygame.K_DOWN:
print('DOWN')
饰演结果:


2)Pygame常用模块
import pygame
import sys
pygame.init() #初始化pygame
size=width, height=320,240 #设置窗口大小
screen=pygame.display.set_mode(size) #显示窗口
while True: #死循环确保窗口一直显示
for event in pygame.event.get(): #遍历所有事件
if event.type== pygame.QUIT: #如果单击关闭窗口,则退出
sys.exit()
pygame.quit() #退出pygame
打印结果如下:

二.项目案例
项目案例一: 栈与队列的封装
栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素时称为“空栈”。
向一个栈内插入元素称为是进栈(push); 从一个栈删除元素称为是出栈(pop)。
特点 :后进先出(LIFO)。

队列是限制在一端进行插入操作和另一端删除操作的线性表,允许进行插入操作的一端称为“队尾”,允许进行删除操作的一端称为“队头”,当队列中没有元素时称为“空队”。
特点 :先进先出(FIFO)。

如:实现一个简单的入栈出栈功能:
class Stack(object):
"""
根据列表的数据结构封装栈的数据结构
属性: 栈元素stack
方法:
get_top()
get_bootom()
push()
pop()
"""
def __init__(self):
self.stack=[]
def top(self):
return self.stack[-1]
def bootom(self):
return self.stack[0]
def push(self,item):
self.stack.append(item)
return True
def pop(self):
item=self.stack.pop()
return item
def show(self):
return self.stack
#魔术方法:(对于已封装好的模块(stack),不能直接调用内置方法len求长度,只有用了魔术方才可以调用len()这个函数)
def __len__(self):
return len(self.stack)
if __name__ =='__main__':
stack=Stack()
print(stack.show())
stack.push(1)
stack.push(2)
stack.push(3)
print("入栈后:",stack.show())
item=stack.pop()
print("出栈元素为:", item)
print("出栈后:",stack.show())
print("栈元素个数:",len(stack)) #或者print("栈元素个数:", stack.__len__()),两种写法同样的效果。
打印结果:
[]
入栈后: [1, 2, 3]
出栈元素为: 3
出栈后: [1, 2]
栈元素个数: 2
项目案例二: 二叉树的理解(二叉树节点的封装)

1)(lchild, rchild)
class Node(object):
def __init__(self, data, lchild=None, rchild=None):
self.data = data
self.lchild = lchild
self.rchild = rchild
# 魔术方法__str__
def __str__(self):
return 'Node<%s>' % (self.data)
if __name__ == '__main__':
D = Node('D')
B = Node('B', D)
C = Node('C')
A = Node('A', B, C)
print("A-left:", str(A.lchild))
print("A-right:", str(A.rchild))
打印结果:
A-left: Node<B>
A-right: Node<C>
2)先序遍历: 根节点-左子树节点-右子树节点;
后序遍历: -左子树节点-右子树节点-根节点;
中序遍历: -左子树节点--根节点-右子树节点
class Node(object):
def __init__(self, data, lchild=None, rchild=None):
self.data = data
self.lchild = lchild
self.rchild = rchild
# 魔术方法: len(), __len__. str(), __str__
def __str__(self): # 友好的字符串显示信息
return 'Node<%s>' % (self.data)
def pre_view( root):
"""
先序遍历: 根节点-左子树节点-右子树节点
传递根节点
:param root:
:return:
"""
if root == None:
return
print(root.data)
pre_view(root.lchild)
pre_view(root.rchild)
def last_view(root):
"""
后序遍历: -左子树节点-右子树节点-根节点
传递根节点
:param root:
:return:
"""
if root == None:
return
last_view(root.lchild)
last_view(root.rchild)
print(root.data)
def mid_view(root):
"""
中序遍历: -左子树节点--根节点-右子树节点
传递根节点
:param root:
:return:
"""
if root == None:
return
mid_view(root.lchild)
print(root.data)
mid_view(root.rchild)
if __name__ == '__main__':
D = Node('D')
B = Node('B', D)
C = Node('C')
A = Node('A', B, C)
# 先序遍历(根左右)、中序遍历(左根右)、后序遍历(左右根)
print("先序遍历:")
pre_view(A)
print("后序遍历:")
last_view(A)
print("中序遍历:")
mid_view(A)
打印结果:
先序遍历:
A
B
D
C
后序遍历:
D
B
C
A
中序遍历:
D
B
A
C
项目案例二: 乌龟(小聪)吃鱼(热狗)游戏
游戏规则: 1). 假设游戏场景为范围(x,y)为0<=x<=10,0<=y<=10 2). 游戏生成1只乌龟和10条鱼, 它们的移动方向均随机 3). 乌龟的最大移动能力为2(它可以随机选择1还是2移动), 鱼儿的最大移动能力是1当移动到场景边缘,自动向反方向移动 4). 乌龟初始化体力为100(上限), 乌龟每移动一次,体力消耗1 当乌龟和鱼坐标重叠,乌龟吃掉鱼,乌龟体力增加20, 鱼暂不计算体力 5). 当乌龟体力值为0(挂掉)或者鱼儿的数量为0游戏结束
import random
import pygame
class SiCong(object):
"""
小聪(人)类:
属性: (x,y), power
方法: move(), eat()
"""
def __init__(self):
self.x = random.randint(50, width - 50)
self.y = random.randint(50, height - 50)
self.power = 100
def move(self, new_x, new_y):
"""小聪移动的方法"""
self.x = new_x % width
self.y = new_y % height
def eat(self):
"""小聪吃热狗"""
self.power += 20
print("小聪吃到热狗, 能量+20!")
class HotDog(object):
"""
食物类:
属性: (x,y)
方法: move()
"""
def __init__(self):
self.x = random.randint(50, width - 50)
self.y = random.randint(50, height - 50)
def move(self):
"""
热狗的最大移动能力是1当移动到场景边缘,
"""
# 热狗的最大移动能力是1当移动到场景边缘,
move_skills = [-8]
# 计算热狗最新的x轴坐标;()
new_x = self.x + random.choice(move_skills)
# 当移动到场景边缘如何处理?
self.x = new_x % width
def main():
pygame.init()
# 显示游戏界面
screen = pygame.display.set_mode((width, height))
# 设置界面标题
pygame.display.set_caption("吃热狗游戏")
# 加载游戏中需要的图片
bg = pygame.image.load('./img/bg2.png').convert()
hotdogImg = pygame.image.load('./img/hot-dog.png').convert_alpha()
sicongImg = pygame.image.load('./img/sicong.png').convert_alpha()
hd_width, hd_height = hotdogImg.get_width(), hotdogImg.get_height()
sc_width, sc_height = sicongImg.get_width(), sicongImg.get_height()
# 加载游戏音乐(背景音乐和吃掉热狗的音乐)
pygame.mixer.music.load('./img/game_music.mp3')
pygame.mixer.music.play(loops=0, start=0.0) # 播放设置, 不循环且从0.0s开始播放
# 设置分数显示参数信息(显示位置、字体颜色、字体大小)
scoreCount = 0
font = pygame.font.SysFont('arial', 30) # 系统设置字体的类型和大小
# 颜色表示法: RGB (255, 0, 0)-红色 (255, 255, 255)-白色 (0, 0, 0)-黑色
score = font.render("Score: %s" % (scoreCount), True, (0, 0, 0))
# 创建一个Clock对象,跟踪游戏运行时间
fpsClock = pygame.time.Clock()
# 创建一个小聪和15个热狗
sicong = SiCong()
hotdogs = [HotDog() for item in range(15)]
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
print("游戏结束......")
exit(0)
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
# 移动人物向上多少个像素
sicong.move(sicong.x, sicong.y - 15)
elif event.key == pygame.K_DOWN:
sicong.move(sicong.x, sicong.y + 15)
if event.key == pygame.K_LEFT:
# 移动人物向上多少个像素
sicong.move(sicong.x - 15, sicong.y)
elif event.key == pygame.K_RIGHT:
sicong.move(sicong.x + 15, sicong.y)
# 绘制背景和分数
screen.blit(bg, (0, 0))
screen.blit(score, (200, 20))
# 绘制热狗,并实现热狗的移动
for hd in hotdogs:
screen.blit(hotdogImg, (hd.x, hd.y))
hd.move()
# 绘制sicong
screen.blit(sicongImg, (sicong.x, sicong.y))
# 判断游戏是否结束: 当人物体力值为0(挂掉)或者热狗的数量为0游戏结束
if sicong.power == 0:
print("Game Over: Sicong Power is 0")
exit(1)
if len(hotdogs) == 0:
print("Game Over: hot-dog count is 0")
exit(2)
# 判断人物是否吃到热狗:人物和热狗的坐标值相同, 则认为吃掉
for hd in hotdogs:
if 0 < sicong.x - hd.x < 50 and 0 < sicong.y - hd.y < 50:
# 增加人物的能量值
sicong.eat()
# 移除被吃掉的热狗
hotdogs.remove(hd)
# 增加得分
scoreCount += 10
# 重新设置得分信息
score = font.render("Score: %s" % (scoreCount), True, (0, 0, 0))
# 更新内容到游戏窗口
pygame.display.update()
fpsClock.tick(10) # 每秒更新10帧
if __name__ == '__main__':
width =785
height = 570
main()
运行结果:


|