// step 事件
show_debug_message("onGround = " + string(onGround));
// 获取控件
getControls();
// X 移动
// 方向
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 {
// 检查是否有Ceiling slopes, 否则进行正常碰撞检测
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;
}
}
} else {
// 满地而下
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;
}
// Y 移动
// 重力
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 (!jumpKey) {
jumpHoldTimer = 0;
}
// 跳跃 (持续按住跳跃键)
if (jumpHoldTimer > 0) {
// 设置yspd为跳跃速度
var index = clamp(jumpCount - 1, 0, array_length(jspd) - 1);
yspd = jspd[index];
// 减少计时器
jumpHoldTimer--;
}
// Y 碰撞检测和移动
#region
// 限制下落速度
if (yspd > termVel) {
yspd = termVel;
}
// 上方向Y 碰撞检测
if (yspd < 0 && 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;
} else 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;
} else {
// 正常Y 碰撞检测
if (!slopeSlide) {
// 移动到墙壁精确地
var pixelCheck = subPixel * sign(yspd);
while (!place_meeting(x, y + pixelCheck, obj_wall)) {
y += pixelCheck;
}
// 滬 (可选)
if (yspd < 0) {
jumpHoldTimer = 0;
}
// 设定yspd为0以碰撞
yspd = 0;
// 告知游戏我们已经处于地面上
setOnGround(true);
}
}
}
// 地面Y 碰撞检测
// 检测是否有以下方块 (半像素)
var clamYspd = Math.max(0, yspd);
var list = ds_list_create(); // 为每个碰撞实例创建数据集列表
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 || (myFloorPlat && yspd == 0)) && (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 ||
bbox_bottom < listInst.bbox_top - listInst.yspd) {
// 返回最高的实体
if (!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);
// 最后一次检查以确保.floorPlatform 位于我们下方
if (myFloorPlat && !place_meeting(x, y + moveplatMaxYspd, myFloorPlat)) {
myFloorPlat = noone;
}
// 向地面跳跃
if (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;
}
}
// 碰撞
yspd = 0;
setOnGround(true);
}
// 跳跃准备
if (jumpKeyBuffered && onGround) {
// 基准
var index = 0;
// 应用跳跃速度
yspd = jspd[index];
// 设定跳跃计时器
jumpHoldTimer = jumpHoldFrames[index];
// 将玩家设为离地状态
setOnGround(false);
// 清空跳跃缓冲
jumpKeyBuffered = 0;
// 重置小幅度跳跃计时器
coyoteJumpTimer = 0;
}
// 移动
y += yspd;
#endregion
// 精灵控制
// 行走
if (Math.abs(xspd) > 0) {
sprite_index = walkSpr;
}
// Running
if (Math.abs(xspd) >= moveSpd[1]) {
sprite_index = runSpr;
}
// 未移动
if (xspd == 0) {
sprite_index = idleSpr;
}
// 空中
if (!onGround) {
sprite_index = jumpSpr;
}
// 设定碰撞遮蔽物
mask_index = idleSpr;
// create 事件
setOnGround(true);
// 设定玩家属性
depth = -30;
controlsSetup();
face = 1;
maskSpr = spr_Waluigi;
idleSpr = spr_Waluigi;
walkSpr = spr_walugi_run;
runSpr = spr_walugi_dash;
jumpSpr = spr_walugi_jump;
// 移动
moveDir = 0;
runType = 0;
moveSpd[0] = 4;
moveSpd[1] = 5.5;
xspd = 3;
yspd = 0;
// 跳跃
grav = 0.275;
termVel = 8;
onGround = true;
jumpMax = 1;
jumpCount = 0;
jumpHoldTimer = 0;
// 跳跃速度
jspd[0] = -3.15;
jumpHoldFrames[0] = 18;
jspd[1] = -2.85;
jumpHoldFrames[1] = 10;
// 小幅度时间
// 应用重力
coyoteHangFrames = 2;
coyoteHangTimer = 0;
// 跳跃缓冲时间
coyoteJumpFrames = 10;
coyoteJumpTimer = 0;
// 移动平台
myFloorPlat = noone;
moveplatXspd = 0;
moveplatMaxYspd = termVel;
评论 (0)