Python+Turtle制作海龜迷宮小游戲
導語
哈嘍!大家好!我是木木子~
縱觀之前的文章——我發(fā)現(xiàn)了一個特點,很多小伙伴兒都喜歡學習Turtle或游戲代碼,沒錯吧~
那今天這篇文章就是為這2方面的小伙伴兒精心準備滴!Turtle+游戲一起安排一波啦!
從Turtle開始介紹—基礎(chǔ)知識到實踐案例這篇文章都寫到了嘞!不要以為是單單一個項目哦,想學Turtle的必學篇,不要錯過啦~
最后今天小編會帶大家寫一個利用Turtle的一款海龜闖關(guān)的三大迷宮哦!這工程量還是挺大的!都是繪制下來的話代碼量比較多了撒,400行代碼才完成這款“海龜闖關(guān)走迷宮的”小游戲!
一、簡介
1.什么是Turtle
Turtle英譯過來為烏龜,不過我們介紹的不是這種動物,而是以此命名的一個繪圖軟件。
在python文檔中介紹了Turtle本身是一款簡單、易上手的繪圖軟件,非常適合新手進入編程的世界。
海龜繪圖Turtle是Python內(nèi)置模塊,總之是非常簡單好玩的一個庫。
其動作主要有:抬筆,此后的動作只是移動畫筆,畫布上不會留下痕跡;落筆,只要移動畫筆,畫布上就會留下痕跡。
畫筆動作只絕對移動、相對移動、向前(后)移動、轉(zhuǎn)向(絕對角度、相對角度)、圓或圓弧、點(實心圓),故畫不了橢圓,繪制函數(shù)曲線困難!
2.怎么玩轉(zhuǎn)Turtle
當然在這里需要進入python編程環(huán)境,然后在這個python文件中就可以開始動手寫有關(guān)turtle的代碼。
Turtle是python安裝時自帶的內(nèi)置模塊,調(diào)用該模塊非常簡單,直接使用import方式加載:
import turtle 或 from turtle import *
這也是程序的第一行代碼,用于準備好使用turtle這個模塊。
3.畫布的設(shè)置
1.1設(shè)置畫布大小
turtle.screensize() # 返回默認大小(400, 300)
1.2以默認繪圖窗口大小顯示窗口,窗口居屏幕中心
turtle.screensize(width, hight[, bg])
其中:width——表示畫布寬度(單位像素);Hight——表示畫布高度(單位像素);bg——畫布背景顏色,該參數(shù)可缺省,缺省時為白色背景
1.3案例
如:
turtle.screensize(800, 600, "green"),表示畫布大小為800×600,綠色畫布。
turtle.setup(width, hight[, x, y])
其中:width, height——表示畫布寬和高。當為整數(shù)時表示像素;為小數(shù)時則表示占據(jù)計算機屏幕的比例
4.設(shè)置背景/畫布顏色
turtle.bgcolor()
二、Turtle的畫筆設(shè)置
turtle.pensize(size)
其中:size——畫筆粗細,用像素表示。
1.turtle繪圖的基本方法
導入turtle庫繪圖模塊后,就可以實現(xiàn)繪圖,基本操作是向前(后)畫直線,旋轉(zhuǎn)(向左向右改變方向),畫圓(圓弧)等。
這里介紹幾個最常用的命令。
1.1設(shè)置畫筆的屬性
| 命令 | 說明 |
|---|---|
| turtle.pensize(width) | 用于設(shè)置畫筆的寬度(即粗細),width越大越粗 |
| turtle.pencolor(color) | 用于設(shè)置畫筆的顏色,color參數(shù)可以是字符串如"green","red",也可以是RGB三元組 |
| turtle.shape(shape) | 用于設(shè)置畫筆的形狀,shape參數(shù)為字符串,主要包含“turtle”烏龜形狀,“square”正方形形狀等 |
| turtle.speed(speed) | 用于設(shè)置畫筆的移動速度。speed參數(shù)可以是字符串如“fast”,"slow"等,也可以是0到10間的整數(shù) |
1.2畫筆繪圖的命令
| 命令 | 說明 |
|---|---|
| turtle.fd(dis) | 沿當前畫筆方向向前移動dist像素長度 |
| turtle.bk(dist) | 沿當前畫筆相反方向移動dist像素長度 |
| turtle.right(degree) | 沿當前畫筆方向向右轉(zhuǎn)degree° |
| turtle.left(degree) | 沿當前畫筆方向向左轉(zhuǎn)degree° |
| turtle.down() | 將畫筆放下,開始畫圖 |
| turtle.up() | 提起筆移動,不繪制圖形 |
| turtle.circle() | 畫圓,半徑為正(負),表示圓心在畫筆的左邊(右邊)畫圓 |
| setx( ) | 將當前x軸移動到指定位置 |
| sety( ) | 將當前y軸移動到指定位置 |
| setheading(degree) | 用于設(shè)置畫筆的方向,參數(shù)degree為畫筆方向與海龜坐標系x軸正向的夾角度數(shù) |
| ht() | 用于將畫筆隱藏 |
三、最后的案例Turtle小游戲
1.設(shè)計思路游戲規(guī)則
這個海龜闖關(guān)的小迷宮游戲是設(shè)計了三個關(guān)卡,運行代碼之后會有相應的關(guān)卡彈窗設(shè)置,想完那關(guān)可以直接玩那關(guān), 也可以按照順序闖關(guān)。
特別注意:
很多人擔心過不了關(guān)?沒關(guān)系,小編給大家開了一個掛,這個掛就是按住F1就出現(xiàn)了迷宮的路線圖哦!按住F2就是出現(xiàn)了一個海龜?shù)狡瘘c自己走路線哈!
2.準備環(huán)節(jié)
小編用的Python3、Pycharm2021、Turtle模塊導入即可。
然后相應的圖片素材:

3.正式敲代碼
# -*- coding: UTF-8 -*-
"""
源碼基地:#806965976#
csdn賬號:顧木子吖
海龜迷宮闖關(guān)游戲
"""
import turtle # 導入海龜繪圖模塊
import random # 導入隨機數(shù)模塊
game_title = '小海龜大迷宮闖關(guān)小游戲' # 游戲名字
level = 0 # 關(guān)卡
'''繪制地圖用的全局變量'''
txt_path = 'map/map1.txt' # 地圖信息文本文件路徑及名稱
road_color = (191, 217, 225) # 迷宮通道的顏色
R, C = 0, 0 # 迷宮地圖的總行數(shù)R、總列數(shù)C
cell_size = 20 # 一個格子的尺寸
area_sign = {} # 記錄入口和出口索引位置
mazeList = [] # 地圖列表
'''海龜對象'''
map_t = turtle.Turtle() # 繪制地圖的海龜
map_t.speed(0) # 設(shè)置繪圖速度最快(地圖繪制)
sign_t = turtle.Turtle() # 繪制入口和出口標記的海龜
auto_t = turtle.Turtle() # 自動走迷宮的海龜
auto_t.pensize(5) # 畫筆粗細(自動)
auto_t.speed(0) # 設(shè)置繪圖速度最快(手動)
auto_t.ht() # 隱藏海龜光標
manual_t = turtle.Turtle() # 手動走迷宮的海龜
manual_t.pensize(5) # 畫筆粗細(手動)
manual_t.speed(0) # 設(shè)置繪圖速度最快(手動)
manual_t.shape('turtle') # 設(shè)置海龜光標為小海龜(手動)
manual_t.ht() # 隱藏手動走迷宮所用的海龜光標(手動)
# 要探索4個方向?qū)饕淖兓?guī)則
direction = [
(1, 0), # 右
(-1, 0), # 左
(0, 1), # 上
(0, -1) # 下
]
def imoveto(ci, ri):
"""
功能:根據(jù)索引位置移動海龜(不畫線)
:param ci: 列索引
:param ri: 行索引
:return:
"""
auto_t.penup() # 抬筆
cx, cy = itoc((ci, ri)) # 將索引位置轉(zhuǎn)換為坐標位置
auto_t.goto(cx, cy) # 移動到指定位置
auto_t.pendown() # 落筆
auto_t.shape('turtle') # 設(shè)置海龜光標的形狀
auto_t.color('red') # 設(shè)置畫筆顏色為紅色
auto_t.st() # 顯示海龜光標
def c_move_to(t, ctuple): # 移動到指定位置
"""
功能:根據(jù)坐標位置移動到指定位置(不畫線)
:param t: 海龜對象
:param ctuple: 記錄坐標位置的元組
:return:
"""
t.ht() # 隱藏海龜光標
t.penup() # 抬筆
t.goto(ctuple[0], ctuple[1]) # 移動到坐標指定的位置
t.pendown() # 落筆
def itoc(ituple):
"""
將索引位置轉(zhuǎn)換為實際坐標位置
:param ituple: 行、列索引組成的元組
:return: 實際坐標位置
"""
ci = ituple[0]
ri = ituple[1]
tx = ci * cell_size - C * cell_size / 2 # 根據(jù)索引值計算每個正方形的起點(x坐標)
ty = R * cell_size / 2 - ri * cell_size # 根據(jù)索引值計算每個正方形的起點(y坐標)
cx = tx + cell_size / 2 # 正方形中心的x坐標
cy = ty - cell_size / 2 # 正方形中心的y坐標
return (cx, cy)
def ctoi(cx, cy):
"""
根據(jù)cx和cy求在列表中對應的索引
:param cx: x軸坐標
:param cy: y軸坐標
:return: 元組,(ci,ri)
"""
ci = ((C - 1) * cell_size / 2 + cx) / cell_size # 計算列索引
ri = ((R - 1) * cell_size / 2 - cy) / cell_size # 計算行索引
return (int(ri), int(ci)) # 返回行列索引的元組
def get_map(filename):
"""
功能:讀取保存地圖的文本文件內(nèi)容到列表
:param filename: 地圖文件名
:return: 地圖列表
"""
with open(filename, 'r') as f: # 打開文件
fl = f.readlines() # 讀取全部行
maze_list = [] # 保存地圖的列表
for line in fl: # 將讀取的內(nèi)容以空格分割為二維列表
line = line.strip() # 去掉空格
line_list = line.split(" ") # 以空格進行分割為列表
maze_list.append(line_list) # 將分割后的列表添加到地圖列表中
return maze_list # 返回地圖列表
def draw_square(ci, ri, colorsign):
"""
功能:繪制組成地圖的小正方形
:param ci: 列索引
:param ri: 行索引
:param colorsign: 填充顏色
:return:
"""
tx = ci * cell_size - C * cell_size / 2 # 根據(jù)索引值計算每個正方形的起點(x坐標)
ty = R * cell_size / 2 - ri * cell_size # 根據(jù)索引值計算每個正方形的起點(y坐標)
map_t.penup() # 抬筆
map_t.goto(tx, ty) # 移動到繪圖起點(正方形的左上角)
if colorsign == '1': # 判斷是否為墻(如果為墻,則隨機生成填充顏色)
r = random.randint(100, 130) # 紅色值
g = random.randint(150, 180) # 綠色值
map_t.color(r, g, 200) # 指定顏色為隨機生成的顏色
else:
map_t.color(colorsign) # 設(shè)置為指定的通道顏色
map_t.pendown() # 落筆
map_t.begin_fill() # 填充開始
for i in range(4): # 繪制正方形
map_t.fd(cell_size)
map_t.right(90)
map_t.end_fill() # 填充結(jié)束
map_t.ht() # 隱藏海龜光標
def draw_map(mazelist):
"""
功能:遍歷地圖列表繪制迷宮地圖
:param mazelist: 保存地圖數(shù)據(jù)的列表
:return:
"""
turtle.tracer(0) # 隱藏動畫效果
global area_sign # 全局變量,記錄入口和出口索引位置
for ri in range(R): # 遍歷行
for ci in range(C): # 遍歷列
item = mazelist[ri][ci]
if item in ['1']: # 判斷墻
draw_square(ci, ri, '1') # 繪制墻
elif item == "S": # 判斷入口
draw_square(ci, ri, road_color) # 繪制通道
draw_sign(ci - 1, ri, '入口') # 標記入口
area_sign['entry_i'] = (ci, ri) # 保存入口索引
elif item == "E": # 判斷出口
draw_square(ci, ri, road_color) # 繪制通道
draw_sign(ci - 1, ri, '出口') # 標記出口
area_sign['exit_i'] = (ci, ri) # 保存出口索引
else:
draw_square(ci, ri, road_color) # 繪制通道
turtle.tracer(1) # 顯示動畫效果
def draw_sign(ci, ri, word):
"""
功能:繪制入口和出口標記
:param ci: 列索引
:param ri: 行索引
:param word: 標記文字內(nèi)容
:return:
"""
cx, cy = itoc((ci, ri)) # 將索引位置轉(zhuǎn)換為坐標位置
sign_t.ht() # 隱藏海龜光標
sign_t.penup() # 抬筆
sign_t.goto(cx, cy) # 移動到標記位置
sign_t.color('red') # 設(shè)置畫筆為紅色
sign_t.write(word, font=('黑體', 12, 'normal')) # 繪制標記文字
def win_tip():
"""
功能:制作過關(guān)提示
:return:
"""
global level
c_move_to(manual_t, (-150, 0))
manual_t.color('blue')
if int(level) == 3:
manual_t.write('\n恭喜您順利通關(guān)!', font=('黑體', 20, 'bold'))
turtle.onkey(turtle.bye, key='Return') # 監(jiān)聽按下Enter鍵退出游戲
else:
manual_t.write('\n恭喜過關(guān)!\n按下Enter進入下一關(guān)!', font=('黑體', 20, 'bold'))
level += 1
manual_t.color('red')
turtle.onkey(level_init, key='Return') # 監(jiān)聽按下Enter鍵
def manual_move(d):
"""
功能:手動走迷宮時通用探索并移動函數(shù)
:param d: 向不同方面走時索引的變化規(guī)則
:return:
"""
dc, dr = d # 將表示方向的元組分別賦值給兩個變量dc和dr,其中dc為x軸方向,dr為y軸方向
rici = ctoi(round(manual_t.xcor(), 1) + dc * cell_size, round(manual_t.ycor(), 1) + dr * cell_size) # 獲取行列索引
point = mazeList[rici[0]][rici[1]] # 獲取地圖列表中對應點的值
print('移動:', rici, point)
if point == '0': # 通路
manual_t.color('red')
mazeList[rici[0]][rici[1]] = '$' # 將當前位置標記為已探索
manual_t.forward(cell_size) # 向前移動
print('00')
elif point == '$': # 已探索
manual_t.color(road_color) # 繪制和通道相同顏色的線,達到擦除痕跡的效果
mazeList[rici[0] + dr][rici[1] - dc] = '0' # 將當前位置的前一個點設(shè)置為未探索(目的是取消標記)
manual_t.forward(road_color) # 向前移動
manual_t.color('red')
elif point == 'E': # 出口
win_tip()
def up_move(): # 朝上
manual_t.setheading(90) # 設(shè)置海龜朝向
manual_move(direction[2]) # 手動探索并移動
def down_move(): # 朝下
manual_t.setheading(270) # 設(shè)置海龜朝向
manual_move(direction[3]) # 手動探索并移動
def left_move(): # 朝左
manual_t.setheading(180) # 設(shè)置海龜朝向
manual_move(direction[1]) # 手動探索并移動
def right_move(): # 朝右
manual_t.setheading(0) # 設(shè)置海龜朝向
manual_move(direction[0]) # 手動探索并移動
def manual_path():
"""
功能:手動走迷宮
:return:
"""
manual_t.clear() # 清除繪圖
auto_t.ht() # 隱藏海龜
auto_t.clear() # 清除繪圖
global mazeList # 定義全局變量
mazeList = get_map(txt_path) # 重新讀取地圖數(shù)據(jù)
# print(area_sign['entry_i'][0],area_sign['entry_i'][1])
c_move_to(manual_t, itoc(area_sign['entry_i'])) # 移動到入口位置
manual_t.st() # 顯示手動走迷宮所用的海龜光標
manual_t.width(3) # 設(shè)置畫筆粗細為3像素
manual_t.color('red') # 設(shè)置畫筆為紅色
manual_t.getscreen().listen() # 讓海龜屏幕(TurtleScreen)獲得焦點
manual_t.getscreen().onkeyrelease(up_move, 'Up') # 按下向上方向鍵
manual_t.getscreen().onkeyrelease(down_move, 'Down') # 按下向下方向鍵
manual_t.getscreen().onkeyrelease(left_move, 'Left') # 按下向左方向鍵
manual_t.getscreen().onkeyrelease(right_move, 'Right') # 按下向右方向鍵
def auto_path():
"""
功能:查看答案(自動走迷宮)
:return:
"""
global mazeList # 定義全局變量
mazeList = get_map(txt_path) # 重新讀取地圖數(shù)據(jù)
manual_t.ht() # 隱藏海龜
manual_t.clear() # 清除繪圖
auto_t.clear() # 清除繪圖
auto_t.pensize(5) # 設(shè)置畫筆粗細
auto_t.speed(0) # 繪圖速度
auto_t.ht() # 隱藏海龜光標
find(mazeList) # 開始探索
def find(mazeList):
"""
功能:開始探索
:param mazeList: 地圖列表
:return:
"""
auto_t.clear() # 清空幫助
start_r, start_c = 0, 0
for ri in range(R):
for ci in range(C):
item = mazeList[ri][ci]
if item == "S":
start_r, start_c = ri, ci
auto_t.penup() # 抬筆
draw_path(start_c, start_r)
find_next(mazeList, start_c, start_r)
def find_next(mlist, ci, ri):
"""
功能:遞歸搜索判斷是否為通路
:param mlist: 地圖列表
:param ci: 列索引
:param ri: 行索引
:return: 布爾值,表示是否為通路
"""
if mlist[ri][ci] == "E":
imoveto(ci, ri) # 移動到出口
return True
if not (0 <= ci < C and 0 <= ri < R): # 判斷位置是否不合法
return False
if mlist[ri][ci] in ['1', '$']: # 判斷是否為墻或者已探索過的
return False
mlist[ri][ci] = "$" # 標記已探索過
for d in direction: # 嘗試從不同方向探索是否為通路,如果發(fā)現(xiàn)一條通路,則不再繼續(xù)探索
dc, dr = d # # 將索引變化規(guī)則的值分別賦值給dc和dr,其中dc為x軸方向,dr為y軸方向
found = find_next(mlist, ci + dc, ri + dr) # 遞歸調(diào)用
if found: # 如果是通路則繪制線路
draw_path(ci, ri) # 繪制線路
return True # 返回True,不再探索
return False # 當所有方向都不通時,返回False
def draw_path(ci, ri, color="green"): # 自動繪制用
"""
功能:根據(jù)索引位置移動海龜(畫線)
:param ci: 列索引
:param ri: 行索引
:param color: 畫筆顏色
:return:
"""
auto_t.st() # 顯示海龜光標
cx, cy = itoc((ci, ri)) # 將索引位置轉(zhuǎn)換為坐標位置
auto_t.color(color)
auto_t.goto(cx, cy)
def level_init():
"""
功能:關(guān)卡初始化
游戲規(guī)則:
按下F2鍵開始手動走迷宮;按下F1鍵查看答案
按下↑↓←→方向鍵控制小海龜移動,闖關(guān)成功后,按Enter進入下一關(guān)
:return:
"""
manual_t.clear() # 清除繪圖
auto_t.clear() # 清除繪圖
turtle.clear() # 清除繪圖
global txt_path, level, mazeList, R, C # 定義全局變量
if level == 1: # 第一關(guān)的地圖文件和背景
txt_path = "map/map1.txt"
levelbg = 'image/level1.png'
elif level == 2: # 第二關(guān)的地圖文件和背景
txt_path = "map/map2.txt"
levelbg = 'image/level2.png'
elif level == 3: # 第三關(guān)的地圖文件和背景
txt_path = "map/map3.txt"
levelbg = 'image/level3.png'
else:
turtle.bye() # 退出程序
return
mazeList = get_map(txt_path) # 獲取地圖數(shù)據(jù)
R, C = len(mazeList), len(mazeList[0])
turtle.setup(width=C * cell_size + 50, height=R * cell_size + 100) # 根據(jù)地圖調(diào)整窗口尺寸
turtle.bgpic(levelbg) # 設(shè)置背景圖片
'''
# 如果想要手動繪制關(guān)卡數(shù),可以使用下面的兩行代碼
cmoveto(turtle, (1 * cellsize - C * cellsize / 2, R * cellsize / 2+10))
turtle.write('關(guān)卡:'+str(int(level)), font=('宋體', 16, 'normal'))
'''
turtle.ht() # 隱藏海龜光標
draw_map(mazeList) # 繪制地圖
四、效果圖
1.運行代碼

2.關(guān)卡一
這是按住了F1所以才出現(xiàn)路線圖的哦!

3.關(guān)卡二
這是按住了F2所以是自己手動在闖關(guān)哈!

4.關(guān)卡三

以上就是Python+Turtle制作海龜迷宮小游戲的詳細內(nèi)容,更多關(guān)于Python Turtle迷宮游戲的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Pycharm終端顯示PS而不顯示虛擬環(huán)境名的解決
這篇文章主要介紹了Pycharm終端顯示PS而不顯示虛擬環(huán)境名的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
python定時采集攝像頭圖像上傳ftp服務器功能實現(xiàn)
本文程序?qū)崿F(xiàn)python定時采集攝像頭圖像上傳ftp服務器功能,大家參考使用吧2013-12-12
在Python中使用matplotlib模塊繪制數(shù)據(jù)圖的示例
這篇文章主要介紹了在Python中使用matplotlib模塊繪制數(shù)據(jù)圖的示例,matplotlib模塊經(jīng)常被用來實現(xiàn)數(shù)據(jù)的可視化,需要的朋友可以參考下2015-05-05

