對比python學julia(第三章:遊戲編程)--(第二節)公主迎聖誕(3)

  2.公主精靈的控制

  在第2階段,將創建一個公主角色,支持玩家使用鍵盤上的左、右方向鍵控制公主角色的左、右移動。在“sdgz”項目目中 ,把 version1.jl複製一份並命名爲version2.jl,在第1個版本的基礎上編寫第2 個版本的代碼,具體步驟如下:

  (1) 用圖像Actor創建一個公主角色,將其定位在窗口底部居中位置。

  princess = Actor(princess_img)

  princess.pos=(400, 305)

  (2) 在窗口的draw()方法中,調用draw()方法將公主精靈的圖繪製到窗口中。在遊戲處於進行狀態纔會顯示公主精靈,即在 game_state 等於 1 時才繪製公主角色的外觀。

  

elseif game_state == 1
   …
   draw(princess)

  提示:“…”號表示省略掉的部分代碼,下同。

  (3) 控制公主角色左、右移動。這裏沒有使用鍵盤事件,而是通過檢測鍵盤按鍵狀態來判斷是否按下左 、右方向鍵。因此需要在窗口的事件循環update()方法中檢測左、右方向鍵的按鍵狀態,並控制公主角色左、右移動。在update()方法中添加如下代碼:

  function update(g::Game,dt)

      princess_control(g,dt)

  end

   princess_control是公主角色控制函數,update事件中每幀切換會調用這個函數。princess_control()函數的代碼如下:

#控制公主左右移動
function princess_control(g::Game,dt)
    global game_state
    if game_state != 1
        return
    end

    if g.keyboard.LEFT
        princess.x -= 400 * dt
        if princess.left < 0
            princess.left = -princess.left
        end
    elseif g.keyboard.RIGHT
        princess.x += 400 * dt
        if princess.right > WIDTH
            princess.right += -(2 * (princess.right - WIDTH))
        end
    end
end

  對上面代碼的說明如下。

  ①在遊戲處於進行狀態時才能控制公主精靈移動,即如果 game_state 不等於1,就退出這個函數。

  ②函數 princess_control ()被調用時,自上次被調用以來經過的時間(單位= S)就會被傳遞給參數 dt。假設公主精靈的移動速度爲400 像素/S,那麼它在 princess_control () 函數披調用時的移動速度則爲 400*dt。在向左移動時,princess.x 的值將減去400*dt;在向右移動時 ,princess.x 的值將增加 400*dt。

  ③公主角色在窗口中移動應該顯示完整的外形。因此princess.left最小值爲0,princess.right最大值是800 。

至此,第 2 個版本的程序編寫完成. 運行程序,就可以用鍵盤上的左、右方向鍵控制公主角色左右移動了。

  3.下落物體角色的控制

  在第3個階段,將實現從天空中隨機落下雪花、禮物或剪刀。從面向對象的角度看,雪花、禮物和剪刀都可以歸結爲一類物體,即“下落物體類”,原書的做法是從Pyglet的Sprite 類中派生一個下落物體類 FallingObject,並運用該類的實例實現雪花、禮物或剪刀的互相切換。

  但是Julia不是傳統意義上的面嚮對象語言,Julia裏沒有class,沒有類的繼承(inheritance),勉強與class能對應上的是struct,且不能派生和繼承,除構造函數外,struct內不能定義其它函數。

  1)   創建FallingObject對象

  原書中,作者定義了一個名爲 FallingObject的類,繼承自Sprite 類,在類中添加一個屬性 type 和一個用於切換雪花、禮物和剪刀的 change()方法。轉換到Julia,可以寫成如下結構的代碼:

 1 mutable struct FallingObject
 2     act::Actor
 3     type::Int
 4 
 5     function FallingObject()
 6         act=Actor(snowflake_img)
 7         type=1
 8         new(obj,type)
 9     end
10 end
11 
12 function change(fo::FallingObject)
13     #隨機切換掉落物體的造型
14     n = rand(1:10)
15     if 1 <= n <= 5
16         fo.type = 1
17         fo.act.image = snowflake_img
18     elseif 6 <= n <= 8
19         fo.type = 2
20         fo.act.image = gift_img
21     else
22         fo.type = 3
23         fo.act.image = clipper_img
24     end
25     #將物體定位到窗口上方隨機位置
26     x=rand(100:700)
27     fo.act.pos =x , -100    
28 end

  筆者原打算按此思路實現下落物體的控制,但是通過研究GameZero的源碼,發現源碼作者對Actor增加了賦予其自定義屬性的能力。由於下落物體本質上是一個Actor,所以我們可以直接這樣定義:

  falling_obj =Actor(snowflake_img;pos=(rand(100:700),-100),type=1)

  上面代碼中參數snowflake_img是雪花的圖片,pos是位置,其x軸座標爲100-700間的隨機值,第三個參數type就是自定屬性。

  這樣一來,代碼將簡潔很多。至於Julia的面向對象編程,筆者將新開貼專題論述。

  

  2)   控制 FallingObject對象

  將version2.jl錄複製一份並命名爲version3.jl,在第 2 個版本的基礎上編寫第 3 個版本的代碼。

  (1) 在窗口的draw()方法中,繪製出 falling_0bj 對象的外觀。與公主精靈一樣 ,都是在遊戲處於進行狀態時纔會顯示下落物體.

elseif game_state == 1
	…
   draw(falling_obj)

  (2) 在窗口的 on_key_down()方法中添加切換下落物體造型的代碼。當在遊戲重新開始時,就調用 Change()方法切換下落物體的造型。

function on_key_down(g, k)
    global game_state
    #println(k)
    if k ==Keys.RETURN  #13
        if game_state != 1
            game_state = 1
            change(falling_obj)
        end
    end

end

  另外,事先將Change()方法稍加修改,添加到version3.jl中:

 1 function change(fo::Actor)
 2     #隨機切換掉落物體的造型
 3     n = rand(1:10)
 4     if 1 <= n <= 5
 5         fo.type = 1
 6         fo.image = snowflake_img
 7     elseif 6 <= n <= 8
 8         fo.type = 2
 9         fo.image = gift_img
10     else
11         fo.type = 3
12         fo.image = clipper_img
13     end
14     #將物體定位到窗口上方隨機位置
15     x=rand(100:700)
16 fo.pos =x , -100  
17 end  

  上面的代碼使用隨機數生成掉落物體的造型 ,並將其隨機定位在窗口上方。隨機生成下落物體的算法在本節的編程思路中已經作過介紹。

  (1) 控制下落物體向下移動 。在update()方法中添加如下代碼:

function update(g::Game,dt)
    falling_control(dt)
end

  函數falling_control()的代碼如下:

 1 function falling_control(dt)
 2     #禮物精靈的控制'''
 3     global game_state
 4     if game_state != 1
 5         return
 6     end
 7 
 8     #控制禮物的落下速度和旋轉速度
 9     falling_obj.angle += 60 * dt
10     falling_obj.y += 200 * dt
11     if falling_obj.y >HEIGHT
12         #println("ddd")
13         change(falling_obj)
14     end
15 end

  對上面代碼的說明如下。

  ①在遊戲處於進行狀態時才能控制下落物體的移動,即如果 game_state 不等於 l,就退出這個函數。

  ②旋轉速度和向下移動速度跟時間有關。下落物體在降落過程中是旋轉的,假設每秒旋轉 60,就使用 60 *dt 算出 faning_0bj.angle每次的增加量;假設每秒向下移動200 像素,就使用 200 *dt 算出 fa]ling_Obj.y 每次減少的距離。

  ③當下落物體移動到窗口底部外面的區域時,就將其重新放到窗口的頂部,並隨機切換新的造型,調用 change()方法來實現。

  至此,第 3 個版本的程序編寫完成。運行程序,就可以看到在遊戲時會從天空中隨機掉下雪花、禮物或者剪刀。

  代碼下載地址:https://files.cnblogs.com/files/zjzkiss/sdgz_v2.rar

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章