简体   繁体   English

使用Corona SDK的非Box2D物理

[英]Non-Box2D Physics with Corona SDK

I'm making a tile-based platformer game with Corona SDK. 我正在使用Corona SDK制作基于图块的平台游戏。 I decided to scrap the built-in Box2D physics engine (for a number of reasons), and I'm attempting to make my own physics system. 我决定取消内置的Box2D物理引擎(出于多种原因),并且我试图制作自己的物理系统。 Again, my game is built on tiles, which makes it easy to collect possible colliders. 同样,我的游戏是基于图块构建的,因此可以轻松收集可能的对撞机。 Also, the only object that needs to collide with tiles is my player, which should make it even easier. 另外,唯一需要与图块碰撞的对象是我的播放器,这应该使它更加容易。

I've got gravity and velocity working, and now I'm starting with collisions. 我已经有了重力和速度,现在我从碰撞开始。 I read on multiple sites how to do it, but it never seems to work for me. 我在多个站点上阅读了如何执行此操作,但它似乎对我没有用。 The process I've seen goes something like this: 我所看到的过程是这样的:

  1. Find possible colliders (easy with tile-based games) 查找可能的对撞机(轻松玩基于图块的游戏)
  2. Check for collisions (AABB's in my case) 检查碰撞(在我的情况下为AABB)
  3. Calculate penetration depth X and Y 计算穿透深度X和Y
  4. Move object by the penetration amount 按穿透量移动物体
  5. Adjust velocity based on penetration 根据穿透力调整速度

I've got steps 1-3 down, but, for some reason, when I start into steps 4 and 5, nothing works like the tutorials say it should. 我将步骤1-3调低了,但是由于某种原因,当我开始执行步骤4和5时,没有什么能像教程中所说的那样工作。 When colliding with the floor, the player instantly moves to the left. 当与地板碰撞时,玩家会立即向左移动。 I know why it does that - it's calculating the width of the player as the penetration depth - but when I try to fix it, things get odd. 我知道为什么会这么做-它会根据穿透深度来计算播放器的宽度-但是当我尝试修复它时,事情会变得很奇怪。

I call this function for each tile that's colliding with the player (after being found with a simple AABB collision check): 我为与播放器碰撞的每个图块调用此函数(在通过简单的ABB碰撞检查发现后):

local resolveCollision = function(guy, tile)
    local guyX, guyY, tileX, tileY = guy.x, guy.y, tile.x, tile.y
    local guyHW, guyHH = guy.width * 0.5, guy.height * 0.5
    local tileHW, tileHH = tile.width * 0.5, tile.height * 0.5

    local distX = guyX - tileX
    local minDistX = guyHW + tileHW

    local absDistX = (distX < 0 and -distX) or distX

    -- Calculate X penetration
    local xPen = 0
    if absDistX >= minDistX then
        xPen = 0
    else
        xPen = (distX > 0 and minDistX - distX) or -minDistX - distX
    end

    local distY = guyY - tileY
    local minDistY = guyHH + tileHH
    local absDistY = (distY < 0 and -distY) or distY

    -- Calculate Y penetration
    local yPen = 0
    if absDistY >= minDistY then
        yPen = 0
    else
        yPen = (distY > 0 and minDistY - distY) or -minDistY - distY
    end

    local absXPen = (xPen < 0 and -xPen) or xPen
    local absYPen = (yPen < 0 and -yPen) or yPen

    -- Trim off larger penetration
    if absXPen > absYPen and absYPen ~= 0 then
        xPen = 0
        guy.setYVel(0)
    elseif absYPen > absXPen and absXPen ~= 0 then
        yPen = 0
        guy.setXVel(0)
    end

    guy:translate(xPen, yPen)
end

Does anyone know how to do correct collision response? 有谁知道如何做正确的碰撞反应? FYI, my "physics" framework gives the following methods/values (among others): 仅供参考,我的“物理学”框架提供了以下方法/值(以及其他方法):

obj.setXVel(n)         - Set X-velocity
obj.setYVel(n)         - Set Y-velocity
obj.setVelocity(x, y)  - Set both velocities at once
obj.xVel               - Read-only, X-velocity value
obj.yVel               - Read-only, Y-velocity value

I think the problem is that your movement function is frame-based and will get triggered many times in one second. 我认为问题在于您的运动功能是基于帧的,并且在一秒钟内将被触发多次。

I suggest you change it to time-based movement. 我建议您将其更改为基于时间的运动。 To do this you need to find delta time (elapsed time between a frame and the next) and mutiply it by your move amount. 为此,您需要找到增量时间(一帧与下一帧之间经过的时间),并根据移动量来确定时间。 Use this tutorial to get deltaTime: http://coronalabs.com/blog/2013/06/18/guest-tutorial-delta-time-in-corona/ 使用本教程获取deltaTime: http : //coronalabs.com/blog/2013/06/18/guest-tutorial-delta-time-in-corona/

Once you have dT, use it like this: 一旦有了dT,就可以像这样使用它:

moveAmount = velocity * deltaTime

This will ensure that your movement speed is constant across devices. 这样可以确保您在各个设备上的移动速度保持恒定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM