用户:淏芃查看:0 回复:1 评论:0 创建时间:2020-07-27T22:29:08
【作品展示】

【作品介绍】
pygame制作新增速度等级
版本V5.0
【作品源代码】
# 修复缓动和已知bug,新增速度等级功能
"""速度等级规则"""
"""0分等级1"""
"""1000分等级2"""
"""5000分等级3"""
"""10000分等级4"""
"""100000分等级5"""
"""1000000分等级10"""
#PS:SpeedLevel是速度等级,Score是分数
#小贴士:越过障碍物+100分,碰撞金币+1000分
''' 主程序 '''
import sys
import time
from initData import *
from easing import *
pygame.init()
# 障碍物列表
barrierList = []
# 自定义事件
ADDBARIER = pygame.USEREVENT + 1
# 自定义事件(角色动画)
ANIMATION = pygame.USEREVENT + 2
# 自定义事件(角色跳跃)
JUMP = pygame.USEREVENT + 3
# 自定义事件(角色掉落)
DROP = pygame.USEREVENT + 4
# 障碍物生成频率
BARRIERFPS = 0.6
# 主循环频率
FPS = 喵00000
# 获取时钟对象
clock = pygame.time.Clock()
# 游戏初始状态
gameState = GAMEREADY
# 记录游戏分数
score = 0
# 角色生命数
hp = 3
# 背景&地面&障碍物的移动速度
speed = 2
speed1 = 4
# 速度等级
speedLevel = 1
# 碰撞次数
pong = 0
def times(times):
ctime = time.sleep(times)
return ctime
# 启动定时器
def startTimer():
pygame.time.set_timer(ADDBARIER, int(1000/BARRIERFPS))
pygame.time.set_timer(ANIMATION, int(1000/player['animationFPS']))
# 停止定时器
def stopTimer():
pygame.time.set_timer(ADDBARIER, 0)
pygame.time.set_timer(ANIMATION, 0)
pygame.time.set_timer(JUMP, 0) # →→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
#初始化窗口
def initScreen():
global screen
# 创建窗口对象
screen = pygame.display.set_mode(SCREENSIZE)
# 设置窗口标题
pygame.display.set_caption('火柴人街头跑酷')
# 设置标题logo
pygame.display.set_icon(iconImg)
# 绘制
def draw():
screen.blit(bg['img'], [bg['x'], bg['y']])
screen.blit(bg['img'], [bg['x'] + bg['width'], bg['y']])
screen.blit(gd['img'], [gd['x'], gd['y']])
screen.blit(gd['img'], [gd['x'] + gd['width'], gd['y']])
screen.blit(player['img'], [player['x'], player['y']])
screen.blit(gold['img'], [gold['x'], gold['y']])
for barrier in barrierList:
screen.blit(barrier['img'], [barrier['x'], barrier['y']])
if gameState == GAMEOVER:
rect = overImg.get_rect()
rect.center = screen.get_rect().center
screen.blit(overImg, rect)
drawText(str(score), 'center', 30)
elif gameState == GAMERUNNING:
drawText('score:' + str(score),
(SCREENSIZE[0] - 200, 20), size=35, color=[0, 0, 0])
drawText('Speed Level:' + str(speedLevel),
(SCREENSIZE[0] - 400, 20), size=35, color=[0, 0, 0])
# 绘制准备界面
elif gameState == GAMEREADY:
rect = readyImg.get_rect()
rect.center = screen.get_rect().center
screen.blit(readyImg, rect)
# 绘制文本
def drawText(text, coordinate, size=35, color=[255, 255, 255]):
font = pygame.font.SysFont('SimHei', size)
content = font.render(text, True, color)
if coordinate == 'center':
rect = content.get_rect()
rect.center = screen.get_rect().center
coordinate = rect
screen.blit(content, coordinate)
# 移动
def move():
# 获取速度等级
speedlisten()
# 移动背景&地面
bg['x'] -= speed
if bg['x'] <= -bg['width']:
bg['x'] = 0
gd['x'] -= speed1
if gd['x'] <= -gd['width']:
gd['x'] = 0
# 移动障碍物
# 因为要从列表中删除元素,所以需要倒序遍历列表
for i in range(len(barrierList)-1, -1, -1):
barrier = barrierList[i]
# 感觉有多处需要自增自减,是否可以使用 -= 的形式
barrier['x'] -= speed1
if barrier['x'] <= -barrier['width']:
# 移出屏幕就从障碍物列表中删除该元素
barrierList.remove(barrierList[i])
# 移动金币
gold['x'] -= speed1
if gold['x'] <= -gold['width']:
setRandXY(gold, barrierList, player)
# 更新金币的坐标
def setRandXY(gold, group, player):
if len(group) != 0:
# 获取障碍物列表中的最后一个元素
lastBarrier = group[-1]
# 获取最后一个障碍物的x坐标
x = lastBarrier['x']
else:
# 没有障碍物时也要保证金币不会瞬间出现
x = SCREENSIZE[0]
# 根据最后一个障碍物x坐标计算金币图片x坐标
gold['x'] = x + random.randint(420, 750)
gold['y'] = random.randint(220 - player['height'], 330 - gold['height'])
# 角色起跳时的数据
def jumpPlayer():
# 主角在起跳时不能再执行起跳操作
if player['state'] == 'jumping':
while True:
return
# 更改主角状态为跳起
player['state'] = 'jumping'
# 主角跳起时要用的图片
player['img'] = runImgList[4]
# 跳起的起始时间
player['jumpTime'] = 0
# 跳起的起始Y坐标
player['jumpBegin'] = player['y']
# 跳起的高度
player['jumpHeight'] = -150
# 持续时间(分为跳起和落下两部分时间)
player['jumpDuring'] = 400
# 跳跃的状态,先跳起后落下
player['jumpStatus'] = 'up'
# 用于计算和设置主角跳起时的Y坐标
pygame.time.set_timer(JUMP, 10)
# 计算和设置角色跳起时的Y坐标
def setJumpY():
jumpTime = player['jumpTime']
jumpBegin = player['jumpBegin']
jumpHeight = player['jumpHeight']
jumpDuring = player['jumpDuring']
if player['jumpStatus'] == 'up':
player['y'] = easeOut(jumpTime, jumpBegin, jumpHeight, jumpDuring)
jumpTime += 10
player['jumpTime'] = jumpTime
if jumpTime > jumpDuring:
player['jumpTime'] = 0
player['jumpBegin'] = player['y']
player['jumpHeight'] = -player['jumpHeight']
player['jumpStatus'] = 'down'
elif player['jumpStatus'] == 'down':
player['y'] = easeIn(jumpTime, jumpBegin, jumpHeight, jumpDuring)
jumpTime += 10
player['jumpTime'] = jumpTime
if jumpTime > jumpDuring:
player['state'] = 'running'
# 这行目的防止事件队列中仍有该事件
player['jumpStatus'] = None
# 清除定时器
pygame.time.set_timer(JUMP, 0)
# 碰撞检测
def checkHit(ob1, ob2):
ob1Top = ob1['y']
ob1Bottom = ob1['y'] + ob1['height']
ob1Left = ob1['x']
ob1Right = ob1['x'] + ob1['width']
ob2Top = ob2['y']
ob2Bottom = ob2['y'] + ob2['height']
ob2Left = ob2['x']
ob2Right = ob2['x'] + ob2['width']
if ob1Right >= ob2Left and ob1Left <= ob2Right:
if ob1Bottom >= ob2Top and ob1Top <= ob2Bottom:
return True
# 这里的这个判断是星原哥为了防止学生使用该函数时传参顺序错误
else:
if 'ischeck' in ob1:
if ob1['x'] <= ob2['x']:
ob1['ischeck'] = True
elif 'ischeck' in ob2:
if ob2['x'] <= ob1['x']:
ob2['ischeck'] = True
# 讲解了函数没有返回值时默认返回None,None在判断时为False,此处是否要省略
return False
# 根据碰撞检测结果作出响应
def check():
global gameState, score, hp, pong
# 检测障碍物
for barrier in barrierList:
if checkHit(player, barrier):
gameState = GAMEOVER
dropPlayer()
break
else:
if barrier['ischeck'] and barrier['score']:
score += barrier['score']
barrier['score'] = None
# 检测金币
if checkHit(player, gold):
setRandXY(gold, barrierList, player)
score += 1000
# 主角掉落
def dropPlayer():
# 更改主角状态为掉落
player['status'] = 'dropping'
# 主角掉落时的图片
player['img'] = dropImg
# 初始化角色掉落数据
initDropData(player['x'], player['y'], 200,
SCREENSIZE[1] - player['y'] + 200, 600)
# 用于计算和设置主角掉落时的X、Y坐标
pygame.time.set_timer(DROP, 10)
# 用于存储主角掉落所需要的数据
dropData = {}
# 初始化主角要掉落时的数据
# x:起始X坐标,y:起始Y坐标,upHeight:要跳起的高度,downHeight:跳起后要下降的高度, during:整个跳起掉落持续的时间
def initDropData(x, y, upHeight, downHeight, during):
# 存储当前计算出的X坐标值
dropData['x'] = x
# 存储当前计算出的Y坐标值
dropData['y'] = y
# 掉落的起始时间
dropData['time'] = 0
# 掉落的起始Y坐标
dropData['begin'] = y
# 用于存储跳起和下落的高度,初始值为要跳起的高度
dropData['height'] = -upHeight
# 掉落的下降高度
dropData['downHeight'] = downHeight
# 掉落的持续时间(分为跳起和下落)
dropData['during'] = during
# 掉落的状态,先跳起后下落
dropData['status'] = 'up'
# 计算和设置主角掉落时的X、Y坐标
def setDropXY():
x, y = getDropXY()
# 如果掉落完成,关闭定时器
if x == -1:
pygame.time.set_timer(DROP, 0)
else:
player['x'] = x
player['y'] = y
# 计算和设置主角掉落时的X、Y坐标
def getDropXY():
time = dropData['time']
begin = dropData['begin']
height = dropData['height']
during = dropData['during']
if dropData['status'] == 'up':
time += 10
dropData['x'] += 3
dropData['y'] = easeOut(time, begin, height, during)
dropData['time'] = time
if time >= during:
dropData['time'] = 0
dropData['begin'] = dropData['y']
dropData['height'] = dropData['downHeight']
dropData['status'] = 'down'
elif dropData['status'] == 'down':
time += 10
dropData['x'] += 3
dropData['y'] = easeIn(time, begin, height, during)
dropData['time'] = time
# 如果掉落动作完成,则返回-1
if time > during:
return -1, -1
return dropData['x'], dropData['y']
#事件监听
def eventListen():
global gameState, player, barrierList, gd, bg, gold, score, speedLevel
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
sys.exit()
# 加入准备状态判断
if gameState == GAMEREADY:
if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
gameState = GAMERUNNING
startTimer()
elif gameState == GAMERUNNING:
if event.type == ADDBARIER:
barrierList.append(getBarrier())
elif event.type == ANIMATION and player['state'] == 'running':
animation(player)
elif event.type == pygame.KEYDOWN and event.key in [pygame.K_SPACE, pygame.K_w, pygame.K_UP]:
jumpPlayer()
elif event.type == JUMP:
setJumpY()
elif gameState == GAMEOVER:
if event.type == DROP:
setDropXY()
# 判断是否要进行重玩操作
elif event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
# 初始化数据
# 角色
player['x'] = 60
player['y'] = 330 - runImgList[0].get_rect().height
player['state'] = 'running'
# 障碍物
barrierList = []
# 地面
gd['x'] = 0
gd['y'] = 330
# 背景
bg['x'] = 0
bg['y'] = 0
# 金币
gold['x'] = 0
gold['y'] = 0
# 分数
score = 0
# 移动速度
speedLecel = 1
# 障碍物生成速度
BERRIERFPS = 0.5
# 启动定时器
startTimer()
# 更改游戏状态
gameState = GAMERUNNING
# 角色动画
def animation(role):
index = role['imgIndex'] + 1
if index >= len(runImgList):
index = 0
role['img'] = runImgList[index]
role['imgIndex'] = index
def speedlisten():
global speed, speed1, BARRIERFPS, speedLevel
if score <= 1000:
speed = 2
speed1 = 4
speedLevel = 1
if score >= 1000:
speed = 4
speed1 = 6
speedLevel = 2
if score >= 5000:
speed = 7
speed1 = 9
speedLevel = 3
if score >= 10000:
speed = 10
speed1 = 15
speedLevel = 4
if score >= 100000:
speed = 15
speed1 = 20
speedLevel = 5
if score >= 1000000:
speed = 30
speed1 = 40
speedLevel = 10
initScreen()
setRandXY(gold, barrierList, player)
while True:
clock.tick(FPS)
# 监听窗口
eventListen()
draw()
if gameState == GAMERUNNING:
move()
check()
elif gameState == GAMEOVER:
stopTimer()
pygame.display.update()
【提示】
部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:
https://python.codemao.cn