首页 > 编程 > Python > 正文

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

2019-11-14 17:52:05
字体:
来源:转载
供稿:网友

 

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

   

 

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

一、玩法及逻辑相关:

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

  

 1        FlashIsOn=round(time.time(),1)*10%2==1 2         if not gameOverMode and not (invulnerableMode and flashIsOn): 3             playerobj['rect']=pygame.Rect((playerobj['x']-camerax,playerobj['y'] 4                                            -cameray,playerobj['size'],playerobj['size'])) 5             SCREEN.blit(playerobj['surface'],playerobj['rect']) 6         for event in pygame.event.get(): 7             if event.type == QUIT: 8                 pygame.quit() 9                 sys.exit()10             elif event.type==KEYDOWN:11                 if event.key in (K_UP,K_w):12                     moveDown =False13                     moveUp = True14                 elif event.key in (K_DOWN,K_s):15                     moveDown =True16                     moveUp = False17                 elif event.key in (K_LEFT,K_a):18                     moveRight = False19                     moveLeft= True20                     if playerobj['facing']==RIGHT:21                         playerobj['surface']=playersurfaceset(playerobj['size'], True)22                     playerobj['facing']=LEFT23                 elif event.key in (K_RIGHT,K_d):24                     moveRight = True25                     moveLeft= False26                     if playerobj['facing']==LEFT:27                         playerobj['surface']=playersurfaceset(playerobj['size'], False)28                     playerobj['facing']=RIGHT29                 elif winMode and event.key == K_r:30                     return31             elif event.type==KEYUP:32                     if event.key in (K_LEFT,K_a):33                         moveLeft=False34                     elif event.key in (K_RIGHT,K_d):35                         moveRight=False36                     elif event.key in (K_UP,K_w):37                         moveRight=False38                     elif event.key in (K_DOWN,K_s):39                         moveRight=False40             if not gameOverMode:41                 if moveLeft:42                     playerobj['x']-=MOVESPEED43                 if moveRight:44                     playerobj['x']+=MOVESPEED45                 if moveUp:46                     playerobj['y']-=MOVESPEED47                 if moveDown:48                     playerobj['y']+=MOVESPEED49                 for i in range(len(fishobjs)-1,-1,-1):50                     obj=fishobjs[i]51                     if 'rect' in obj and playerobj['rect'].colliderect(obj['rect']):52                         if obj['width']*obj['height']<=playerobj['size']**2:53                             playerobj['size']+=int((obj['width']*obj['height'])**0.2)54                             del fishobjs[i]55                             if playerobj['face']== LEFT:56                                 playerobj['surface']=playersurfaceset(playerobj['size'],True)57                             if playerobj['face']== RIGHT:58                                     playerobj['surface']=playersurfaceset(playerobj['size'],False)                 59                             if playerobj['size']>WINSIZE:60                                 winMode=True61                         elif not invulnerableMode:62                             invulnerableMode=True63                             invulnerableStartTime=time.time()64                             playerobj['health']-=165                             if playerobj['health']==0:66                                 gameOverMode =True67                                 gameOverStartTime=time.time()
View Code

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

二、敌方鱼的生成处理

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

1 for i in range(len(fishobjs)-1,-1,-1):2             if isOutsideArea(camerax,cameray,fishobjs[i]):3                 del fishobjs[i]4         while len(fishobjs)<10:5             fishobjs.append(makeNewfish(camerax,cameray))
 1 def makeNewfish(camerax,cameray): 2     sq={} 3     generalSize=random.randint(5,25) 4     multiplier = random.randint(1,3) 5     sq['width'] = (generalSize +random.randint(0,10))*multiplier 6     sq['height']= (generalSize +random.randint(0,10))*multiplier 7     sq['x'],sq['y']=getRandomoffCameraPos(camerax,cameray,sq['width'],sq['height']) 8     sq['movx'] = getRandomVelcocity() 9     sq['movy'] = getRandomVelcocity()10     if sq['movx']<0:11         sq['surface']=surfaceset(sq['width'],sq['height'],True)12     else:13         sq['surface']=surfaceset(sq['width'],sq['height'],False)14     return sq

三、跟随视角的处理

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

  

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

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

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

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

import pygame,sys,time,randomfrom pygame.locals import *WINWIDTH=640WINHEIGHT=480CAMERASLACK=70lfish_img=[]FISHSIZE=8PLAYERSIZE=3SCREEN=Nonerfish_img=[]lplayer_img=[]rplayer_img=[]backgroundimg=Nonerboss_img=Nonelboss_img=NoneFPS=30WHITE=[255,255,255]MAXHEALTH=3MINSPEED=3MAXSPEED=9MOVESPEED=7HALF_WINWIDTH=int(WINWIDTH/2)HALF_WINHEIGHT=int(WINHEIGHT/2)WINSIZE=300def main():    global FPSCLOCK,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)    for i in range(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)    for i in range(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")        while True:        runGame()def runGame():     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=1    fishobjs=[]    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 = False        while True:        if invulnerableMode and time.time() - invulnerableStartTime>2:            invulnerableMode =False        for sobj in fishobjs:            sobj['x']+=sobj['movx']            sobj['y']+=sobj['movy']                    for i in range(len(fishobjs)-1,-1,-1):            if isOutsideArea(camerax,cameray,fishobjs[i]):                del fishobjs[i]        while len(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_WINWIDTH        elif playerCenterx-(camerax+HALF_WINWIDTH)>CAMERASLACK:            camerax=playerCenterx-CAMERASLACK-HALF_WINWIDTH        if (cameray+HALF_WINHEIGHT)-playerCentery>CAMERASLACK:            cameray=playerCentery+CAMERASLACK-HALF_WINHEIGHT        elif playerCentery-(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)                for obj in fishobjs:            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==1        if not gameOverMode and not (invulnerableMode and flashIsOn):            playerobj['rect']=pygame.Rect((playerobj['x']-camerax,playerobj['y']                                           -cameray,playerobj['size'],playerobj['size']))            SCREEN.blit(playerobj['surface'],playerobj['rect'])        for event in pygame.event.get():            if event.type == QUIT:                pygame.quit()                sys.exit()            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']=playersurfaceset(playerobj['size'], True)                    playerobj['facing']=LEFT                elif event.key in (K_RIGHT,K_d):                    moveRight = True                    moveLeft= False                    if playerobj['facing']==LEFT:                        playerobj['surface']=playersurfaceset(playerobj['size'], False)                    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):                        moveRight=False                    elif event.key in (K_DOWN,K_s):                        moveRight=False            if not gameOverMode:                if moveLeft:                    playerobj['x']-=MOVESPEED                if moveRight:                    playerobj['x']+=MOVESPEED                if moveUp:                    playerobj['y']-=MOVESPEED                if moveDown:                    playerobj['y']+=MOVESPEED                for i in range(len(fishobjs)-1,-1,-1):                    obj=fishobjs[i]                    if 'rect' in obj and playerobj['rect'].colliderect(obj['rect']):                        if obj['width']*obj['height']<=playerobj['size']**2:                            playerobj['size']+=int((obj['width']*obj['height'])**0.2)                            del fishobjs[i]                            if playerobj['face']== LEFT:                                playerobj['surface']=playersurfaceset(playerobj['size'],True)                            if playerobj['face']== RIGHT:                                    playerobj['surface']=playersurfaceset(playerobj['size'],False)                                             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()                if winMode:                    SCREEN.blit(winSurf,winRect)                    SCREEN.blit(winSurf2,winRect2)                 pygame.display.update()        FPSCLOCK.tick(FPS)def isOutsideArea(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'])    return not boundsRect.colliderect(objRect)def makeNewfish(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()    if sq['movx']<0:        sq['surface']=surfaceset(sq['width'],sq['height'],True)    else:        sq['surface']=surfaceset(sq['width'],sq['height'],False)    return sqdef playersurfaceset(size,Face):    surface=None    if size<100:        if Face ==True:            surface= pygame.transform.scale(lplayer_img[0],(size,size))        else:            surface= pygame.transform.scale(rplayer_img[0],(size,size))    elif size<200 and size>=100:        if Face ==True:            surface= pygame.transform.scale(lplayer_img[1],(size,size))        else:            surface= pygame.transform.scale(rplayer_img[1],(size,size))    else:        if Face ==True:            surface= pygame.transform.scale(lplayer_img[2],(size,size))        else:            surface= pygame.transform.scale(rplayer_img[2],(size,size))    return surfacedef surfaceset(width,height,Face):    surface=None    if width*height>200*200:        if Face == 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))        if Face == True:            surface= pygame.transform.scale(lfish_img[index],(width,height))        else:            surface= pygame.transform.scale(rfish_img[index],(width,height))    return surface       def getRandomVelcocity():    speed=random.randint(MINSPEED,MAXSPEED)    if random.randint(0,1):        return speed    else:        return -speed    def getRandomoffCameraPos(camerax,cameray,objwidth,objheight):    cameraRect=pygame.Rect(camerax,cameray,WINWIDTH,WINHEIGHT)    while True:        x=random.randint(camerax-WINWIDTH,camerax+2*(WINWIDTH))        y=random.randint(camerax-WINHEIGHT,camerax+2*(WINHEIGHT))        objrect=pygame.Rect(x,y,objwidth,objheight)         if not objrect.colliderect(cameraRect):            return x,y                if __name__ == '__main__':    main()
View Code

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


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表