002_Snake_FreePythonGames用海龜畫圖實現簡單的貪吃蛇游戲


一 相關知識

1 randrange()函數

  • 功能:randrange() 方法返回指定遞增基數集合中的一個隨機數,基數默認值為1。
  • 語法:random.randrange ([start,] stop [,step])
    • 注意:randrange()是不能直接訪問的,需要導入 random 模塊,然后通過 random 靜態對象調用該方法。
      • 方法一:import random
      • 方法二:from random import randrange
  • 參數:
    • start -- 指定范圍內的開始值,包含在范圍內。
    • stop -- 指定范圍內的結束值,不包含在范圍內。
    • step -- 指定遞增基數。
  • 返回值:從給定的范圍返回隨機項。

2 turtle.tracer()函數

  • 功能:啟用/禁用海龜動畫並設置刷新圖形的延遲時間。——可看作是為了加快/減慢作圖的,你可以在里面添加參數
  • 語法:turtle.tracer(n=None,delay=None)
    • 如果指定 n 值,則只有每第 n 次屏幕刷新會實際執行。(可被用來加速復雜圖形的繪制。) 如果調用時不帶參數,則返回當前保存的 n 值。第二個參數設置延遲值 
    • n -- 非負整型數;delay -- 非負整型數
      • turtle.tracer(False)或者duturtle.tracer(0):圖形將一次性畫好
      • turtle.tracer(1):圖形按照正常速度進行,可有可無
      • turtle.tracer(4):在循環中,圖形將一次畫出4次循環的圖

3 turtle.update():執行一次 TurtleScreen 刷新。在禁用追蹤時使用。

4 turtle.clear():從中刪除所有海龜的全部繪圖。將已清空的 TurtleScreen 重置為初始狀態: 白色背景,無背景片,無事件綁定並啟用追蹤。

5 turtle.ontimer(fun,t):安裝一個計時器,在tms后調用fun函數

 

二 分析過程https://www.jb51.net/article/153788.htm

貪吃蛇的身體是由list構成的,list中每一個元組代表貪吃蛇在棋盤上的坐標,我們只需在這些位置畫上圖案,就能制作出一條圓滾滾的貪吃蛇來。但是如果想讓貪吃蛇活蹦亂跳,我們就要寫一個move函數。

1貪吃蛇怎么移動

如果貪吃蛇沒吃到食物,那么我們就刪除list中最后一個坐標,再在蛇頭部分插入新的位置。如何確定新的位置呢,我們就要設定貪吃蛇移動的方向(x,y),將原蛇頭位置的坐標在移動方向上進行加減操作。這樣貪吃蛇就實現了向前移動的目標。如果貪吃蛇恰好吃到了食物,唯一的不同就是不需要刪除貪吃蛇尾部的元素。其中需要注意的是,貪吃蛇不能朝着當前移動方向的反方向移動。體現在代碼中,就是當前方向與改變方向的乘積不能為負值。

2 如何知道貪吃蛇吃到了食物呢

如果貪吃蛇蛇頭的坐標與食物的坐標重合的話,貪吃蛇就吃到了食物。如果貪吃蛇吃到了食物,就在棋盤上隨機更新食物。如果隨機生成的食物的坐標,恰好與貪吃蛇的位置重合的話,就繼續隨機產生坐標,直到確保與貪吃蛇的坐標不同的時候。

3 如何知道游戲失敗了呢

如果貪吃蛇蛇頭的坐標與邊框的坐標重合的話,蛇卒。如果貪吃蛇各個部分的坐標有重合的話,就說明貪吃蛇咬到了自己,游戲結束。

三  代碼

代碼功能都是齊全的,然后按鍵控制onkey函數中的參數是'Right',我一直以為是通過輸入這個字符串控制貪吃蛇移動的,結果它的意思是按鍵盤上的向上的方向鍵,並不是輸入字符串,所以我一直沒辦法通過鍵盤控制貪吃蛇的移動方向,導致我還以為是代碼有問題。。。。

然后跟原來的代碼相比,我加了一部分改變食物位置的changeFood函數,原理跟改變貪吃蛇移動方向的changeSnake函數一致。

該貪吃蛇程序是利用turtle庫完成的,網上很多貪吃蛇代碼都是利用pygame庫實現的,那些資料里面可能游戲開始結束設置的比較全面一點,但是用turtle庫感覺簡單了好多有木有!!!

 1 """Snake,classic arcade game
 2 Exercise
 3 1. How do you make the snake faster or slower?    通過改變ontimer(move,500)語句中的第二個參數
 4 2. How can you make the snake go around the edges?可將初始坐標定為(180,0)、(-180,0)、(0,180)、(0,-180)、(180,180)、(-180,180)、(180,-180)、(-180,-180)
 5 3  How would you move the food?                   通過onkey函數調用changeFood函數改變食物坐標
 6 4. Change the snake to respond to arrow keys.     已經實現了吧,Right、Left、Up、Down分別對應向右、向左、向上、向下箭頭
 7 """
 8 
 9 from turtle import *                         # 導入turtle庫,此種方式導入可直接使用庫內函數,不使用trutle.做前導
10 from random import randrange                 # 從random庫中導入randrange()函數,使food隨機出現
11 from freegames import square,vector          # 從freegames庫中導入square和vector,用square正方形表示food、snake,用vector這個二維向量表示snake
12 
13 food = vector(0,0)                           # 初始化food變量,用來表示第一個食物在坐標為(0,0)處
14 snake = [vector(180,0)]                      # 初始化snake,而且snake是列表,其元素是向量
15 aim = vector(0,-10)                          # 用來控制貪吃蛇的移動方向和距離
16 aim2 = vector(10,10)                         # 用來控制食物移動的方向和距離
17 
18 
19 def changeSnake(x,y):                        # 改變貪吃蛇移動方向部分,通過onkey函數和lambda表達式調用changeSnake函數,獲得下一個移動坐標(x,y)
20     "Change snake direction."
21     aim.x = x                                # 將x的值賦給aim.x改變貪吃蛇目標的橫坐標
22     aim.y = y                                # 將y的值賦給aim.x改變貪吃蛇目標的縱坐標
23 
24 def changeFood(x,y):                         # 改變食物移動方向部分,通過onkey函數和lambda表達式調用changeFood函數,獲得下一個移動坐標(x/2,y/2)
25     "Change food direction."
26     aim2.x = x/2                             # 將x/2的值賦給aim2.x改變食物目標的橫坐標
27     aim2.y = y/2                             # 將y/2的值賦給aim2.y改變食物目標的縱坐標
28 
29 def inside(head):                            # 判斷貪吃蛇有沒有碰到畫布邊界部分,限制貪吃蛇的移動范圍
30     "Return True if head inside the boundaries."
31     return -200 < head.x < 190 and -200 < head.y < 190
32 
33 def move():
34     "Move snake forward one segment."
35     # 更改食物和貪吃蛇蛇頭坐標
36     head = snake[-1].copy()                   # 表示復制snake列表的最后一個元素,這里用列表的最后一個元素表示蛇頭
37     head.move(aim)                            # 每調用一次move函數,貪吃蛇就移動到(head.x+aim.x,head.y+aim.y)的位置
38     food.move(aim2)                           # 每調用一次move函數,食物就移動到(food.x+aim2.x,food.y+aim2.y)的位置
39     
40     #判斷游戲是否結束
41     if not inside(head) or head in snake:     # 判斷是否結束游戲部分:head碰到牆壁|頭碰到身體
42         square(head.x,head.y,9,'red')         # 將貪吃蛇蛇頭的正方形改成紅色,表示游戲結束
43         update()                              # 執行一次屏幕刷新
44         return                                # 用來終止程序的運行,其后語句不會再執行
45     
46     # 更新貪吃蛇的身體
47     snake.append(head)                        # 蛇頭坐標已經更改,將新的蛇頭目標添加到snake列表中
48 
49     if head == food:                          # snake吃到food,下一個food會隨機出現在畫布的另一個地方
50         print('Snake',len(snake))             # 打印貪吃蛇的長度
51         food.x = randrange(-15,15) * 10       # 隨機產生食物橫坐標
52         food.y = randrange(-15,15) * 10       # 隨機產生食物縱坐標
53     else:                                     # snake沒有吃到food
54         snake.pop(0)                          # snake沒有吃到食物,所以將snake列表最后一個元素刪除,保持貪吃蛇長度不變,這里用列表的第一個元素表示蛇尾
55     
56     # 清空畫布,重新畫好食物和貪吃蛇的位置,利用ontimer函數調用move函數,控制貪吃蛇進行下一次移動
57     clear()                                   # 相當於刷新操作,將所有的繪圖全部刪了
58 
59     for body in snake:                        # 重新畫出貪吃蛇的身體部分
60         square(body.x,body.y,9,'black')       # 黑色方塊表示貪吃蛇的身體
61     square(food.x,food.y,9,'green')           # 畫出食物,綠色方塊表示食物
62     update()                                  # 執行一次屏幕刷新
63     ontimer(move,500)                         # 經過500ms后繼續調用move函數
64 
65 setup(420,420,370,0)                          # 初始畫布尺寸
66 hideturtle()                                  # 隱藏鼠標
67 tracer(False)                                 # 保證畫圖操作(食物和貪吃蛇身體)一次性完成
68 move()
69 listen()                                      # 監聽,屏幕聚焦
70 # 綁定鍵盤方向,改變貪吃蛇的移動方向
71 onkey(lambda:changeSnake(10,0),'Right')       # 右轉,Right是鍵盤方向鍵的右鍵,不是輸入單詞Right
72 onkey(lambda:changeSnake(-10,0),'Left')       # 左轉
73 onkey(lambda:changeSnake(0,10),'Up')          # 向上走
74 onkey(lambda:changeSnake(0,-10),'Down')       # 向下走
75 # 綁定鍵盤方向,改變食物的移動方向
76 onkey(lambda:changeFood(10,0),'D')            # 右轉,在鍵盤上輸入大寫字母'D'
77 onkey(lambda:changeFood(-10,0),'A')           # 左轉
78 onkey(lambda:changeFood(0,10),'W')            # 向上走
79 onkey(lambda:changeFood(0,-10),'S')           # 向下走
80 
81 done()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM