【Godot4.2】实现鼠标控制对象(控件)旋转

概述

在一些情况下我们可能需要使用鼠标控制对一个图形或对象(如控件)进行旋转。
通过如下图的分析:
image.png
我们可以知道:

  • 我们只需要求出对象(如控件)中心点C到鼠标点击的位置start的向量与中心点C到鼠标移动后的位置start的向量之间的夹角θ
  • 然后将这个角度加到对象(如控件)的rotation属性上就可以了。

测试

原理清楚,实践开始。我们创建一个如下的UI场景:
image.png
为Control节点添加如下代码:

extends Control

@export var border_color = Color.YELLOW_GREEN
@export var border_width = 2

var rect = get_draw_safety_rect()


func _draw():
	# 绘制边框和对角线
	draw_rect(rect,border_color,false,border_width)
	draw_line(rect.position,rect.position+rect.size,border_color,border_width)
	draw_line(rect.position+Vector2(rect.size.x,0),rect.position++Vector2(0,rect.size.y),border_color,border_width)


# 获取绘制函数能正确使用的控件Rect2
func get_draw_safety_rect() -> Rect2:
	var rect = get_rect()
	return Rect2(rect.position - position,rect.size/scale)

它主要是绘制出控件的矩形边界,并绘制出对角线:
image.png
为根节点添加如下代码:

extends Control

@onready var control = $Control
@export var line_color = Color.YELLOW  # 辅助线颜色

var can_rotate:bool        # 是否处于旋转状态
var start_vector:Vector2   # 起始向量
var line:Array[Vector2] = []   # 记录辅助线


func _input(event):
	# 鼠标左键
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT:
			if event.is_pressed(): # 按下
				# 开启旋转状态
				can_rotate = true
				
				# 计算和记录初始控件中心到鼠标位置的向量
				var pos = event.position
				var c = control.position + control.pivot_offset
				start_vector = pos - c
				# 构造控件中心到鼠标位置的线段
				line.clear()
				line.append(c)
				line.append(pos)
				# 申请重绘
				queue_redraw()
			else: # 松开
				# 关闭旋转状态
				can_rotate = false
				# 申请重绘
				queue_redraw()
	# 鼠标移动
	if event is InputEventMouseMotion:
		# 如果是可旋转状态
		if can_rotate:
			# 计算和新的控件中心到鼠标位置的向量
			var pos = event.position
			var c = control.position + control.pivot_offset
			var end_vector:Vector2 = pos - c
			# control跟随鼠标旋转
			control.rotation += start_vector.angle_to(end_vector)
			# 将新的向量记录到start_vector
			start_vector = end_vector
			# 构造新的控件中心到鼠标位置的线段
			line.clear()
			line.append(c)
			line.append(pos)
			# 申请重绘
			queue_redraw()

func _draw():
	# 绘制控件中心到鼠标位置的线段
	if line.size()>0 and can_rotate:
		draw_line(line[0],line[1],line_color,1)

注意:默认情况下Control类型的位置是从左上角顶点算起的,而且其旋转中心也位于左上角。
image.png
所以我们需要手动或代码形式将其旋转中心设定为其矩形范围的中心。
image.png
运行后就可以使用鼠标控制控件进行旋转。
鼠标控制矩形旋转.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/477065.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32最小核心板使用HAL库实现CAN接口通讯(轮询方式)

这里使用了CAN1的接口,具体使用MX创建项目就不放了 需要注意的是,由于是最小核心没有CAN的收发模块需要外接一个 STM32核心板接CAN收发模块不需要交叉 /**CAN GPIO ConfigurationPA11 ------> CAN_RXPA12 ------> CAN_TX */ CAN收发模块…

力扣454. 四数相加 II

思路:把四个数组拆成两对,两个分别相加,记录第一对的相加结果进map里,再把第二对数组 0-nums2-nums4 去map里面找出现了几次,这题不用对重复的四元组去重,所以出现多次都有效。 class Solution {public int…

[flask] flask的基本介绍、flask快速搭建项目并运行

笔记 Flask Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login,数据库Flask-SQLAlchemy),都需要用第三方的扩展来实现。比如可以用 Flask 扩展加入ORM、…

ubuntu20.04搭建nginx rtmp视频服务到指定位置解决权限不足

1.安装依赖 apt-get install build-essential libpcre3 libpcre3-dev libssl-dev2.建一个目录 mldir rtmp_nginx 3.源码下载 wget http://nginx.org/download/nginx-1.21.6.tar.gz wget https://github.com/arut/nginx-rtmp-module/archive/master.zip4.解压缩 tar -xf ng…

新能源汽车充电桩站点烟火AI识别检测算法应用方案

新能源汽车作为现代科技与环保理念的完美结合,其普及和应用本应带给人们更加便捷和绿色的出行体验。然而,近年来新能源汽车充电火灾事故的频发,无疑给这一领域投下了巨大的阴影。这不禁让人深思,为何这一先进的交通工具在充电过程…

计算机服务器中了faust勒索病毒怎么办,faust勒索病毒解密工具流程

网络是一把利剑,可以方便企业开展各项工作业务,为企业提供极大的便利,但随着网络技术的不断发展与应用,网络数据安全威胁也在不断增加,给企业的正常生产运营带来了极大困扰,近日,云天数据恢复中…

AJAX-Promise

定义 Promise对象用于表示(管理)一个异步操作的最终完成(或失败)及其结果值。 好处:1)成功和失败状态,可以关联对应处理程序 2)了解axios函数内部运作机制 3)能解决回调函数地狱问题 语法&…

七仔充电桩平台 二轮电动自行车 四轮汽车 云快充1.5 云快充1.6

文章目录 一、产品功能部分截图1.手机端(小程序、安卓、ios)2.PC端 二、小程序体验账号以及PC后台体验账号1.小程序体验账号2.PC后台体验账号关注公众号获取最新资讯 三、产品简介?1. 充电桩云平台(含硬件充电桩)&…

ORACLE查询拼接字段,显示clob原因,及解决办法

今天查询一个字段,使用了拼接,然后查出来就显示clob: 代码如下: SELECT LOAD_DATE, CINO, WM_CONCAT(CITYP) AS CITYPFROM ODS.ZN_CUSTCITYP GROUP BY CINO,LOAD_DATE 显示如图: 解决办法: select t.普…

Java-SSM医院在线预约系统

Java-SSM医院在线预约系统 1.服务承诺: 包安装运行,如有需要欢迎联系(VX:yuanchengruanjian)。 2.项目所用框架: 前端:JSP、layui等。 后端:SSM,即Spring、SpringMvc、Mybatis等。 3.项目功能点: 1.管理员功能: a.修改个人信息…

[ Django ] 统计接口访问频次

需求及实现思路 需求:统计django项目中接口的调用次数 思路:中间件异步任务celery缓存redis/直接使用中间件(会增加中间件的压力) 具体思路: 定义中间件,在中间件中响应走的时候判断该请求的url是否存在…

【吾爱破解】Android初级题(二)的解题思路 _

拿到apk,我们模拟器打开看一下 好好,抽卡模拟器是吧😀 jadx反编译看一下源码 找到生成flag的地方,大概逻辑就是 java signatureArr getPackageManager().getPackageInfo(getPackageName(), 64).signaturesfor (int i 0; i &l…

综合知识篇15-开发管理考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html案例分析篇00-【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例…

C# 读取二维数组集合输出到Word预设表格

目录 应用场景 设计约定 范例运行环境 配置Office DCOM 实现代码 组件库引入 核心代码 DataSet转二维数组 导出写入WORD表格 调用举例 小结 应用场景 存储或导出个人WORD版简历是招聘应用系统中的常用功能,我们通常会通过应用系统采集用户的个人简历信息…

01、Lua 入门教程

Lua 入门教程 Lua是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 Lua是巴西里约热内卢天主教大学(Pontifical Catholic University of…

使用uni-app框架进行移动端的适配(uniapp px转rpx)

1、打开uniapp 官网找到 插件市场介绍2、点击插件市场 px2rpx - DCloud 插件市场3、选择使用HBuilderX导入插件4、在HBuilder中点击右键选择开启px2rpx 5、开启成功后会有提示 6、根据设计搞的尺寸就行,我的是在这750*1620的,正常写px,保存…

ES6中的Set集合

Set集合 ES6 提供了新的数据结构Set(集合)。 它类似于数组,但成员的值都是唯一的集合实现了 iterator 接口,所以可以使用「扩展运算符」和[for…of…」进行遍历集合的属性和方法 集合的属性和方法: 1)size,返回集合的元…

Java-SSM学生信息管理统

Java-SSM学生信息管理统 1.服务承诺: 包安装运行,如有需要欢迎联系(VX:yuanchengruanjian)。 2.项目所用框架: 前端:JSP、layui等。 后端:SSM,即Spring、SpringMvc、Mybatis等。 3.项目功能点: 1.前台功能: 1.注册、登录 2.课程…

分布式链上随机数和keyless account

1. 引言 相关论文见: Aptos团队2024年论文 Distributed Randomness using Weighted VRFs 相关代码实现见: https://github.com/aptos-labs/aptos-core(Rust) 在链中生成和集成共享随机数,以扩展应用和强化安全。该…

四、C语言中的数组:如何输入与输出二维数组(数组,完)

本章的学习内容如下 四、C语言中的数组:数组的创建与初始化四、C语言中的数组:数组的输入与元素个数C语言—第6次作业—十道代码题掌握一维数组四、C语言中的数组:二维数组 1.二维数组的输入与输出 当我们输入一维数组时需要一个循环来遍历…