在屏幕的任意位置拖拽,控制角色移动

简介: 在屏幕的任意位置拖拽,控制角色移动

嗨!大家好,我是小蚂蚁。


最近一直在录制视频教程,很少写图文教程,难免有些生疏。一项技能练习多了就会熟练,练习少了就会生疏,为了防止写作技能的生疏,还是隔三差五的写一点儿为好。


在屏幕的任意位置按住拖拽,然后控制屏幕中指定的精灵移动,这个前几天@stack发过一个示例,刚好最近又有几位同学来问,说是看不懂其中的逻辑。索性就在这里详细的讲一下,原理很简单,理解透了原理,其中的积木逻辑也就很容易理解了。



如图,有一个小飞机,你可以点击屏幕上的任意位置,开始拖拽,控制飞机的移动,而且飞机不会移出屏幕区域。


我们来看一下其中的实现逻辑。


首先创建几个全局变量。



margin: 用于设置飞机可移动区域与屏幕边缘的间距。这个变量会在判断飞机能不能移出屏幕的计算中使用到。

plane_x: 计算出的飞机的 x 坐标。

plane_y: 计算出的飞机的 y 坐标。

pos_x: 飞机与手指的偏移位置 x。

pox_y: 飞机与手指的偏移位置 y。


接着,先来看一下手指在屏幕上按下的逻辑。



什么是偏移位置呢?看下图。

假设绿色棱形表示的是飞机,红色圆点表示的手指在屏幕上按下的位置。此时,我们以红色的圆点为中心构建一个坐标系,那么绿色飞机相对于红色圆点的水平位置(pos_x)就可以使用“飞机的x坐标 - 红点的x坐标”,绿色飞机相对于红色圆点垂直位置(pos_y)就可以使用“飞机的y坐标 - 红点的y坐标”。


这个“偏移位置”或许叫做“相对位置”更确切一点儿,指的就是飞机相对于红点的位置。

因为它们两个之间的相对位置是固定的,所以不论红点移动到哪里,绿色飞机相对于红点的位置都始终不变。


不论手指移动到哪里,只要用手指当前的位置坐标加上“偏移位置”,就能够计算出飞机相对于手指的位置,这个就是点击屏幕任意位置控制飞机移动的原理了。


接着,我们来看一下,限制飞机不能飞出屏幕的原理是什么。


首先来看一下手指移动的积木逻辑。



其中对于屏幕边缘的判断比较难以理解,不过看个图就明白了。


如图,灰色的为屏幕区域,绿色的为可移动区域,屏幕边缘与可移动区域的边缘的间隙就叫做 margin,知道了屏幕的宽度高度,以及 margin 值,就能够计算出可移动区域的宽度和高度。


在游戏中,整个游戏世界的坐标系的中心位于屏幕的中心,也就是说屏幕中心的位置是(0,0),此时我们再来看一下判断条件的积木。



先来看一下左边的部分,plane_x 是飞机当前的位置坐标 x,它的数值可能是正的(在屏幕右侧)也可能是负的(在屏幕左侧),这里使用“绝对值”就可以把两种情况一并包含在里面。


为什么要乘以 2 呢?看下图。

判断公式右边的部分,计算的就是飞机可移动区域的宽度了,这里“场景的宽度”就是“屏幕宽度”。


最后,如果判断出飞机超出了可移动区域,根据飞机的位置坐标(plane_x),设置飞机是位于可移动区域的左侧还是右侧。


上下两侧的判断也是一样的道理,这个就是限制飞机在指定区域移动的原理了。当前示例的 margin 指的是屏幕四个边缘的间隙,你完全可以根据游戏的需要,单独设置左右两侧和上下两侧的间隙。


回顾一下,想要自主的实现这样的一个控制移动方法,对于开发者来讲都需要具备哪些东西。


首先,你要知道偏移位置,相对位置这些概念,然后才能看透其中相对移动的原理。


接着,你需要了解开发工具,知道在游戏世界中,坐标系的中心位于屏幕的中间,你需要知道哪些积木能处理手指在屏幕上事件,哪个积木能获得屏幕的宽度/高度,哪些积木能够进行数学运算等等。


第一点,对于原理的理解,需要你能将游戏进行简单的抽象化处理,找到其中的数据模型,再利用一些数学知识找到解决方法。


对于这一点,没有什么好的方法,只能通过多练习,另外要克服对于数学的恐惧,其实真的是没有多少高深的数学知识(尤其是对于2D游戏来说),加减乘除,加上个三角函数基本上就能应对大部分问题。


还有就是我之前反复提到过的,很多功能背后的原理都想通,做的多了你就能够发现这种规律,也就能够做到,即使是遇到一个从没做过的功能,你也能够发现它其实跟你曾经做过的某个功能是相似的,而它们背后原理大概率都是相通的。


第二点,对于开发工具的熟练度也非常的重要。当你原理懂了,方法也找到了,但是却发现工具不会用,这个还是很尴尬的。如果说原理方法是一件事情的前半部分,那对于工具的使用就是后半部分,两部分组合起来才能把一件事情做成,熟练的使用工具能够帮助你快速的验证和实现自己的想法。


至于工具如何熟练呢?就一个字“用”,或者三个字“使劲用” !


熟能生巧是一个很朴素却非常有用的智慧。

文中示例项目的开源连接在这里: https://gamemaker.weixin.qq.com/#/game?game_id=lbMmVlYmRkM2YtMjEyYS00MDY0LWEyM2UtN2ZmMzYzZmRkZDk4
相关文章
|
4月前
|
C语言
51开发板数码管:固定显示\闪烁显示\走灯显示“--8051--“,字符可以任意更改,较为灵活
51开发板数码管:固定显示\闪烁显示\走灯显示“--8051--“,字符可以任意更改,较为灵活
|
7月前
|
定位技术 iOS开发
在地图页面,自动布局控件开始是隐藏或在屏幕外需要正常显示时再为正常的显示状态的,需要在显示之前加入
在地图页面,自动布局控件开始是隐藏或在屏幕外需要正常显示时再为正常的显示状态的,需要在显示之前加入
50 0
|
7月前
如何在屏幕的任意位置拖拽控制图片的移动?
如何在屏幕的任意位置拖拽控制图片的移动?
125 1
|
7月前
【sgDragMove】自定义组件:自定义拖拽组件,仅支持拖拽、设置吸附屏幕边界距离。
【sgDragMove】自定义组件:自定义拖拽组件,仅支持拖拽、设置吸附屏幕边界距离。
|
开发工具 开发者
在屏幕的任意位置拖拽,控制精灵移动
在屏幕的任意位置按住拖拽,然后控制屏幕中指定的精灵移动,这个前几天@stack发过一个示例,刚好最近又有几位同学来问,说是看不懂其中的逻辑。索性就在这里详细的讲一下,原理很简单,理解透了原理,其中的积木逻辑也就很容易理解了。
120 0
布局之悬浮显示更多文本并增加箭头指示效果
布局之悬浮显示更多文本并增加箭头指示效果
129 0
布局之悬浮显示更多文本并增加箭头指示效果
|
C#
【WindowsAPI之MoveWindow】 C#调整目标窗体的位置、大小
首先查看一下WindowsAPI给我们的解释  函数功能:该函数改变指定窗口的位置和尺寸。对于顶层窗口,位置和尺寸是相对于屏幕的左上角的:对于子窗口,位置和尺寸是相对于父窗口客户区的左上角坐标的。 函数原型:bool MoveWindow(HWND hWnd,int x,int y,int nWidth,int nHeight,bool BRePaint);   参数: hWnd:窗口句柄。
1965 0
关于 Qt图形视图框架自绘图元放到左边和上边之外,部分在内进行拉伸后,拉伸多余的区域无法碰撞 的解决方法
关于 Qt图形视图框架自绘图元放到左边和上边之外,部分在内进行拉伸后,拉伸多余的区域无法碰撞 的解决方法
关于 Qt图形视图框架自绘图元放到左边和上边之外,部分在内进行拉伸后,拉伸多余的区域无法碰撞 的解决方法
QML学习笔记(三)-按钮控制窗口的状态取反
实现功能:点击按钮打开子窗口,再次点击该按钮可以关闭子窗口,主要就是状态取反。 代码如下:
1733 0