<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
turtle (小海龜) 是 Python 內建的一個繪圖模組,其實它不僅可以用來繪圖,還可以製作簡單的小遊戲,甚至可以當成簡易的 GUI 模組,編寫簡單的 GUI程式。
本文使用 turtle 模組編寫一個簡單的小遊戲,通過此程式的編寫過程聊一聊對 turtle 模組的感悟。
編寫遊戲,如果要做專業的、趣味性高的,還是請找 pygame,本文用 turtle 編寫遊戲的目的是為了深度理解 turtle 的功能。
turtle 模組的使用相對而言較簡單,對於基礎方法不做講解。只聊 turtle 模組中稍難或大家忽視的地方。
程式執行時,畫布上會出現一個紅色的小球和很多綠色、藍色的小球。
剛開始紅色的小球會朝某一個方向移動,使用者可以通過按下上、下、左、右方向鍵控制紅色小球的運動方向。
綠色、藍色小球以初始的預設方向在畫布上移動。
當紅色的小球碰到綠色小球時,紅色小球球體會變大,當紅色小球碰到藍色小球時,紅色球體會變小。
當紅色小球球體縮小到某一個閾值時,遊戲結束。
本程式需要使用到 turtle、random、math 模組,使用之前,先匯入。
import turtle import random import math ''' 初始化遊戲介面大小 ''' # 遊戲區域的寬度 game_wid = 600 # 遊戲區域的高度 game_hei = 400 # 磚塊的大小,以及每一個小球初始大小 cell = 20 # 紅球初始大小 red_size = cell # 紅色小球 red_ball = None # 儲存綠色小球的列表 green_balls = [] # 儲存藍色小球的列表 blue_balls = [] # 紅色小球的方向 當前方向 0 向右,90 向上 180 向左 -90 向下 dir = 0
上述程式碼說明:
紅色小球只有一個,由變數 red_ball
儲存,紅色小球在運動過程中可以改大小,red_size
儲存其大小。
綠色和藍色小球會有很多,這裡使用 green_balls
和 blue_balls
2 個列表儲存。
隨機位置計算函數: 為小球們隨機生成剛開始出現的位置。
''' 隨機位置計算函數 ''' def rand_pos(): # 水平有 30 個單元格,垂直有 20 個單元格 x = random.randint(-14, 14) y = random.randint(-9, 9) return x * cell, y * cell
繪製指定填充顏色的小正方形: 在遊戲裡有一個虛擬區域,四周使用很多小正方形圍起來。
''' 繪製一個指定填充顏色的正方形 填充顏色可以不指定 ''' def draw_square(color): if color is not None: # 的顏色就填充 turtle.fillcolor(color) turtle.begin_fill() for i in range(4): turtle.fd(cell) turtle.left(90) if color is not None: turtle.end_fill()
自定義畫筆形狀:
使用 turtle 製作遊戲的底層思想:
當我們匯入 turtle
模組時,意味著我們有了一支可以在畫布上畫畫的畫筆,畫筆的預設形狀是一個小海龜。
本文稱這支預設畫筆叫主畫筆,可以使用 turtle
模組中的 turtle.Turtle()
類建立更多畫筆 ,並且可以使用 ``turtle模組提供的
turtle.register_shape(name, shape)` 方法為每一支畫筆客製化畫筆形狀。
如上所述,是使用 turtle
設計遊戲的關鍵。
強調一下:
通過主畫筆建立更多的畫筆,以及為每一支畫筆設定不同的形狀。是編寫遊戲的關鍵,遊戲中的每一個角色,其本質是一支支畫筆,我們只是在控制畫筆在畫布上按我們設計好的軌跡移動。
本遊戲中紅、綠、藍 3 種顏色的小球就是形狀為圓形的畫筆。
畫筆清單:
紅色小球畫筆一支。
綠色小球畫筆 n 支。
藍色小球畫筆 n 支。
''' 自定義畫筆形狀 name:畫筆名稱 color:可選項 ''' def custom_shape(name, size): turtle.begin_poly() turtle.penup() turtle.circle(size) turtle.end_poly() cs = turtle.get_poly() turtle.register_shape(name, cs)
turtle.register_shape(name, shape)
方法引數說明:
開發者繪製的哪一部分圖形用來充當畫筆形狀?
由 turtle.begin_poly() 記錄的第一點到由 turtle.end_poly() 記錄的最後一點之間的圖形作為畫筆形狀。
cs = turtle.get_poly()
可以理解為獲取到剛繪製的圖形,然後使用 turtle.register_shape(name, cs)
註冊畫筆形狀,以後就可以隨時使用此形狀。
如上程式碼記錄了一個圓的繪製過程,也就是建立了一個圓形的畫筆形狀。
移動到某個位置函數:
此函數用來讓某一支畫筆移到指定位置,不留下移動過程中的軌跡。
''' 移到某點 ''' def move_pos(pen, pos): pen.penup() pen.goto(pos) pen.pendown()
引數說明:
pen
: 畫筆物件。pos
:要移到的目標地。註冊鍵盤事件函數:
使用者可以通過鍵盤上的方向鍵更改紅色小球的方向。
turtle
模組提供有很多事件,可以以互動式的方式使用turtle
。turtle
模組中主要有 2 類事件:鍵盤事件、點選事件。因 turtle
的工作重點還是繪製靜態圖案上,其動畫繪製比較弱,所以它的事件少而簡單。
''' 改變紅色小球 4 方向的函數, 這些函數只有當使用者觸發按鍵後方可呼叫,故這些函數也稱為回撥函數。 ''' def dir_right(): global dir dir = 0 def dir_left(): global dir dir = 180 def dir_up(): global dir dir = 90 def dir_down(): global dir dir = -90 ''' 註冊鍵盤響應事件,用來改變紅球的方向 ''' def register_event(): for key, f in {"Up": dir_up, "Down": dir_down, "Left": dir_left, "Right": dir_right}.items(): turtle.onkey(f, key) turtle.listen() ''' 當紅色小球遇到牆體後,也要修改方向 ''' def is_meet_qt(): global dir if red_ball.xcor() < -220: dir = 0 if red_ball.xcor() > 240: dir = 180 if red_ball.ycor() > 140: dir = -90 if red_ball.ycor() < -120: dir = 90
紅色的小球在 2 個時間點需要改變方向,一是使用者按下了方向鍵,一是碰到了牆體。
繪製牆體函數:
牆體是遊戲中的虛擬區域,用來限制小球的活動範圍。
Tips: 牆體由主畫筆繪製。
''' 繪製四面的牆體 ''' def draw_blocks(): # 隱藏畫筆 turtle.hideturtle() # 上下各30個單元格,左右各 20 個單元格 for j in [30, 20, 30, 20]: for i in range(j): # 呼叫前面繪製正方形的函數 draw_square('gray') turtle.fd(cell) turtle.right(90) turtle.fd(-cell) # 回到原點 move_pos(turtle, (0, 0))
建立小球畫筆: 此函數用來建立新畫筆。本程式中的紅色、藍色、綠色小球都是由此函數建立的畫筆,且外觀形狀是圓。
def init_ball(pos, color, shape): # 由主畫筆建立新畫筆 ball = turtle.Turtle() ball.color(color) # 指定新畫筆的形狀,如果不指定,則為預設形狀 ball.shape(shape) # 移到隨機位置 move_pos(ball, pos) # 移動過程要不顯示任何軌跡 ball.penup() return ball
引數說明:
pos
: 建立畫筆後畫筆移動的位置。color
:指定畫筆和填充顏色。shape
: 已經定義好的畫筆形狀名稱。建立綠色、藍色小球:
def ran_gb_ball(balls, color): # 隨機建立藍色、綠色小球的頻率, # 也就是說,不是呼叫此函數就一定會建立小球,概率大概是呼叫 5 次其中會有一次建立 ran = random.randint(1, 5) # 隨機一個角度 a = random.randint(0, 360) # 1/5 的概率 if ran == 5: turtle.tracer(False) # 每一個小球就是一隻畫筆 ball = init_ball(rand_pos(), color, 'ball') ball.seth(a) # 新增到列表中 balls.append(ball) turtle.tracer(True)
為什麼要設定一個概率值?
適當控制藍色、綠色小球的數量。
turtle.tracer(False)
方法的作用:是否顯示畫筆繪製過程中的動畫。False
關閉動畫效果,True
開啟動畫效果。
這裡設定為 False
的原因是不希望使用者看到新畫筆建立過程。
藍色、綠色小球的移動函數:
藍色、綠色小球被建立後會移到一個隨機位置,然後按預設方向移動。
def gb_ball_m(balls): s = 20 a = random.randint(0, 360) r = random.randint(0, 10) for b in balls: b.fd(s) if b.xcor() < -220 or b.xcor() > 240 or b.ycor() > 140 or b.ycor() < -120: b.goto(rand_pos())
當小球碰到牆體後讓其再隨機移到牆體內部(簡單粗粗暴!!)。
紅色球是否碰到了藍色或綠色小球:
此函數邏輯不復雜,計算小球相互之間的座標,判斷座標是否重疊。
''' 紅球是否碰到綠、藍球 ''' def r_g_b_meet(): global red_size # 紅色小球的座標 s_x, s_y = red_ball.pos() # 迭代綠色小球,藍色小球列表 for bs in [green_balls, blue_balls]: for b in bs: # 計算藍色或綠色小球座標 f_x, f_y = b.pos() # 計算和紅色球之間的距離 x_ = math.fabs(s_x - f_x) y_ = math.fabs(s_y - f_y) # 碰撞距離:兩個球的半徑之和 h = cell + red_size if 0 <= x_ <= h and y_ >= 0 and y_ <= h: if b in green_balls: # 遇到綠色球紅球變大 red_size += 2 if b in blue_balls: # 遇到藍色球紅球變大 red_size -= 2 # 關鍵程式碼 custom_shape('red', red_size) return True return False
上述程式碼整體邏輯不復雜。而 custom_shape('red', red_size)
是關鍵程式碼,因紅色小球的半徑發生了變化,所以需要重新客製化紅色小球的外觀形狀,這樣才能在畫布上看到半徑變化的紅色小球。
怎樣讓小球動起來?
每隔一定時間,讓小球重新移動。 turtle.ontimer(ball_move, 100)
是讓小球動起來的核心邏輯,每隔一定時間,重新移動紅、藍、綠外觀如圓形狀的小球。
def ball_move(): red_ball.seth(dir) red_ball.fd(40) # 檢查紅球是否碰到牆體 is_meet_qt() # 隨機建立綠色小球 ran_gb_ball(green_balls, 'green') # 隨機建立藍色小球 ran_gb_ball(blue_balls, 'blue') # 讓綠色小球移動 gb_ball_m(green_balls) # 讓藍色小球移動 gb_ball_m(blue_balls) # 檢查紅球是否碰到藍色、綠色小球 r_g_b_meet() # 定時器 turtle.ontimer(ball_move, 100)
主方法:
if __name__ == "__main__": # 關閉動畫效果 turtle.tracer(False) # 註冊事件 register_event() # 客製化 2 種畫筆形狀 for name in ['red', 'ball']: custom_shape(name, cell) # 主畫筆移動牆體的左上角 move_pos(turtle, (-300, 200)) # 繪製牆體 draw_blocks() red_ball = init_ball(rand_pos(), 'red', 'red') turtle.tracer(True) # 讓紅球移動起來 ball_move() # turtle.done()
以上為此遊戲程式中的每一個函數講解。
執行後,可以控制紅色小球,當遇到綠色球和藍色球時,紅色球體會變大或變小。
使用 turtle
模組的過程說明了一個道理,沒有所謂簡單的知識,如果你認為簡單,那是因為你對它的認知太淺。只是學到了大家都學到的內容。
如果要真正悟透知識點的核心,需要多查閱官方檔案,把所有內容吃透,並試著把這些知識向更高層面拔高。
到此這篇關於Python turtle編寫簡單的球類小遊戲的文章就介紹到這了,更多相關Python turtle遊戲內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45