Bullet Player Controller gravity is sideways - libgdx

I am making a 3D game using LibGDX and bullet by following the directions in the book Building a 3D Game with LibGDX by Sebastian Di Giuseppe. I've gotten to the part where you add a controllable character and for some reason instead of being thrown down, hes thrown sideways. My code is almost word for word the same as in the book.
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.badlogic.gdx.physics.bullet.collision.btBoxShape;
import com.badlogic.gdx.physics.bullet.collision.btBroadphaseProxy;
import com.badlogic.gdx.physics.bullet.collision.btCapsuleShape;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
import com.badlogic.gdx.physics.bullet.collision.btCollisionShape;
import com.badlogic.gdx.physics.bullet.collision.btPairCachingGhostObject;
import com.badlogic.gdx.physics.bullet.dynamics.btKinematicCharacterController;
import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody;
import Components.BulletComponent;
import Components.CharacterComponent;
import Components.ModelComponent;
import Components.PlayerComponent;
import States.MotionState;
import Systems.BulletSystem;
public class EntityFactory
{
static ModelBuilder modelBuilder = new ModelBuilder();
static Texture playerTexture = new Texture("data/badlogic.jpg");
static Material material = new Material(TextureAttribute.createDiffuse(playerTexture), ColorAttribute.createSpecular(1, 1, 1, 1), FloatAttribute.createShininess(8f));
static Model playerModel = modelBuilder.createCapsule(2f, 6f, 16, material, VertexAttributes.Usage.Position | VertexAttributes.Usage.Normal | VertexAttributes.Usage.TextureCoordinates);
public static Entity createStaticEntity(Model model, float x, float y, float z)
{
final BoundingBox boundingBox = new BoundingBox();
model.calculateBoundingBox(boundingBox);
Vector3 tmpV = new Vector3();
btCollisionShape col = new btBoxShape(tmpV.set(boundingBox.getWidth() * 0.5f, boundingBox.getHeight() * 0.5f, boundingBox.getDepth() * 0.5f));
Entity entity = new Entity();
ModelComponent modelComponent = new ModelComponent (model, x, y, z);
entity.add(modelComponent);
BulletComponent bulletComponent = new BulletComponent();
bulletComponent.bodyInfo = new btRigidBody.btRigidBodyConstructionInfo(0, null, col, Vector3.Zero);
bulletComponent.body = new btRigidBody(bulletComponent.bodyInfo);
bulletComponent.body.userData = entity;
bulletComponent.motionState = new MotionState(modelComponent.modelInstance.transform);
((btRigidBody)bulletComponent.body).setMotionState(bulletComponent.motionState);
entity.add(bulletComponent);
return entity;
}
public static Entity createCharacter(BulletSystem bulletSystem, float x, float y, float z)
{
Entity entity = new Entity();
ModelComponent modelComponent = new ModelComponent(playerModel, x, y, z);
entity.add(modelComponent);
CharacterComponent characterComponent = new CharacterComponent();
characterComponent.ghostObject = new btPairCachingGhostObject();
characterComponent.ghostObject.setWorldTransform(modelComponent.modelInstance.transform);
characterComponent.ghostShape = new btCapsuleShape(2f, 2f);
characterComponent.ghostObject.setCollisionShape(characterComponent.ghostShape);
characterComponent.ghostObject.setCollisionFlags(btCollisionObject.CollisionFlags.CF_CHARACTER_OBJECT);
characterComponent.characterController = new btKinematicCharacterController(characterComponent.ghostObject, characterComponent.ghostShape, .35f);
characterComponent.ghostObject.userData = entity;
entity.add(characterComponent);
bulletSystem.collisionWorld.addCollisionObject(entity.getComponent(CharacterComponent.class).ghostObject,
(short) btBroadphaseProxy.CollisionFilterGroups.CharacterFilter,
(short) (btBroadphaseProxy.CollisionFilterGroups.AllFilter));
bulletSystem.collisionWorld.addAction(entity.getComponent(CharacterComponent.class).characterController);
return entity;
}
public static Entity createPlayer(BulletSystem bulletSystem, float x, float y, float z)
{
Entity entity = createCharacter(bulletSystem, x, y ,z);
entity.add(new PlayerComponent());
return entity;
}
}
package Systems;
import com.badlogic.ashley.core.Engine;
import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.EntityListener;
import com.badlogic.ashley.core.EntitySystem;
import com.badlogic.ashley.core.Family;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.laterdated.hotbox.GameWorld;
import Components.CharacterComponent;
import Components.ModelComponent;
import Components.PlayerComponent;
public class PlayerSystem extends EntitySystem implements EntityListener
{
private Entity player;
private PlayerComponent playerComponent;
private CharacterComponent characterComponent;
private ModelComponent modelComponent;
private GameWorld gameWorld;
private final Vector3 tmp = new Vector3();
private final Camera camera;
public PlayerSystem(GameWorld gameWorld, Camera camera)
{
this.camera = camera;
this.gameWorld = gameWorld;
}
#Override
public void addedToEngine(Engine engine)
{
engine.addEntityListener(Family.all(PlayerComponent.class).get(), this);
}
#Override
public void entityAdded(Entity entity)
{
player = entity;
playerComponent = entity.getComponent(PlayerComponent.class);
characterComponent = entity.getComponent(CharacterComponent.class);
modelComponent = entity.getComponent(ModelComponent.class);
}
#Override
public void update(float delta)
{
if(player == null)
return;
updateMovement(delta);
}
private void updateMovement(float delta) {
float deltaX = -Gdx.input.getDeltaX() * 0.5f;
float deltaY = -Gdx.input.getDeltaY() * 0.5f;
tmp.set(0, 0, 0);
camera.rotate(camera.up, deltaX);
tmp.set(camera.direction).crs(camera.up).nor();
camera.direction.rotate(tmp, deltaY);
tmp.set(0, 0, 0);
characterComponent.characterDirection.set(-1, 0,
0).rot(modelComponent.modelInstance.transform).nor();
characterComponent.walkDirection.set(0, 0, 0);
if (Gdx.input.isKeyPressed(Input.Keys.W))
characterComponent.walkDirection.add(camera.direction);
if (Gdx.input.isKeyPressed(Input.Keys.S))
characterComponent.walkDirection.sub(camera.direction);
if (Gdx.input.isKeyPressed(Input.Keys.A))
tmp.set(camera.direction).crs(camera.up).scl(-1);
if (Gdx.input.isKeyPressed(Input.Keys.D))
tmp.set(camera.direction).crs(camera.up);
characterComponent.walkDirection.add(tmp);
characterComponent.walkDirection.scl(10f * delta);
characterComponent.characterController.setWalkDirection(characterComponent.
walkDirection);
Matrix4 ghost = new Matrix4();
Vector3 translation = new Vector3();
characterComponent.ghostObject.getWorldTransform(ghost); //TODO export this
ghost.getTranslation(translation);
modelComponent.modelInstance.transform.set(translation.x,
translation.y,
translation.z, camera.direction.x, camera.direction.y,
camera.direction.z,
0);
camera.position.set(translation.x, translation.y, translation.z);
camera.update(true);
}
#Override
public void entityRemoved(Entity entity)
{
}
}
package Systems;
import com.badlogic.ashley.core.Engine;
import com.badlogic.ashley.core.Entity;
import com.badlogic.ashley.core.EntityListener;
import com.badlogic.ashley.core.EntitySystem;
import com.badlogic.ashley.core.Family;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.bullet.collision.btAxisSweep3;
import com.badlogic.gdx.physics.bullet.collision.btBroadphaseInterface;
import com.badlogic.gdx.physics.bullet.collision.btCollisionConfiguration;
import com.badlogic.gdx.physics.bullet.collision.btCollisionDispatcher;
import com.badlogic.gdx.physics.bullet.collision.btDefaultCollisionConfiguration;
import com.badlogic.gdx.physics.bullet.collision.btGhostPairCallback;
import com.badlogic.gdx.physics.bullet.dynamics.btConstraintSolver;
import com.badlogic.gdx.physics.bullet.dynamics.btDiscreteDynamicsWorld;
import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody;
import com.badlogic.gdx.physics.bullet.dynamics.btSequentialImpulseConstraintSolver;
import Components.BulletComponent;
import Components.CharacterComponent;
public class BulletSystem extends EntitySystem implements EntityListener {
public final btCollisionConfiguration collisionConfiguration;
public final btCollisionDispatcher dispatcher;
public final btBroadphaseInterface broadphase;
public final btConstraintSolver solver;
public final btDiscreteDynamicsWorld collisionWorld;
private btGhostPairCallback ghostPairCallback;
public int maxSubSteps = 5;
public float fixedTimeStep = 1f / 60f;
#Override
public void addedToEngine(Engine engine) {
engine.addEntityListener(Family.all(BulletComponent.class).get(), this);
}
public BulletSystem() {
collisionConfiguration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfiguration);
broadphase = new btAxisSweep3(new Vector3(-1000, -1000, -1000), new Vector3(1000, 1000, 1000));
solver = new btSequentialImpulseConstraintSolver();
collisionWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
ghostPairCallback = new btGhostPairCallback();
broadphase.getOverlappingPairCache().setInternalGhostPairCallback(ghostPairCallback);
this.collisionWorld.setGravity(new Vector3(0, -0.5f, 0));
}
#Override
public void update(float delta) {
collisionWorld.stepSimulation(delta);
}
public void dispose() {
collisionWorld.dispose();
if (solver != null) solver.dispose();
if (broadphase != null) broadphase.dispose();
if (dispatcher != null) dispatcher.dispose();
if (collisionConfiguration != null) collisionConfiguration.dispose();
ghostPairCallback.dispose();
}
#Override
public void entityAdded(Entity entity) {
BulletComponent bulletComponent = entity.getComponent(BulletComponent.class);
if (bulletComponent.body != null) {
collisionWorld.addRigidBody((btRigidBody) bulletComponent.body);
}
}
public void removeBody(Entity entity) {
BulletComponent comp = entity.getComponent(BulletComponent.class);
if (comp != null)
collisionWorld.removeCollisionObject(comp.body);
CharacterComponent character = entity.getComponent(CharacterComponent.class);
if (character != null) {
collisionWorld.removeAction(character.characterController);
collisionWorld.removeCollisionObject(character.ghostObject);
}
}
#Override
public void entityRemoved(Entity entity) {
}
}
package com.laterdated.hotbox;
import com.badlogic.ashley.core.Engine;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.physics.bullet.Bullet;
import com.badlogic.gdx.physics.bullet.dynamics.btKinematicCharacterController;
import Components.CharacterComponent;
import Components.ModelComponent;
import Managers.EntityFactory;
import Systems.BulletSystem;
import Systems.PlayerSystem;
import Systems.RenderSystem;
public class GameWorld
{
private static final float FOV = 90f;
private ModelBatch modelBatch;
private Environment environment;
private PerspectiveCamera camera;
private Engine engine;
private Entity character;
public BulletSystem bulletSystem;
public ModelBuilder modelBuilder = new ModelBuilder();
Model wallHorizontal = modelBuilder.createBox(40, 20, 1,
new Material(ColorAttribute.createDiffuse(Color.WHITE),
ColorAttribute.createSpecular(Color.RED), FloatAttribute
.createShininess(16f)), VertexAttributes.Usage.Position
| VertexAttributes.Usage.Normal);
Model wallVertical = modelBuilder.createBox(1, 20, 40,
new Material(ColorAttribute.createDiffuse(Color.GREEN),
ColorAttribute.createSpecular(Color.WHITE),
FloatAttribute.createShininess(16f)),
VertexAttributes.Usage.Position |
VertexAttributes.Usage.Normal);
Model groundModel = modelBuilder.createBox(40, 1, 40,
new Material(ColorAttribute.createDiffuse(Color.YELLOW),
ColorAttribute.createSpecular(Color.BLUE),
FloatAttribute.createShininess(16f)),
VertexAttributes.Usage.Position
| VertexAttributes.Usage.Normal);
public GameWorld()
{
Bullet.init();
initiatePerspectiveCamera();
initiateEnvironment();
initiateModelBatch();
addSystems();
addEntities();
}
private void addEntities()
{
createGround();
createPlayer(5, 3, 5);
}
private void createGround()
{
engine.addEntity(EntityFactory.createStaticEntity(groundModel, 0, 0, 0));
engine.addEntity(EntityFactory.createStaticEntity(wallHorizontal, 0, 10, -20));
engine.addEntity(EntityFactory.createStaticEntity(wallHorizontal, 0, 10, 20));
engine.addEntity(EntityFactory.createStaticEntity(wallVertical, 20, 10, 0));
engine.addEntity(EntityFactory.createStaticEntity(wallVertical, -20, 10, 0));
}
private void createPlayer(float x, float y, float z)
{
character = EntityFactory.createPlayer(bulletSystem, x, y, z);
engine.addEntity(character);
}
public void render(float delta)
{
renderWorld(delta);
}
protected void renderWorld(float delta)
{
modelBatch.begin(camera);
engine.update(delta);
modelBatch.end();
}
private void initiatePerspectiveCamera()
{
camera = new PerspectiveCamera(FOV, Core.VIRTUAL_WIDTH, Core.VIRTUAL_HEIGHT);
}
private void initiateEnvironment()
{
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.3f, 0.3f, 0.3f, 1f));
}
private void initiateModelBatch()
{
modelBatch = new ModelBatch();
}
private void addSystems()
{
engine = new Engine();
engine.addSystem(new RenderSystem(modelBatch, environment));
engine.addSystem(bulletSystem = new BulletSystem());
engine.addSystem(new PlayerSystem(this, camera));
}
public void dispose()
{
bulletSystem.collisionWorld.removeAction(character.getComponent(CharacterComponent.class).characterController);
bulletSystem.collisionWorld.removeCollisionObject(character.getComponent(CharacterComponent.class).ghostObject);
character.getComponent(CharacterComponent.class).characterController.dispose();
character.getComponent(CharacterComponent.class).ghostObject.dispose();
character.getComponent(CharacterComponent.class).ghostShape.dispose();
bulletSystem.dispose();
bulletSystem = null;
wallHorizontal.dispose();
wallVertical.dispose();
groundModel.dispose();
modelBatch.dispose();
modelBatch = null;
}
public void resize(int width, int height)
{
camera.viewportHeight = height;
camera.viewportWidth = width;
}
}

I found the solution if anyone else has the same problem. You have to add a new vector3 or your walk direction at the end of your characterController.
characterComponent.characterController = new btKinematicCharacterController(characterComponent.ghostObject, characterComponent.ghostShape, .35f);
characterComponent.characterController = new btKinematicCharacterController(characterComponent.ghostObject, characterComponent.ghostShape, .35f, characterComponent.walkDirection);

Related

sprite's setPosition method does not work

So i have been trying to move the sprite wherever my body moves in the world. So i was using the sprite's setPosition method but turns out it didn't help. My Image just sits at the position (0,0) and i cant understand why.
Here is the code:
package com.example.shapetest;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
class ShapeTest implements ApplicationListener {
SpriteBatch batch;
World world;
OrthographicCamera camera;
Box2DDebugRenderer debugRenderer;
Texture squareTx;
Sprite square;
Body body;
#Override
public void create() {
batch = new SpriteBatch();
world = new World(new Vector2(0,-10),false);
squareTx = new Texture(Gdx.files.internal("sq.png"));
square = new Sprite(squareTx);
debugRenderer = new Box2DDebugRenderer();
camera = new OrthographicCamera();
camera.setToOrtho(false);
BodyDef bd = new BodyDef();
bd.type = BodyType.DynamicBody;
bd.position.set(new Vector2((Gdx.graphics.getWidth() / 2) * 0.01f, Gdx.graphics.getHeight() * 0.01f));
body = world.createBody(bd);
BodyDef bd2 = new BodyDef();
bd2.type = BodyType.StaticBody;
bd2.position.set(new Vector2(Gdx.graphics.getWidth()/2 * 0.01f, 100 * 0.01f));
Body body2 = world.createBody(bd2);
square.setSize(100,100);
PolygonShape shape = new PolygonShape();
shape.setAsBox(0.5f,0.5f);
PolygonShape shape2 = new PolygonShape();
shape2.setAsBox(1.6f,0.3f);
FixtureDef fd = new FixtureDef();
fd.density = 1;
fd.restitution = 0.2f;
fd.shape = shape;
fd.friction = 0.4f;
body.createFixture(fd);
body2.createFixture(shape2, 0f);
shape.dispose();
}
#Override
public void resize(int width, int height) {
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Vector2 pos = body.getPosition();
square.setPosition(pos.x ,pos.y);
camera.update();
batch.setProjectionMatrix(camera.combined);
Matrix4 cameraCopy = camera.combined.cpy();
debugRenderer.render(world, cameraCopy.scl(100f));
world.step(1/60f,10,10);
batch.begin();
square.draw(batch);
batch.end();
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
batch.dispose();
}
}
Here is the result:
(sprite should follow the pink box position)
body.getPosition() return small value so for drawing you need to convert that value into pixel value.
According to you, sprite size is 100 pixels, and it represent dynamic physics body that is polygonShape having size 0.5f * 2 = 1; unit in physics i.e you assuming 1 unit/meter of physics is equal to 100 pixels.
Vector2 pos = body.getPosition(); // value return in physics unit
square.setPosition(pos.x*100 ,pos.y*100);

How to visualize my R plot in my JFrame with JavaGD?

I am new to JRI/rJava/JavaGD and have some problems with it. I drew a simple R plot with JRI and want to include this plot in my customized JFrame. I added the GDCanvas in which the plot should appear to my JFrame. However the plot is not displayed in the GDCanvas, but opens in a new Frame. How can I visualize my R plot in my JFrame, instead of appearing in its own frame?
For me, another possibility would be to modify the new frame in which my plot pops up. But I couldn't add or modify anything there either. Is there a special way to modify frames that appear with JavaGD()?
Can someone please help me? Many thanks in advance.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.rosuda.JRI.Rengine;
import org.rosuda.javaGD.GDCanvas;
public class RjavaGD extends JFrame implements ActionListener {
private Rengine engine;
public static GDCanvas gdc;
private JButton btn;
public RjavaGD() {
super();
super.setTitle("My R Plot");
btn = new JButton("show plot");
btn.addActionListener(this);
gdc = new GDCanvas(400, 400);
gdc.setBackground(Color.PINK);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(btn, BorderLayout.PAGE_START);
this.getContentPane().add((GDCanvas) gdc, BorderLayout.CENTER);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
// initialize R
engine = new Rengine(new String[] { "--vanilla" }, false, null);
engine.eval("library(JavaGD)");
engine.eval("Sys.putenv('JAVAGD_CLASS_NAME'='RjavaGDInterface')");
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new RjavaGD();
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btn) {
engine.eval("JavaGD()");
engine.eval("a <- c(1,2,3,2,4)");
engine.eval("plot(a,type=\"l\")");
gdc.initRefresh();
engine.end();
this.setTitle("new random plot");
}
}
}
import org.rosuda.javaGD.GDInterface;
public class RjavaGDInterface extends GDInterface {
public void gdOpen(double w, double h)
{
c = RjavaGD.gdc;
}
}
I used Sys.setenv() instead of Sys.putenv().
I also found a way to integrate the plot into my own customized frame, so that I can add buttons and other stuff directly below the plot, which was not possible with the standard frame that opens automatically.
This code worked fine for me:
import org.rosuda.JRI.Rengine;
import org.rosuda.javaGD.GDCanvas;
public class RjavaGD extends JFrame implements ActionListener {
private Rengine engine;
private JButton btn;
public RjavaGD() {
super();
super.setTitle("My R Plot");
btn = new JButton("show plot");
btn.addActionListener(this);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(btn, BorderLayout.PAGE_START);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.pack();
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btn) {
// initialize R
engine = new Rengine(new String[] { "--vanilla" }, false, null);
engine.eval("Sys.setenv('JAVAGD_CLASS_NAME'='RjavaGDInterface')");
engine.eval("library(JavaGD)");
engine.eval("JavaGD()");
engine.eval("a <- c(1,2,3,2,4)");
engine.eval("plot(a,type=\"l\")");
engine.end();
}
}
}
import org.rosuda.javaGD.GDInterface;
public class RjavaGDInterface extends GDInterface {
JFrame f;
#Override
public void gdOpen(double w, double h) {
super.gdOpen(w,h);
f = new JFrame();
f.setLayout(new BorderLayout());
c = new GDCanvas(w, h);
f.setTitle("New Plot");
f.getContentPane().add((GDCanvas) c, BorderLayout.CENTER);
f.getContentPane().add(buttonPanel(), BorderLayout.NORTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
private JPanel buttonPanel(){
JPanel p = new JPanel();
p.setBackground(Color.pink);
p.add(new JLabel("Options“));
p.add(new JButton("option1“))
return p;
}
}
I hope this will help other people with the same problem :)

Libgdx collision using box2d working for desktop but failed to collide in Android emulator

My code for collision of a dynamic body to a static body works perfectly for desktop , but when running in Android emulator it can not able to detect collision ,Dynamic body goes down without collision.
I used Libgdx version : 1.5.0 .
Code :
package com.kg.game;
import java.util.Random;
import aurelienribon.tweenengine.BaseTween;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenCallback;
import aurelienribon.tweenengine.TweenManager;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
private static final float VIEWPORT_WIDTH = 10;
private static final float BALL_RADIUS = 0.15f;
private static final int MAX_BALLS = 200;
private World world;
private Body[] ballModels;
private Texture bottleTexture;
private Texture ballTexture;
private Sprite[] ballSprites;
private Texture whiteTexture;
private Sprite groundSprite;
private SpriteBatch batch;
private BitmapFont font;
private OrthographicCamera camera;
private final Random rand = new Random();
float w;
float h;
Box2DDebugRenderer debugRenderer;
private final TweenManager tweenManager = new TweenManager();
#Override
public void create() {
debugRenderer = new Box2DDebugRenderer();
world = new World(new Vector2(0, -10), true);
createGround();
createBalls();
batch = new SpriteBatch();
font = new BitmapFont();
font.setColor(Color.BLACK);
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_WIDTH * h / w);
camera.position.set(0, (VIEWPORT_WIDTH * h / w) / 2, 0);
camera.update();
createSprites();
Gdx.input.setInputProcessor(new InputAdapter() {
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
restart();
return true;
}
});
restart();
}
private void createGround() {
BodyDef bd = new BodyDef();
bd.position.set(0, 0);
bd.type = BodyType.StaticBody;
PolygonShape shape = new PolygonShape();
shape.setAsBox(100, 4);
FixtureDef fd = new FixtureDef();
fd.density = 1;
fd.friction = 0.5f;
fd.restitution = 0.5f;
fd.shape = shape;
world.createBody(bd).createFixture(fd);
shape.dispose();
}
private void createBalls() {
BodyDef ballBodyDef = new BodyDef();
ballBodyDef.type = BodyType.DynamicBody;
CircleShape shape = new CircleShape();
shape.setRadius(BALL_RADIUS);
FixtureDef fd = new FixtureDef();
fd.density = 1;
fd.friction = 0.5f;
fd.restitution = 0.5f;
fd.shape = shape;
ballModels = new Body[MAX_BALLS];
for (int i = 0; i < MAX_BALLS; i++) {
ballModels[i] = world.createBody(ballBodyDef);
ballModels[i].createFixture(fd);
}
shape.dispose();
}
private void createSprites() {
ballTexture = new Texture(Gdx.files.internal("ball.png"));
ballTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
ballSprites = new Sprite[MAX_BALLS];
for (int i = 0; i < MAX_BALLS; i++) {
ballSprites[i] = new Sprite(ballTexture);
ballSprites[i].setSize(BALL_RADIUS * 2, BALL_RADIUS * 2);
ballSprites[i].setOrigin(BALL_RADIUS, BALL_RADIUS);
}
whiteTexture = new Texture(Gdx.files.internal("ground.png"));
groundSprite = new Sprite(whiteTexture);
groundSprite.setSize(100, 4);
groundSprite.setPosition(-VIEWPORT_WIDTH / 2, 0);
groundSprite.setColor(Color.BLACK);
}
private float elapsed = 0;
#Override
public void render() {
tweenManager.update(1 / 60f);
world.step(1 / 60f, 10, 10);
debugRenderer.render(world, camera.combined);
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
GL20 gl = Gdx.gl20;
gl.glClearColor(1, 1, 1, 1);
gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// Update
for (int i = 0; i < MAX_BALLS; i++) {
Vector2 ballPos = ballModels[i].getPosition();
ballSprites[i].setPosition(ballPos.x - ballSprites[i].getWidth()
/ 2, ballPos.y - ballSprites[i].getHeight() / 2);
ballSprites[i].setRotation(ballModels[i].getAngle()
* MathUtils.radiansToDegrees);
}
// Render
batch.setProjectionMatrix(camera.combined);
batch.begin();
groundSprite.draw(batch);
for (int i = 0; i < MAX_BALLS; i++)
ballSprites[i].draw(batch);
batch.end();
// batch.getProjectionMatrix().setToOrtho2D(0, 0, w, h);
batch.begin();
font.draw(batch, "Touch the screen to restart", 5, h - 5);
batch.end();
}
#Override
public void dispose() {
bottleTexture.dispose();
ballTexture.dispose();
batch.dispose();
font.dispose();
world.dispose();
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return true;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
private void restart() {
Vector2 vec = new Vector2();
for (int i = 0; i < MAX_BALLS; i++) {
float tx = rand.nextFloat() * 1.0f - 0.5f;
float ty = VIEWPORT_WIDTH * h / w;
float angle = rand.nextFloat() * MathUtils.PI * 2;
ballModels[i].setActive(false);
ballModels[i].setLinearVelocity(vec.set(0, 0));
ballModels[i].setAngularVelocity(0);
ballModels[i].setTransform(vec.set(tx, ty), angle);
}
tweenManager.killAll();
Tween.call(new TweenCallback() {
private int idx = 0;
#Override
public void onEvent(int type, BaseTween<?> source) {
if (idx < ballModels.length) {
ballModels[idx].setAwake(true);
ballModels[idx].setActive(true);
idx += 1;
}
}
}).repeat(-1, 0.1f).start(tweenManager);
}
}
Screensots :
this is an idea, looking at the proportions of your images, I think the error may be out there, I would look at these lines:
groundSprite.setSize(100, 4); //<--especially here
groundSprite.setPosition(-VIEWPORT_WIDTH / 2, 0); //<--especially here
.
private void createGround() {
BodyDef bd = new BodyDef();
bd.position.set(0, 0); //<--especially here
bd.type = BodyType.StaticBody;
PolygonShape shape = new PolygonShape();
shape.setAsBox(100, 4); //<--especially here
especially the position and size, if it is standing in the same place, with the change of screen "device".
You tried to render debug? I see out there, if so, you can see your object in the emulated device?
I hope I understand, but not if that be the error

Why does my Player follow the OrthographicCamera

My game renders a tiledmap. I let the OrthographicCamera change its position.x to the right and can see the background (the tiledmap) scroll. This is fine.
But other Objects (the player and some balls) do (visually) change their position corresponding to the camera. They should not move, because only the camera moves.
package com.me.drop;
import java.util.Iterator;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.math.Circle;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.GdxNativesLoader;
import com.badlogic.gdx.utils.TimeUtils;
public class MyTestGame extends Game {
Texture dropImage;
Texture bucketImage;
Sound dropSound;
Music rainMusic;
SpriteBatch batch;
OrthographicCamera camera;
Rectangle bucket;
Array<Rectangle> raindrops;
long lastDropTime;
Animator animator = new Animator();
Body animatorBody;
private Physics physics;
public Environment environment;
// public PerspectiveCamera cam;
public Model model;
public ModelBatch modelBatch;
public ModelInstance instance;
static final int WIDTH = 1600;
static final int HEIGHT = 960;
public final static float ORTHO_SCALE=1;
public final static float WORLD_SCALE=32;
Ball balls[] = new Ball[10];
Spieler player;
#Override
public void create() {
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
glViewport = new Rectangle(0, 0, WIDTH, HEIGHT);
// load the images for the droplet and the bucket, 64x64 pixels each
dropImage = new Texture(Gdx.files.internal("droplet.png"));
bucketImage = new Texture(Gdx.files.internal("bucket.png"));
// load the drop sound effect and the rain background "music"
dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
// start the playback of the background music immediately
rainMusic.setLooping(true);
rainMusic.play();
// create the camera and the SpriteBatch
camera = new OrthographicCamera();
//camera.setToOrtho(false, 400, 240);
camera.setToOrtho(false, 800/ORTHO_SCALE, 480/ORTHO_SCALE);
batch = new SpriteBatch();
ModelBuilder modelBuilder = new ModelBuilder();
model = modelBuilder.createBox(5f, 5f, 5f,
new Material(ColorAttribute.createDiffuse(Color.GREEN)),
Usage.Position | Usage.Normal);
instance = new ModelInstance(model);
// Box2d
physics = Physics.getInstance();
// floor
physics.initFloor(0f, 0f, camera.viewportWidth, 0f);
// ceiling
// physics.initFloor(0f, camera.viewportHeight, camera.viewportWidth, 10f);
// left Wall
physics.initFloor(0f, 0f, 0f, camera.viewportHeight);
// right Wall
physics.initFloor(camera.viewportWidth, 0f, 0f, camera.viewportHeight);
float x = 150;
float y = camera.viewportHeight;
for (int i = 0; i < balls.length; i++) {
if (i%10==0) {
x += 10;
y = camera.viewportHeight / 2;
}
y += x;
balls[i] = new Ball(x, y , 20f , 20f, 0.4f, 0.8f);
}
player = new Spieler(50, camera.viewportHeight, 60f, 120f);
loadBackground();
}
TiledMapRenderer tileRenderer;
public void loadBackground() {
TiledMap map = new TmxMapLoader().load("maps/mymap.tmx");
System.out.println(map.getTileSets().toString());
float unitScale = 1 / 1;
tileRenderer = new OrthogonalTiledMapRenderer(map, unitScale);
physics.createFixturesForMap(map);
}
private Rectangle glViewport;
//#Override
public void render() {
GL10 gl = Gdx.graphics.getGL10();
// Camera --------------------- /
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glViewport((int) glViewport.x, (int) glViewport.y,
(int) glViewport.width, (int) glViewport.height);
//
// tell the camera to update its matrices.
camera.update();
camera.apply(gl);
// tell the SpriteBatch to render in the
// coordinate system specified by the camera.
batch.setProjectionMatrix(camera.combined);
// background
tileRenderer.setView(camera);
tileRenderer.render();
for (Ball b : balls)
b.render();
player.render();
grabUserAction();
// Box2d
physics.step();
updateObjects();
physics.debugRenderer.render(physics.world, camera.combined);
}
private void grabUserAction() {
// process user input
if(Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
bucket.x = touchPos.x - 64 / 2;
}
Vector2 vel = this.player.getBody().getLinearVelocity();
Vector2 pos = this.player.getBody().getPosition();
// apply left impulse, but only if max velocity is not reached yet
if (Gdx.input.isKeyPressed(Keys.LEFT)) { // && vel.x > -MAX_VELOCITY) {
// this.animatorBody.localPoint2.x -= 200 *
// Gdx.graphics.getDeltaTime();
pos.x -= 2 * Gdx.graphics.getDeltaTime();
this.player.getBody().setTransform(pos, 0);
// this.animatorBody.applyLinearImpulse(0, -0.8f, pos.x, pos.y,
// true);
// this.animatorBody.applyLinearImpulse(-5000, 0, pos.x, pos.y,
// true);
}
// apply right impulse, but only if max velocity is not reached yet
if (Gdx.input.isKeyPressed(Keys.RIGHT)) { // && vel.x < MAX_VELOCITY) {
// this.animatorBody.localPoint2.x += 200 *
// Gdx.graphics.getDeltaTime();
pos.x += 2 * Gdx.graphics.getDeltaTime();
this.player.getBody().setTransform(pos, 0);
// this.animatorBody.applyLinearImpulse(5000, 0, pos.x, pos.y,
// true);
}
if (Gdx.input.isKeyPressed(Keys.UP)) {
Vector2 impuls = new Vector2(0, 500f);
this.player.getBody().applyLinearImpulse(impuls, player.getBody().getWorldCenter(),true);
// this.animatorBody.applyAngularImpulse(-5.0f, true);
//(impulse, wake);(new b2Vec2(0.0, -3.0), Body.GetWorldCenter());
}
if (Gdx.input.isKeyPressed(Keys.D)) {
this.camera.position.x += 2;
this.camera.update();
}
else if (Gdx.input.isKeyPressed(Keys.A)) {
this.camera.position.x -= 2;
this.camera.update();
}
}
private void updateObjects() {
Array<Body> array = new Array<Body>();
physics.world.getBodies(array);
Iterator<Body> bi = array.iterator();
while (bi.hasNext()){
Body b = bi.next();
// Get the body's user data - in this example, our user
// data is an instance of the Entity class
IObject e = (IObject) b.getUserData();
if (e != null) {
// Update the entities/sprites position and angle
e.setPosition((b.getPosition().x - e.getWidth()/2/WORLD_SCALE) * WORLD_SCALE
, (b.getPosition().y - e.getHeight()/2/WORLD_SCALE) * WORLD_SCALE);
// We need to convert our angle from radians to degrees
//e.setRotation(MathUtils.radiansToDegrees * b.getAngle());
}
}
}
#Override
public void dispose() {
// dispose of all the native resources
dropImage.dispose();
bucketImage.dispose();
dropSound.dispose();
rainMusic.dispose();
batch.dispose();
// modelBatch.dispose();
model.dispose();
}
#Override
public void resize(int width, int height) {
super.resize(width, height);
//
// Vector3 oldpos = new Vector3(camera.position);
// camera.setToOrtho(false,
// width/WORLD_SCALE,
// height/WORLD_SCALE);
// camera.translate(oldpos.x-camera.position.x,oldpos.y-camera.position.y);
}
#Override
public void pause() {
super.pause();
}
#Override
public void resume() {
super.resume();
}
}

jgoodies binding: using a JTextField with a formatted number?

I am trying to bind a JTextField to a bean's field that is a double using JGoodies Binding:
JTextField myJTextField = ...
BeanAdapter adapter = ...
Bindings.bind(myJTextField,
ConverterFactory.createStringConverter(adapter.getValueModel("amplitude"),
new DecimalFormat("0.00000")));
This works, at least in the bean → JTextField direction. In the JTextField → bean direction, it has one hitch: if I start typing in the JTextField it takes my update immediately after the first digit after the decimal point, messes up the JTextField focus, and tweaks my JTextField value.
(the problem seems to come from trying to adapt a GUI's String to a model's double)
How do I fix this????
sample program that demonstrates this:
package com.example.test.gui;
import java.awt.GridLayout;
import java.beans.PropertyChangeListener;
import java.text.DecimalFormat;
import java.util.Hashtable;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.binding.adapter.BoundedRangeAdapter;
import com.jgoodies.binding.beans.BeanAdapter;
import com.jgoodies.binding.beans.ExtendedPropertyChangeSupport;
import com.jgoodies.binding.value.ConverterFactory;
public class FloatPointBinding {
public static class MyModel {
private int x;
final private ExtendedPropertyChangeSupport changeSupport =
new ExtendedPropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener x) {
this.changeSupport.addPropertyChangeListener(x);
}
public void removePropertyChangeListener(PropertyChangeListener x) {
this.changeSupport.removePropertyChangeListener(x);
}
static private int clip(int a)
{
return Math.min(Math.max(a, -32768), 32767);
}
static private int d2i(double a) {
return clip((int) Math.floor(a*32768 + 0.5));
}
static private double i2d(int a) {
return (clip(a)/32768.0);
}
public void setXCount(int x) {
int oldX = this.x;
int newX = x;
this.x=newX;
this.changeSupport.firePropertyChange("x", i2d(oldX), i2d(newX));
this.changeSupport.firePropertyChange("XCount", oldX, newX);
}
public void setX(double x) { setXCount(d2i(x)); }
public double getX() { return i2d(this.x); }
public int getXCount() { return this.x; }
}
public static class MyView extends JFrame
{
public MyView(MyModel model, String title)
{
super(title);
JTextField jtf = new JTextField();
JSlider jsl = new JSlider();
jsl.setMinimum(-32768);
jsl.setMaximum(32767);
jsl.setMajorTickSpacing(4096);
jsl.setPaintTicks(true);
Hashtable labelTable = new Hashtable();
labelTable.put( new Integer( -32768 ), new JLabel("-1") );
labelTable.put( new Integer( 0 ), new JLabel("0") );
labelTable.put( new Integer( 32767 ), new JLabel("1") );
jsl.setLabelTable( labelTable );
jsl.setPaintLabels(true);
setLayout(new GridLayout());
add(jsl);
add(jtf);
BeanAdapter adapter = new BeanAdapter(model, true);
Bindings.bind(jtf,
ConverterFactory.createStringConverter(adapter.getValueModel("x"),
new DecimalFormat("0.#####")));
jsl.setModel(new BoundedRangeAdapter(adapter.getValueModel("XCount"), 0, -32768, 32767));
}
}
public static void main(String[] args)
{
MyModel model = new MyModel();
MyView view = new MyView(model, "FloatPointBinding");
view.pack();
view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
view.setVisible(true);
}
}
I am not sure if this is what you are trying to solve, but if you change the binding to only commit on focus lost you shouldn't have that issue anymore. Just specify true as the third argument to the bind method below:
Bindings.bind(jtf,
ConverterFactory.createStringConverter(adapter.getValueModel("x"),
new DecimalFormat("0.#####")),
true);