我正在关注Youtube上的视频教程,名为“使用Overlap2D和libGDX制作简单的Sidescroller - 教程 - 003”。 我在视频中看到他使用raycast来检测碰撞。但是当我试图跟随时,玩家会在视频中掉落地面,玩家可以停在地面上。 以下是下载my libgdx project和my 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");
}
});
}
}
答案 0 :(得分:1)
在Xeon的帮助下,我解决了我的问题。我只是忘了调用rayCast()函数。 我这样调用raycast()函数:
@Override
public void act(float delta) {
...
rayCast();
}
它有效。非常感谢Xeon。