基于Pygame實現(xiàn)簡單的貪吃蛇游戲
導(dǎo)入相關(guān)的包
import pygame, sys, random from pygame.locals import *
設(shè)置屏幕大小以及基本參數(shù)
設(shè)置屏幕大小為400*400,mainClock = pygame.time.Clock()用來設(shè)置時間同步,不會根據(jù)計算機(jī)的運行來決定運行多少次, mainClock.tick(1) 一秒只會運行一次,設(shè)置了屏幕的底色為白色。
# 定義屏幕的寬高 WIDTH = 400 HEIGHT = 400 # 初始化屏幕 設(shè)置窗口標(biāo)題 surface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32) pygame.display.set_caption('貪吃蛇') pygame.init() mainClock = pygame.time.Clock() # 定義使用的顏色 BLACK = (0, 0, 0) GREEN = (0, 255, 0) WHITE = (255, 255, 255) while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() surface.fill(WHITE) pygame.display.update() mainClock.tick(1)
設(shè)置貪吃蛇的位置,以及移動的大小
這里設(shè)置了貪吃蛇的長度和起始位置,和食物和蛇的寬度,這里必須設(shè)置為可以被食物和蛇的寬度整除的數(shù),這樣才能保證蛇能到任意的位置
# 設(shè)置蛇的初始長度 snakeWidth = 4 # 設(shè)置蛇的起始位置為(40,40) snakeX = 40 snakeY = 40 # 食物和蛇的寬度設(shè)置為8 FOODSNAKEWIDTH = 8 # 定義四個方向 moveLeft = False moveRight = False moveUp = False moveDown = False # 定義初始的方向 moveRight = True def getSnake(): # 設(shè)置蛇的初始長度為4,并設(shè)置蛇的初始位置為(40,40) # 因為貪吃蛇會拐彎,所以將蛇設(shè)置為一個列表 snake = [] for i in range(snakeWidth): snake.append(pygame.Rect(snakeX + i * FOODSNAKEWIDTH, snakeY, FOODSNAKEWIDTH, FOODSNAKEWIDTH)) return snake # 貪吃蛇 snake = getSnake()
繪制蛇
surface.fill(WHITE) for s in snake: pygame.draw.rect(surface, BLACK, s)
讓蛇動起來
這里將蛇列表最后一位移除,然后將第一位的位置根據(jù)方向加減坐標(biāo)
snake.pop() newTop = copy.deepcopy(snake[0]) # 改變蛇的位置 if moveRight: newTop.left += FOODSNAKEWIDTH if moveLeft: newTop.left -= FOODSNAKEWIDTH if moveUp: newTop.top -= FOODSNAKEWIDTH if moveDown: newTop.top += FOODSNAKEWIDTH snake.insert(0, newTop)
這樣會有一個問題,如果超出屏幕呢,我們將超出屏幕,那么就會消失,我們只需要你移動第一個元素的時候,如果超出則將元素移動另一個位置。
# 改變蛇的位置 if moveRight: if newTop.right == WIDTH: newTop.left = 0 else: newTop.left += FOODSNAKEWIDTH if moveLeft: if newTop.left == 0: newTop.right == WIDTH else: newTop.left -= FOODSNAKEWIDTH if moveUp: if newTop.top == 0: newTop.bottom = HEIGHT else: newTop.top -= FOODSNAKEWIDTH if moveDown: if newTop.bottom == HEIGHT: newTop.top = 0 else: newTop.top += FOODSNAKEWIDTH
實現(xiàn)貪吃蛇拐彎
為了實現(xiàn)對應(yīng)的功能,我們將方向變量改為一個變量,這樣我們方便修改方向
# 定義四個方向 # moveLeft moveRight moveUp moveDown # 定義初始的方向 snakeDirection = "moveRight" ---- 省略的代碼 ---- for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == KEYDOWN: if event.key == K_LEFT: if snakeDirection == "moveRight": snake.reverse() snakeDirection = "moveLeft" if event.key == K_RIGHT: if snakeDirection == "moveLeft": snake.reverse() snakeDirection = "moveRight" if event.key == K_UP: if snakeDirection == "moveDown": snake.reverse() snakeDirection = "moveUp" if event.key == K_DOWN: if snakeDirection == "moveUp": snake.reverse() snakeDirection = "moveDown"
為了方便看到效果,我將mainClock.tick(1) 設(shè)置為mainClock.tick(3)
實現(xiàn)隨機(jī)食物
這里用了很啰嗦的代碼,我自己也看不下去,有點含糊,這里為了簡單只設(shè)計了一個食物,遍歷屏幕上不是貪吃蛇的可以放食物的集合,然后隨機(jī)生成一個食物。
if len(foods) < foodnum: canFoodColl = [] # 獲取當(dāng)前不是貪吃蛇的位置集合 for x in range(sizeNum): for y in range(sizeNum): foodExist = True for sn in snake: if x * FOODSNAKEWIDTH == sn.left and y * FOODSNAKEWIDTH == sn.top: foodExist = False break if foodExist: canFoodColl.append({'x': x, 'y': y}) f = canFoodColl[random.randint(0, len(canFoodColl))] foods.append(pygame.Rect(f['x'], f['y'], FOODSNAKEWIDTH, FOODSNAKEWIDTH))
吃食物
這里用 colliderect判斷二者是否相撞,然后食物集合置空,不減去貪吃蛇集合的最后一個元素。
if len(foods) < foodnum: canFoodColl = [] # 獲取當(dāng)前不是貪吃蛇的位置集合 for x in range(sizeNum): for y in range(sizeNum): foodExist = True for sn in snake: if x * FOODSNAKEWIDTH == sn.left and y * FOODSNAKEWIDTH == sn.top: foodExist = False break if foodExist: canFoodColl.append({'x': x, 'y': y}) f = canFoodColl[random.randint(0, len(canFoodColl))] foods.append(pygame.Rect(f['x'] * FOODSNAKEWIDTH, f['y'] * FOODSNAKEWIDTH, FOODSNAKEWIDTH, FOODSNAKEWIDTH)) print(f['x']) print(f['y']) else: if newTop.colliderect(foods[0]): foods = [] eatFlg = True print('xxx')
完整代碼?
import pygame, sys, random from pygame.locals import * import copy # 定義屏幕的寬高 WIDTH = 400 HEIGHT = 400 # 初始化屏幕 設(shè)置窗口標(biāo)題 surface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32) pygame.display.set_caption('貪吃蛇') pygame.init() mainClock = pygame.time.Clock() # 定義使用的顏色 BLACK = (0, 0, 0) GREEN = (0, 255, 0) WHITE = (255, 255, 255) # 設(shè)置蛇的初始長度 snakeWidth = 4 # 設(shè)置蛇的起始位置為(40,40) snakeX = 40 snakeY = 40 # 食物和蛇的寬度設(shè)置為8 FOODSNAKEWIDTH = 8 # 定義四個方向 # moveLeft moveRight moveUp moveDown # 定義初始的方向 snakeDirection = "moveRight" # 食物區(qū)間 foods = [] # 用去寬度處以對應(yīng)的 大小,減去1 就是食物矩形起點可以存在的區(qū)間 #sizeNum = HEIGHT / FOODSNAKEWIDTH - 1 # 這里為了減少計算 sizeNum = 39 # 為了簡單我們只設(shè)置一個食物 foodnum = 1 def getSnake(): # 設(shè)置蛇的初始長度為4,并設(shè)置蛇的初始位置為(40,40) # 因為貪吃蛇會拐彎,所以將蛇設(shè)置為一個列表 snake = [] for i in range(snakeWidth): snake.append(pygame.Rect(snakeX + i * FOODSNAKEWIDTH, snakeY, FOODSNAKEWIDTH, FOODSNAKEWIDTH)) return snake # 貪吃蛇 snake = getSnake() while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == KEYDOWN: if event.key == K_LEFT: if snakeDirection == "moveRight": snake.reverse() snakeDirection = "moveLeft" if event.key == K_RIGHT: if snakeDirection == "moveLeft": snake.reverse() snakeDirection = "moveRight" if event.key == K_UP: if snakeDirection == "moveDown": snake.reverse() snakeDirection = "moveUp" if event.key == K_DOWN: if snakeDirection == "moveUp": snake.reverse() snakeDirection = "moveDown" surface.fill(WHITE) for s in snake: pygame.draw.rect(surface, BLACK, s) for f in foods: pygame.draw.rect(surface, GREEN, f) pygame.display.update() # 是否吃了食物 eatFlg = False newTop = copy.deepcopy(snake[0]) # 改變蛇的位置 if snakeDirection == "moveRight": if newTop.right == WIDTH: newTop.left = 0 else: newTop.left += FOODSNAKEWIDTH if snakeDirection == "moveLeft": if newTop.left == 0: newTop.right = WIDTH else: newTop.left -= FOODSNAKEWIDTH if snakeDirection == "moveUp": if newTop.top == 0: newTop.bottom = HEIGHT else: newTop.top -= FOODSNAKEWIDTH if snakeDirection == "moveDown": if newTop.bottom == HEIGHT: newTop.top = 0 else: newTop.top += FOODSNAKEWIDTH if len(foods) < foodnum: canFoodColl = [] # 獲取當(dāng)前不是貪吃蛇的位置集合 for x in range(sizeNum): for y in range(sizeNum): foodExist = True for sn in snake: if x * FOODSNAKEWIDTH == sn.left and y * FOODSNAKEWIDTH == sn.top: foodExist = False break if foodExist: canFoodColl.append({'x': x, 'y': y}) f = canFoodColl[random.randint(0, len(canFoodColl))] foods.append(pygame.Rect(f['x'] * FOODSNAKEWIDTH, f['y'] * FOODSNAKEWIDTH, FOODSNAKEWIDTH, FOODSNAKEWIDTH)) print(f['x']) print(f['y']) else: if newTop.colliderect(foods[0]): foods = [] eatFlg = True print('xxx') snake.insert(0, newTop) if not eatFlg: snake.pop() mainClock.tick(3)
以上就是基于Pygame實現(xiàn)簡單的貪吃蛇游戲的詳細(xì)內(nèi)容,更多關(guān)于Pygame 貪吃蛇游戲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
pandas實現(xiàn)datetime64與unix時間戳互轉(zhuǎn)
這篇文章主要介紹了pandas實現(xiàn)datetime64與unix時間戳互轉(zhuǎn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07Python3.5以上版本lxml導(dǎo)入etree報錯的解決方案
這篇文章主要介紹了Python3.5以上版本lxml導(dǎo)入etree報錯的解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-06-06Django admin實現(xiàn)TextField字段changelist頁面換行、空格正常顯示
本文主要介紹了Django admin實現(xiàn)TextField字段changelist頁面換行、空格正常顯示,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01教你使用Python實現(xiàn)一個簡易版Web服務(wù)器
這篇文章主要介紹了教你使用Python實現(xiàn)一個簡易版Web服務(wù)器,本篇文章將通過實現(xiàn)一個簡易版的Web服務(wù)器,幫助讀者理解Python網(wǎng)絡(luò)編程的基本概念和技巧,需要的朋友可以參考下2023-04-04在PyCharm中找不到Conda創(chuàng)建的環(huán)境的解決方法
本文主要介紹了在PyCharm中找不到Conda創(chuàng)建的環(huán)境的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07