写简单游戏,学编程语言-python篇:大鱼吃小鱼

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

很常见的游戏之一,实现原理并不复杂,并且参考了几个相关的代码。这边主要还是以学习编程语言和学习编程思路为重点记录一下吧。最近时间有点吃紧,只能匆忙记录一下。用pygame做的大鱼吃小鱼的游戏截图如下:(有些鱼的图片背景没有做透明处理,这块确实需要点美工时间,只能先凑合了)。

下面的图片是网上随便找的素材,这里用于切换主角的图片有三张,其他则是其他小鱼和boss鱼。我们控制的主人鱼的大小范围来决定加载不同的图片。以上准备的素材,其中一些背景色没有时间做处理,所以游戏中会有难看的背景色,只能凑合着用。。。

一、玩法及逻辑相关:

控制你的鱼,有个初始大小,当碰到比你小的鱼的时候,你会吃掉它,并且会变大;遇到比你大的鱼,受到一点伤害,当总生命值为0时,失败游戏结束;当你控制的鱼大小增大最大时,游戏获胜。当鱼受到伤害时,有一段时间是无敌时间,且会闪烁。下面是主要的逻辑处理代码

1FlashIsOn=round(time.time(),1)*10%2==12ifnotgameOverModeandnot(invulnerableModeandflashIsOn):3playerobj['rect']=pygame.Rect((playerobj['x']-camerax,playerobj['y']4-cameray,playerobj['size'],playerobj['size']))5SCREEN.blit(playerobj['surface'],playerobj['rect'])6foreventinpygame.event.get():7ifevent.type ==QUIT:8pygame.quit()9sys.exit()10elifevent.type==KEYDOWN:11ifevent.keyin(K_UP,K_w):12moveDown =False13moveUp =True14elifevent.keyin(K_DOWN,K_s):15moveDown =True16moveUp =False17elifevent.keyin(K_LEFT,K_a):18moveRight =False19moveLeft=True20ifplayerobj['facing']==RIGHT:21playerobj['surface']=playersurfaceset(playerobj['size'], True)22playerobj['facing']=LEFT23elifevent.keyin(K_RIGHT,K_d):24moveRight =True25moveLeft=False26ifplayerobj['facing']==LEFT:27playerobj['surface']=playersurfaceset(playerobj['size'], False)28playerobj['facing']=RIGHT29elifwinModeandevent.key ==K_r:30return31elifevent.type==KEYUP:32ifevent.keyin(K_LEFT,K_a):33moveLeft=False34elifevent.keyin(K_RIGHT,K_d):35moveRight=False36elifevent.keyin(K_UP,K_w):37moveRight=False38elifevent.keyin(K_DOWN,K_s):39moveRight=False40ifnotgameOverMode:41ifmoveLeft:42playerobj['x']-=MOVESPEED43ifmoveRight:44playerobj['x']+=MOVESPEED45ifmoveUp:46playerobj['y']-=MOVESPEED47ifmoveDown:48playerobj['y']+=MOVESPEED49foriinrange(len(fishobjs)-1,-1,-1):50obj=fishobjs[i]51if'rect'inobjandplayerobj['rect'].colliderect(obj['rect']):52ifobj['width']*obj['height']<=playerobj['size']**2:53playerobj['size']+=int((obj['width']*obj['height'])**0.2)54delfishobjs[i]55ifplayerobj['face']==LEFT:56playerobj['surface']=playersurfaceset(playerobj['size'],True)57ifplayerobj['face']==RIGHT:58playerobj['surface']=playersurfaceset(playerobj['size'],False)59ifplayerobj['size']>WINSIZE:60winMode=True61elifnotinvulnerableMode:62invulnerableMode=True63invulnerableStartTime=time.time()64playerobj['health']-=165ifplayerobj['health']==0:66gameOverMode =True67gameOverStartTime=time.time()

View Code

主人公的控制类似一般的处理,这边用flashIsonl来生成时间差(偶数值时间为真)playersurfaceset()函数决定主人公的图片类型。

二、敌方鱼的生成处理

上篇做的敌方的处理会在当前视口随即出现,这个突兀感太强,鱼的出现也不能随机显示在当前视口,应该由摄像机视角之外生成才符合常理。并且当鱼离摄像区域太远的距离,需要删除掉鱼对象。

1foriinrange(len(fishobjs)-1,-1,-1):2ifisOutsideArea(camerax,cameray,fishobjs[i]):3delfishobjs[i]4whilelen(fishobjs)<10:5fishobjs.append(makeNewfish(camerax,cameray))

1defmakeNewfish(camerax,cameray):2sq={}3generalSize=random.randint(5,25)4multiplier = random.randint(1,3)5sq['width'] = (generalSize +random.randint(0,10))*multiplier6sq['height']= (generalSize +random.randint(0,10))*multiplier7sq['x'],sq['y']=getRandomoffCameraPos(camerax,cameray,sq['width'],sq['height'])8sq['movx'] =getRandomVelcocity()9sq['movy'] =getRandomVelcocity()10ifsq['movx']<0:11sq['surface']=surfaceset(sq['width'],sq['height'],True)12else:13sq['surface']=surfaceset(sq['width'],sq['height'],False)14returnsq

三、跟随视角的处理

这个主要是跟随主人公视角的问题,计算出主人公的中心点距离摄像机中心点的距离,当距离偏大的时候,需要移动摄像机的位置,具体处理代码如下:

1playerCenterx=playerobj['x']+int(playerobj['size']/2)2playerCentery=playerobj['y']+int(playerobj['size']/2)3if(camerax+HALF_WINWIDTH)-playerCenterx>CAMERASLACK:4camerax=playerCenterx+CAMERASLACK-HALF_WINWIDTH5elifplayerCenterx-(camerax+HALF_WINWIDTH)>CAMERASLACK:6camerax=playerCenterx-CAMERASLACK-HALF_WINWIDTH7if(cameray+HALF_WINHEIGHT)-playerCentery>CAMERASLACK:8cameray=playerCentery+CAMERASLACK-HALF_WINHEIGHT9elifplayerCentery-(camerax+HALF_WINHEIGHT)>CAMERASLACK:10cameray=playerCentery-CAMERASLACK-HALF_WINHEIGHT

大部分应该介绍的应该就这些了,只能说游戏这块水比较深,只能浅尝辄止一番,python做游戏只能简单玩玩,这块不是他的优势。有人感兴趣的话可以研究它,推荐一本不错的书《Making games with python $ pygame》,哎 只能说有巨人的肩膀上站真好。

园友交流群:21735072 有兴趣请加入~欢迎来灌水~~~~ 注明:博客园

附全部源代码如下,比较粗陋,建议以书上源码学习为主:

importpygame,sys,time,randomfrompygame.localsimport*WINWIDTH=640WINHEIGHT=480CAMERASLACK=70lfish_img=[]

FISHSIZE=8PLAYERSIZE=3SCREEN=None

rfish_img=[]

lplayer_img=[]

rplayer_img=[]

backgroundimg=None

rboss_img=None

lboss_img=None

FPS=30WHITE=[255,255,255]

MAXHEALTH=3MINSPEED=3MAXSPEED=9MOVESPEED=7HALF_WINWIDTH=int(WINWIDTH/2)

HALF_WINHEIGHT=int(WINHEIGHT/2)

WINSIZE=300defmain():globalFPSCLOCK,SCREEN,lfish_img,rfish_img,lplayer_img,rplayer_img,BASICFONT\

,rboss_img,lboss_img,backgroundimg

pygame.init()

FPSCLOCK=pygame.time.Clock()

SCREEN=pygame.display.set_mode((WINWIDTH,WINHEIGHT))

pygame.display.set_caption("fish eat fish")

BASICFONT=pygame.font.Font("freesansbold.ttf",32)foriinrange(FISHSIZE):

fishimg=pygame.image.load("Fish%s.bmp"%i)

fishimg.set_colorkey(WHITE)

lfish_img.append(fishimg)

rfishimg=pygame.transform.flip(fishimg,True,False)

rfish_img.append(rfishimg)foriinrange(PLAYERSIZE):

playerimg=pygame.image.load("player%s.png"%i)

playerimg.set_colorkey(WHITE)

lplayer_img.append(playerimg)

rplayerimg=pygame.transform.flip(playerimg,True,False)

rplayerimg.set_colorkey(WHITE)

rplayer_img.append(rplayerimg)

bossimg=pygame.image.load("boss.png")#bossimg.set_colorkey([0,0,0])#SCREEN.blit(bossimg,(0,0))lboss_img=bossimg

rbossimg=pygame.transform.flip(bossimg,True,False)

rboss_img=rbossimg

backgroundimg=pygame.image.load("background.jpg")whileTrue:

runGame()defrunGame():

invulnerableMode=False

invulnerableStartTime=0

gameOverMode=False

gameOverStartTime=0

winMode=False

gameOverSurf=BASICFONT.render('Game Over',True,WHITE)

gameOverRect=gameOverSurf.get_rect()

gameOverRect.center=(HALF_WINWIDTH,HALF_WINHEIGHT)

winSurf=BASICFONT.render('you succeed',True,WHITE)

winRect=winSurf.get_rect()

winRect.center=(HALF_WINWIDTH,HALF_WINHEIGHT)

winSurf2=BASICFONT.render('you succeed',True,WHITE)

winRect2=winSurf2.get_rect()

winRect2.center=(HALF_WINWIDTH,HALF_WINHEIGHT+30)

camerax=0

cameray=0

LEFT=0

RIGHT=1fishobjs=[]

playerobj={'surface':pygame.transform.scale(lplayer_img[0],(25,25)),'size':25,'facing':LEFT,'x':HALF_WINWIDTH,'y':HALF_WINHEIGHT,'health':MAXHEALTH}

moveLeft=False

moveRight=False

moveUp=False

moveDown=FalsewhileTrue:ifinvulnerableModeandtime.time() - invulnerableStartTime>2:

invulnerableMode=Falseforsobjinfishobjs:

sobj['x']+=sobj['movx']

sobj['y']+=sobj['movy']foriinrange(len(fishobjs)-1,-1,-1):ifisOutsideArea(camerax,cameray,fishobjs[i]):delfishobjs[i]whilelen(fishobjs)<5:

fishobjs.append(makeNewfish(camerax,cameray))

playerCenterx=playerobj['x']+int(playerobj['size']/2)

playerCentery=playerobj['y']+int(playerobj['size']/2)if(camerax+HALF_WINWIDTH)-playerCenterx>CAMERASLACK:

camerax=playerCenterx+CAMERASLACK-HALF_WINWIDTHelifplayerCenterx-(camerax+HALF_WINWIDTH)>CAMERASLACK:

camerax=playerCenterx-CAMERASLACK-HALF_WINWIDTHif(cameray+HALF_WINHEIGHT)-playerCentery>CAMERASLACK:

cameray=playerCentery+CAMERASLACK-HALF_WINHEIGHTelifplayerCentery-(camerax+HALF_WINHEIGHT)>CAMERASLACK:

cameray=playerCentery-CAMERASLACK-HALF_WINHEIGHT

backrect=pygame.Rect((camerax-WINWIDTH,cameray-WINHEIGHT,WINWIDTH*3,WINHEIGHT*3))

newbackgroundimg=pygame.transform.scale(backgroundimg,(WINWIDTH*3,WINHEIGHT*3))

SCREEN.blit(newbackgroundimg,backrect)forobjinfishobjs:

obj['rect']=pygame.Rect((obj['x']-camerax,obj['y']-cameray,obj['width']

,obj['height']))

SCREEN.blit(obj['surface'],obj['rect'])

flashIsOn=round(time.time(),1)*10%2==1ifnotgameOverModeandnot(invulnerableModeandflashIsOn):

playerobj['rect']=pygame.Rect((playerobj['x']-camerax,playerobj['y']-cameray,playerobj['size'],playerobj['size']))

SCREEN.blit(playerobj['surface'],playerobj['rect'])foreventinpygame.event.get():ifevent.type ==QUIT:

pygame.quit()

sys.exit()elifevent.type==KEYDOWN:ifevent.keyin(K_UP,K_w):

moveDown=False

moveUp=Trueelifevent.keyin(K_DOWN,K_s):

moveDown=True

moveUp=Falseelifevent.keyin(K_LEFT,K_a):

moveRight=False

moveLeft=Trueifplayerobj['facing']==RIGHT:

playerobj['surface']=playersurfaceset(playerobj['size'], True)

playerobj['facing']=LEFTelifevent.keyin(K_RIGHT,K_d):

moveRight=True

moveLeft=Falseifplayerobj['facing']==LEFT:

playerobj['surface']=playersurfaceset(playerobj['size'], False)

playerobj['facing']=RIGHTelifwinModeandevent.key ==K_r:returnelifevent.type==KEYUP:ifevent.keyin(K_LEFT,K_a):

moveLeft=Falseelifevent.keyin(K_RIGHT,K_d):

moveRight=Falseelifevent.keyin(K_UP,K_w):

moveRight=Falseelifevent.keyin(K_DOWN,K_s):

moveRight=FalseifnotgameOverMode:ifmoveLeft:

playerobj['x']-=MOVESPEEDifmoveRight:

playerobj['x']+=MOVESPEEDifmoveUp:

playerobj['y']-=MOVESPEEDifmoveDown:

playerobj['y']+=MOVESPEEDforiinrange(len(fishobjs)-1,-1,-1):

obj=fishobjs[i]if'rect'inobjandplayerobj['rect'].colliderect(obj['rect']):ifobj['width']*obj['height']<=playerobj['size']**2:

playerobj['size']+=int((obj['width']*obj['height'])**0.2)delfishobjs[i]ifplayerobj['face']==LEFT:

playerobj['surface']=playersurfaceset(playerobj['size'],True)ifplayerobj['face']==RIGHT:

playerobj['surface']=playersurfaceset(playerobj['size'],False)ifplayerobj['size']>WINSIZE:

winMode=TrueelifnotinvulnerableMode:

invulnerableMode=True

invulnerableStartTime=time.time()

playerobj['health']-=1ifplayerobj['health']==0:

gameOverMode=True

gameOverStartTime=time.time()ifwinMode:

SCREEN.blit(winSurf,winRect)

SCREEN.blit(winSurf2,winRect2)

pygame.display.update()

FPSCLOCK.tick(FPS)defisOutsideArea(camerax,cameray,fishobj):

boundsLeftEdge=camerax-WINWIDTH

boundsTopEdge=cameray-WINHEIGHT

boundsRect=pygame.Rect(boundsLeftEdge,boundsTopEdge,WINWIDTH*3,WINHEIGHT*3)

objRect=pygame.Rect(fishobj['x'],fishobj['y'],fishobj['width'],fishobj['height'])returnnotboundsRect.colliderect(objRect)defmakeNewfish(camerax,cameray):

sq={}

generalSize=random.randint(5,25)

multiplier= random.randint(1,3)

sq['width'] = (generalSize +random.randint(0,10))*multiplier

sq['height']= (generalSize +random.randint(0,10))*multiplier

sq['x'],sq['y']=getRandomoffCameraPos(camerax,cameray,sq['width'],sq['height'])

sq['movx'] =getRandomVelcocity()

sq['movy'] =getRandomVelcocity()ifsq['movx']<0:

sq['surface']=surfaceset(sq['width'],sq['height'],True)else:

sq['surface']=surfaceset(sq['width'],sq['height'],False)returnsqdefplayersurfaceset(size,Face):

surface=Noneifsize<100:ifFace ==True:

surface=pygame.transform.scale(lplayer_img[0],(size,size))else:

surface=pygame.transform.scale(rplayer_img[0],(size,size))elifsize<200andsize>=100:ifFace ==True:

surface= pygame.transform.scale(lplayer_img[1],(size,size))else:

surface= pygame.transform.scale(rplayer_img[1],(size,size))else:ifFace ==True:

surface= pygame.transform.scale(lplayer_img[2],(size,size))else:

surface= pygame.transform.scale(rplayer_img[2],(size,size))returnsurfacedefsurfaceset(width,height,Face):

surface=Noneifwidth*height>200*200:ifFace ==True:

surface=pygame.transform.scale(lboss_img,(width,height))else:

surface=pygame.transform.scale(rboss_img,(width,height))else:

index= int((width*height)%(FISHSIZE-1))ifFace ==True:

surface=pygame.transform.scale(lfish_img[index],(width,height))else:

surface=pygame.transform.scale(rfish_img[index],(width,height))returnsurfacedefgetRandomVelcocity():

speed=random.randint(MINSPEED,MAXSPEED)ifrandom.randint(0,1):returnspeedelse:return-speeddefgetRandomoffCameraPos(camerax,cameray,objwidth,objheight):

cameraRect=pygame.Rect(camerax,cameray,WINWIDTH,WINHEIGHT)whileTrue:

x=random.randint(camerax-WINWIDTH,camerax+2*(WINWIDTH))

y=random.randint(camerax-WINHEIGHT,camerax+2*(WINHEIGHT))

objrect=pygame.Rect(x,y,objwidth,objheight)ifnotobjrect.colliderect(cameraRect):returnx,yif__name__=='__main__':

main()

View Code

ps:最近越来越懒了,不知道当初订的每周至少写一篇随笔的目标能否坚持下去。另外鄙视下12306上刷票的黄牛,刷了一天没买到票,哎 不说了都是泪。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航