中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python中怎么用pygame實現貪吃蛇游戲

發布時間:2022-02-28 14:53:23 來源:億速云 閱讀:145 作者:iii 欄目:開發技術

這篇文章主要介紹“python中怎么用pygame實現貪吃蛇游戲”,在日常操作中,相信很多人在python中怎么用pygame實現貪吃蛇游戲問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”python中怎么用pygame實現貪吃蛇游戲”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

創建蛇

首先,先分析一下蛇的移動,不然我們一定會吃虧的(別問,問就是自己寫了一堆無效代碼)。

蛇的移動其實并沒有想象中那樣復雜,每一個模塊都需要有一個方向,按照方向進行移動。
其實實際上就是一個出隊的感覺,即每一個元素都取代上一個元素的位置,然后再按照貪吃蛇當前的方向,移動一下頭節點即可。
snake.py:

""""????類"""
import pygame
class Snake():
    def __init__(self,snake_color,snake_head_color,x,y,lattice_wh):
        self.color = snake_color
        self.head_color = snake_head_color
        # 格子的左上角坐標
        self.pos = (x,y)
        self.lattice_wh = lattice_wh
        self.rect = pygame.Rect(x,y,self.lattice_wh,self.lattice_wh)

        self.move_distance = {
            0:(0,0),
            1:(0,-self.lattice_wh),
            2:(0, self.lattice_wh),
            3:(-self.lattice_wh,0),
            4:( self.lattice_wh,0)
        }
    
    def move(self,direction):
        self.rect.x += self.move_distance[direction][0]
        self.rect.y += self.move_distance[direction][1]
    
    def forecast(self,direction):
        return (self.rect.x+self.move_distance[direction][0],
        		self.rect.y+self.move_distance[direction][1])

創建蛇,需要給一個位置(坐標),同時也需要輸入一個顏色。
這里為了區分頭節點,我傳入了兩個顏色,一個為頭節點的顏色,另一個為身子部分的顏色。
(其實顏色不需要給在這里,在update傳入一個即可)

蛇的主要部分就是移動,這里我給出了兩個方法:

1.移動方法,是針對頭節點的移動
2.預測移動位置方法,是判斷下一步蛇的移動的位置,看看是否會撞到自己/墻壁,或者吃到食物。

為了方便我們針對方向進行處理,我使用了哈希的方式(其實就是字典),將每一個方向移動一次(x,y)坐標變化量記錄好。

【那個方向0,是最開始我們的蛇是固定的,所以我添加了一個(0,0)】

最開始,我們在main文件中創建一個snakes列表,來存儲所有的蛇節點,并且添加了最開始的兩個節點(頭和第一部分的身子)

# 蛇頭&1個蛇身
snakes = []
snakes.append(Snake(snake_color,snake_head_color,lattice_wh,24*lattice_wh,lattice_wh))
snakes.append(Snake(snake_color,snake_head_color,0,24*lattice_wh,lattice_wh))

創建食物

這部分,主要就是隨機生成一個位置,然后保證這個位置不在蛇身上即可。
食物類:
傳入顏色、渲染的界面、一個格子的寬度以及坐標
另外我還提供了一個繪制圓的方法(pos為坐標,radius為直徑)
circle函數參數:界面screen,顏色,位置(元組形式),直徑,線條寬度。
這里我們將線條設置為直徑,就能繪制一個圓盤。(注意寬度一定要是int類型,需要強轉)

"""食物類"""
import pygame
class Food():
    def __init__(self,food_color,screen,lattice_wh,x,y):
        self.screen = screen
        self.food_color = food_color
        self.lattice_wh = lattice_wh
        self.radius = lattice_wh/2
        self.x,self.y = x,y

    def draw(self):
        pos = (self.x+self.lattice_wh/2,self.y+self.lattice_wh/2)
        pygame.draw.circle(self.screen,self.food_color,pos,self.radius,int(self.radius))

fuc.py中,寫了一個生成食物的函數:

def create_food(food_color,screen,lattice_wh,snakes):
    success = 0
    x,y = 0,0
    while not success:
        x,y = randint(0,24),randint(0,24)
        x *= lattice_wh
        y *= lattice_wh
        for i in snakes:
            if (x,y) != (i.rect.x,i.rect.y):
                success = 1
                break
    food = Food(food_color,screen,lattice_wh,x,y)
    return food

randint生成一個整數位置,乘上格子的寬度,我們就能得到一個格子的左上角坐標,看看是否在蛇身上,不在就可以生成了。

蛇的移動

之前只給出了方法,現在我們來實現一下。
蛇的移動就三種情況:

  • 撞到自己或者邊界

  • 吃到食物

  • 正常移動

如果是第一種,直接結束游戲,第三中我們就按照上面說的,將身子向前移動一位,修改一下頭節點即可。
但是第二種,涉及到了需要在snakes添加一個對象,我們就需要搞清楚添加的位置。

在即將碰到食物時,我們將食物位置添加到列表首項。

實現:
這里的game_stats為游戲種需要傳遞并需要被修改的項,整合成一個列表好看一點:
game_stats =[if_lose,direction,num,food]
游戲是否結束的狀態變量、蛇頭方向(1234:上下左右,0為靜止)、吃到的食物個數、食物的實例

def going(snakes,snake_color,snake_head_color,lattice_wh,game_stats,food_color,screen):
    """蛇的移動和轉向問題"""
    # 初始狀態,不需要移動
    if not game_stats[1]:
        return
    # 預測位置
    (x,y) = snakes[0].forecast(game_stats[1])
    # 撞到邊界
    if x == -lattice_wh or x == 25*lattice_wh or y == -lattice_wh or y == 25*lattice_wh:
        game_stats[0] = 0
        return
    # 吃到食物
    if (x,y) == (game_stats[3].x,game_stats[3].y):
        head = Snake(snake_color,snake_head_color,x,y,lattice_wh)
        snakes.insert(0,head)
        game_stats[2] += 1
        game_stats[3] = create_food(food_color,screen,lattice_wh,snakes)
        return
    # 撞到蛇身
    for i in snakes:
        if (x,y) == (i.rect.x,i.rect.y):
            game_stats[0] = 0
            return
    # 都沒有,就正常移動
    for i in range(len(snakes)-1,0,-1):
        snakes[i].rect.x = snakes[i-1].rect.x
        snakes[i].rect.y = snakes[i-1].rect.y
    snakes[0].move(game_stats[1])

這里的正常移動,我們是否可以這樣寫?
snake[i] = snakes[i-1
這樣是不行的,在python中,賦值是將地址賦值過去,所以實際上我們是將兩個實例指向一個地址。
對于snakes[1],當我們指向snakes[0],然后修改snakes[0]之后,兩者會合并為一個,而整個蛇身就會缺失一部分。

按鍵感應

對于蛇方向的控制,我們是通過上下左右四個按鍵實現的,所以我們還需要修改一下check_events。

先說明一下,這里我沒有使用正常的if-elif對每一個方向進行判斷,其實都一樣的。

首先,蛇不能在向上的情況下按向下,所以是有一個方向沖突的,拿小本本記下來。

# 方向沖突
conflict = {
    pygame.K_RIGHT:4,
    pygame.K_LEFT :3,
    pygame.K_UP   :1,
    pygame.K_DOWN :2,
    0:0,	# 這個純屬湊數,問題不大
    1:2,
    2:1,
    3:4,
    4:3
}

事件檢測:

def check_events(game_stats,conflict,snakes,snake_color,snake_head_color,
				 lattice_wh,food_color,screen):
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
        	# 按鍵匹配
            if event.key in conflict:
                ret = conflict[event.key]
                # 判斷我們輸入的方向和當前方向是否沖突,不沖突就可以修改,然后賦值
                if conflict[ret] != game_stats[1]:
                    game_stats[1] = ret
                    # 調用移動函數
                    going(snakes,snake_color,snake_head_color,
                    	  lattice_wh,game_stats,food_color,screen)
        elif event.type == pygame.QUIT:
            sys.exit()

(這部分,其實改變方向不使用going,也沒什么問題)

整合部分

剩下的工作,就是將整體串起來。
換掉了之前的time.sleep,改成了設置幀率。

import pygame
from fuc import *
from snake import Snake
from time import sleep
from food import Food
# 基本屬性
lattice_wh = 20 #長寬
snake_color = (84, 255, 159)
snake_head_color = (123, 104, 238)
food_color = (255, 64, 64)

# 繪制界面
pygame.init()
screen = pygame.display.set_mode((25*lattice_wh,25*lattice_wh))
pygame.display.set_caption('貪吃蛇')

# 設置幀率
FPS=10
level = 0.9     # 每吃掉一個,間隔時間縮短系數
FPSClock=pygame.time.Clock()

if_lose = 1
if_food = 1

# 蛇的方向
direction = 0
# 得分,吃一個一分
num = 0

# 蛇頭&1個蛇身
snakes = []
snakes.append(Snake(snake_color,snake_head_color,lattice_wh,24*lattice_wh,lattice_wh))
snakes.append(Snake(snake_color,snake_head_color,0,24*lattice_wh,lattice_wh))

# 食物
food = create_food(food_color,screen,lattice_wh,snakes)

# 游戲狀態打包
game_stats =[if_lose,direction,num,food]

# 方向沖突
conflict = {
    pygame.K_RIGHT:4,
    pygame.K_LEFT :3,
    pygame.K_UP   :1,
    pygame.K_DOWN :2,
    0:0,
    1:2,
    2:1,
    3:4,
    4:3
}

while game_stats[0]:
    update(screen,lattice_wh,snakes,game_stats)
    check_events(game_stats,conflict,snakes,snake_color,snake_head_color,
    			 lattice_wh,food_color,screen)
    going(snakes,snake_color,snake_head_color,lattice_wh,game_stats,food_color,screen)
    FPSClock.tick(FPS* level**num)

然后修改一下update函數:

def update(screen,lattice_wh,snakes,game_stats):
    """屏幕刷新"""
    # 背景顏色
    screen.fill((255,255,255))
    # 畫蛇,需要先畫,不然網格會被蓋住
    pygame.draw.rect(screen,snakes[0].head_color,snakes[0].rect)
    for i in range(1,len(snakes)):
        pygame.draw.rect(screen,snakes[i].color,snakes[i].rect)
    # 繪制網格
    for i in range(25):
        pygame.draw.line(screen,(105, 105, 105),(0,lattice_wh*i),(500,lattice_wh*i))
    for i in range(25):
        pygame.draw.line(screen,(105, 105, 105),(lattice_wh*i,0),(lattice_wh*i,500))
    # 繪制食物
    game_stats[3].draw()
    pygame.display.flip()

到此,關于“python中怎么用pygame實現貪吃蛇游戲”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

酒泉市| 肥东县| 沙坪坝区| 吉安县| 调兵山市| 贵港市| 汨罗市| 连州市| 怀化市| 开原市| 庆城县| 金华市| 航空| 大冶市| 榆社县| 广东省| 安图县| 洪雅县| 通榆县| 葵青区| 洪泽县| 遂川县| 鲁甸县| 鄯善县| 镶黄旗| 修水县| 屏南县| 沅陵县| 金乡县| 仙桃市| 德庆县| 铅山县| 大庆市| 玉树县| 年辖:市辖区| 乐业县| 鲁山县| 陆川县| 乌兰浩特市| 青浦区| 同心县|