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

 

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

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

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

 

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

一、玩法及逻辑相关:

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

  

写简单游戏,学编程语言-python篇:大鱼吃小鱼
 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 =False
13                     moveUp = True
14                 elif event.key in (K_DOWN,K_s):
15                     moveDown =True
16                     moveUp = False
17                 elif event.key in (K_LEFT,K_a):
18                     moveRight = False
19                     moveLeft= True
20                     if playerobj[facing]==RIGHT:
21                         playerobj[surface]=playersurfaceset(playerobj[size], True)
22                     playerobj[facing]=LEFT
23                 elif event.key in (K_RIGHT,K_d):
24                     moveRight = True
25                     moveLeft= False
26                     if playerobj[facing]==LEFT:
27                         playerobj[surface]=playersurfaceset(playerobj[size], False)
28                     playerobj[facing]=RIGHT
29                 elif winMode and event.key == K_r:
30                     return
31             elif event.type==KEYUP:
32                     if event.key in (K_LEFT,K_a):
33                         moveLeft=False
34                     elif event.key in (K_RIGHT,K_d):
35                         moveRight=False
36                     elif event.key in (K_UP,K_w):
37                         moveRight=False
38                     elif event.key in (K_DOWN,K_s):
39                         moveRight=False
40             if not gameOverMode:
41                 if moveLeft:
42                     playerobj[x]-=MOVESPEED
43                 if moveRight:
44                     playerobj[x]+=MOVESPEED
45                 if moveUp:
46                     playerobj[y]-=MOVESPEED
47                 if moveDown:
48                     playerobj[y]+=MOVESPEED
49                 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=True
61                         elif not invulnerableMode:
62                             invulnerableMode=True
63                             invulnerableStartTime=time.time()
64                             playerobj[health]-=1
65                             if playerobj[health]==0:
66                                 gameOverMode =True
67                                 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))
写简单游戏,学编程语言-python篇:大鱼吃小鱼
 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
写简单游戏,学编程语言-python篇:大鱼吃小鱼

三、跟随视角的处理

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

  

写简单游戏,学编程语言-python篇:大鱼吃小鱼
 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篇:大鱼吃小鱼

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

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

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

写简单游戏,学编程语言-python篇:大鱼吃小鱼
import pygame,sys,time,random
from pygame.locals import *
WINWIDTH=640
WINHEIGHT=480
CAMERASLACK=70
lfish_img=[]
FISHSIZE=8
PLAYERSIZE=3
SCREEN=None
rfish_img=[]
lplayer_img=[]
rplayer_img=[]
backgroundimg=None
rboss_img=None
lboss_img=None
FPS=30
WHITE=[255,255,255]
MAXHEALTH=3
MINSPEED=3
MAXSPEED=9
MOVESPEED=7
HALF_WINWIDTH=int(WINWIDTH/2)
HALF_WINHEIGHT=int(WINHEIGHT/2)
WINSIZE=300
def 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 sq
def 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 surface
def 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上刷票的黄牛,刷了一天没买到票,哎 不说了都是泪。

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

上一篇:正则表达式学习与python中的应用


下一篇:uni-app中websocket的使用 断开重连、心跳机制