今天,突發奇想的想用python寫一款小游戲--貪吃蛇。相信大家都玩過,那麼玩一款自己寫的是一種什麼樣的體驗呢。
我們首先導入相關模塊
## 導入相關模塊import randomimport pygameimport sys 那麼這三個模塊有什麼意思呢。我們一一介紹。1.random
Python中的random模塊用於生成隨機數,它提供了很多函數。常用函數總結如下:1. random.random()用於生成一個0到1的隨機浮點數: 0 <= n < 1.02. random.seed(n)用於設定種子值,其中的n可以是任意數字。random.random() 生成隨機數時,每一次生成的數都是隨機的。但是,使用 random.seed(n) 設定好種子之後,在先調用seed(n)時,使用 random() 生成的隨機數將會是同一個。3. random.uniform(a,b)返回a,b之間的隨機浮點數,若a<=b則范圍[a,b],若a>=b則范圍[b,a] ,a和b可以是實數。4. random.randint(a,b)返回a,b之間的整數,范圍[a,b],注意:傳入參數必須是整數,a一定要比b小。5. random.randrange([start=0], stop[, step=1])返回前閉後開區間[start,stop)內的整數,可以設置step。只能傳入整數。6. random.choice(sequence)從sequence(序列,列表、元組和字符串)中隨機獲取一個元素。7. random.choice(sequence, k)從sequence(序列,列表、元組和字符串)中隨機獲取k個元素,可能重復,k用參數名傳值,k省略則默認取1個,返回list。8. random. shuffle(x)用於將列表中的元素打亂順序,俗稱為洗牌。9. random. sample(sequence,k)從指定序列中隨機獲取k個不重復元素作為一個列表返回, sample函數不會修改原有序列。知識點擴展:python random模塊導入及用法random是程序隨機數,很多地方用到,驗證碼,圖片上傳的圖片名稱等,下面說說python random模塊導入及用法1,模塊導入import random2,random用法random.randomrange(1,10) 返回1-10隨機數,不包括10random.randomint(1,10) 返回1-10隨機數,包括10random.randomrange(1,100,2) 隨機選取0-100的偶數random.random() 返回浮點數random.choice()random.sample() 從多個字符選取特定字符2.pygame
pygame簡介pygame可以實現python游戲的一個基礎包。pygame實現窗口初始化pygame,init()類似於java類的初始化方法,用於pygame初始化。pygame.init()設置屏幕,(500,400)設置屏幕初始大小為500 * 400的大小,0和32 是比較高級的用法。這樣我們便設置了一個500*400的屏幕。surface = pygame.display.set_mode((500, 400), 0, 32)如果不設置pygame事件的話,窗口會一閃而逝。這裡去捕捉pygame的事件,如果沒有按退出,那麼窗口就會一直保持著,這樣方便我們去設置不同的內容展示。3.sys
sys模塊 與 os包一樣,也是對系統資源進行調用。功能同樣也是非常豐富,接下來我們會對 sys模塊的一些簡單且常用的函數進行介紹,主要針對一些非功能性的函數與屬性來認識一些不太常見的 Python 背後的事件。sys 中的常用方法
編輯 示例如下:
//author:愛吃餅干的小白鼠
import sys
modules = sys.modules # 將 sys 模塊的 modules 屬性 賦值給 modules 並打印輸出 Python啟動時加載的模塊集合
print(modules)
# sys.exit(0) # 取消注釋該行代碼,下方所有的代碼將不再執行
path = sys.path
print(path) # 將 sys 模塊的 path 屬性 賦值給 path 並打印輸出 python 環境可以導入內置、第三方包與函數的所在路徑
code = sys.getdefaultencoding() # 將 sys 模塊 的 getdefaultencoding()函數 賦值給 code 並打印輸出當前系統的編碼[utf-8]
print(code)
# >>> 執行結果如下:
# >>> utf-8
print(sys.platform) # 獲取當前系統平台(如windows、Mac、linux)
# >>> 執行結果如下:
# >>> darwin
print(sys.version) # 獲取當前 Python 的版本
# >>> 執行結果如下:
# >>> 3.8.7 (v3.8.7:6503f05dd5, Dec 21 2020, 12:45:15)
# >>> [Clang 6.0 (clang-600.0.57)]
言歸正傳,我們繼續說說下一步我們要怎麼做。
初始化
snake_speed = 10 #貪吃蛇的速度
windows_width = 800
windows_height = 600 #游戲窗口的大小
cell_size = 20 #貪吃蛇身體方塊大小,注意身體大小必須能被窗口長寬整除
顏色定義
# 顏色定義
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 = black #游戲背景顏色
我們接下來定義一下四個方向
# 定義方向
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("Python 貪吃蛇小游戲") #設置標題
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 == QUIT:
terminate()
elif event.type == KEYDOWN:
if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT:
direction = LEFT
elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT:
direction = RIGHT
elif (event.key == K_UP or event.key == K_w) and direction != DOWN:
direction = UP
elif (event.key == K_DOWN or event.key == K_s) and direction != UP:
direction = DOWN
elif event.key == K_ESCAPE:
terminate()
move_snake(direction, snake_coords) #移動蛇
ret = snake_is_alive(snake_coords)
if 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 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)}
接下來,我們設計一個開局畫面,代碼如下:
while True: #鍵盤監聽事件
for event in pygame.event.get(): # event handling loop
if event.type == QUIT:
terminate() #終止程序
elif event.type == KEYDOWN:
if (event.key == K_ESCAPE): #終止程序
terminate() #終止程序
else:
return #結束此函數, 開始游戲
我們再來設計游戲結算的畫面。
#游戲結束信息顯示
def show_gameover_info(screen):
font = pygame.font.Font('myfont.ttf', 40)
tip = font.render('按Q或者ESC退出游戲, 按任意鍵重新開始游戲~', True, (65, 105, 225))
gamestart = pygame.image.load('gameover.png')
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 == QUIT:
terminate() #終止程序
elif event.type == KEYDOWN:
if event.key == K_ESCAPE or event.key == K_q: #終止程序
terminate() #終止程序
else:
return #結束此函數, 重新開始游戲
當我們貪吃蛇吃一個食物得多少分,我們可以這樣寫:
#畫成績
def draw_score(screen,score):
font = pygame.font.Font('myfont.ttf', 30)
scoreSurf = font.render('得分: %s' % score, True, Green)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (windows_width - 120, 10)
screen.blit(scoreSurf, scoreRect)
到這裡,我們貪吃蛇的主體程序已經寫出來,我們稍加完善就能運行。