生活随笔
收集整理的這篇文章主要介紹了
在Godot中制作杀戮尖塔的箭头
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
殺戮尖塔的卡牌箭頭
殺戮尖塔里面使用卡牌時的箭頭是這樣的:
?
貝塞爾曲線
箭頭的形態(tài)非常符合貝塞爾曲線。
PS 中的鋼筆工具就是用的貝塞爾曲線:
?
如圖,一條貝塞爾曲線需要用四個點來確定,一個起點,一個終點,加上兩個控制點。
我們把四個點分別命名:起點(startPos),終點(endPos),控制點 A(ctrlAPos),控制點 B(ctrlBPos)
貝塞爾曲線的公式是:
?
position = startPos*(1-t)*(1-t)*(1-t)? ? + 3*ctrlAPos*t*(1-t)*(1-t)? ? + 3*ctrlBPos*t*t*(1-t)? ? + endPos*t*t*t 復(fù)制代碼
四個點都確定后,公式里的 t 就是唯一的變量,t 是指從起點到終點的百分比,取值是 0~1。
比如 0 代表曲線起點,0.2 代表曲線從起點開始 20% 的位置,0.5 代表曲線中間位置,1 代表曲線終點。
公式的計算結(jié)果 position 就是當(dāng)前 t 值所對應(yīng)的曲線上的點。
不過在游戲中我們是使用兩個點來確定曲線的,卡牌所在位置是曲線的起點,鼠標(biāo)所在位置是曲線的終點。
那么兩個控制點就要根據(jù)起點和終點來進行計算。
殺戮尖塔里的曲線大致是這樣:
?
我們可以大致的寫出控制點的計算公式:
?
ctrlAPos.x = startPos.x + (startPos.x - endPos.x) * 0.2ctrlAPos.y = endPos.y - (endPos.y - startPos.y) * 0.2ctrlBPos.x = startPos.x - (startPos.x - endPos.x) * 0.2ctrlBPos.y = endPos.y + (endPos.y - startPos.y) * 0.2 復(fù)制代碼
當(dāng)然這個計算公式可以自己微調(diào),使曲線更符合自己想要的形態(tài)
Godot 中的實現(xiàn)
理解了曲線的原理,現(xiàn)在開始在 godot 中實現(xiàn)。
我畫了兩個箭頭,箭頭 1 和箭頭 2,如圖。
?
在 godot 中新建一個場景,新建 Node2D,命名為貝塞爾箭頭。添加腳本。
?
開始寫腳本。首先我們的箭頭有20節(jié),我們需要在初始化的時候準(zhǔn)備好。
之后更新箭頭時重新排好每一節(jié)就能形成一條曲線。
?
extends Node2Dvar list=[] #數(shù)組,用來保存20節(jié)小箭頭func _ready():? ? #生成19節(jié)尾巴小箭頭,用箭頭1的圖片? ? for i in range(19):? ?? ???var sprite=Sprite.new()? ? #新建 Sprite 節(jié)點? ?? ???add_child(sprite)? ?? ?? ? #添加到場景里? ?? ???list.append(sprite)? ?? ???#添加到數(shù)組里? ?? ???sprite.texture=load("res://Sprites/箭頭1.png")??#把圖片換成箭頭1? ?? ???sprite.scale=Vector2(1,1)*(0.2+float(i)/18*0.8) #改變縮放,根據(jù)殺戮尖塔,箭頭是一節(jié)節(jié)越來越大的? ?? ???sprite.offset=Vector2(-25,0)??#由于我畫的圖片中心點在箭頭中間,? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ???#這里改變一下圖片偏移,把圖片中心點移動到箭頭頭部? ? #最后生成終點的箭頭,用箭頭2的圖片? ? var sprite=Sprite.new()? ?? ? add_child(sprite)? ? list.append(sprite)? ? sprite.texture=load("res://Sprites/箭頭2.png")? ? sprite.offset=Vector2(-25,0) 復(fù)制代碼
然后我們需要一個函數(shù)來設(shè)置箭頭的起點和終點
?
func reset(startPos,endPos):? ? #根據(jù)傳入的起點和終點來計算兩個控制點? ? var ctrlAPos=Vector2()? ? var ctrlBPos=Vector2()? ? ctrlAPos.x=startPos.x+(startPos.x-endPos.x)*0.1 #這里我把參數(shù)做了微調(diào),感覺這樣更加符合殺戮尖塔的效果? ? ctrlAPos.y=endPos.y-(endPos.y-startPos.y)*0.2? ? ctrlBPos.y=endPos.y+(endPos.y-startPos.y)*0.3? ? ctrlBPos.x=startPos.x-(startPos.x-endPos.x)*0.3? ?#根據(jù)貝塞爾曲線重新設(shè)置所有小箭頭的位置? ? for i in range(20):? ?? ???var t=float(i)/19? ?? ???var pos=startPos*(1-t)*(1-t)*(1-t)+3*ctrlAPos*t*(1-t)*(1-t)+3*ctrlBPos*t*t*(1-t)+endPos*t*t*t? ?? ???list[i].position=pos? ?#雖然更改了箭頭的位置,不過還需要重新計算箭頭的方向? ?? ?updateAngle()? ?#重新計算所有箭頭的方向 復(fù)制代碼
接下來我們需要完成 updateAngle()這個函數(shù)
思路是二手游戲拍賣每個小箭頭根據(jù)前一個箭頭和自己的位置來計算角度
func updateAngle():? ? for i in range(20):? ?? ???if i==0:? ?? ?? ?? ?list[0].rotation_degrees=270? ? #第一個小箭頭就讓他固定朝上好了? ?? ???else:? ?? ?? ?? ?var current=list[i]? ? #當(dāng)前的小箭頭? ?? ?? ?? ?var last=list[i-1]? ???#前一個小箭頭? ?? ?? ?? ?var lenVec=current.position-last.position? ?? ?#兩個箭頭連線的向量? ?? ?? ?? ?var a=lenVec.angle()? ?? ? #計算這個向量的角度,這個 angle()返回值是弧度? ?? ?? ?? ?a=rad2deg(a)? ?? ?? ?? ?? ?#弧度轉(zhuǎn)成角度? ?? ?? ???? ?? ?? ?? ?current.rotation_degrees=a #更新小箭頭的方向 復(fù)制代碼
效果
我們的貝塞爾箭頭就做好了,外界只要調(diào)用 reset 方法就能更新箭頭,
不需要用的時候可以用 visible = false 把它隱藏掉
我把它放到游戲中看看效果
?
非常完美!
總結(jié)
以上是生活随笔為你收集整理的在Godot中制作杀戮尖塔的箭头的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。