修复跳一跳运行态方向与贴图刷新
恢复跳一跳运行态拖拽方向提交与后端方向落点计算 补齐平台六面贴图刷新签名和对应前端测试 更新跳一跳玩法链路文档与PRD方向契约说明
This commit is contained in:
@@ -64,8 +64,8 @@ pub fn start_run(
|
||||
pub fn apply_jump(
|
||||
run: &JumpHopRunSnapshot,
|
||||
drag_distance: f32,
|
||||
_drag_vector_x: Option<f32>,
|
||||
_drag_vector_y: Option<f32>,
|
||||
drag_vector_x: Option<f32>,
|
||||
drag_vector_y: Option<f32>,
|
||||
jumped_at_ms: u64,
|
||||
) -> Result<JumpHopRunSnapshot, JumpHopError> {
|
||||
if run.status != JumpHopRunStatus::Playing {
|
||||
@@ -88,8 +88,12 @@ pub fn apply_jump(
|
||||
let vector_x = target.x - current.x;
|
||||
let vector_y = target.y - current.y;
|
||||
let target_distance = vector_x.hypot(vector_y).max(0.0001);
|
||||
let unit_x = vector_x / target_distance;
|
||||
let unit_y = vector_y / target_distance;
|
||||
let (unit_x, unit_y) = normalize_jump_direction(
|
||||
drag_vector_x,
|
||||
drag_vector_y,
|
||||
vector_x / target_distance,
|
||||
vector_y / target_distance,
|
||||
);
|
||||
let landed_x = current.x + unit_x * jump_distance;
|
||||
let landed_y = current.y + unit_y * jump_distance;
|
||||
let landed_on_target = is_landing_inside_platform_footprint(target, landed_x, landed_y);
|
||||
@@ -138,6 +142,29 @@ fn is_landing_inside_platform_footprint(
|
||||
error_x.abs() <= half_width && error_y.abs() <= half_height
|
||||
}
|
||||
|
||||
fn normalize_jump_direction(
|
||||
drag_vector_x: Option<f32>,
|
||||
drag_vector_y: Option<f32>,
|
||||
fallback_x: f32,
|
||||
fallback_y: f32,
|
||||
) -> (f32, f32) {
|
||||
let Some(drag_x) = drag_vector_x.filter(|value| value.is_finite()) else {
|
||||
return (fallback_x, fallback_y);
|
||||
};
|
||||
let Some(drag_y) = drag_vector_y.filter(|value| value.is_finite()) else {
|
||||
return (fallback_x, fallback_y);
|
||||
};
|
||||
// 前端提交屏幕拖拽向量:x 轴同向,y 轴向下为正;真实起跳反向弹出,世界 y 向上为正。
|
||||
let jump_x = -drag_x;
|
||||
let jump_y = drag_y;
|
||||
let length = jump_x.hypot(jump_y);
|
||||
if length < 0.0001 {
|
||||
(fallback_x, fallback_y)
|
||||
} else {
|
||||
(jump_x / length, jump_y / length)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restart_run(
|
||||
run: &JumpHopRunSnapshot,
|
||||
next_run_id: String,
|
||||
@@ -450,7 +477,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jump_resolution_ignores_client_drag_direction_and_targets_next_center() {
|
||||
fn jump_resolution_uses_client_drag_direction_for_landing() {
|
||||
let path = generate_jump_hop_path("seed-screen-axis", JumpHopDifficulty::Easy);
|
||||
let run = start_run(
|
||||
"run-screen-axis".to_string(),
|
||||
@@ -465,9 +492,34 @@ mod tests {
|
||||
let target_distance = (target.x - current.x).hypot(target.y - current.y);
|
||||
let charge = (target_distance / run.path.scoring.charge_to_distance_ratio).round() as u32;
|
||||
|
||||
let result = apply_jump(&run, charge as f32, Some(-999.0), Some(-999.0), 200)
|
||||
let result = apply_jump(&run, charge as f32, Some(999.0), Some(-999.0), 200)
|
||||
.expect("jump should resolve");
|
||||
|
||||
assert_eq!(result.status, JumpHopRunStatus::Failed);
|
||||
assert_eq!(
|
||||
result.last_jump.as_ref().unwrap().result,
|
||||
JumpHopJumpResultKind::Miss
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jump_resolution_falls_back_to_next_center_when_drag_direction_missing() {
|
||||
let path = generate_jump_hop_path("seed-screen-axis", JumpHopDifficulty::Easy);
|
||||
let run = start_run(
|
||||
"run-screen-axis".to_string(),
|
||||
"user-screen-axis".to_string(),
|
||||
"profile-screen-axis".to_string(),
|
||||
path,
|
||||
100,
|
||||
)
|
||||
.expect("run should start");
|
||||
let current = &run.path.platforms[0];
|
||||
let target = &run.path.platforms[1];
|
||||
let target_distance = (target.x - current.x).hypot(target.y - current.y);
|
||||
let charge = (target_distance / run.path.scoring.charge_to_distance_ratio).round() as u32;
|
||||
|
||||
let result = apply_jump(&run, charge as f32, None, None, 200).expect("jump should resolve");
|
||||
|
||||
let last_jump = result.last_jump.as_ref().expect("last jump should exist");
|
||||
assert_eq!(result.status, JumpHopRunStatus::Playing);
|
||||
assert_eq!(last_jump.result, JumpHopJumpResultKind::Hit);
|
||||
|
||||
Reference in New Issue
Block a user