我已经为你翻译了该内容。以下是内容的中文翻译:
我的2D 平台游戏是在GameMaker里制作的,我已经添加了半实体平台和半实体移动平台,但是当我跳跃时,我却不能跨越它们。
我的角色步进事件如下:
//取得控制器
getControls();
//水平移动
//方向
moveDir = rightKey - leftKey;
//取得角色头部方向
if moveDir != 0 { face = moveDir; };
//取得水平速度
runType = runKey;
xspd = moveDir * moveSpd[runType];
//水平碰撞检测
var _subPixel = 0.5;
if place_meeting( x + xspd, y, obj_wall )
{
//首先检测是否有斜坡可以上去
if !place_meeting( x + xspd, y - abs(xspd)-1, obj_wall )
{
while place_meeting( x + xspd, y, obj_wall ) { y -= _subPixel; };
}
//其次检测天花板斜坡,否则进行常规碰撞检测
else
{
//天花板斜坡
if !place_meeting( x + xspd, y + abs(xspd*2)+1, obj_wall )
{
while place_meeting( x + xspd, y, obj_wall ) { y += _subPixel; };
}
else
{
//精确地靠近墙壁
var pixelCheck = _subPixel * sign(xspd);
while !place_meeting( x + pixelCheck, y, obj_wall ) { x += pixelCheck; };
//将 xspd 更改为 0 以进行碰撞检测
xspd = 0;
}
}
}
//向下滑行检测
if yspd >= 0 && !place_meeting( x + xspd, y + 1, obj_wall ) && place_meeting( x + xspd, y + abs(xspd)+1, obj_wall )
{
while !place_meeting( x + xspd, y + _subPixel, obj_wall ) { y += _subPixel; };
}
//水平移动
x += xspd;
//垂直移动
//重力
if coyoteHangTimer > 0
{
//减少计时器
coyoteHangTimer--;
}
else
{
//将重力加在上玩家身上
yspd += grav;
//玩家不再站在地面上
setOnGround(false);
}
//复位和准备跳跃变量
if onGround
{
jumpCount = 0;
coyoteJumpTimer = coyoteHangFrames;
}
else {
//如果玩家在空中,确保他们不能进行双跳
coyoteJumpTimer--;
if jumpCount == 0 && coyoteJumpTimer <= 0 { jumpCount = 1; };
}
//进行跳跃
if jumpKeyBuffered && jumpCount < jumpMax
{
//复位缓冲区
jumpKeyBuffered = false;
jumpKeyBufferTimer = 0;
//增加跳跃次数
jumpCount++;
//设置跳跃持续时间
jumpHoldTimer = jumpHoldFrames[jumpCount-1];
//告诉自己玩家不再站在地面上
setOnGround(false);
coyoteJumpTimer = 0;
}
//使用缓冲区释放跳跃按钮
if !jumpKey
{
jumpHoldTimer = 0;
}
//使用跳跃计时器或按住跳跃按钮
if jumpHoldTimer > 0
{
//使得 yspd 始终为跳跃速度
yspd = jspd[jumpCount-1];
//减少计时器
jumpHoldTimer--;
}
//垂直碰撞和移动
region
//限制落地速度
if yspd > termVel { yspd = termVel };
//垂直碰撞检测
var _subPixel = 0.5;
//上方垂直碰撞(天花板斜坡)
if place_meeting(x, y + yspd, obj_wall)
{
//跳跃进入斜坡
var _slopeSlide = false;
//上跳向左斜坡
if moveDir != 1 && !place_meeting( x - abs(yspd)-1, y + yspd, obj_wall )
{
while place_meeting( x, y + yspd, obj_wall ) { x -= 1; };
_slopeSlide = true;
}
//上跳向右斜坡
if moveDir != -1 && !place_meeting( x + abs(yspd)+1, y + yspd, obj_wall )
{
while place_meeting( x, y + yspd, obj_wall ) { x += 1; };
_slopeSlide = true;
}
//正常垂直碰撞检测
if !_slopeSlide
{
//精确地靠近墙壁
var _pixelCheck = _subPixel * sign(yspd);
while !place_meeting( x, y + _pixelCheck, obj_wall ) { y += _pixelCheck; };
//Optional:让玩家受到反弹
//if yspd < 0 { jumpHoldTimer = 0; } ;
//垂直速度设置为 0 以进行碰撞检测
yspd = 0;
//告诉游戏玩家已经站在地面上了
setOnGround(true);
}
}
//检查半密实地面
//检查固体和半实体底座
var _clamYspd = max( 0, yspd );
var _list = ds_list_create(); // 创建一个存储所有遇到的实体的 DS 列表
var _array = array_create(0);
array_push( _array, obj_wall, obj_SemiSolidWall );
//实际检查和添加实体
var _listSize = instance_place_list( x, y+1 + _clamYspd + moveplatMaxYspd, _array, _list, false );
//循环遍历碰撞对象,仅返回顶部位置低于玩家的实体
for( var i = 0; i < _listSize; i++ )
{
//从列表中获取实体
var _listInst = _list[i];
//避免磁力
if ( _listInst.yspd <= yspd || instance_exists(myFloorPlat) )
&& ( _listInst.yspd > 0 || place_meeting( x, y+1 + _clamYspd, _listInst ) )
{
//返回一个密实地面或半实体地面
if _listInst.object_index == obj_wall
|| object_is_ancestor( _listInst.object_index, obj_wall )
|| _listInst.object_index == obj_SemiSolidMovePlat
|| floor(bbox_bottom) <= ceil( _listInst.bbox_top - _listInst.yspd )
{
//返回最顶部的墙实体
if !instance_exists(myFloorPlat)
|| _listInst.bbox_top + _listInst.yspd <= myFloorPlat.bbox_top + myFloorPlat.yspd
|| _listInst.bbox_top + _listInst.yspd <= bbox_bottom
{
myFloorPlat = _listInst;
}
}
}
//销毁 DS 列表以避免内存泄漏
ds_list_destroy(_list);
//最后一个检查确定地面平台确实在以下它
if instance_exists(myFloorPlat) && !place_meeting( x, y + moveplatMaxYspd, myfloorPlat )
{
myFloorPlat = noone;
}
//落地在地面平台上如果存在
if instance_exists(myFloorPlat)
{
//精确地靠近地面平台
var _subPixel = 0.5;
while !place_meeting( x, y + _subPixel, myFloorPlat ) && !place_meeting( x, y, obj_wall ) { y += _subPixel; };
//确保玩家不结束在半实体地面
if myFloorPlat.object_index == obj_SemiSolidWall || object_is_ancestor(myFloorPlat.object_index, obj_SemiSolidWall) || myFloorPlat.object_index == obj_SemiSolidMovePlat
{
while place_meeting( x, y, myFloorPlat ) { y -= _subPixel; };
}
//将 y 值设置为四舍五入值
y = floor(y);
//与地面碰撞
yspd = 0;
setOnGround(true);
}
//水平移动后的平台碰撞和移动
//垂直 - 使玩家贴近地面平台
//动画
//走路
if abs(xspd) > 0 { sprite_index = walkSpr; };
//跑动
if abs(xspd) >= moveSpd[1] { sprite_index = runSpr };
//不移动
if xspd == 0 { sprite_index = idleSpr; };
//空中
if !onGround { sprite_index = jumpSpr; };
//设置碰撞遮蔽
mask_index = idleSpr;
评论 (0)