使用pygame实现创意游戏《勇闯BUBU星》
窗口与坐标
游戏效果在Pygame窗口中显示,要把窗口设置成合适的大小。
设置窗口大小
Pygame中,用WIDTH和HEIGHT分别表示窗口的宽和高,设置变量的值,就可以改变窗口大小。
py
代码语言:javascript复制import pgzrun #先导入pgzrun
WIDTH = 500 #设置窗口的宽
HEIGHT = 700 #设置窗口的高
pgzrun.go() #写在程序最后,启动Pygame
宽(WIDTH)和高(HEIGHT)变量名的字母都要大写。
窗口的坐标 1 窗口的坐标原点在左上角,坐标为(0, 0) 2 水平方向用x坐标表示,越向右,x坐标越大 竖直方向用y坐标表示,越向下,y坐标越大 3 一对儿x和y坐标,能确定窗口中的一个位置
Actor() 创建角色
Actor()用于创建角色,括号中需要填写一个图片名称,作为角色的造型。
创建角色:Actor()
格式
角色名 = Actor(图片名)
py
代码语言:javascript复制player = Actor('小王子')
使用Actor()首字母A要大写,创建出的角色要存储在一个变量中,比如player。
创建角色,并显示角色
py
代码语言:javascript复制import pgzrun
WIDTH = 500
HEIGHT = 700
#创建角色
player = Actor('小王子')
def draw():
#显示角色
player.draw()
pgzrun.go()
总结 Pygame中使用Actor()创建角色,括号中的参数为图片名,数据类型是字符串; 将角色存储在一个变量中,之后可以使用这个变量操作角色。
draw() 窗口绘制
draw()用于在窗口中绘制背景、角色等内容,所有在窗口中显示内容的代码,都需要写在这个函数中。
窗口绘制:draw()
程序会自动调用draw()函数, 只需要定义函数,不需要写调用函数的代码。
def draw():
绘制背景和绘制角色
绘制背景
py
代码语言:javascript复制def draw():
screen.blit(背景图片, 图片位置)
py
代码语言:javascript复制def draw():
screen.blit('星球', [0. 0])
绘制角色
py
代码语言:javascript复制def draw():
角色.draw()
py
代码语言:javascript复制player = Actor('小王子')
def draw():
player.draw()
on_key_down() 按键控制
on_key_down()
可以实现按键控制,当有按键被按下时, 函数就会执行。
按键控制:on_key_down()
有键被按下时,程序自动调用函数,只需要定义。
py
代码语言:javascript复制def on_key_down(key): #参数key,存储被按下的按键名
#分别判断key的值,可以实现多按键控制
if key == 按键1:
......
if key == 按键2:
......
侦测按键从抬起到落下,即使一直按住按键,函数也只会执行一次。
update()更新状态
update是“更新”的意思,游戏运行时,会不断地重复调用update()函数,写在函数中的代码会不断地重复执行。
更新状态:update()
程序会以60次/秒的速度不停地调用update()函数,函数中的代码会不断地重复执行,直到游戏结束。
py
代码语言:javascript复制def update():
函数体
py
代码语言:javascript复制weapons = []
def draw():
screen.blit('星球', [0,0])
player.draw()
for w in weapons: #遍历存储所有子弹角色的列表,依次绘制每个子弹
w.draw()
def on_key_down(key):
#按下空格键创建子弹角色
if key == keys.SPACE:
weapon = Actor('子弹')
weapon.x = player.x
weapon.y = player.y
weapons.append(weapon)
def update():
#在update()中让每个子弹的y坐标减小5,子弹会一直向上飞
for w in weapons:
w.y -= 5
on_key_down()和update()下都可以书写键盘控制的代码。
py
代码语言:javascript复制def on_key_down(key):
if key == keys.LEFT:
player.x -= 5
if key == keys.RIGHT:
player.y = 5
实现每按下左、右方向键时,角色会对应向左右移动一次。
py
代码语言:javascript复制key == keys.按键
按键 —-> 大写字母
py
代码语言:javascript复制def update():
if keyboard.left:
player.x -= 5
if keyboard.right
plaer.x = 5
实现每按下左、右方向键时,角色会对应向左右移动,如果按住不放,角色可以连续移动。
py
代码语言:javascript复制keyboard.按键
按键 —-> 小写字母
总结
运行机制 on_key_down()函数,只有按下按键时,会执行一次; update()函数,在程序启动之后就一直重复执行。
按键判断
on_key_down()函数
可以通过参数key
来判断哪个按键被按下。
而update()函数
没有参数,要通过keyboard.键
的形式判断。
在update()中实现了通过按住键不放,控制子弹连续发射以及小核桃的连续移动。
BUBU兽的随机重复出现
游戏中,3只BUBU兽从窗口最上方随机位置出现,飞出窗口之后,还会重新回到窗口最上方。
BUBU兽在随机位置出现
py
代码语言:javascript复制bubus = []
for i in range(3):
b = Actor('bubu')
b.x = random.randint(0,500)
bubus.append(b)
创建BUBU兽角色,设置随机的初始位置。 ◆ 生成随机数:
py
代码语言:javascript复制random.randint(起始数,结束数)
BUBU兽随机重复地出现
py
代码语言:javascript复制def update():
for b in bubus:
if b.y > 700:
b.x = random.randint(0,500)
b.y = 0
角色如果飞出边界,就重新设置它的坐标。
◆判断条件: 'b.y > 700'
是根据窗口大小,以及要飞出哪个边界来确定的。
实现角色的随机重复移动:先使用random.randint()设置初始位置,再使用if判断坐标,超出范围就重新设置初始坐标。
colliderect()碰撞检测
colliderect()
用于判断两个角色是否发生碰撞,如果发生碰撞返回True,没有发生碰撞返回False。
碰撞检测:colliderect()
格式: 角色1.colliderect(角色2)
py
代码语言:javascript复制if hemu.colliderect(xiaohetao):
print('碰到了~~')
◆colliderect函数的返回值是布尔类型,因此常作为if后的判断条件。 游戏中,BUBU兽碰到子弹后,重新设置BUBU兽的初始坐标。
py
代码语言:javascript复制#bubu兽和子弹碰撞后回到初始位置
for b in bubus:
for w in weapons:
if b.colliderect(w):
b.x = random.randint(0,500)
b.y = 0
游戏结束
bubu兽碰到了小核桃,游戏结束,小核桃切换失败造型。
设置角色造型
格式:角色.image = 图片名
py
代码语言:javascript复制for b in bubus:
if b.colliderect(player):
player.image = '小核桃失败'
◆ 遍历bubus列表,如果bubu兽碰到了小核桃,小核桃切换成失败造型。
游戏结束以后还要清空窗口的子弹角色和bubu兽角色。
py
代码语言:javascript复制def draw():
screen.blit('星球', pos=[0,0])
player.draw()
if player.image != '小核桃失败'
for w in weapons:
w.draw()
for b in bubus:
b.draw()
◆ 只要小核桃不是失败造型,游戏就没有结束,需要绘制子弹和BUBU兽, 否则就不再绘制了。
背景音乐
pygame中可以使用music模块,给游戏添加音效。让游戏变得更加生动有趣。
播放音乐
py
代码语言:javascript复制music.play(音乐名)
停止播放音乐
py
代码语言:javascript复制music.stop()
游戏启动前,播放音乐,小核桃碰到了bubu兽,音乐停止。
py
代码语言:javascript复制def update():
for b in bubus:
if b.colliderect(player):
player.image = '小核桃失败'
music.stop()
music.play('music1')
pgzrun.go()
注意:播放音乐的代码需要书写在pgzrun.go()之前。