最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python?turtle編寫(xiě)簡(jiǎn)單的球類(lèi)小游戲

 更新時(shí)間:2022年03月31日 11:54:48   作者:一枚大果殼  
turtle?(小海龜)?是?Python?內(nèi)置的一個(gè)繪圖模塊,其實(shí)它不僅可以用來(lái)繪圖,還可以制作簡(jiǎn)單的小游戲。本文將利用Turtle制作一個(gè)簡(jiǎn)單的球類(lèi)小游戲,感興趣的可以學(xué)習(xí)一下

1. 前言

turtle (小海龜) 是 Python 內(nèi)置的一個(gè)繪圖模塊,其實(shí)它不僅可以用來(lái)繪圖,還可以制作簡(jiǎn)單的小游戲,甚至可以當(dāng)成簡(jiǎn)易的 GUI 模塊,編寫(xiě)簡(jiǎn)單的 GUI程序。

本文使用 turtle 模塊編寫(xiě)一個(gè)簡(jiǎn)單的小游戲,通過(guò)此程序的編寫(xiě)過(guò)程聊一聊對(duì) turtle 模塊的感悟。

編寫(xiě)游戲,如果要做專(zhuān)業(yè)的、趣味性高的,還是請(qǐng)找 pygame,本文用 turtle 編寫(xiě)游戲的目的是為了深度理解 turtle 的功能。

turtle 模塊的使用相對(duì)而言較簡(jiǎn)單,對(duì)于基礎(chǔ)方法不做講解。只聊 turtle 模塊中稍難或大家忽視的地方。

2. 需求描述

程序運(yùn)行時(shí),畫(huà)布上會(huì)出現(xiàn)一個(gè)紅色的小球和很多綠色、藍(lán)色的小球。

剛開(kāi)始紅色的小球會(huì)朝某一個(gè)方向移動(dòng),使用者可以通過(guò)按下上、下、左、右方向鍵控制紅色小球的運(yùn)動(dòng)方向。

綠色、藍(lán)色小球以初始的默認(rèn)方向在畫(huà)布上移動(dòng)。

當(dāng)紅色的小球碰到綠色小球時(shí),紅色小球球體會(huì)變大,當(dāng)紅色小球碰到藍(lán)色小球時(shí),紅色球體會(huì)變小。

當(dāng)紅色小球球體縮小到某一個(gè)閾值時(shí),游戲結(jié)束。

3. 制作流程

3.1 初始化變量

本程序需要使用到 turtle、random、math 模塊,使用之前,先導(dǎo)入。

import turtle
import random
import math
'''
初始化游戲界面大小
'''
# 游戲區(qū)域的寬度
game_wid = 600  
# 游戲區(qū)域的高度
game_hei = 400  
# 磚塊的大小,以及每一個(gè)小球初始大小
cell = 20
# 紅球初始大小
red_size = cell
# 紅色小球
red_ball = None
# 存儲(chǔ)綠色小球的列表
green_balls = []
# 存儲(chǔ)藍(lán)色小球的列表
blue_balls = []
# 紅色小球的方向 當(dāng)前方向 0 向右,90 向上 180 向左 -90 向下
dir = 0

上述代碼說(shuō)明:

紅色小球只有一個(gè),由變量 red_ball 保存,紅色小球在運(yùn)動(dòng)過(guò)程中可以改大小,red_size 保存其大小。

綠色和藍(lán)色小球會(huì)有很多,這里使用 green_balls 和 blue_balls 2 個(gè)列表存儲(chǔ)。

3.2 通用函數(shù)

隨機(jī)位置計(jì)算函數(shù): 為小球們隨機(jī)生成剛開(kāi)始出現(xiàn)的位置。

'''
隨機(jī)位置計(jì)算函數(shù)
'''
def rand_pos():
    # 水平有 30 個(gè)單元格,垂直有 20 個(gè)單元格
    x = random.randint(-14, 14)
    y = random.randint(-9, 9)
    return x * cell, y * cell

繪制指定填充顏色的小正方形: 在游戲里有一個(gè)虛擬區(qū)域,四周使用很多小正方形圍起來(lái)。

'''
繪制一個(gè)指定填充顏色的正方形
填充顏色可以不指定
'''
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()

自定義畫(huà)筆形狀:

使用 turtle 制作游戲的底層思想:

當(dāng)我們導(dǎo)入 turtle 模塊時(shí),意味著我們有了一支可以在畫(huà)布上畫(huà)畫(huà)的畫(huà)筆,畫(huà)筆的默認(rèn)形狀是一個(gè)小海龜。

本文稱(chēng)這支默認(rèn)畫(huà)筆叫主畫(huà)筆,可以使用 turtle 模塊中的 turtle.Turtle() 類(lèi)創(chuàng)建更多畫(huà)筆 ,并且可以使用 ``turtle模塊提供的turtle.register_shape(name, shape)` 方法為每一支畫(huà)筆定制畫(huà)筆形狀。

如上所述,是使用 turtle 設(shè)計(jì)游戲的關(guān)鍵。

強(qiáng)調(diào)一下:

通過(guò)主畫(huà)筆創(chuàng)建更多的畫(huà)筆,以及為每一支畫(huà)筆設(shè)置不同的形狀。是編寫(xiě)游戲的關(guān)鍵,游戲中的每一個(gè)角色,其本質(zhì)是一支支畫(huà)筆,我們只是在控制畫(huà)筆在畫(huà)布上按我們?cè)O(shè)計(jì)好的軌跡移動(dòng)。

本游戲中紅、綠、藍(lán) 3 種顏色的小球就是形狀為圓形的畫(huà)筆。

畫(huà)筆清單:

紅色小球畫(huà)筆一支。

綠色小球畫(huà)筆 n 支。

藍(lán)色小球畫(huà)筆 n 支。

'''
自定義畫(huà)筆形狀
name:畫(huà)筆名稱(chēng)
color:可選項(xiàng)
'''
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) 方法參數(shù)說(shuō)明:

  • name: 自定義形狀的名稱(chēng)。
  • shape: 由開(kāi)發(fā)者繪制的形狀。

開(kāi)發(fā)者繪制的哪一部分圖形用來(lái)充當(dāng)畫(huà)筆形狀?

由 turtle.begin_poly() 記錄的第一點(diǎn)到由 turtle.end_poly() 記錄的最后一點(diǎn)之間的圖形作為畫(huà)筆形狀。

cs = turtle.get_poly() 可以理解為獲取到剛繪制的圖形,然后使用 turtle.register_shape(name, cs) 注冊(cè)畫(huà)筆形狀,以后就可以隨時(shí)使用此形狀。

如上代碼記錄了一個(gè)圓的繪制過(guò)程,也就是創(chuàng)建了一個(gè)圓形的畫(huà)筆形狀。

移動(dòng)到某個(gè)位置函數(shù):

此函數(shù)用來(lái)讓某一支畫(huà)筆移到指定位置,不留下移動(dòng)過(guò)程中的軌跡。

'''
移到某點(diǎn)
'''
def move_pos(pen, pos):
    pen.penup()
    pen.goto(pos)
    pen.pendown()

參數(shù)說(shuō)明:

  • pen : 畫(huà)筆對(duì)象。
  • pos:要移到的目標(biāo)地。

注冊(cè)鍵盤(pán)事件函數(shù):

使用者可以通過(guò)鍵盤(pán)上的方向鍵更改紅色小球的方向。

turtle 模塊提供有很多事件,可以以交互式的方式使用turtleturtle 模塊中主要有 2 類(lèi)事件:鍵盤(pán)事件、點(diǎn)擊事件。因 turtle 的工作重點(diǎn)還是繪制靜態(tài)圖案上,其動(dòng)畫(huà)繪制比較弱,所以它的事件少而簡(jiǎn)單。

'''
改變紅色小球 4 方向的函數(shù),
這些函數(shù)只有當(dāng)使用者觸發(fā)按鍵后方可調(diào)用,故這些函數(shù)也稱(chēng)為回調(diào)函數(shù)。
'''
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
   
'''
注冊(cè)鍵盤(pán)響應(yīng)事件,用來(lái)改變紅球的方向
'''
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()
'''
當(dāng)紅色小球遇到墻體后,也要修改方向
'''    
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 個(gè)時(shí)間點(diǎn)需要改變方向,一是使用者按下了方向鍵,一是碰到了墻體。

3.3 游戲角色函數(shù)

繪制墻體函數(shù):

墻體是游戲中的虛擬區(qū)域,用來(lái)限制小球的活動(dòng)范圍。

Tips: 墻體由主畫(huà)筆繪制。

'''
繪制四面的墻體
'''
def draw_blocks():
    # 隱藏畫(huà)筆
    turtle.hideturtle()
    # 上下各30個(gè)單元格,左右各 20 個(gè)單元格
    for j in [30, 20, 30, 20]:
        for i in range(j):
            # 調(diào)用前面繪制正方形的函數(shù)
            draw_square('gray')
            turtle.fd(cell)
        turtle.right(90)
        turtle.fd(-cell)
    # 回到原點(diǎn)
    move_pos(turtle, (0, 0))

創(chuàng)建小球畫(huà)筆: 此函數(shù)用來(lái)創(chuàng)建新畫(huà)筆。本程序中的紅色、藍(lán)色、綠色小球都是由此函數(shù)創(chuàng)建的畫(huà)筆,且外觀形狀是圓。

def init_ball(pos, color, shape):
    #  由主畫(huà)筆創(chuàng)建新畫(huà)筆
    ball = turtle.Turtle()
    ball.color(color)
    # 指定新畫(huà)筆的形狀,如果不指定,則為默認(rèn)形狀
    ball.shape(shape)
    # 移到隨機(jī)位置
    move_pos(ball, pos)
    # 移動(dòng)過(guò)程要不顯示任何軌跡
    ball.penup()
    return ball

參數(shù)說(shuō)明:

  • pos: 創(chuàng)建畫(huà)筆后畫(huà)筆移動(dòng)的位置。
  • color:指定畫(huà)筆和填充顏色。
  • shape: 已經(jīng)定義好的畫(huà)筆形狀名稱(chēng)。

創(chuàng)建綠色、藍(lán)色小球:

def ran_gb_ball(balls, color):
    # 隨機(jī)創(chuàng)建藍(lán)色、綠色小球的頻率,
    # 也就是說(shuō),不是調(diào)用此函數(shù)就一定會(huì)創(chuàng)建小球,概率大概是調(diào)用 5 次其中會(huì)有一次創(chuàng)建
    ran = random.randint(1, 5)
    # 隨機(jī)一個(gè)角度
    a = random.randint(0, 360)
    # 1/5 的概率
    if ran == 5:
        turtle.tracer(False)
        # 每一個(gè)小球就是一只畫(huà)筆
        ball = init_ball(rand_pos(), color, 'ball')
        ball.seth(a)
        # 添加到列表中
        balls.append(ball)
        turtle.tracer(True)

為什么要設(shè)置一個(gè)概率值?

適當(dāng)控制藍(lán)色、綠色小球的數(shù)量。

turtle.tracer(False) 方法的作用:是否顯示畫(huà)筆繪制過(guò)程中的動(dòng)畫(huà)。False 關(guān)閉動(dòng)畫(huà)效果,True 打開(kāi)動(dòng)畫(huà)效果。

這里設(shè)置為 False 的原因是不希望用戶(hù)看到新畫(huà)筆創(chuàng)建過(guò)程。

藍(lán)色、綠色小球的移動(dòng)函數(shù):

藍(lán)色、綠色小球被創(chuàng)建后會(huì)移到一個(gè)隨機(jī)位置,然后按默認(rèn)方向移動(dòng)。

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())

當(dāng)小球碰到墻體后讓其再隨機(jī)移到墻體內(nèi)部(簡(jiǎn)單粗粗暴?。。?。

紅色球是否碰到了藍(lán)色或綠色小球:

此函數(shù)邏輯不復(fù)雜,計(jì)算小球相互之間的坐標(biāo),判斷坐標(biāo)是否重疊。

'''
紅球是否碰到綠、藍(lán)球
'''
def r_g_b_meet():
    global red_size
    # 紅色小球的坐標(biāo)
    s_x, s_y = red_ball.pos()
    # 迭代綠色小球,藍(lán)色小球列表
    for bs in [green_balls, blue_balls]:
        for b in bs:
            # 計(jì)算藍(lán)色或綠色小球坐標(biāo)
            f_x, f_y = b.pos()
            # 計(jì)算和紅色球之間的距離
            x_ = math.fabs(s_x - f_x)
            y_ = math.fabs(s_y - f_y)
            # 碰撞距離:兩個(gè)球的半徑之和
            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:
                    # 遇到藍(lán)色球紅球變大
                    red_size -= 2
                # 關(guān)鍵代碼    
                custom_shape('red', red_size)
                return True
    return False

上述代碼整體邏輯不復(fù)雜。而 custom_shape('red', red_size) 是關(guān)鍵代碼,因紅色小球的半徑發(fā)生了變化,所以需要重新定制紅色小球的外觀形狀,這樣才能在畫(huà)布上看到半徑變化的紅色小球。

3.4 讓小球動(dòng)起來(lái)

怎樣讓小球動(dòng)起來(lái)?

每隔一定時(shí)間,讓小球重新移動(dòng)。 turtle.ontimer(ball_move, 100) 是讓小球動(dòng)起來(lái)的核心邏輯,每隔一定時(shí)間,重新移動(dòng)紅、藍(lán)、綠外觀如圓形狀的小球。

def ball_move():
    red_ball.seth(dir)
    red_ball.fd(40)
    # 檢查紅球是否碰到墻體
    is_meet_qt()
    # 隨機(jī)創(chuàng)建綠色小球
    ran_gb_ball(green_balls, 'green')
    # 隨機(jī)創(chuàng)建藍(lán)色小球
    ran_gb_ball(blue_balls, 'blue')
    # 讓綠色小球移動(dòng)
    gb_ball_m(green_balls)
    # 讓藍(lán)色小球移動(dòng)
    gb_ball_m(blue_balls)
    # 檢查紅球是否碰到藍(lán)色、綠色小球
    r_g_b_meet()
    # 定時(shí)器
    turtle.ontimer(ball_move, 100)

主方法:

if __name__ == "__main__":
    # 關(guān)閉動(dòng)畫(huà)效果
    turtle.tracer(False)
    # 注冊(cè)事件
    register_event()
    # 定制 2 種畫(huà)筆形狀
    for name in ['red', 'ball']:
        custom_shape(name, cell)
    # 主畫(huà)筆移動(dòng)墻體的左上角
    move_pos(turtle, (-300, 200))
    # 繪制墻體
    draw_blocks()
    red_ball = init_ball(rand_pos(), 'red', 'red')
    turtle.tracer(True)
    # 讓紅球移動(dòng)起來(lái)
    ball_move()
    #
    turtle.done()

以上為此游戲程序中的每一個(gè)函數(shù)講解。

運(yùn)行后,可以控制紅色小球,當(dāng)遇到綠色球和藍(lán)色球時(shí),紅色球體會(huì)變大或變小。

4. 總結(jié)

使用 turtle 模塊的過(guò)程說(shuō)明了一個(gè)道理,沒(méi)有所謂簡(jiǎn)單的知識(shí),如果你認(rèn)為簡(jiǎn)單,那是因?yàn)槟銓?duì)它的認(rèn)知太淺。只是學(xué)到了大家都學(xué)到的內(nèi)容。

如果要真正悟透知識(shí)點(diǎn)的內(nèi)核,需要多查閱官方文檔,把所有內(nèi)容吃透,并試著把這些知識(shí)向更高層面拔高。

到此這篇關(guān)于Python turtle編寫(xiě)簡(jiǎn)單的球類(lèi)小游戲的文章就介紹到這了,更多相關(guān)Python turtle游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python多線程調(diào)用exit無(wú)法退出的解決方法

    python多線程調(diào)用exit無(wú)法退出的解決方法

    今天小編就為大家分享一篇python多線程調(diào)用exit無(wú)法退出的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • 徹底解決No?module?named?‘torch_geometric‘報(bào)錯(cuò)的辦法

    徹底解決No?module?named?‘torch_geometric‘報(bào)錯(cuò)的辦法

    這篇文章主要給大家介紹了關(guān)于如何徹底解決No?module?named?‘torch_geometric‘報(bào)錯(cuò)的辦法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Python將MP4視頻轉(zhuǎn)換為GIF圖像的三種方法

    Python將MP4視頻轉(zhuǎn)換為GIF圖像的三種方法

    在數(shù)字時(shí)代,將視頻轉(zhuǎn)換為GIF圖像已成為一種流行的內(nèi)容創(chuàng)作方式,在Python中,有多種庫(kù)可以幫助你將MP4視頻轉(zhuǎn)換為GIF圖像,本文將介紹三種常用的方法:使用moviepy庫(kù)、imageio庫(kù)以及結(jié)合opencv和PIL庫(kù),需要的朋友可以參考下
    2024-12-12
  • 如何利用PyQt5制作一個(gè)簡(jiǎn)單的登錄界面

    如何利用PyQt5制作一個(gè)簡(jiǎn)單的登錄界面

    初學(xué)者制作登錄界面時(shí)常遇到網(wǎng)上代碼看不懂、不會(huì)用、用不了的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于如何利用PyQt5制作一個(gè)簡(jiǎn)單的登錄界面,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • python實(shí)現(xiàn)xlwt xlrd 指定條件給excel行添加顏色

    python實(shí)現(xiàn)xlwt xlrd 指定條件給excel行添加顏色

    這篇文章主要介紹了python實(shí)現(xiàn)xlwt xlrd 指定條件給excel行添加顏色,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-07-07
  • Restful_framework視圖組件代碼實(shí)例解析

    Restful_framework視圖組件代碼實(shí)例解析

    這篇文章主要介紹了Restful_framework視圖組件代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • tensorflow之并行讀入數(shù)據(jù)詳解

    tensorflow之并行讀入數(shù)據(jù)詳解

    今天小編就為大家分享一篇tensorflow之并行讀入數(shù)據(jù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02
  • python深度學(xué)習(xí)tensorflow安裝調(diào)試教程

    python深度學(xué)習(xí)tensorflow安裝調(diào)試教程

    這篇文章主要為大家介紹了python深度學(xué)習(xí)tensorflow安裝調(diào)試教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • python super()函數(shù)的基本使用

    python super()函數(shù)的基本使用

    這篇文章主要介紹了python super()函數(shù)的基本使用,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-09-09
  • Python之split函數(shù)的深入理解

    Python之split函數(shù)的深入理解

    split函數(shù)主要應(yīng)用場(chǎng)景是Python對(duì)字符串的處理中(數(shù)據(jù)分析,數(shù)據(jù)處理),以及計(jì)算機(jī)二級(jí)考試的常考基礎(chǔ)知識(shí)點(diǎn),這篇文章主要介紹了Python之split函數(shù)的詳解,需要的朋友可以參考下
    2023-02-02

最新評(píng)論

柳河县| 玛曲县| 宣武区| 公安县| 沾化县| 东宁县| 武穴市| 芦山县| 分宜县| 临邑县| 民县| 长子县| 安顺市| 乐清市| 台前县| 连州市| 兴仁县| 客服| 平陆县| 依兰县| 阿拉善右旗| 静安区| 静海县| 丹阳市| 海兴县| 石河子市| 澄城县| 云阳县| 连州市| 双辽市| 阳城县| 康乐县| 洛宁县| 克山县| 太原市| 石泉县| 泸水县| 溧阳市| 定结县| 扶绥县| 乌审旗|