[Godot]用GDScript实现《杀戮尖塔》的指向施法箭头(贝塞尔曲线)

本文介绍了如何在Godot游戏开发引擎中使用贝塞尔曲线技术,特别是在模拟《杀戮尖塔》中卡牌施法箭头效果时的计算和实现过程,展示了三阶贝塞尔曲线在游戏UI中的具体应用和控制点的使用技巧。
摘要由CSDN通过智能技术生成

这张是在网络上下载的一张《杀戮尖塔》的游戏截图,里面卡牌施法的箭头通用于各类卡牌游戏的开发,但本质上是一个三阶贝塞尔曲线。 

贝塞尔曲线是一种平滑曲线,由数学家 Pierre Bézier 在 20 世纪 60 年代提出。它通过控制点的位置来定义曲线的形状。贝塞尔曲线常用于计算机图形学、几何建模和动画等领域。

贝塞尔曲线的特点是它的起点和终点由控制点确定,而曲线在起点和终点之间的形状则由额外的控制点来调整。这些额外的控制点称为控制点或锚点。通过调整控制点的位置和个数,可以创造出各种不同形状的曲线,包括直线、曲线、圆弧等。

贝塞尔曲线的度数决定了控制点的数量。一阶贝塞尔曲线(线性贝塞尔曲线)只有两个控制点,即起点和终点。二阶贝塞尔曲线(二次贝塞尔曲线)有三个控制点,其中两个控制点位于曲线的两侧,起到调整曲线形状的作用。三阶贝塞尔曲线(三次贝塞尔曲线)有四个控制点,可以更加灵活地调整曲线的形状。

贝塞尔曲线的计算公式使用了多项式插值的方法,通过参数化的方式来生成曲线上的点。通过调整参数的取值范围,可以获得曲线上的各个点,从而绘制出整条曲线。

贝塞尔曲线在计算机图形学中广泛应用,例如绘制平滑的曲线、形状变换、曲面细分等。其优点是简单易懂、计算效率高,并且能够通过调整控制点来实现精确的形状设计。

在这里我们要实现的利用贝塞尔曲线的原理实现一条曲线,先在Godot里面新建一个Control类,并且添加.gd代码, 然后编辑如下代码。

extends Control
class_name bezier
#贝塞尔曲线,使用方法:
#作为组件添加调用 reset(起点,终点),箭头和圆点样式可以自己改


var arrow_num:int =10
var list=[]

@export var t_arrow_head:Texture2D
@export var t_arrow_body:Texture2D

func _ready() -> void:

	#创建界面箭头图形
	for i in range(arrow_num-1):#把身体加进去
		var sprite = Sprite2D.new()
		add_child(sprite)
		list.append(sprite)
		sprite.texture = t_arrow_body
		sprite.scale = Vector2(1,1)*(i/arrow_num*1+0.2)
		sprite.offset = Vector2(-50,0)
	var sprite = Sprite2D.new()#把箭头加进去
	add_child(sprite)
	list.append(sprite)
	sprite.texture = t_arrow_head
	sprite.offset = Vector2(-50,0)

func reset(start_Pos,end_Pos):
	self.show()
	var ctrl_a_pos = Vector2()
	var ctrl_b_pos = Vector2()
	ctrl_a_pos.x = start_Pos.x + (start_Pos.x - end_Pos.x) * 0.1
	ctrl_a_pos.y = end_Pos.y - (end_Pos.y - start_Pos.y) * 0.2
	ctrl_b_pos.x = start_Pos.x - (start_Pos.x - end_Pos.x) * 0.3
	ctrl_b_pos.y = end_Pos.y + (end_Pos.y - start_Pos.y) * 0.3
	
	for i in range(arrow_num):
		var t = float(i)/(arrow_num - 1)
		var pos = (start_Pos * ((1-t)*(1-t)*(1-t)))+(3*ctrl_a_pos*t*(1-t)*(1-t))+(3*ctrl_b_pos*t*t*(1-t))+(end_Pos*t*t*t)
		#list[i].position = pos
		
		var sprite = list[i]
		sprite.global_position = pos
		sprite.scale = Vector2(1, 1) * (t + 0.2)
		sprite.offset = Vector2(-50, 0)
	update_angle()	
		
func update_angle():
	for i in range(arrow_num):
		if i == 0:
			list[i].rotation_degrees = 270
		else:
			var current = list[i]
			var last = list[i-1]
			var lenvec = current.global_position - last.global_position
			var a = lenvec.angle()
			a = rad_to_deg(a)#弧度制转角度制
			current.rotation_degrees = a	

这个代码也并不是我原创,更详细的讲解可以参考: 

老李godot4.2仿《杀戮尖塔》战斗系统-18-贝塞尔曲线的设计与实现_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1xA4m137GR/?spm_id_from=333.788&vd_source=fc347fedea8422d015bd5dd27d971487

1.在reset 方法中,使用了贝塞尔曲线的计算公式来确定曲线上每个点的位置:

for i in range(arrow_num):
    var t = float(i)/(arrow_num - 1)
    var pos = (start_Pos * ((1-t)*(1-t)*(1-t))) + (3*ctrl_a_pos*t*(1-t)*(1-t)) + (3*ctrl_b_pos*t*t*(1-t)) + (end_Pos*t*t*t)

 在这段代码中,根据贝塞尔曲线的公式,通过控制点 ctrl_a_posctrl_b_pos 和起点终点 start_Posend_Pos 来计算出曲线上各个点的位置。

2.在 update_angle 方法中,根据曲线上相邻两个点的位置计算角度,并将箭头图形旋转至该角度:

for i in range(arrow_num):
    if i == 0:
        list[i].rotation_degrees = 270
    else:
        var current = list[i]
        var last = list[i-1]
        var lenvec = current.global_position - last.global_position
        var a = lenvec.angle()
        a = rad_to_deg(a) # 弧度制转角度制
        current.rotation_degrees = a

在这段代码中,通过计算相邻两点的向量,并根据向量的角度来设置箭头的旋转角度,从而使箭头沿着贝塞尔曲线的方向进行旋转。resetupdate_angle 方法体现了贝塞尔曲线的核心算法公式,其中reset是对外提供的接口,只需要传入起点坐标和终点坐标,基本是vector2类型,就能对路径进行均匀的曲线补间。

然后在@export暴露出的t_arrow_head和t_arrow_body接口添加合适的图片,就能实现正确的效果。

在我使用Godot开发的游戏《威小鼠和猪大常》 (Mighty Mouse and Great Piggy)里面三阶贝塞尔曲线施法箭头就得到了应用。

[Godot]独立开发的小游戏分享(无代码)-CSDN博客

  • 41
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值