Android - 2D平台碰撞检测/ w重力物理

时间:2013-12-12 01:09:50

标签: android 2d collision-detection game-physics

由于这似乎是关于“堆栈”的一个反复出现的主题,我将强化我的问题,因为没有涵盖的东西。所涉及的是用于平台游戏等的2D平铺碰撞,但是通过我制作游戏的方式,没有平铺。我也没有使用额外的库,一切都是我自己写的。

我所拥有的是为游戏中的每个对象绑定Rect。到目前为止,只有两个对象类正在使用,即Platform和Entity。实体包含玩家移动等所有内容,而平台则适用于坚固的非移动平台。

Platform.java:

package com.toongames.game.objects;

import android.graphics.Color;
import android.graphics.Rect;

import com.toongames.framework.Graphics;

public class Platform {

    private int x, y;
    private int width, height;

    public Platform(int par1, int par2, int par3, int par4) {
        x = par1;
        y = par2;
        width = par3;
        height = par4;
    }

    public Rect getBounds() {
        return new Rect(x, y, x + width, y + height);
    }
}

Entity.java:

    package com.toongames.game.entity;

import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;

import com.toongames.framework.Graphics;
import com.toongames.framework.Image;

public class Entity {

    public final float GRAVITY = 0.1F;

    private String entityID;
    private Point pos;
    private int dx;
    private float vel;

    public Point desiredPos;
    public boolean onGround;

    public Entity(String par0String, int par1, int par2) {
        entityID = par0String;
        pos = new Point(par1, par2);

        desiredPos = pos;
        dx = 0;
        vel = 0;
    }

    public void update(float deltaTime) {
        vel = vel + (GRAVITY * deltaTime);

        pos.y += (vel * deltaTime);
        pos.x += dx;
    }

    public void setDx(int par1) {
        dx = par1;
    }

    public int getDx() {
        return dx;
    }

    public void setVelocity(int par1) {
        vel = par1;
    }

    public float getVelocity() {
        return vel;
    }

    public void setPos() {
        pos = desiredPos;
    }

    public Rect getBounds() {
        return new Rect(desiredPos.x, desiredPos.y, desiredPos.x + 80, desiredPos.y + 80);
    }
}

我已成功让玩家上下碰撞,但我不能为我的生活设法让玩家左右碰撞。每当我向左或向右移动时与平台碰撞,我只是跳到我碰撞的平台顶部。

我知道它与我的逻辑有关,但我无法弄清楚使用的正确逻辑。

ScreenGame.java:

    package com.toongames.game.screen;

// Imports here...

public class ScreenGame extends Screen {

    private Entity player;

    private Button left, right, jump;

    private Platform floor, p, p2, p3;
    private ArrayList<Platform> platforms;

    public ScreenGame(Game game) {
        super(game);

        player = new Entity("PLAYER", 300, 100, Assets.charRight);

        left = new Button(Assets.move_left, 10, 790 - Assets.move_left.getHeight(), Assets.move_left.getWidth(), Assets.move_left.getHeight());
        right = new Button(Assets.move_right, 20 + Assets.move_left.getWidth(), 790 - Assets.move_right.getHeight(), Assets.move_right.getWidth(), Assets.move_right.getHeight());
        jump = new Button(Assets.jump, 1270 - Assets.jump.getWidth(), 790 - Assets.jump.getHeight(), Assets.jump.getWidth(), Assets.jump.getHeight());

        floor = new Platform(0, 790, 1280, 80);
        p = new Platform(1280 - 500, 500, 400, 80);
        p2 = new Platform(0, 200, 400, 80);
        p3 = new Platform(400, 120, 200, 80);
        platforms = new ArrayList<Platform>();
        platforms.add(floor);
        platforms.add(p);
        platforms.add(p2);
        platforms.add(p3);
    }

    // An update method calls these
    public void updateMovement(float deltaTime) {
        List<TouchEvent> touchEvents = game.getInput().getTouchEvents();

        int len = touchEvents.size();
        for (int i = 0; i < len; i++) {
            TouchEvent event = touchEvents.get(i);
            if (event.type == TouchEvent.TOUCH_DOWN) {
                if (inBounds(left.getBounds(), event)) {
                    player.setDx((int) -(deltaTime * 1.5F));
                } else if (inBounds(right.getBounds(), event)) {
                    player.setDx((int) deltaTime * 2);
                } else if (inBounds(jump.getBounds(), event)) {
                    if (player.onGround) {
                        player.setVelocity(-8);
                    }
                }
            } else if (event.type == TouchEvent.TOUCH_DRAGGED) {
                if (inBounds(left.getBounds(), event)) {
                    player.setDx((int) -deltaTime * 2);
                } else if (inBounds(right.getBounds(), event)) {
                    player.setDx((int) deltaTime * 2);
                } else if (inBounds(jump.getBounds(), event)) {
                    if (player.onGround) {
                        player.setVelocity(-8);
                    }
                } else {
                    player.setDx(0);
                    player.jumpCounter = 0;
                }
            } else if (event.type == TouchEvent.TOUCH_UP) {
                player.setDx(0);
                player.jumpCounter = 0;
            }
        }
    }

    // An update method calls these
    public void updateGameObjects(float deltaTime) {
        for (Platform p : platforms)
            p.update();

        player.update(deltaTime);
    }

    // An update method calls these
    public void checkCollisions() {
        Rect playerRect = player.getBounds();

        for (Platform p : platforms) {
            Rect pRect = p.getBounds();

            if (Rect.intersects(playerRect, pRect)) {
                Rect intersection = playerRect;
                intersection.intersect(pRect);

                if (player.getVelocity() != player.GRAVITY) {
                    int resolutionHeight;

                    if (player.getVelocity() < player.GRAVITY)
                        resolutionHeight = intersection.height();
                    else {
                        resolutionHeight = -intersection.height();
                        player.onGround = true;
                    }

                    player.setVelocity(0);

                    player.desiredPos = new Point(player.desiredPos.x, player.desiredPos.y + resolutionHeight);
                }
            }
        }

        player.setPos();
    }
}

作为一个额外的注释,我已经删除了一些不必要的代码来处理实体和实体健康等的图像。此外,我已经删除了空方法和那些与之无关的东西。< / p>

[编辑]剪掉大部分绘图代码和导入。所有绝对必要的东西都在那里。

1 个答案:

答案 0 :(得分:0)

player.desiredPos = new Point(player.desiredPos.x, player.desiredPos.y + resolutionHeight);

这不是“向上移动,从不向右/向左移动吗?”

我认为您的Rect.intersects方法应返回{ NONE, LEFT, RIGHT, UP, DOWN }中的一个,指示发生碰撞的方向。所以你可以在正确的方向上对碰撞作出反应......