如何在overlap2d和libgdx中检测玩家和地面的碰撞

时间:2015-11-16 02:17:05

标签: java libgdx collision-detection overlap2d

我正在关注Youtube上的视频教程,名为“使用Overlap2D和libGDX制作简单的Sidescroller - 教程 - 003”。 我在视频中看到他使用raycast来检测碰撞。但是当我试图跟随时,玩家会在视频中掉落地面,玩家可以停在地面上。 以下是下载my libgdx projectmy overlap2d project供您查看的链接。 这是Player.java的代码

package com.test.superninja;

import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.uwsoft.editor.renderer.scripts.IScript;
import com.uwsoft.editor.renderer.components.TransformComponent;
import com.uwsoft.editor.renderer.components.DimensionsComponent;
import com.uwsoft.editor.renderer.utils.ComponentRetriever;
import com.uwsoft.editor.renderer.physics.PhysicsBodyLoader;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.RayCastCallback;
import com.badlogic.gdx.physics.box2d.World;

public class Player implements IScript {

  private Entity player;
  private TransformComponent transformComponent;
  private DimensionsComponent dimensionsComponent;
  private Vector2 speed;
  private float gravity = -500f;
  private float jumpSpeed = 170f;
  private World world;

  public Player(World world) {
    this.world = world;
  }

  @Override
  public void init(Entity entity) {
    player = entity;
    transformComponent = ComponentRetriever.get(entity, TransformComponent.class);
    dimensionsComponent = ComponentRetriever.get(entity, DimensionsComponent.class);
    speed = new Vector2(50, 0);
  }
  @Override
  public void act(float delta) {
    //transformComponent.scaleY = 0.5;
    if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
      transformComponent.x -= speed.x * delta;
      transformComponent.scaleX = -1f;
    }
    if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
      transformComponent.x += speed.x * delta;
      transformComponent.scaleX = 1f;
    }
    if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
      speed.y = jumpSpeed;
    }
    speed.y += gravity * delta;
    transformComponent.y += speed.y * delta;
    /*
    if (transformComponent.y < 16f){
      speed.y = 0;
      transformComponent.y = 16f;
    }
    */
  }
  private void rayCast() {
    float rayGap = dimensionsComponent.height / 2;

    // Ray size is the exact size of the deltaY change we plan for this frame
    float raySize = -(speed.y) * Gdx.graphics.getDeltaTime();

    //if(raySize < 5f) raySize = 5f;

    // only check for collisions when moving down
    if (speed.y > 0) return;

    // Vectors of ray from middle middle
    Vector2 rayFrom = new Vector2((transformComponent.x + dimensionsComponent.width / 2) * PhysicsBodyLoader.getScale(), (transformComponent.y + rayGap) * PhysicsBodyLoader.getScale());
    Vector2 rayTo = new Vector2((transformComponent.x + dimensionsComponent.width / 2) * PhysicsBodyLoader.getScale(), (transformComponent.y - raySize) * PhysicsBodyLoader.getScale());
    // Cast the ray
    world.rayCast(new RayCastCallback() {
      @Override
      public float reportRayFixture(Fixture fixture, Vector2 point, Vector2 normal, float fraction) {
        // Stop the player
        speed.y = 0;

        // reposition player slightly upper the collision point
        transformComponent.y  = point.y / PhysicsBodyLoader.getScale() + 0.1f;

        return 0;
      }
    }, rayFrom, rayTo);
  }
  public float getX() {
    return transformComponent.x;
  }
  public float getY() {
    return transformComponent.y;
  }
  public float getWidth() {
    return dimensionsComponent.width;
  }
  @Override
  public void dispose() {

  }
}

这是SuperNinja.java

package com.test.superninja;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.uwsoft.editor.renderer.SceneLoader;
import com.badlogic.gdx.utils.viewport.Viewport;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.uwsoft.editor.renderer.utils.ItemWrapper;
import com.uwsoft.editor.renderer.components.additional.ButtonComponent;
import com.badlogic.gdx.graphics.OrthographicCamera;


public class SuperNinja extends ApplicationAdapter {

    private SceneLoader sceneLoader;
    private Viewport viewport;
    private ItemWrapper root;
    private Player player;
    private UIStage uiStage;

    @Override
    public void create () {
        viewport = new FitViewport(266, 160);
        sceneLoader = new SceneLoader();
        sceneLoader.loadScene("MainScene", viewport);
        root = new ItemWrapper(sceneLoader.getRoot());
        player = new Player(sceneLoader.world);
        root.getChild("player").addScript(player);
        uiStage = new UIStage(sceneLoader.getRm());

    }

    @Override
    public void render () {
        Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        sceneLoader.getEngine().update(Gdx.graphics.getDeltaTime());
        uiStage.act();
        uiStage.draw();
        ((OrthographicCamera)viewport.getCamera()).position.x=player.getX()+player.getWidth()/2f;

    }
}

这是UIStage.java

package com.uwsoft.platformer;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.uwsoft.editor.renderer.data.CompositeItemVO;
import com.uwsoft.editor.renderer.data.ProjectInfoVO;
import com.uwsoft.editor.renderer.resources.IResourceRetriever;
import com.uwsoft.editor.renderer.scene2d.CompositeActor;

/**
 * Created by azakhary on 8/5/2015.
 */
public class UIStage extends Stage {

    public UIStage(IResourceRetriever ir) {

        Gdx.input.setInputProcessor(this);

        ProjectInfoVO projectInfo = ir.getProjectVO();

        CompositeItemVO menuButtonData = projectInfo.libraryItems.get("menuButton");
        CompositeActor buttonActor = new CompositeActor(menuButtonData, ir);

        addActor(buttonActor);

        buttonActor.setX(getWidth() - buttonActor.getWidth());
        buttonActor.setY(getHeight() - buttonActor.getHeight());

        buttonActor.addListener(new ClickListener() {
            @Override
            public void clicked (InputEvent event, float x, float y) {
                System.out.println("Hi");
            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

在Xeon的帮助下,我解决了我的问题。我只是忘了调用rayCast()函数。 我这样调用raycast()函数:

  @Override
  public void act(float delta) {
    ...
    rayCast();
  }

它有效。非常感谢Xeon。