1. 程式人生 > >貪吃蛇遊戲開發

貪吃蛇遊戲開發

設計思路

1.有一個地盤,四周有牆

2.有四個方形來組成一條蛇,蛇在此地盤內活動

3隨機生成一個食物,蛇吃到食物後身體變長。

4蛇遇到牆時死亡

5鍵盤上下來控制蛇的行走方向、

有待完善

程式碼

#!/user/bin/env python
#-*- coding:utf-8 -*-
# @Time    : 2018/12/13 19:21
# @Author  : 劉
# @Site    : 
# @File    : 貪吃蛇.py
# @Software: PyCharm
import random
import pygame
import sys
from pygame.locals import *


snake_speed = 4 #貪吃蛇的速度
windows_width = 800
windows_height = 600 #遊戲視窗的大小
cell_size = 20       #貪吃蛇身體方塊大小,注意身體大小必須能被視窗長寬整除

''' #初始化區
由於我們的貪吃蛇是有大小尺寸的, 因此地圖的實際尺寸是相對於貪吃蛇的大小尺寸而言的
'''
map_width = int(windows_width / cell_size)
map_height = int(windows_height / cell_size)

# 顏色定義
white = (255, 255, 255)
black = (0, 0, 0)
gray = (230, 230, 230)
dark_gray = (40, 40, 40)
DARKGreen = (0, 155, 0)
Green = (0, 255, 0)
Red = (255, 0, 0)
blue = (0, 0, 255)
dark_blue =(0,0, 139)


BG_COLOR = white  #遊戲背景顏色

# 定義方向
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4
HEAD = 0 #貪吃蛇頭部下標

#主函式
def main():

    pygame.init() # 模組初始化
    snake_speed_clock = pygame.time.Clock() # 建立Pygame時鐘物件
    screen = pygame.display.set_mode((windows_width, windows_height)) #
    screen.fill(white)

    pygame.display.set_caption("劉先生貪吃蛇小遊戲") #設定標題
    show_start_info(screen)               #歡迎資訊
    while True:
       running_game(screen, snake_speed_clock)
       show_gameover_info(screen)


#遊戲執行主體
def running_game(screen,snake_speed_clock):
    startx = random.randint(3, map_width - 8) #開始位置
    starty = random.randint(3, map_height - 8)
    snake_coords = [{'x': startx, 'y': starty},  #初始貪吃蛇
                  {'x': startx - 1, 'y': starty},
                  {'x': startx - 2, 'y': starty}]

    direction = RIGHT       #  開始時向右移動

    food = get_random_location()     #實物隨機位置

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                terminate()
            elif event.type == pygame.KEYDOWN:

                if (event.key == pygame.K_LEFT or event.key == pygame.K_a) and direction != RIGHT:
                    direction = LEFT
                elif (event.key == pygame.K_RIGHT or event.key ==pygame.K_d) and direction != LEFT:
                    direction = RIGHT
                elif (event.key == pygame.K_UP or event.key == pygame.K_w) and direction != DOWN:
                    direction = UP
                elif (event.key == pygame.K_DOWN or event.key == pygame.K_s) and direction != UP:
                    direction = DOWN
                elif event.key == pygame.K_ESCAPE:
                    terminate()

        move_snake(direction, snake_coords) #移動蛇

        ret = snake_is_alive(snake_coords)
        if not ret:
           break
        snake_is_eat_food(snake_coords, food) #判斷蛇是否吃到食物

        screen.fill(BG_COLOR)
        #draw_grid(screen)
        draw_snake(screen, snake_coords)
        draw_food(screen, food)
        draw_score(screen, len(snake_coords) - 3)
        pygame.display.update()
        snake_speed_clock.tick(snake_speed) #控制fps
#將食物畫出來
def draw_food(screen, food):
    x = food['x'] * cell_size
    y = food['y'] * cell_size
    appleRect = pygame.Rect(x, y, cell_size, cell_size)
    pygame.draw.rect(screen, Red, appleRect)
#將貪吃蛇畫出來
def draw_snake(screen, snake_coords):
    for coord in snake_coords:
        x = coord['x'] * cell_size
        y = coord['y'] * cell_size
        wormSegmentRect = pygame.Rect(x, y, cell_size, cell_size)
        pygame.draw.rect(screen, dark_blue, wormSegmentRect)
        wormInnerSegmentRect = pygame.Rect(                #蛇身子裡面的第二層亮綠色
            x + 4, y + 4, cell_size - 8, cell_size - 8)
        pygame.draw.rect(screen, blue, wormInnerSegmentRect)
#畫網格(可選)
def draw_grid(screen):
    for x in range(0, windows_width, cell_size):  # draw 水平 lines
        pygame.draw.line(screen, dark_gray, (x, 0), (x, windows_height))
    for y in range(0, windows_height, cell_size):  # draw 垂直 lines
        pygame.draw.line(screen, dark_gray, (0, y), (windows_width, y))
#移動貪吃蛇
def move_snake(direction, snake_coords):
    if direction == UP:
        newHead = {'x': snake_coords[HEAD]['x'], 'y': snake_coords[HEAD]['y'] - 1}
    elif direction == DOWN:
        newHead = {'x': snake_coords[HEAD]['x'], 'y': snake_coords[HEAD]['y'] + 1}
    elif direction == LEFT:
        newHead = {'x': snake_coords[HEAD]['x'] - 1, 'y': snake_coords[HEAD]['y']}
    elif direction == RIGHT:
        newHead = {'x': snake_coords[HEAD]['x'] + 1, 'y': snake_coords[HEAD]['y']}

    snake_coords.insert(0, newHead)
#判斷蛇死了沒
def snake_is_alive(snake_coords):
    tag = True
    if snake_coords[HEAD]['x'] == -1 or snake_coords[HEAD]['x'] == map_width or snake_coords[HEAD]['y'] == -1 or \
            snake_coords[HEAD]['y'] == map_height:
        tag = False # 蛇碰壁啦
    for snake_body in snake_coords[1:]:
        if snake_body['x'] == snake_coords[HEAD]['x'] and snake_body['y'] == snake_coords[HEAD]['y']:
            tag = False # 蛇碰到自己身體啦
    return tag
#判斷貪吃蛇是否吃到食物
def snake_is_eat_food(snake_coords, food):  #如果是列表或字典,那麼函式內修改引數內容,就會影響到函式體外的物件。
    if snake_coords[HEAD]['x'] == food['x'] and snake_coords[HEAD]['y'] == food['y']:
        food['x'] = random.randint(0, map_width - 1)
        food['y'] = random.randint(0, map_height - 1) # 實物位置重新設定
    else:
        del snake_coords[-1]  # 如果沒有吃到實物, 就向前移動, 那麼尾部一格刪掉
#食物隨機生成
def get_random_location():
    return {'x': random.randint(0, map_width - 1), 'y': random.randint(0, map_height - 1)}
#開始資訊顯示
def show_start_info(screen):
    font = pygame.font.Font(None , 40)
    tip = font.render('按任意鍵開始遊戲~~~', True, (65, 105, 225))
    gamestart = pygame.image.load('sn.png')
    screen.blit(gamestart, (140, 30))
    screen.blit(tip, (240, 550))
    pygame.display.update()

    while True:  #鍵盤監聽事件
        for event in pygame.event.get():  # event handling loop
            if event.type == pygame.QUIT:
                terminate()     #終止程式
            elif event.type == pygame.KEYDOWN:
                if (event.key == pygame.K_ESCAPE):  #終止程式
                    terminate() #終止程式
                else:
                    return #結束此函式, 開始遊戲
#遊戲結束資訊顯示
def show_gameover_info(screen):
    font = pygame.font.Font(None, 40)
    tip = font.render('按Q或者ESC退出遊戲, 按任意鍵重新開始遊戲~', True, (65, 105, 225))
    screen.blit(gamestart, (60, 0))
    screen.blit(tip, (80, 300))
    pygame.display.update()

    while True:  #鍵盤監聽事件
        for event in pygame.event.get():  # event handling loop
            if event.type == pygame.QUIT:
                terminate()     #終止程式
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE or event.key == pygame.K_q:  #終止程式
                    terminate() #終止程式
                else:
                    return   #結束此函式, 重新開始遊戲
#畫成績
def draw_score(screen,score):
    font = pygame.font.Font(None, 30)
    scoreSurf = font.render('得分: %s' % score, True, Green)
    scoreRect = scoreSurf.get_rect()
    scoreRect.topleft = (windows_width - 120, 10)
    screen.blit(scoreSurf, scoreRect)
#程式終止
def terminate():
     pygame.quit()
     sys.exit()


main()