(原) Godot做个圆形可旋转的菜单

原创文章,请后转载,并注明出处。


因为购买了一个圆形按钮,想着用它来作什么。它有五个按键:左、右、按下、按下左、按下右。

使用Godot制作一个圆形菜单,按下键作为确认,左右进行选择。多余的按下左右作为旋转控制(实际没啥用)。
把工程设为透明,置顶,无窗口。代码实现了拖动功能。定义好功能按钮。
为了简单(懒),通过前端定义了RichTextlLabel,代码直接复制过来用。
完善一下,从配置文件读取,即可实现选择并执行的功能。

extends Node2D

var default_font = ThemeDB.fallback_font
var default_font_size = ThemeDB.fallback_font_size
var center_point = Vector2(250,250)
var _time = 0
var textNum = 8
var richTextObj = []
var speed = 0
var richTextTitle = ["关闭计算机","我的电脑","截屏","静音","打开工作","打开博客","系统设置","快捷功能"]
var Select = 0

# 关于拖动窗口
var is_dragging
var relaty

func setRichText():
	var num = 0
	for n in richTextTitle:
		var tmpStr = "[center]"
		var fontSize = 32
		for i in n:
			tmpStr = tmpStr + "[font_size=" + str(fontSize) + "]" + i + "[/font_size]\r"
			fontSize=fontSize-4
		richTextTitle[num] = tmpStr + "[/center]"
		num=num+1

func _input(event: InputEvent) -> void:
	# 拖动
	if event is InputEventMouseMotion and is_dragging:
		get_tree().root.position = relaty + DisplayServer.mouse_get_position()
		
	if event is InputEvent:
		if event.is_action_pressed("SpeedAdd"):
			speed=speed+5
			if speed>100:
				speed=100
		elif event.is_action_pressed("SpeedSub"):
			speed=speed-5
			if speed<0:
				speed=0
		elif event.is_action_pressed("SelectDown"):
			Select=Select+1
			if Select>7:
				Select=0
		elif event.is_action_pressed("SelectUp"):
			Select=Select-1
			if Select<0:
				Select=7
		elif event.is_action_pressed("SelectEnter"):  # 按回车键
			if speed==0:   # 不旋转时,选择功能
				print(Select)
			else:  # 旋转时,停转
				speed=0
		
func _ready() -> void:
	setRichText()
	for i in textNum:
		richTextObj.append($RichTextLabel.duplicate())
		richTextObj[i].text = richTextTitle[i]
		richTextObj[i].rotation_degrees = 45*i + 22.5
		richTextObj[i].visible = true
		add_child(richTextObj[i])
	$RichTextLabel.visible = false

func _process(delta: float) -> void:
	# 拖动处理
	if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
		if(is_dragging==false):
			var mouse_pos = DisplayServer.mouse_get_position()
			var root_pos = get_tree().root.position
			relaty=(root_pos-mouse_pos)
			#print(relaty)
		is_dragging=true
	else:
		is_dragging=false
		
	_time += delta*speed
	for i in textNum:
		richTextObj[i].rotation_degrees = richTextObj[i].rotation_degrees + delta * speed
		#if richTextObj[i].rotation_degrees>=340 && richTextObj[i].rotation_degrees<370:
		if i==Select:
			richTextObj[i].text = "[outline_size=5][outline_color=black]\r" + richTextTitle[i] + "\r[/outline_color][/outline_size]"
		else:
			richTextObj[i].text = richTextTitle[i]
	if (_time>360):
		_time = 0
		for i in textNum:
			richTextObj[i].rotation_degrees = 45 * i + 22.5
	queue_redraw()

func _draw() -> void:
	draw_arc(center_point,252,0,PI*2,100,Color(1.0,1.0,1.0,0.3),0.4,true)					# 画一个圆弧(2PI就是画一个圆)
	draw_circle(center_point,248,Color.BLACK)

	for i in range(_time+0,_time+360,45):
		draw_circle_arc_poly(center_point,246,i,i+44.0,Color(0.6,0.6,(i-_time)/360.0,1.0))

	#draw_string_outline(default_font, Vector2(66, 66), "圆形菜单", HORIZONTAL_ALIGNMENT_CENTER, 350, default_font_size * 2.0,2,Color(0.1,0.1,0.1,0.3))
	#draw_string(default_font,Vector2(64,64),"圆形菜单",HORIZONTAL_ALIGNMENT_CENTER,350,default_font_size*2.0,Color.BLUE)

# 画一个扇形
func draw_circle_arc_poly(center, radius, angle_from, angle_to, color):
	var nb_points = 32
	var points_arc = PackedVector2Array()
	points_arc.push_back(center)
	var colors = PackedColorArray([color])
	for i in range(nb_points + 1):
		var angle_point = deg_to_rad(angle_from + i * (angle_to - angle_from) / nb_points - 90)
		points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius)
	draw_polygon(points_arc, colors)

相关文章