基於python的基礎版貪吃蛇
遊戲效果圖:
1、貪吃蛇模組
遊戲中的蛇本質是由一個列表組成的,利用列表可以新增和修改的特性,完成小蛇的移動和成長。我們先定義一個蛇的初始列表self.item=[(20,15),(20,16)]。
那麼如何畫出一條蛇呢,首先我們需要畫出蛇頭,蛇頭是一個圓形,這時便可以用到模組pygame中畫圓形的功能:
pygame.draw.circle(screen,color,position,radius,width)
其中:screen代表遊戲圖框的大小,color代表顏色,如color=(0,255,0)即代表綠色,position則代表圓心的位置,radius代表圓的半徑,width代表線寬,需要注意的是width不能超過radius的數值,否者便會報錯。這樣一個蛇頭便畫出來了,同理,蛇的身體也是相同的原理。蛇頭與蛇身,共同組成了一個蛇的列表。為了讓貪吃蛇動起來,我們就需要對position這個引數下手了,首先需要定義一個蛇頭朝向的函式,蛇頭是朝左還是朝右運動,便是由此引數所決定的,我們先定義一個蛇頭的基礎朝向:self.X=1,self.Y=0,那麼位置引數可以令為:
head=(self.item[0][0]+self.x,self.item[0][1]+self.y)`
self.item.insert(0,head)
這樣,通過改變self.X,self.y的值,就可以改變蛇頭的方向。在蛇沒有吃到食物的情況下,需要加一句:self.item.pop()否者小蛇便要無限的長大了。本貪吃蛇遊戲採用鍵盤控制的方式,那麼,我們便需要將蛇頭的朝向和鍵盤的按鍵對應起來:
def press(self,keys): global score if keys[K_w] or keys[K_UP]: self.toward(0, -1) elif keys[K_s] or keys[K_DOWN]: self.toward(0, 1) elif keys[K_a] or keys[K_LEFT]: self.toward(-1, 0) elif keys[K_d] or keys[K_RIGHT]: self.toward(1, 0)
不過我們仍然要解決一個問題,即蛇頭僅能90°的轉向,而不能180°的轉向,這需要增加一個判斷來解決這個問題:
def toward(self,x,y):
if self.x*x>=0 and self.y*y>=0:
self.x=x
self.y=y
2、食物模組
與貪吃蛇模組相同,食物同樣是一個列表,同樣通過pygame.draw畫出形狀,不同的是,食物模組再被吃掉後,需要重新在遊戲框內更新食物的位置,這便要用到np.random.randint來隨機生成食物的位置座標,即:
seld.item[0]=random.randint(1,BOARDWIDTH-2),np.random.randint(1,BOARDHEIGHT-2)
同時,如果生成的食物座標在貪吃蛇上,則需要重新生產座標,程式碼如下:
while self.item in snack.item:
self.item[0]=np.random.randint(1, BOARDWIDTH - 2), np.random.randint(1, BOARDHEIGHT - 2)
3、其他模組
定義貪吃蛇與食物模組對於一個貪吃蛇遊戲還是遠遠不夠的,遊戲介面,記分牌,遊戲的結束等,都需要定義對應的函式。
遊戲的介面:pygame.init是對pygame模組進行初始化,如果沒有這個模組則程式便會報錯。pygame.display.set_mode用來設定遊戲介面的大小。pygame.display.set_caption用來顯示遊戲標題。
def game_init():
pygame.init()
screen=pygame.display.set_mode((BOARDWIDTH*20 , BOARDHEIGHT*20 ))
pygame.display.set_caption("snack")
return screen
記分牌:每當貪吃蛇吃到食物時,記分牌則增加100,首先需要判斷貪食蛇吃到食物的狀態,即蛇頭和食物的座標重合的狀態,一個判斷即可搞定:
snack_x,snack_y=snack.item[0]
food_x,food_y=attak_chichken.item[0]
if(snack_x==food_x)and(snack_y==food_y):
score+=100
return 1
那麼如何讓記分牌的分數顯示在遊戲介面上呢:定義text = u"score: {} ch".format(score),使記分牌的數值與score保持一致。同時定義一個print_text函式,使得輸出的數值到指定的位置上去:
def print_text(screen,font,x,y,text,color=(255,0,0)):
imgText = font.render(text, True, color)
screen.blit(imgText, (x, y))
然後再主函式中輸入:print_text(screen, font, 0, 0, text)則在遊戲介面的左上角生成了記分牌。
遊戲的結束:當貪吃蛇頭碰到自己的身體或者遊戲的邊界,則遊戲結束。
def game_over(snack):
broad_x,broad_y=snack.get_head()
flag=0
old=len(snack.item)
new=len(set(snack.item))
if new<old:
flag=1
if broad_x==0 or broad_x==BOARDWIDTH-1:
flag=1
if broad_y==0 or broad_y==BOARDHEIGHT-1:
flag=1
if flag:
return True
else:
return False
最後是運行遊戲的主函式,貪吃蛇遊戲便可以順利執行:
def game(screen):
snack=Snack()
food=attak_chichken()
font=pygame.font.SysFont('simHei',20)
is_fail=0
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
screen.fill((65, 240, 75))
init_board(screen=screen)
keys = pygame.key.get_pressed()
snack.press(keys)
if is_fail:
font2 = pygame.font.Font('E:\ freesansbold.ttf', 40)
print_text(screen, font, 0, 0, text)
print_text(screen, font2, 400, 200, "GAME OVER")
if not is_fail:
enlarge = snack.eat_food(food)
text = u"score: {} ch".format(score)
print_text(screen, font, 0, 0, text)
food.update(screen, enlarge, snack)
food.chicken_move()
snack.move(enlarge)
is_fail = game_over(snack=snack)
snack.draw(screen)
pygame.display.update()
time.sleep(0.10)