【Python】 Python小遊戲-貪吃蛇大冒險

專注的阿熊發表於2022-02-21

import sys

import time

import pygame

from random import *

# Position 類,透過其建構函式,設定 x y

class Position(object):

     def __init__(self, x, y):

         self.x = x

         self.y = y

# 生成隨機的食物

def new_food(head):

     while True:

         new_food = Position(randint(0, 48) * 20, randint(0, 29) * 20)

         # 判斷新生成的事物是否和貪吃蛇蛇頭重合,重合則不創鍵

         if new_food.x != head.x and new_food.y != head.y:

             break

         else:

             continue

     return new_food

# 繪製,在窗體中繪製貪吃蛇、食物

# color: 顏色, position: 座標

def rect(color, position):

     pygame.draw.circle(window, color, (position.x, position.y), 10)

# 初始介面和遊戲中點差退出遊戲時

def exit_end():

     pygame.quit()

     quit()

# 遊戲結束時,顯示得分的窗體的設定

def show_end():

     # 設計視窗

     # 定義視窗大小

     small_window = pygame.display.set_mode((960, 600))

     init_background = pygame.image.load("image/init_bgimg.jpg")

     small_window.blit(init_background, (0, 0))

     # 定義標題

     pygame.display.set_caption(" 貪吃蛇大冒險 ")

     # 定義背景圖片

     font = pygame.font.SysFont("simHei", 40)

     fontsurf = font.render(' 遊戲結束 ! 你的得分為 : %s' % score, False, black)

     small_window.blit(fontsurf, (250, 200))

     pygame.display.update()

     time.sleep(2)

     pygame.quit()

     sys.exit()

# 正常模式死亡設定

# head: 蛇頭, snake_body: 蛇身

def die_snake(head, snake_body):

     # 定義標誌物,預設為 false true 時判定貪吃蛇碰到自己,死亡

     die_flag = False

     # 遍歷存放貪吃蛇位姿的列表,從第 1 個開始, ( 0 個位蛇頭 )

     for body in snake_body[1:]:

         # 如果蛇頭的 xy 和蛇身 xy 相等,則判定相撞,設定 flag ture

         if head.x == body.x and head.y == body.y:

             die_flag = True

     # 若蛇頭的 xy 在顯示窗體外,或 flag true ,則顯示結束介面,並退出遊戲

     if head.x < 0 or head.x > 960 or head.y < 0 or head.y > 600 or die_flag:

         pygame.mixer.music.stop()

         show_end()

# 正常模式主體設定

def start_game():

     # 定義存分數的全域性變數

     global score

     global color

     color = (randint(10, 255), randint(10, 255), randint(10, 255))

     # 定義存放玩家鍵盤輸入運動方向的變數,初始為向右

     run_direction = "right"

     # 定義貪吃蛇運動方向的變數,初始為玩家鍵入方向

     run = run_direction

     # 例項化蛇頭、蛇身、食物物件

     head = Position(160, 160)

     # 初始化蛇身長度為 3 個單位

     snake_body = [Position(head.x, head.y + 20), Position(head.x, head.y + 40), Position(head.x, head.y + 60)]

     # 初始化食物位置

     food = Position(300, 300)

     # 死迴圈

     while True:

         window.blit(background, (0,0))

         # 監聽玩家鍵盤輸入的運動方向值,並根據輸入轉為 up down right left ,方便程式中呼叫

         for event in pygame.event.get():

             if event.type == pygame.QUIT:

                 show_end()

             elif event.type == pygame.KEYDOWN:

                 if event.key == pygame.K_UP:

                     run_direction = "up"

                 elif event.key == pygame.K_RIGHT:

                     run_direction = "right"

                 elif event.key == pygame.K_LEFT:

                     run_direction = "left"

                 elif event.key == pygame.K_DOWN:

                     run_direction = "down"

         # 食物

         rect(color, food)

         # 蛇頭

         rect(black, head)

         # 蛇身

         for pos in snake_body:

             rect(white, pos)

         # 判斷貪吃蛇原運動方向與玩家鍵盤輸入的運動方向是否違反正常運動情況

         if run == "up" and not run_direction == "down":

             run = run_direction

         elif run == "down" and not run_direction == "up":

             run = run_direction

         elif run == "left" and not run_direction == "right":

             run = run_direction

         elif run == "right" and not run_direction == "left":

             run = run_direction

         # 插入蛇頭位置到蛇身列表中

         snake_body.insert(0, Position(head.x, head.y))

         # 根據玩家鍵入方向進行蛇頭 xy 的更新

         if run == "up":

             head.y -= 20

         elif run == "down":

             head.y += 20

         elif run == "left":

             head.x -= 20

         elif run == "right":

             head.x += 20

         # 判斷是否死亡

         die_snake(head, snake_body)

         # 判斷蛇頭和食物座標,若相等,則加分,並生成新的食物

         if head.x == food.x and head.y == food.y:

             score += 1

             food = new_food(head)

             color = (randint(10, 255), randint(10, 255), randint(10, 255))

         else:

             snake_body.pop()

         font = pygame.font.SysFont("simHei", 25)

         mode_title = font.render(' 正常模式 ', False, grey)

         socre_title = font.render(' 得分 : %s' % score, False, grey)

         window.blit(mode_title, (50, 30))

         window.blit(socre_title, (50, 65))

         # 繪製更新

         pygame.display.update()

         # 透過幀率設定貪吃蛇速度

         clock.tick(8)

# 可穿牆模式死亡設定

# head: 蛇頭, snake_body: 蛇身

def through_snake(head, snake_body):

     # 定義標誌位

     die_flag = False

     # 遍歷,蛇頭碰到蛇身時, flag true 退出遊戲

     for body in snake_body[1:]:

         if head.x == body.x and head.y == body.y:

             die_flag = True

     if die_flag:

         pygame.mixer.music.stop()

         show_end()

     else:  # 當蛇頭的 xy 出窗體時

         # 四種穿牆情況,分別設定

         if head.x < 0:

             head.x = 960

         if head.x > 960:

             head.x = 0

         if head.y < 0:

             head.y = 600

         if head.y > 600:

             head.y = 0

# 穿牆模式主體設定

def start_kgame():

     global score

     global color

     color = (randint(10, 255), randint(10, 255), randint(10, 255))

     # 定義蛇初始方向

     run_direction = "up"

     run = run_direction

     # 例項化蛇頭、蛇身、食物物件

     head = Position(160, 160)

     # 三格

     snake_body = [Position(head.x, head.y + 20), Position(head.x, head.y + 40), Position(head.x, head.y + 60)]

     # 初始化事物位置

     food = Position(300, 300)

     # 死迴圈,監聽鍵盤鍵值

     while True:

         window.blit(background, (0, 0))

         for event in pygame.event.get():

             if event.type == pygame.QUIT:

                 show_end()

             elif event.type == pygame.KEYDOWN:

                 if event.key == pygame.K_UP:

                     run_direction = "up"

                 elif event.key == pygame.K_RIGHT:

                     run_direction = "right"

                 elif event.key == pygame.K_LEFT:

                     run_direction = "left"

                 elif event.key == pygame.K_DOWN:

                     run_direction = "down"

         # 食物

         rect(color, food)

         # 蛇頭

         rect(black, head)

         # 蛇身

         for pos in snake_body:

             rect(white, pos)

         # 判斷貪吃蛇原運動方向與玩家鍵盤輸入的運動方向是否違反正常運動情況

         if run == "up" and not run_direction == "down":  # 若運動方向為向上,玩家輸入運動方向向下,則違背貪吃蛇正常運動情況

             run = 外匯跟單gendan5.comrun_direction

         elif run == "down" and not run_direction == "up":

             run = run_direction

         elif run == "left" and not run_direction == "right":

             run = run_direction

         elif run == "right" and not run_direction == "left":

             run = run_direction

         # 插入蛇頭位置到蛇身列表中

         snake_body.insert(0, Position(head.x, head.y))

         # 根據玩家鍵入方向進行蛇頭 xy 的更新

         if run == "up":

             head.y -= 20

         elif run == "down":

             head.y += 20

         elif run == "left":

             head.x -= 20

         elif run == "right":

             head.x += 20

         # 穿牆實現

         through_snake(head, snake_body)

         # 判斷是否加分和隨機生成新的食物

         if head.x == food.x and head.y == food.y:

             score += 1

             food = new_food(head)

             color = (randint(10, 255), randint(10, 255), randint(10, 255))

         else:

             snake_body.pop()

         font = pygame.font.SysFont("simHei", 25)

         mode_title = font.render(' 穿牆模式 ', False, grey)

         socre_title = font.render(' 得分 : %s' % score, False, grey)

         window.blit(mode_title, (50, 30))

         window.blit(socre_title, (50, 65))

         # 繪製更新

         pygame.display.update()

         # 透過幀率設定貪吃蛇速度

         clock.tick(8)

# 監聽函式,監聽鍵盤輸入

# msg: 按鈕資訊, x: 按鈕的 x 軸, y: 按鈕的 y 軸, w: 按鈕的寬, h: 按鈕的高, ic: 按鈕初始顏色, ac: 按鈕按下顏色, action: 按鈕按下的動作

def button(msg, x, y, w, h, ic, ac, action=None):

     # 獲取滑鼠位置

     mouse = pygame.mouse.get_pos()

     # 獲取鍵盤輸入

     click = pygame.mouse.get_pressed()

     if x + w > mouse[0] > x and y + h > mouse[1] > y:

         pygame.draw.rect(window, ac, (x, y, w, h))

         if click[0] == 1 and action != None:

             action()

     else:

         pygame.draw.rect(window, ic, (x, y, w, h))

     # 設定按鈕中的文字樣式和居中對齊

     font = pygame.font.SysFont('simHei', 20)

     smallfont = font.render(msg, True, white)

     smallrect = smallfont.get_rect()

     smallrect.center = ((x + (w / 2)), (y + (h / 2)))

     window.blit(smallfont, smallrect)

# 遊戲初始介面,選擇模式

def into_game():

     into = True

     while into:

         window.blit(init_background, (0, 0))

         for event in pygame.event.get():

             if event.type == pygame.QUIT:

                 exit_end()

         # 設定字型

         font = pygame.font.SysFont("simHei", 50)

         # 初始介面顯示文字

         fontsurf = font.render(' 歡迎來到貪吃蛇大冒險 !', True, black)  # 文字

         fontrect = fontsurf.get_rect()

         fontrect.center = ((width / 2), 200)

         window.blit(fontsurf, fontrect)

         button(" 正常模式 ", 370, 370, 200, 40, blue, brightred, start_game)

         button(" 可穿牆模式 ", 370, 420, 200, 40, violte, brightred, start_kgame)

         button(" 退出 ", 370, 470, 200, 40, red,brightred, exit_end)

         pygame.display.update()

         clock.tick(15)


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2856740/,如需轉載,請註明出處,否則將追究法律責任。

相關文章