zoukankan      html  css  js  c++  java
  • HTML5 2D平台游戏开发#11斜坡物理

      在游戏中会经常遇到斜坡地形,比如众所周知的魂斗罗,角色可以在坡上移动和跳跃:

    斜坡在2D游戏中很常见,处理起来也较为棘手。最初我打算用分离轴定律来实现,在建立了一个物理模型之后:

    发现上坡时没什么问题,但下坡时有比较明显的弹跳,这并不是预期的结果,因为我想让物体“粘”在坡上。产生这个问题的根本原因是物体的运动分为两个阶段,

    首先是水平方向的移动,最后是垂直方向的移动:

    如果X轴和Y轴的速度没有一定的方式关联起来,就会产生跳跃问题。根据力的平行四边形法则,物体的运行轨迹应该像这样(以向右下坡为例):

     

    接下来要做的工作就是计算出xspeedyspeed

    为了简单起见,先将斜坡统一设置成45°,即等边直角三角形,此时只需要将Y轴速度设置为与X轴速度相同即可。

    由上图可以发现,当x与y相等时,角色会贴着斜坡下降,而如果x轴的速度比y轴快,角色就会脱离斜坡,此时再加上y轴的重力加速度,将会出现上述跳跃的效果。

    当然这里不是说跳跃就是错误的,有些游戏也会需要这种效果,只是在当前场景下让角色“粘”在坡上更符合需求。

    任意角度的斜坡速度处理

      45°斜坡只是理想情况,实际上开发者可能要面对各种角度的斜坡,这里的“各种角度”是指小于90°,因为等于90°就相当于一面墙了。现在假设角色要在斜坡上移动的距离为distance(一般将其赋值为角色的水平速度speedX),那么其水平分量为

    vx = Math.cosθ * distance;

    然后令

    vy = vx;

    即可得出在斜坡上速度的水平和垂直分量。由于现在的水平速度是平时速度的分量,所以在斜坡上移动的速度比在平地时要慢一些。

    如果不记得三角函数,可以通过下图复习一下:

    上述方法都是在θ角已知的情况下展开讨论的,如果不知道θ角也没关系,它可以通过斜面的法线与垂直方向的夹角计算出来。

    至此角色在下坡时跳跃的问题已经有了初步的解决方案。

    现在还有一个关键问题需要解决,就是判断角色何时处于斜坡上,在斜坡上的水平移动使角色有一段时间是脱离斜坡的,必须让程序知道这个阶段的角色仍处于斜坡之上而不是离开了。

    //Pseudocode
    function checkCollision() {
        player.onSlope = false;
    
        if(checkPlayerOnSlope()) {
            player.onSlope = true;
        } 
    
        if(player.onSlope) {
            vy = vx = Math.cosθ * distance;
    
            //计算角色在斜坡上的坐标...
        }   
    }

    为实现上面伪代码中的checkPlayerOnSlope这个方法,需要做一些额外的准备工作。

    光线投射法

      光线投射法(RayCasting)是一种游戏中常见的碰撞检测手段。可以想象成一个点朝某个方向发出光线,直到光线击中或穿过待测目标。在光线投射过程中,如果记录下其穿过的Tiles,就会得到一个结果集,用这个结果集来分析判断角色所处的位置。现在假设某条光线穿过的区域如下图所示:

    蓝色线段所占的区域用红色表示,但还不够精确,预期得到的结果应该像这样:

    这里需要用到Bresenham画线算法(Bresenham's line algorithm)。计算机在画一条直线时,是通过像素来表现的,当像素点密集后,肉眼就看不出来了。

    (图片来自wikipedia)

    将该线段上所有点的坐标计算出来,观察其位于哪个Tiles内,最后就能得到线段经过的Tiles集合。

    现在为角色的脚部添加3条光线:

    如果其中一条经过的Tiles有斜坡,那就说明角色位于斜坡上。

    斜坡物理

      当角色位于斜坡上与在平地时不一样,应该忽略重力以及其它方向上的力的影响,否则会干扰其“粘”在斜坡上。角色位于斜坡上的y坐标很容易根据下图求出:

    A点的y坐标为BA'。左右移动时,根据角色的x坐标即可求出对应的y坐标slopeY,并一直令

    player.y = slopeY;

    直到离开斜坡。

    在斜坡上忽略重力影响并不意味着角色不能进行跳跃,触发跳跃时让角色强制离地即可。

    更新日志

      2017/04/09  更新角色跳跃

      2017/04/21  更新角色冲刺

      2017/05/01  更新角色状态机

      2017/05/16  更新角色攻击动画

      2017/05/22  更新角色移动攻击动画

      2017/05/24  更新角色跳跃攻击动画

      2017/06/04  更新地图绘制

      2017/06/22  更新摄像机、长距离冲刺

      2017/07/01  更新指令技

      2017/07/06  更新蓄力技

           2017/07/12  更新wall jump

           2017/10/13  更新斜坡地形 

  • 相关阅读:
    利用jquery进行ajax提交表单和附带的数据
    jquery插件-validate
    function [eigf,eigv,dof]=laplaceeig(node,elem,problem)
    [A,D]=solverAdini(node,elem,bdEdge,h1,h2)
    Example11(June 9,2015)
    加州旅馆
    jpg/png格式图片转eps格式的方法--latex自带命令bmeps
    accumarray
    HDU 1423 最长公共字串+上升子序列
    HDU 1503 带回朔路径的最长公共子串
  • 原文地址:https://www.cnblogs.com/undefined000/p/platformer-slope-physics.html
Copyright © 2011-2022 走看看