美文网首页GMS2入门
Dev_log_3 人物移动的逻辑优化,以及图块碰撞

Dev_log_3 人物移动的逻辑优化,以及图块碰撞

作者: 想当狗策划 | 来源:发表于2021-02-17 01:45 被阅读0次

过年摸了一个假期的鱼,是时候写一写近期慢吞吞地学习的新内容了:

在Dev_log_1中,我曾经很粗浅地通过检测按键情况来直接修改目标的x,y坐标值,藉此来完成人物移动。但是随后,当我需要实现目标和房间的图块之间的碰撞时,我发现这样判定人物移动的逻辑会使得图块碰撞的检验十分冗杂。

因此,后来我参考了许多其他作者做出的案例,我决定对人物移动的结算机制进行优化:
首先,生成两个变量: hspdvspd (即Horizontal Speed和Vertical Speed)

hspd = (keyboard_check(vk_right) - keyboard_check(vk_left)) * 4;
vspd = (keyboard_check(vk_down) - keyboard_check(vk_up)) * 4;

if (hspd > 0) 
{
sprite_index = spr_player_right;
image_speed = 0.5;
}
if (hspd < 0) 
{
sprite_index = spr_player_left;
image_speed = 0.5;
}
if (vspd > 0) 
{
sprite_index = spr_player_down;
image_speed = 0.5;
}
if (vspd < 0) 
{
sprite_index = spr_player_up;
image_speed = 0.5;
}
x += hspd ;
y += vspd ;

//两个变量都为0时,不播放移动动画
if     !((hspd) 
    || (vspd)
    || (-hspd)
    || (-vspd))
{
    image_speed = 0;
}

使用这两个新变量来控制人物移动和碰撞判定,可以使得每个if函数内无需单独判定目标x,y值的变化。并且后续的碰撞判定后,如需使目标无法穿透某些图块,只需在满足条件时将这两个变量归0即可。

然后,我新建了一个Layer,命名为Layer_CMusk(Collision Musk)。
这个图层使用的tile仅有一个纯色的图块:


CMusk使用的图块素材

它的存在意义是将整个房间里所有涉及到碰撞的图块收束在这个Layer里,使用时直接将这个CMusk的深度调低,在所有可见的图层下,然后将这个紫色的图块覆盖在需要判定的其他图层图块上即刻,例如:


CMusk的使用,判定目标与墙壁贴图的碰撞
用CMusk覆盖墙壁贴图
当然,房间内的不可穿越障碍物亦可将CMusk覆盖在其上,这样未来假如我加入了新的Layer用来放屋内装饰物,其他一些障碍物,即可无需将目标分别与不同的layer来判断碰撞,只需与CMusk判断即可。

然后检测目标与图块之间是否发生碰撞,我自定义了一个脚本tile_meeting:

var obj_top ,obj_bot ,obj_left, obj_right ,collide_map ,meeting;  

obj_top = argument0;
obj_bot = argument1;
obj_left = argument2;
obj_right = argument3;
collide_map = layer_get_id(argument4);

meeting = tilemap_get_at_pixel(collide_map ,obj_right ,obj_top)
          ||
          tilemap_get_at_pixel(collide_map ,obj_right ,obj_bot)
          ||
          tilemap_get_at_pixel(collide_map ,obj_left ,obj_top)
          ||
          tilemap_get_at_pixel(collide_map ,obj_left ,obj_bot);
          
return(meeting);

值得一提的是GMS2中函数引用外部变量,需要先定义Argument,假设我定义了一个叫做A的函数,需引用两个外部变量,则其调用时应该为A(Argument0,Argument1),这个脚本显然判断碰撞的依据是目标贴图的四个顶点是否在发生移动后接触到了目标图块。所以当目标素材的贴图大小比图块大时,图块可能会从目标中间穿过去。我使用的人物贴图是3248的尺寸,图块默认尺寸4848,因此不会出现这种情况。

后面的事就很容易理解了:

if tile_meeting(bbox_top,bbox_bottom,bbox_left+hspd,bbox_right+hspd,"Layer_CMusk")
{
    hspd=0;
}

if tile_meeting(bbox_top+vspd,bbox_bottom+vspd,bbox_left,bbox_right,"Layer_CMusk")
{
    vspd=0;
}

碰撞检定为真时,速度改为0。
此外,多数时候我不希望目标可以穿过没有墙壁的房间边缘到达房间外面,我希望确保目标总是在房间内,这时可以将CMusk围绕着房间途一周,亦可使用clamp函数来确保x,y的范围:

x=clamp(x,sprite_width,room_width);
y=clamp(y,sprite_height,room_height-sprite_height);

相关文章

  • Dev_log_3 人物移动的逻辑优化,以及图块碰撞

    过年摸了一个假期的鱼,是时候写一写近期慢吞吞地学习的新内容了: 在Dev_log_1中,我曾经很粗浅地通过检测按键...

  • CAD插件表格批量提取1.4破解版免费下载附安装教程

    CAD表格批量提取可实现图块拉伸、图块制作、改变颜色、属性移动、属性隐显、属性转文字、文字压缩、文字批处理、扩展数...

  • Unity角色控制器CharacterController

    角色控制器没有碰撞效果,这是和刚体的区别 CharacterController下的Move()方法:人物移动 C...

  • Unity 3D的角色移动

    在Unity控制角色移动时,要注意两大点: 鼠标点击地面,检测射线以及人物面朝移动方向。 控制人物的移动与速度首先...

  • 单一职责原则

    单一职责原则 1:类的单一职责原则 按照正常的逻辑 比如说我要写一个人物移动的代码 人物移动.cs 1:人物Tra...

  • 象形发散

    象形发散 多在嫁接上使用,性质发散多在与人物的碰撞上使用 象形易构图,速度快,性质 易 逻辑、逻辑性强 发散总结练...

  • 移动SEO之页面优化

    连续几篇帖子谈移动搜索优化问题,不过谈的较多的是PC和移动两个版本怎样适配,以及独立URL移动站和自适应移动站怎样...

  • 移动端性能优化

    性能优化的维度 1. 逻辑与架构 1. 逻辑优化 逻辑优化的核心: 1. 业务流的逻辑最优; ...

  • 关于 5G,我们从一个公式谈起

    网络优化系列专题,面对复杂多变的移动网络,我们需要掌握哪些网络基础知识,以及该如何做好网络优化这项工作。 网络优化...

  • 移动 APP 网络优化概述

    移动 APP 网络优化概述 移动 APP 网络优化概述

网友评论

    本文标题:Dev_log_3 人物移动的逻辑优化,以及图块碰撞

    本文链接:https://www.haomeiwen.com/subject/volbxltx.html