用户:英俊小子查看:0 回复:7 评论:0 创建时间:2021-07-13T12:07:10
【作品展示】

【作品介绍】
你能成为长隆喵地上的松鼠霸主吗?(按上下左右、wasd移动。吃掉比你小的松鼠,不要去招惹比你大的松鼠。喵地很大,没有边界)
【作品源代码】
import random,sys,time,math,pygame
from pygame.locals import*
fps=30
kuan=喵0
gao=480
x_kuan=int(kuan/2)
x_gao=int(gao/2)
caos=(24,255,0)
bai=(255,255,255)
hong=(255,0,0)
cameraslack = 90 # 松鼠移动相机前离中心多远
moverate = 9 # 玩家移动的速度
bouncerate = 6 # 玩家弹跳的速度(大的更慢)
bounceheight = 30 # 玩家弹跳的高度
startsize = 25 # 播放器开始时有多大
winsize = 300 # 玩家需要多大才能获胜
invulntime = 2 # 玩家被击中后喵时间的秒数
gameovertime = 3 # “游戏结束”文本在屏幕上停留的时间(以秒为单位)
maxhealth = 3 # 玩家开始时的生命值
numgrass = 80 # 活动区域的喵物体数量ttf
numsquirrels = 30 # 活动区域的松鼠数量
squirrelminspeed = 3 # 最慢的松鼠速度
squirrelmaxspeed = 7 # 最快的松鼠速度
dirchangefreq = 2 # % 每帧方向改变的机会
left = 'left'
right='right'
"""
该程序具有三种数据结构,分别代表玩家、敌对松鼠和喵背景对象。数据结构是具有以下键的字典:
所有三种数据结构使用的键:
'x' - 游戏世界中对象的左边缘坐标(不是屏幕上的像素坐标)
'y' - 游戏世界中对象的上边缘坐标(不是屏幕上的像素坐标)
'rect' - pygame.Rect 对象,表示对象在屏幕上的位置。
播放器数据结构键:
'surface' - pygame.Surface 对象,用于存储将被绘制到屏幕上的松鼠图像。
'face' - 设置为 LEFT 或 RIGHT,存储玩家面向的方向。
'size' - 播放器的宽度和高度(以像素为单位)。(宽度和高度始终相同。)
'bounce' - 表示玩家在弹跳中的哪个点。0 表示站立(没有弹跳),直到 BOUNCERATE(弹跳完成)
'health' - 一个整数,显示玩家在喵亡之前可以被更大的松鼠击中多少次。
Enemy Squirrel 数据结构键:
'surface' - pygame.Surface 对象,用于存储将被绘制到屏幕上的松鼠图像。
'movex' - 每帧松鼠水平移动的像素数。负整数向左移动,正整数向右移动。
'movey' - 每帧松鼠垂直移动的像素数。负整数向上移动,正整数向下移动。
'width' - 松鼠图像的宽度,以像素为单位
'height' - 松鼠图像的高度,以像素为单位
'bounce' - 表示玩家在弹跳中的哪个点。0 表示站立(没有弹跳),直到 BOUNCERATE(弹跳完成)
'bouncerate' - 松鼠弹跳的速度。较低的数字意味着更快的反弹。
'bounceheight' - 松鼠弹跳的高度(以像素为单位)
喵数据结构键:
'grassImage' - 一个整数,指的是用于此喵对象的 GRASSIMAGES 中 pygame.Surface 对象的索引
"""
def main():
global fpsclock,displaysurf,basicfont,l_squir_img,r_squir_img,grassimages
pygame.init()
fpsclock=pygame.time.Clock()
pygame.display.set_icon(pygame.image.load('gameicon.png'))
displaysurf=pygame.display.set_mode((kuan,gao))
pygame.display.set_caption('松鼠争霸')
basicfont = pygame.font.Font('a.ttf', 32)
l_squir_img = pygame.image.load('squirrel.png')
r_squir_img=pygame.transform.flip(l_squir_img,True,False)
grassimages=[]
for i in range(1,5):
grassimages.append(pygame.image.load('grass%s.png'%i))
while True:
runGame()
def runGame():
# 为新游戏的开始设置变量
invulnerablemode=False# 如果玩家喵
invulnerablestarttime=0# 玩家变得喵的时间
gameovermode=False#如果玩家输了
gameoverstarttime=0# 玩家失败的时间
winmode=False# 如果玩家赢了
# 创建表面来保存游戏文本
gameoversurf=basicfont.render('你输了',True,bai)
gameoverrect=gameoversurf.get_rect()
gameoverrect.center=(x_kuan,x_gao)
winsurf=basicfont.render('你成为了长隆喵地上的霸主',True,bai)
winrect=winsurf.get_rect()
winrect.center=(x_kuan,x_gao)
winsurf2=basicfont.render('(点击r重新开始)',True,bai)
winrect2=winsurf2.get_rect()
winrect2.center=(x_kuan,x_gao+30)
# camerax 和 cameray 是相机视图所在位置的左上角
camerax=0
cameray=0
grassobjs=[]# 存储游戏中的所有喵对象
squirrelobjs=[]# 存储所有非玩家松鼠对象
# 存储玩家对象:
playerobj={'surface':pygame.transform.scale(l_squir_img,(startsize,startsize)),
'facing':left,
'size':startsize,
'x':x_kuan,
'y':x_gao,
'bounce':0,
'health':maxhealth}
moveleft=False
moveright=False
moveup=False
movedown=False
# 从屏幕上的一些随机喵图像开始
for i in range(10):
grassobjs.append(makenewgrass(camerax,cameray))
grassobjs[i]['x']=random.randint(0,kuan)
grassobjs[i]['y']=random.randint(0,gao)
while True:# 主游戏循环
# 检查我们是否应该关闭喵
if invulnerablemode and time.time()-invulnerablestarttime>invulntime:
invulnerablemode=False
# 移动所有的松鼠
for sobj in squirrelobjs:
# 移动松鼠,并调整它们的弹跳
sobj['x'] += sobj['movex']
sobj['y'] += sobj['movey']
sobj['bounce'] += 1
if sobj['bounce']>sobj['bouncerate']:
sobj['bounce'] = 0 # 重置反弹量
# 他们改变方向的随机机会
if random.randint(0,99) 0: # 面朝右
sobj['surface'] = pygame.transform.scale(
r_squir_img, (sobj['kuan'], sobj['gao']))
else:#面朝左
sobj['surface'] = pygame.transform.scale(
l_squir_img, (sobj['kuan'], sobj['gao']))
# 遍历所有对象,看看是否有需要删除的对象
for i in range(len(grassobjs)-1 ,-1 ,-1):
if isoutsiedactivearea(camerax,cameray,grassobjs[i]):
del grassobjs[i]
for i in range(len(squirrelobjs)-1, -1, -1):
if isoutsiedactivearea(camerax, cameray, squirrelobjs[i]):
del squirrelobjs[i]
# 如果我们没有足够的喵和松鼠,请添加更多的喵和松鼠
while len(grassobjs) cameraslack:
camerax = playercenterx + cameraslack - x_kuan
elif playercenterx - (camerax + x_kuan) > cameraslack:
camerax = playercenterx - cameraslack - x_kuan
if (cameray + x_gao) - playercentery > cameraslack:
cameray = playercentery + cameraslack - x_gao
elif playercentery - (cameray + x_gao) > cameraslack:
cameray = playercentery - cameraslack - x_gao
# 绘制绿色背景
displaysurf.fill(caos)
# 在屏幕上绘制所有喵物体
for gobj in grassobjs:
grect=pygame.Rect( (gobj['x']-camerax,
gobj['y']-cameray,
gobj['kuan'],
gobj['gao']))
displaysurf.blit(grassimages[gobj['grassimage']],grect)
# 绘制其他松鼠
for sobj in squirrelobjs:
sobj['rect']=pygame.Rect((sobj['x']-camerax,
sobj['y']-cameray-getBounceAmount(sobj['bounce'],sobj['bouncerate'],sobj['bounceheight']),
sobj['kuan'],
sobj['gao']))
displaysurf.blit(sobj['surface'],sobj['rect'])
# 绘制玩家松鼠
flashison=round(time.time(),1)*10%2==1
if not gameovermode and not (invulnerablemode and flashison):
playerobj['rect']=pygame.Rect((playerobj['x']-camerax,
playerobj['y']-cameray-getBounceAmount(playerobj['bounce'],bouncerate,bounceheight),
playerobj['size'],
playerobj['size']))
displaysurf.blit(playerobj['surface'], playerobj['rect'])
# 绘制健康表
drawhealthmeter(playerobj['health'])
for event in pygame.event.get(): # 事件处理循环
if event.type==QUIT:
terminate()
elif event.type==KEYDOWN:
if event.key in (K_UP,K_w):
movedown=False
moveup=True
elif event.key in (K_DOWN, K_s):
movedown = True
moveup = False
elif event.key in (K_LEFT, K_a):
moveright = False
moveleft = True
if playerobj['facing']==right:#调换图像
playerobj['surface']=pygame.transform.scale(
l_squir_img,(playerobj['size'],playerobj['size']))
playerobj['facing']=left
elif event.key in (K_RIGHT, K_d):
moveright = True
moveleft = False
if playerobj['facing'] == left:
playerobj['surface'] = pygame.transform.scale(
r_squir_img, (playerobj['size'], playerobj['size']))
playerobj['facing'] = right
elif winmode and event.key==K_r:
return
elif event.type==KEYUP:
#松开按键
if event.key in (K_LEFT,K_a):
moveleft=False
elif event.key in (K_RIGHT, K_d):
moveright = False
elif event.key in (K_UP, K_w):
moveup = False
elif event.key in (K_DOWN, K_s):
movedown = False
elif event.key==K_ESCAPE:
terminate()
if not gameovermode:
# 实际移动玩家
if moveleft:
playerobj['x']-=moverate
if moveright:
playerobj['x']+=moverate
if moveup:
playerobj['y']-=moverate
if movedown:
playerobj['y']+=moverate
if (moveleft or moveright or moveup or movedown) or playerobj['bounce']!=0:
playerobj['bounce']+=1
if playerobj['bounce']>bouncerate:
playerobj['bounce'] = 0 # 重置反弹量
# 检查玩家是否与任何松鼠发生碰撞
for i in range(len(squirrelobjs)-1,-1,-1):
sqobj=squirrelobjs[i]
if 'rect' in sqobj and playerobj['rect'].colliderect(sqobj['rect']):
# 发生了玩家/松鼠碰撞
if sqobj['kuan']*sqobj['gao']<=playerobj['size']**2:
# 玩家更大,吃松鼠
playerobj['size']+=int((sqobj['kuan']*sqobj['gao'])**0.2)+1
del squirrelobjs[i]
if playerobj['facing']==left:
playerobj['surface']=pygame.transform.scale(
l_squir_img,(playerobj['size'],playerobj['size']))
if playerobj['facing'] == right:
playerobj['surface'] = pygame.transform.scale(
r_squir_img, (playerobj['size'], playerobj['size']))
if playerobj['size']>winsize:
winmode = True # 打开“赢模式”
elif not invulnerablemode:
# 玩家变小并受到伤害
invulnerablemode=True
invulnerablestarttime=time.time()
playerobj['health']-=1
if playerobj['health']==0:
gameovermode = True # 开启“游戏结束模式”
gameoverstarttime = time.time()
else: # 游戏结束,显示“游戏结束”文本
displaysurf.blit(gameoversurf,gameoverrect)
if time.time()-gameoverstarttime>gameovertime:
return # 结束当前游戏
# 检查玩家是否赢了
if winmode:
displaysurf.blit(winsurf,winrect)
displaysurf.blit(winsurf2, winrect2)
pygame.display.update()
fpsclock.tick(fps)
def drawhealthmeter(currenthealth):
for i in range(currenthealth):#绘制生命表红块
pygame.draw.rect(displaysurf,hong,(15,5+(10*maxhealth)-i*10,20,10))
for i in range(maxhealth):#绘制生命表白色轮廓
pygame.draw.rect(displaysurf, bai,(15, 5+(10*maxhealth)-i*10, 20, 10),1)
def terminate():
pygame.quit()
sys.exit()
def getBounceAmount(currentbounce,bouncerate,bouncegao):
# 根据反弹返回要偏移的像素数。
# 较大的反弹率意味着较慢的反弹。
# 更大的反弹高度意味着更高的反弹。
# currentbounce 总是小于bouncerate
return int(math.sin((math.pi/float(bouncerate))*currentbounce)*bouncegao)
def getrandomvelocity():
speed=random.randint(squirrelminspeed,squirrelmaxspeed)
if random.randint(0,1)==0:
return speed
else:
return -speed
def getrandomoffcamerapos(camerax,cameray,objkuan,objgao):
# 创建一个相机视图的矩形
camerarect=pygame.Rect(camerax,cameray,kuan,gao)
while True:
x=random.randint(camerax-kuan,camerax+(2*kuan))
y=random.randint(cameray-gao,cameray+(2*gao))
# 创建一个带有随机坐标的 Rect 对象并使用colliderect()
# 确保右边缘不在相机视图中。
objrect=pygame.Rect(x,y,objkuan,objgao)
if not objrect.colliderect(camerarect):
return x,y
def makenewsquirrel(camerax,cameray):
sq={}
generalSize = random.randint(5, 25)
multiplier = random.randint(1, 3)
sq['kuan'] = (generalSize + random.randint(0, 10)) * multiplier
sq['gao'] = (generalSize + random.randint(0, 10)) * multiplier
sq['x'], sq['y'] = getrandomoffcamerapos(
camerax, cameray, sq['kuan'], sq['gao'])
sq['movex'] = getrandomvelocity()
sq['movey'] = getrandomvelocity()
if sq['movex'] < 0: # 松鼠面向左边
sq['surface'] = pygame.transform.scale(
l_squir_img, (sq['kuan'], sq['gao']))
else: # 松鼠向右边
sq['surface'] = pygame.transform.scale(
r_squir_img, (sq['kuan'], sq['gao']))
sq['bounce'] = 0
sq['bouncerate'] = random.randint(10, 18)
sq['bounceheight'] = random.randint(10, 50)
return sq
def makenewgrass(camerax,cameray):
gr={}
gr['grassimage']=random.randint(0,len(grassimages)-1)
gr['kuan']=grassimages[0].get_width()
gr['gao'] = grassimages[0].get_height()
gr['x'],gr['y']=getrandomoffcamerapos(camerax,cameray,gr['kuan'],gr['gao'])
gr['rect']=pygame.Rect((gr['x'],gr['y'],gr['kuan'],gr['gao']))
return gr
def isoutsiedactivearea(camerax,cameray,obj):
# 如果camerax和cameray超过
#一半,则返回False - 超出窗口边缘的窗口长度。
boundsleftedge=camerax-kuan
boundstopedge=cameray-gao
boundsrect=pygame.Rect(boundsleftedge,boundstopedge,kuan*3,gao*3)
objrect=pygame.Rect(obj['x'],obj['y'],obj['kuan'],obj['gao'])
return not boundsrect.colliderect(objrect)
if __name__ == '__main__':
main()
【提示】
部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:
https://python.codemao.cn