<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 貪食蛇 > 原文: [http://zetcode.com/gui/tcltktutorial/nibbles/](http://zetcode.com/gui/tcltktutorial/nibbles/) 在 Tcl/Tk 教程的這一部分中,我們將創建一個貪食蛇游戲克隆。 貪食蛇是較舊的經典視頻游戲。 它最初是在 70 年代后期創建的。 后來它被帶到 PC 上。 在這個游戲中,玩家控制蛇。 目的是盡可能多地吃蘋果。 蛇每次吃一個蘋果,它的身體就會長大。 蛇必須避開墻壁和自己的身體。 ## 開發 蛇的每個關節的大小為 10px。 蛇由光標鍵控制。 最初,蛇具有三個關節。 游戲立即開始。 游戲結束后,我們在窗口中心顯示`"Game Over"`消息。 我們使用`canvas`小部件來創建游戲。 游戲中的對象是圖像。 我們使用畫布命令創建圖像項。 我們使用畫布命令使用標簽在畫布上查找項目并進行碰撞檢測。 ```tcl #!/usr/bin/wish # ZetCode Tcl/Tk tutorial # # This is simple Nibbles game clone. # # author: Jan Bodnar # last modified: March 2011 # website: www.zetcode.com package require Img set WIDTH 300 set HEIGHT 300 set DELAY 100 set DOT_SIZE 10 set ALL_DOTS [expr $WIDTH * $HEIGHT / ($DOT_SIZE * $DOT_SIZE)] set RAND_POS 27 canvas .c -width $WIDTH -height $HEIGHT -background black pack .c proc initGame {} { set ::left false set ::right true set ::up false set ::down false set ::inGame true set dots 3 set ::apple_x 100 set ::apple_y 190 for {set i 0} {$i<$dots} {incr i} { set x($i) [expr 50 - $i * 10] set y($i) 50 } set ::idot [image create photo img1 -file "dot.png"] set ::ihead [image create photo img2 -file "head.png"] set ::iapple [image create photo img3 -file "apple.png"] createObjects locateApple bind . "<Key>" "onKeyPressed %K" after $::DELAY onTimer } proc createObjects {} { .c create image $::apple_x $::apple_y \ -image $::iapple -tag apple -anchor nw .c create image 50 50 -image $::ihead -tag head -anchor nw .c create image 30 50 -image $::idot -tag dot -anchor nw .c create image 40 50 -image $::idot -tag dot -anchor nw } proc checkApple {} { set apple [.c find withtag apple] set head [.c find withtag head] set l [.c bbox head] set overlap [eval .c find overlapping $l] foreach over $overlap { if {$over == $apple} { set crd [.c coords $apple] set x [lindex $crd 0] set y [lindex $crd 1] .c create image $x $y -image $::idot -anchor nw -tag dot locateApple } } } proc doMove {} { set dots [.c find withtag dot] set head [.c find withtag head] set items [concat $dots $head] set z 0 while {$z < [expr [llength $items] - 1]} { set c1 [.c coords [lindex $items $z]] set c2 [.c coords [lindex $items [expr $z+1]]] .c move [lindex $items $z] [expr [lindex $c2 0] - [lindex $c1 0] ] \ [expr [lindex $c2 1] - [lindex $c1 1] ] incr z } if { [string compare $::left true] == 0} { .c move head -$::DOT_SIZE 0 } if {[string compare $::right true] == 0} { .c move head $::DOT_SIZE 0 } if {[string compare $::up true] == 0} { .c move head 0 -$::DOT_SIZE } if {[string compare $::down true] == 0} { .c move head 0 $::DOT_SIZE } } proc checkCollisions {} { set dots [.c find withtag dot] set head [.c find withtag head] set l [.c bbox head] set overlap [eval .c find overlapping $l] foreach dot $dots { foreach over $overlap { if {$over == $dot} { set ::inGame false } } } set x1 [lindex $l 0] set y1 [lindex $l 1] if {$x1 < 0} { set ::inGame false } if {$x1 > [expr $::WIDTH - $::DOT_SIZE]} { set ::inGame false } if {$y1 < 0} { set ::inGame false } if {$y1 > [expr $::HEIGHT - $::DOT_SIZE]} { set ::inGame false } } proc locateApple {} { set apple [.c find withtag apple] .c delete lindex apple 0 set r [expr round(rand() * $::RAND_POS)] set ::apple_x [expr $r * $::DOT_SIZE] set r [expr round(rand() * $::RAND_POS)] set ::apple_y [expr $r * $::DOT_SIZE] .c create image $::apple_x $::apple_y -anchor nw \ -image $::iapple -tag apple } proc onKeyPressed {key} { set a1 [ expr [string compare $key Left] == 0] set a2 [ expr [string compare $::right true] != 0] if { $a1 && $a2 } { set ::left true set ::up false set ::down false } set b1 [ expr [string compare $key Right] == 0] set b2 [ expr [string compare $::left true] != 0] if { $b1 && $b2 } { set ::right true set ::up false set ::down false } set c1 [ expr [string compare $key Up] == 0] set c2 [ expr [string compare $::down true] != 0] if { $c1 && $c2 } { set ::up true set ::left false set ::right false } set d1 [ expr [string compare $key Down] == 0] set d2 [ expr [string compare $::up true] != 0] if { $d1 && $d2 } { set ::down true set ::left false set ::right false } } proc onTimer {} { if {$::inGame} { checkCollisions checkApple doMove after $::DELAY onTimer } else { gameOver } } proc gameOver {} { .c delete all set x [ expr [winfo width .] / 2 ] set y [ expr [winfo height .] / 2] .c create text $x $y -text "Game over" -fill white } initGame wm title . "Nibbles" wm geometry . +150+150 ``` 首先,我們將定義一些在游戲中使用的常量。 `WIDTH`和`HEIGHT`常數確定電路板的大小。 `DELAY`常數確定游戲的速度。 `DOT_SIZE`是蘋果的大小和蛇的點。 `ALL_DOTS`常數定義了板上可能的最大點數。 `RAND_POS`常數用于計算蘋果的隨機位置。 `initGame`過程初始化變量,加載圖像并啟動超時過程。 ```tcl set ::idot [image create photo img1 -file "dot.png"] set ::ihead [image create photo img2 -file "head.png"] set ::iapple [image create photo img3 -file "apple.png"] ``` 在這些行中,我們加載圖像。 貪食蛇游戲中有三個圖像。 頭,圓點和蘋果。 ```tcl createObjects locateApple ``` `createObjects`過程在畫布上創建項目。 `locateApple`在畫布上隨機放置一個蘋果。 ```tcl bind . "<Key>" "onKeyPressed %K" ``` 我們將鍵盤事件綁定到`onKeyPressed`過程。 游戲由鍵盤光標鍵控制。 `%K`是所按下鍵的 Tk 符號名稱。 它被傳遞到`onKeyPressed`過程。 ```tcl proc createObjects {} { .c create image $::apple_x $::apple_y \ -image $::iapple -tag apple -anchor nw .c create image 50 50 -image $::ihead -tag head -anchor nw .c create image 30 50 -image $::idot -tag dot -anchor nw .c create image 40 50 -image $::idot -tag dot -anchor nw } ``` 在`createObjects`過程中,我們在畫布上創建游戲對象。 這些是帆布物品。 它們被賦予初始的 x,y 坐標。 `-image`選項提供要顯示的圖像。 `-anchor`選項設置為`nw`; 這樣,畫布項目的坐標就是項目的左上角。 如果我們希望能夠在根窗口的邊框旁邊顯示圖像,這很重要。 如果您不理解我們的意思,請嘗試刪除錨點選項。 `-tag`選項用于識別畫布上的項目。 一個標簽可用于多個畫布項目。 `checkApple`過程檢查蛇是否擊中了蘋果對象。 如果是這樣,我們添加另一個蛇形接頭并稱為`locateApple`。 ```tcl set apple [.c find withtag apple] set head [.c find withtag head] ``` `find withtag`命令使用其標簽在畫布上找到一個項目。 我們需要兩個項目。 蛇和蘋果的頭。 ```tcl set l [.c bbox head] set overlap [eval .c find overlapping $l] ``` `bbox`命令返回項目的邊界框點。 `find overlapping`命令查找給定坐標的沖突項。 ```tcl foreach over $overlap { if {$over == $apple} { set crd [.c coords $apple] set x [lindex $crd 0] set y [lindex $crd 1] .c create image $x $y -image $::idot -anchor nw -tag dot locateApple } } ``` 如果蘋果與頭部碰撞,我們將在蘋果對象的坐標處創建一個新的點項目。 我們調用`locateApple`過程,該過程將從畫布上刪除舊的蘋果項目,然后創建并隨機放置一個新的項目。 在`doMove`過程中,我們有了游戲的關鍵算法。 要了解它,請看一下蛇是如何運動的。 您控制蛇的頭。 您可以使用光標鍵更改其方向。 其余關節在鏈上向上移動一個位置。 第二關節移動到第一個關節的位置,第三關節移動到第二個關節的位置,依此類推。 ```tcl set z 0 while {$z < [expr [llength $items] - 1]} { set c1 [.c coords [lindex $items $z]] set c2 [.c coords [lindex $items [expr $z+1]]] .c move [lindex $items $z] [expr [lindex $c2 0] - [lindex $c1 0] ] \ [expr [lindex $c2 1] - [lindex $c1 1] ] incr z } ``` 該代碼將關節向上移動。 ```tcl if { [string compare $::left true] == 0} { .c move head -$::DOT_SIZE 0 } ``` 將頭向左移動。 在`checkCollisions`程序中,我們確定蛇是否擊中了自己或撞墻之一。 ```tcl set l [.c bbox head] set overlap [eval .c find overlapping $l] foreach dot $dots { foreach over $overlap { if {$over == $dot} { set ::inGame false } } } ``` 如果蛇用頭撞到關節之一,我們就結束游戲。 ```tcl if {$y1 > [expr $::HEIGHT - $::DOT_SIZE]} { set ::inGame false } ``` 如果蛇擊中了棋盤的底部,我們將結束游戲。 `locateApple`過程會在板上隨機找到一個新蘋果,然后刪除舊的蘋果。 ```tcl set apple [.c find withtag apple] .c delete lindex apple 0 ``` 在這里,我們找到并刪除了被蛇吃掉的蘋果。 ```tcl set r [expr round(rand() * $::RAND_POS)] ``` 我們得到一個從 0 到`RAND_POS-1`的隨機數。 ```tcl set ::apple_x [expr $r * $::DOT_SIZE] ... set ::apple_y [expr $r * $::DOT_SIZE] ``` 這些行設置了`apple`對象的 x,y 坐標。 在`onKeyPressed`程序中,我們確定所按下的鍵。 ```tcl set a1 [ expr [string compare $key Left] == 0] set a2 [ expr [string compare $::right true] != 0] if { $a1 && $a2 } { set ::left true set ::up false set ::down false } ``` 如果按左光標鍵,則將`left`變量設置為`true`。 在`doMove`過程中使用此變量來更改蛇對象的坐標。 還要注意,當蛇向右行駛時,我們不能立即向左轉。 ```tcl proc onTimer {} { if {$::inGame} { checkCollisions checkApple doMove after $::DELAY onTimer } else { gameOver } } ``` 每`DELAY` ms,將調用`onTimer`過程。 如果我們參與了游戲,我們將調用三個構建游戲邏輯的過程。 否則,游戲結束。 計時器基于`after`命令,該命令僅在`DELAY` ms 之后調用一次過程。 要重復調用計時器,我們遞歸調用`onTimer`過程。 ```tcl proc gameOver {} { .c delete all set x [ expr [winfo width .] / 2 ] set y [ expr [winfo height .] / 2] .c create text $x $y -text "Game over" -fill white } ``` 如果游戲結束,我們將刪除畫布上的所有項目。 然后,在屏幕中央繪制`"Game Over"`。 ![Nibbles](https://img.kancloud.cn/7a/ac/7aacd919815edff3d29e04479c2c503c_302x333.jpg) 圖:貪食蛇 這是用 Tcl/Tk 創建的貪食蛇電腦游戲。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看