pygame實現貪喫蛇小遊戲

pygame實現貪喫蛇小遊戲

由於這段時間實在是太聊了,沒什麼事做,遊戲也玩膩了,所以玩起來pygame。pygame是真的容易上手,但用來做遊戲也有很大的侷限性,做一些小遊戲還是沒什麼問題的。

首先,製作遊戲最大的問題我認爲是確定要製作的遊戲的玩法,具體的細節都確定清楚之後再去實現還是很容易的。所以開發遊戲最大的問題可能是需要一個好的創意,沒有好的創意都沒法開始。貪喫蛇相信沒有人沒玩過了,玩法也很簡單,沒喫一個方塊可以使蛇的身體變長,頭部碰到牆壁或者頭部碰到自己身體就game over了。然後也需要一個計分板記錄分數。由於只是一個簡單的小遊戲,不用一個具體的步驟了,就自己碼代碼的時候不斷完善代碼還是很容易完成的。

初步的版本,實現了蛇的移動和喫方塊身體變長,但還沒有檢測導致game over 的時間。自己想到了不少事情,如可以記錄遊戲分數並保存到本地文件,記錄最高分,但畢竟只是個小遊戲,只要保證遊戲的完整性就算過關了,再怎麼追求完美也不過是用pygame開發的,其價值始終只在於自娛自樂。之後將這個版本完善一下就算完成了。

import pygame,sys,numpy as nu,random as ra
from pygame.sprite import Sprite,Group
class setting():
    def __init__(self,w,h):
        self.w1=0.1*w
        self.w2=0.7*w
        self.w3=0.75*w
        self.w4=0.95*w
        self.h1=0.1*h
        self.h2=0.7*h
        self.length=0.05*self.w1
        self.speed=self.length
        self.wall_length=0.1*self.length
        self.wall_color=(0,0,0)
        self.snake_color=(0,0,230)
        self.head_color=(230,0,0)
class block(Sprite):
    def __init__(self,screen,rect,test,color):
        super().__init__()
        self.screen=screen
        self.rect=rect      #pygame.Rect(0,0,10,10)
        self.test=test
        self.color=color
    def update(self):
        self.rect=self.test(self.rect)
    def draw_bullet(self):
        pygame.draw.rect(self.screen,self.color,self.rect)
class textBlock(Sprite):
    def __init__(self,screen,rect,color,text,text_color):
        super().__init__()
        self.screen=screen
        self.rect=rect      #pygame.Rect(0,0,10,10)
        self.color=color
        self.text_color=text_color
        self.font=pygame.font.SysFont(None,68)
        self.image=self.font.render(text,True,self.text_color,self.color)
        self.image_rect=self.image.get_rect()
        self.image_rect.left=rect.left-200
        self.image_rect.top=rect.top-200
    def update(self):
        pass
    def changeText(self,text):
        self.image=self.font.render(text,True,self.text_color,self.color)
    def draw_bullet(self):
        self.screen.blit(self.image,self.image_rect)
        #pygame.draw.rect(self.screen, self.color, self.rect)
def run_game():
    pygame.init()
    w,h=1200,800
    screen=pygame.display.set_mode((w,h))
    pygame.display.set_caption("pygame1")
    bg_color=(230,230,230)
    settings=setting(w,h)

    g,gg=Group(),Group()

    a = block(screen, pygame.Rect((settings.w1+settings.w2)/2, (settings.h1+settings.h2)/2,
                                  settings.length, settings.length),lambda r:r,settings.head_color)
    aa = block(screen, pygame.Rect((settings.w1 + settings.w2) / 2, (settings.h1 + settings.h2) / 2,
                                  settings.length, settings.length), lambda r: r, settings.snake_color)
    g.add(a)
    #牆壁
    wall=Group()
    w1=block(screen, pygame.Rect(settings.w1, settings.h1, settings.wall_length, settings.h2-settings.h1),
              lambda r:r,settings.wall_color)
    w2 = block(screen, pygame.Rect(settings.w1, settings.h1, settings.w2-settings.w1, settings.wall_length),
               lambda r: r,settings.wall_color)
    w3 = block(screen, pygame.Rect(settings.w2, settings.h1, settings.wall_length, settings.h2-settings.h1),
               lambda r: r,settings.wall_color)
    w4 = block(screen, pygame.Rect(settings.w1, settings.h2, settings.w2-settings.w1, settings.wall_length),
               lambda r: r,settings.wall_color)
    wall.add(w1);wall.add(w2);wall.add(w3);wall.add(w4)

    w5 = block(screen, pygame.Rect(settings.w3, settings.h1, settings.wall_length, settings.h2 - settings.h1),
               lambda r: r, settings.wall_color)
    w6 = block(screen, pygame.Rect(settings.w3, settings.h1, settings.w4 - settings.w3, settings.wall_length),
               lambda r: r, settings.wall_color)
    w7 = block(screen, pygame.Rect(settings.w4, settings.h1, settings.wall_length, settings.h2 - settings.h1),
               lambda r: r, settings.wall_color)
    w8 = block(screen, pygame.Rect(settings.w3, settings.h2, settings.w4 - settings.w3, settings.wall_length),
               lambda r: r, settings.wall_color)
    wall.add(w5)
    wall.add(w6)
    wall.add(w7)
    wall.add(w8)
    timesec = textBlock(screen, pygame.Rect(settings.w3+200, settings.h1+200, 50,50), (230, 230, 230),
                        "time:"+str(pygame.time.get_ticks()), (200, 0, 20))
    leng=1
    snakeLength = textBlock(screen, pygame.Rect(settings.w3 + 200, settings.h1 + 400, 50, 50), (230, 230, 230),
                        "length:" + str(leng), (200, 0, 20))
    start=textBlock(screen,pygame.Rect(w/2,h/2,50,50),(230,230,230),"Gluttonous Snake",(0,200,200))
    start_1 = textBlock(screen, pygame.Rect(w / 2+50, h / 2+100, 50, 50), (230, 230, 230),
                        "Start game",(200,20,20))
    start_2 = textBlock(screen, pygame.Rect(w / 2 + 50, h / 2 + 200, 50, 50), (230, 230, 230),
                        "exit", (200, 20, 20))
    block_=block(screen, pygame.Rect(w / 2-170, h / 2-85, 10, 10),
              lambda r:r,settings.wall_color)
    kw,ks,ka,kd=False,False,False,False
    start_game,exit_game,generator=False,False,False
    timeStart=0
    ls=[start_game,kw,ks,ka,kd,exit_game,timeStart,generator,leng]
    lx,ly,la=[],[],[]
    def check_event(ls,lx,ly,la):
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            elif event.type==pygame.KEYDOWN and ls[0]:
                if event.key==pygame.K_w:
                    ls[1:5]=[True,False,False,False]
                elif event.key==pygame.K_a:
                    ls[1:5]=[False,False,True,False]
                elif event.key==pygame.K_s:
                    ls[1:5]=[False,True,False,False]
                elif event.key==pygame.K_d:
                    ls[1:5]=[False,False,False,True]
            elif event.type==pygame.KEYDOWN:
                if event.key==pygame.K_SPACE :
                    if(ls[5]):
                        sys.exit()
                    else:
                        ls[0],ls[2],ls[7]=True,True,True
                        ls[6]=pygame.time.get_ticks()
                elif event.key==pygame.K_w or event.key==pygame.K_s:
                    if(ls[5]):
                        block_.rect.y-=100
                    else:
                        block_.rect.y+=100
                    ls[5]=not ls[5]
        if(ls[0]):#start game
            if(ls[7]):
                aa.rect.x,aa.rect.y=ra.randint(settings.w1+20,settings.w2-20),\
                                    ra.randint(settings.h1+20,settings.h2-20)
                ls[7]=False
            if(pygame.time.get_ticks()%30==1):
                if(ls[1] and a.rect.y>settings.h1):
                    a.rect.y-=settings.speed
                    lx.append(0)
                    ly.append(-settings.speed)
                elif(ls[2] and a.rect.y<settings.h2-settings.length):
                    a.rect.y+=settings.speed
                    lx.append(0)
                    ly.append(settings.speed)
                elif(ls[3] and a.rect.x>settings.w1):
                    a.rect.x-=settings.speed
                    lx.append(-settings.speed)
                    ly.append(0)
                elif(ls[4] and a.rect.x<settings.w2-settings.length):
                    a.rect.x+=settings.speed
                    lx.append(settings.speed)
                    ly.append(0)
                dir=-2
                for als in la:
                    als.rect.x+=lx[dir]
                    als.rect.y+=ly[dir]
                    dir-=1
            a.draw_bullet()
            g.update()
            aa.draw_bullet()
            for all in gg:
                all.draw_bullet()
            for walls in wall:
                walls.draw_bullet()
            timesec.changeText("time:"+str((pygame.time.get_ticks()-ls[6])//1000))
            timesec.draw_bullet()
            snakeLength.draw_bullet()
            if (pygame.sprite.spritecollideany(aa, g)):
                print("collide")
                ls[7]=True
                ls[8]+=1
                snakeLength.changeText("length:" + str(ls[8]))
                if(len(la)==0):
                    aaa = block(screen, pygame.Rect(a.rect.x,a.rect.y,
                                              settings.length, settings.length), lambda r: r, settings.snake_color)
                else:
                    aaa = block(screen, pygame.Rect(a.rect.x, a.rect.y,
                                                    settings.length, settings.length), lambda r: r,
                                settings.snake_color)
                for x in range(len(la)+1):
                    aaa.rect.x-=lx[-x-1]
                    aaa.rect.y-=ly[-x-1]
                gg.add(aaa)
                la.append(aaa)
        else:
            start.draw_bullet()
            start_1.draw_bullet()
            start_2.draw_bullet()
            block_.draw_bullet()
    while True:
        screen.fill(bg_color)
        check_event(ls,lx,ly,la)
        pygame.display.flip()
run_game()

最終完成版本:

import pygame,sys,numpy as nu,random as ra
from pygame.sprite import Sprite,Group
class setting():
    def __init__(self,w,h):
        self.w1=0.1*w
        self.w2=0.7*w
        self.w3=0.75*w
        self.w4=0.95*w
        self.h1=0.1*h
        self.h2=0.7*h
        self.length=0.05*self.w1
        self.speed=self.length
        self.wall_length=0.1*self.length
        self.wall_color=(0,0,0)
        self.snake_color=(0,0,230)
        self.head_color=(230,0,0)
class block(Sprite):
    def __init__(self,screen,rect,test,color):
        super().__init__()
        self.screen=screen
        self.rect=rect      #pygame.Rect(0,0,10,10)
        self.test=test
        self.color=color
    def update(self):
        self.rect=self.test(self.rect)
    def draw_bullet(self):
        pygame.draw.rect(self.screen,self.color,self.rect)
class textBlock(Sprite):
    def __init__(self,screen,rect,color,text,text_color):
        super().__init__()
        self.screen=screen
        self.rect=rect      #pygame.Rect(0,0,10,10)
        self.color=color
        self.text_color=text_color
        self.font=pygame.font.SysFont(None,68)
        self.image=self.font.render(text,True,self.text_color,self.color)
        self.image_rect=self.image.get_rect()
        self.image_rect.left=rect.left-200
        self.image_rect.top=rect.top-200
    def update(self):
        pass
    def changeText(self,text):
        self.image=self.font.render(text,True,self.text_color,self.color)
    def draw_bullet(self):
        self.screen.blit(self.image,self.image_rect)
        #pygame.draw.rect(self.screen, self.color, self.rect)
def run_game():
    pygame.init()
    w,h=1200,800
    screen=pygame.display.set_mode((w,h))
    pygame.display.set_caption("pygame1")
    bg_color=(230,230,230)
    settings=setting(w,h)

    g,gg=Group(),Group()

    a = block(screen, pygame.Rect((settings.w1+settings.w2)/2, (settings.h1+settings.h2)/2,
                                  settings.length, settings.length),lambda r:r,settings.head_color)
    aa = block(screen, pygame.Rect((settings.w1 + settings.w2) / 2, (settings.h1 + settings.h2) / 2,
                                  settings.length, settings.length), lambda r: r, settings.snake_color)
    g.add(a)
    #牆壁
    wall=Group()
    w1=block(screen, pygame.Rect(settings.w1, settings.h1, settings.wall_length, settings.h2-settings.h1),
              lambda r:r,settings.wall_color)
    w2 = block(screen, pygame.Rect(settings.w1, settings.h1, settings.w2-settings.w1, settings.wall_length),
               lambda r: r,settings.wall_color)
    w3 = block(screen, pygame.Rect(settings.w2, settings.h1, settings.wall_length, settings.h2-settings.h1),
               lambda r: r,settings.wall_color)
    w4 = block(screen, pygame.Rect(settings.w1, settings.h2, settings.w2-settings.w1, settings.wall_length),
               lambda r: r,settings.wall_color)
    wall.add(w1);wall.add(w2);wall.add(w3);wall.add(w4)

    w5 = block(screen, pygame.Rect(settings.w3, settings.h1, settings.wall_length, settings.h2 - settings.h1),
               lambda r: r, settings.wall_color)
    w6 = block(screen, pygame.Rect(settings.w3, settings.h1, settings.w4 - settings.w3, settings.wall_length),
               lambda r: r, settings.wall_color)
    w7 = block(screen, pygame.Rect(settings.w4, settings.h1, settings.wall_length, settings.h2 - settings.h1),
               lambda r: r, settings.wall_color)
    w8 = block(screen, pygame.Rect(settings.w3, settings.h2, settings.w4 - settings.w3, settings.wall_length),
               lambda r: r, settings.wall_color)
    wall.add(w5)
    wall.add(w6)
    wall.add(w7)
    wall.add(w8)
    timesec = textBlock(screen, pygame.Rect(settings.w3+200, settings.h1+200, 50,50), (230, 230, 230),
                        "time:"+str(pygame.time.get_ticks()), (200, 0, 20))
    leng=1
    snakeLength = textBlock(screen, pygame.Rect(settings.w3 + 200, settings.h1 + 400, 50, 50), (230, 230, 230),
                        "length:" + str(leng), (200, 0, 20))
    start=textBlock(screen,pygame.Rect(w/2,h/2,50,50),(230,230,230),"Gluttonous Snake",(0,200,200))
    start_1 = textBlock(screen, pygame.Rect(w / 2+50, h / 2+100, 50, 50), (230, 230, 230),
                        "Start game",(200,20,20))
    start_2 = textBlock(screen, pygame.Rect(w / 2 + 50, h / 2 + 200, 50, 50), (230, 230, 230),
                        "exit", (200, 20, 20))
    block_=block(screen, pygame.Rect(w / 2-170, h / 2-85, 10, 10),
              lambda r:r,settings.wall_color)
    kw,ks,ka,kd=False,False,False,False
    start_game,exit_game,generator,gameOver=False,False,False,False
    timeStart=0
    ls=[start_game,kw,ks,ka,kd,exit_game,timeStart,generator,leng,gameOver]
    lx,ly=[],[]
    def check_event(ls,lx,ly,gg):
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            elif event.type==pygame.KEYDOWN and ls[0] and not ls[9]:
                if event.key==pygame.K_w:
                    ls[1:5]=[True,False,False,False]
                elif event.key==pygame.K_a:
                    ls[1:5]=[False,False,True,False]
                elif event.key==pygame.K_s:
                    ls[1:5]=[False,True,False,False]
                elif event.key==pygame.K_d:
                    ls[1:5]=[False,False,False,True]
            elif event.type==pygame.KEYDOWN and not ls[9]:
                if event.key==pygame.K_SPACE :
                    if(ls[5]):
                        sys.exit()
                    else:
                        ls[0],ls[2],ls[7]=True,True,True
                        ls[6]=pygame.time.get_ticks()
                elif event.key==pygame.K_w or event.key==pygame.K_s:
                    if(ls[5]):
                        block_.rect.y-=100
                    else:
                        block_.rect.y+=100
                    ls[5]=not ls[5]
            elif event.type==pygame.KEYDOWN:
                if event.key==pygame.K_SPACE :
                    if(ls[5]):
                        sys.exit()
                    else:
                        ls[0],ls[2],ls[7],ls[9],ls[8]=True,True,True,False,1
                        la ,lx,ly= [],[],[]
                        snakeLength.changeText("length:" + str(ls[8]))
                        gg.empty()
                        ls[6]=pygame.time.get_ticks()
                        a.rect.x,a.rect.y=(settings.w1+settings.w2)/2, (settings.h1+settings.h2)/2
                elif event.key==pygame.K_w or event.key==pygame.K_s:
                    if(ls[5]):
                        block_.rect.y-=100
                    else:
                        block_.rect.y+=100
                    ls[5]=not ls[5]
        if(ls[0] and not ls[9]):#start game
            if(ls[7]):
                aa.rect.x,aa.rect.y=ra.randint(settings.w1+20,settings.w2-20),\
                                    ra.randint(settings.h1+20,settings.h2-20)
                ls[7]=False
            if(pygame.time.get_ticks()%30==1):
                if(ls[1] and a.rect.y>=settings.h1):
                    a.rect.y-=settings.speed
                    lx.append(0)
                    ly.append(-settings.speed)
                elif(ls[2] and a.rect.y<=settings.h2-settings.length):
                    a.rect.y+=settings.speed
                    lx.append(0)
                    ly.append(settings.speed)
                elif(ls[3] and a.rect.x>=settings.w1):
                    a.rect.x-=settings.speed
                    lx.append(-settings.speed)
                    ly.append(0)
                elif(ls[4] and a.rect.x<=settings.w2-settings.length):
                    a.rect.x+=settings.speed
                    lx.append(settings.speed)
                    ly.append(0)
                dir=-2
                for als in gg:
                    als.rect.x+=lx[dir]
                    als.rect.y+=ly[dir]
                    dir-=1
            a.draw_bullet()
            g.update()
            aa.draw_bullet()
            for all in gg:
                all.draw_bullet()
            for walls in wall:
                walls.draw_bullet()
            timesec.changeText("time:"+str((pygame.time.get_ticks()-ls[6])//1000))
            timesec.draw_bullet()
            snakeLength.draw_bullet()
            if (pygame.sprite.spritecollideany(aa, g)):
                print("collide")
                ls[7]=True
                ls[8]+=1
                snakeLength.changeText("length:" + str(ls[8]))
                aaa = block(screen, pygame.Rect(a.rect.x, a.rect.y,
                                                    settings.length, settings.length), lambda r: r,
                                settings.snake_color)
                for x in range(len(gg)+1):
                    aaa.rect.x-=lx[-x-1]
                    aaa.rect.y-=ly[-x-1]
                gg.add(aaa)
            if pygame.sprite.spritecollideany(a,wall) or pygame.sprite.spritecollideany(a,gg):
                ls[9],ls[1],ls[2],ls[3],ls[4]=True,False,False,False,False
                print("game over")
            if a.rect.x==settings.w1-settings.length or a.rect.x==settings.w2 \
                or a.rect.y==settings.h1-settings.length or a.rect.y==settings.h2:
                ls[9], ls[1], ls[2], ls[3], ls[4] = True, False, False, False, False
                print("game over")
        else:
            if ls[9]:
                start.changeText("again or exit")
                start_1.changeText("again")
            start.draw_bullet()
            start_1.draw_bullet()
            start_2.draw_bullet()
            block_.draw_bullet()
    while True:
        screen.fill(bg_color)
        check_event(ls,lx,ly,gg)
        pygame.display.flip()
run_game()

在這裏插入圖片描述

雖然可能還有不足之處,但玩起來感覺還不錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章