Libgdx multiTouch not working - java

I'm developing a game , and I'm using Libgdx Library in this game. It will work on Android and must play with two players on one screen. But I can't get the another player inputs. I can play with bottom or top player, but not both.
This is the get input codes:
public class PlayStateInput implements InputProcessor {
private PlayState playState;
private Vector2 touchPos;
private Vector2 bodyCord;
public PlayStateInput(PlayState playState){
this.playState = playState;
touchPos = new Vector2();
bodyCord = new Vector2();
touchPos.x=Gdx.input.getX();
touchPos.y=Gdx.input.getY();
bodyCord.x=playState.getGameWorld().getPaddle().getBody().getPosition().x;
bodyCord.y=playState.getGameWorld().getPaddle().getBody().getPosition().y;
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if(playState.getGameWorld().getPuck().getCircleRect().contains(screenX,screenY)){
System.out.println("collision");
}
if(screenY > Gdx.graphics.getHeight()/2 && (pointer <= 2)){
playState.getGameWorld().getPaddle2().setBottomPaddle(true);
}
if(screenY < Gdx.graphics.getHeight()/2 && (pointer <= 2)){
playState.getGameWorld().getPaddle().setTopPaddle(true);
}
return false;
}
And the use this inputs here:
public class Paddle implements GameObject {
private World world;
private Body body;
private Body body2;
private BodyDef bodyDef;
private BodyDef bodyDef2;
private Fixture fixture;
private Fixture fixture2;
private FixtureDef fixtureDef;
private FixtureDef fixtureDef2;
private Circle circleRect;
private Circle circleRect2;
boolean TopPaddle = false;
boolean BottomPaddle = false;
private float PPM=100f;
private float power=100f;
private Vector2 touchPos;
private Sprite sprite;
String koordinatlar;
public Paddle(World world){
this.world = world;
bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set((Gdx.graphics.getWidth()/2)/PPM,(Gdx.graphics.getHeight()/3)/PPM);
body = world.createBody(bodyDef);
fixtureDef = new FixtureDef();
fixtureDef.density = 1.0f;
fixtureDef.friction = 1.0f;
fixtureDef.restitution=0.3f;
CircleShape circleShape = new CircleShape();
circleShape.setRadius((Gdx.graphics.getWidth()/16)/PPM);
fixtureDef.shape = circleShape;
fixture = body.createFixture(fixtureDef);
circleRect = new Circle(body.getPosition().x,body.getPosition().y,(Gdx.graphics.getWidth()/16));
Sprite.split(ImageLoader.playButtonRegion.getTexture(),20,20);
sprite = new Sprite(ImageLoader.paddle);
sprite.setSize((Gdx.graphics.getWidth()/8),(Gdx.graphics.getWidth()/8));
sprite.setPosition((Gdx.graphics.getWidth()/2)-30f,(Gdx.graphics.getHeight()/3)-30f);
touchPos = new Vector2();
}
#Override
public void render(SpriteBatch sb) {
sprite.draw(sb);
sprite.setPosition(body.getPosition().x*PPM-30f,body.getPosition().y*PPM-30f);
}
#Override
public void update(float delta) {
touchPos.x=Gdx.input.getX()/PPM;
touchPos.y=Gdx.input.getY()/PPM;
System.out.println(touchPos);
if (TopPaddle) {
body.setLinearVelocity(power*(touchPos.x-body.getPosition().x),power*(touchPos.y-body.getPosition().y));
body.setAngularVelocity(0.0f);
if(Gdx.input.getY()>Gdx.graphics.getHeight()/2){
body.setLinearVelocity(0f,0f);
}
//System.out.println(Gdx.input.getX()+" "+Gdx.input.getY());
}
}
I hope, I made myself clear.

I think I see your problem, you are relying on the fact that only one input is being taken at a time. As a result, you will be ignoring one of the two players if both are giving input simultaneously.
There are multiple ways to go about solving your multi-touch input problem but I'll go about explaining a simple technique - modified from this answer.
To allow both players to take in input you will need two variables - I'll call them topTouchPos and bottomTouchPos. Each of these will be a Vector2 like your current touchPos and they will be calculated as follows (inside your update method):
//Initialise both vectors to vectors that can't be touched (negative)
Vector2 topTouchPos = new Vector2(-1,-1), bottomTouchPos = new Vector2(-1,-1);
//Two people can have up to 20 fingers (most touchscreen devices will have a lower limit anyway)
for (int i = 0; i < 20; i++) {
//Check if this finger ID is touched
if (Gdx.input.isTouched(i)) {
//Classify it as either the top or bottom player
bool bottom = Gdx.input.getY(i) > Gdx.graphics.getHeight()/2;
if (bottom) bottomTouchPos.set(Gdx.input.getX(i), Gdx.input.getY(i));
else topTouchPos.set(Gdx.input.getX(i), Gdx.input.getY(i));
}
}
When you get into your main game code you will have to check for both players. If either topTouchPos or bottomTouchPos are not negative then use their touch values for their respective players.
Hope this helps (I haven't tested any code so beware of any typos).

Related

How do I reposition a moving animation during a gameplay?

I am using the Android Studio IDE, with the libGDX framework to develop a game. It is a clone of the Pac-Man game with a similar gameplay to flappy bird. The concept is that the pac man moves through the planks while avoiding the ghosts coming from the right direction, that are moving off straight into the left direction (not chasing the position of the player). I am not sure how I create a 'for loop' for the ghost animations, I want the ghosts to consistently reposition and re-appear from the right side after a few seconds, with the exception that they completely gone off the screen initially.
The class for one of the Ghosts.
public class Blinky {
private Vector3 position; //x y and z axis
private Rectangle bounds;
private Texture texture1;
private Animation blinkyAnimLeft;
public Blinky(int x, int y) {
position = new Vector3(x, y, 0);
Texture texture1 = new Texture("blinkyLeft.png");
blinkyAnimLeft = new Animation(new TextureRegion(texture1), 2, 0.5f);
//bounds = new Rectangle(x,y,texture1.getWidth() / 2, texture1.getHeight());
}
public void update(float dt) {
blinkyAnimLeft.update(dt);
//bounds.setPosition(position.x, position.y);
}
public Vector3 getPosition() {
return position;
}
public TextureRegion getTexture() {
return blinkyAnimLeft.getFrame();
}
//public Rectangle getBounds() {
return bounds;
}
public void dispose() {
texture1.dispose();
}
}
Ghosts and Player initialised in the GamePlayState Class
public class GamePlayState extends State {
//Variables
private float timePassed = 0;
private Texture background;
public static final int WALK = 1;
public static final double GHOST_WALK = 0.5;
private static final int PLANKS_SPACING = 125; //gap betwen the planks
private static final int PLANK_COUNT = 4;
private Array<Obstacle> planks;
private Player player;
private Blinky blinky;
private Inky inky;
private Texture missile;
public GamePlayState(GameStateManager gsm) {
super(gsm);
player = new Player(50, 100);
blinky = new Blinky(400, 220);
inky = new Inky(400, 240);
// missile = new Texture("missile.png");
background = new Texture("black.jpg");
cam.setToOrtho(false, PacMan.WIDTH/2, PacMan.HEIGHT/2);
planks = new Array<Obstacle>();
for (int i = 1; i<= PLANK_COUNT; i++) {
planks.add(new Obstacle(i * (PLANKS_SPACING + Obstacle.PLANK_WIDTH)));
}
}
#Override
public void handleInput() {
}
#Override
public void update(float dt) {
handleInput();
player.update(dt);
blinky.update(dt);
inky.update(dt);
cam.position.x = player.getPosition().x + 80; //update the position of the camera with the bird
//update when pacman cam viewport has passed plank
//make cam follow the player
for (Obstacle plank: planks) {
if (cam.position.x - (cam.viewportWidth/1) > plank.getPosTopPlank().x + plank.getTopPlank().getWidth()) {
plank.respositionPlanks(plank.getPosTopPlank().x + ((Obstacle.PLANK_WIDTH + PLANKS_SPACING * PLANK_COUNT )));
}
if (plank.collision (player.getBounds()))
gsm.set(new GamePlayState(gsm));
}
cam.update();
}
#Override
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(cam.combined);
sb.begin();
sb.draw(background, cam.position.x - (cam.viewportWidth/2), 0);
timePassed += Gdx.graphics.getDeltaTime();
//Moving Inky
sb.draw(inky.getTexture(), inky.getPosition().x, inky.getPosition().y);
inky.getPosition().x -= GHOST_WALK;
//Moving Blinky
sb.draw(blinky.getTexture(), blinky.getPosition().x, blinky.getPosition().y);
blinky.getPosition().x -= GHOST_WALK;
You should get x, y( and z) position from Vector3.
Then check for borders
if (inky.getPosition().x < 0){
Thread.sleep(/*a few sdeconds*/2000);/*Android studio would ask you about wrapping it with try - catch*/
inky.setPostion( x + /*screen x size*/,
inky.getPosition().y,inky.getPosition().z)/*add setter in ghost class*/
}
In fact, this is not the best way to do it, but the simplest one

how to move randomly generated object to the center of the screen in android Using LIBgdx

I'm a beginner android game programmer, I use LIBgdx
I have a playState class
public PlayState(GameStateManager gsm) {
super(gsm);
obj = new Objects();
cam.setToOrtho(false, Game.WIDTH , Game.HEIGHT);
}
#Override
public void update(float dt) {
obj.update(dt);
}
I have an Objects class
public class Objects {
private Vector2 posObj;
private static final int MOVEMENT = 2;
private Vector2 velo;
private Texture objTx;
private Random rand;
private static final int FLUCTUATION = 400;
public Objects(){
objTX = new Texture("objies.png");
rand = new Random();
posObj = new Vector2(rand.nextInt(FLUCTUATION),rand.nextInt(FLUCTUATION));
velo = new Vector2(0, 0);
}
public void update(float dt){
}
Now, What I'm tring to do is:
Move this randomly generated object to the center of the screen and then dispose.
Serious Help required! Thank-you
Well, you know where your object is and you know where the middle is (Game.WIDTH/2 , Game.HEIGHT/2)
If the center is to the left of the object move it to the left, if center is above move object up etc.
So a very simple solution:
public void update(float delta){
if(posObj.x < Game.WIDTH/2){
velocity.x = MOVEMENT;
}
else {
velocity.x = -MOVEMENT;
}
if(posObj.y < Game.HEIGHT/2){
velocity.y = MOVEMENT;
}
else {
velocity.y = -MOVEMENT;
}
posObj.y += velocity.y * delta;
posObj.x += velocity.x * delta;
}
This might cause your object to jump around the middle without ever really hitting the exact coordinates. So you can check the distance from the object to the middle by adding this method to your object:
public Vector2d getPosition(){
return posObj;
}
And then check for the distance:
if( obj.dst(Game.WIDTH , Game.HEIGHT) <= closeEnough ){
obj = new Objects();
}
closeEnough is a distance you set.

Libgdx Box2d collision detection using physics body editor

Hy guys,
I am developing a game for android using libgdx. I am completely stuck at the part of detecting collision between two bodies.
I have a player which I create through the function below
public Body createPlayer(String file_path, String fixture_name) {
// 0. Create a loader for the file saved from the editor.
BodyEditorLoader loader = new BodyEditorLoader(Gdx.files.internal(file_path));
// 1. Create a BodyDef, as usual.
BodyDef bd = new BodyDef();
bd.type = BodyDef.BodyType.DynamicBody;
// 2. Create a FixtureDef, as usual.
FixtureDef fd = new FixtureDef();
fd.density = 1;
fd.friction = 0.5f;
fd.restitution = 0.3f;
// 3. Create a Body, as usual.
body= world.createBody(bd);
//body.setBullet(true);
// 4. Create the body fixture automatically by using the loader.
loader.attachFixture(body, fixture_name, fd, 1);
body.setUserData(this);
return body;
}
and an enemy that I create with the same function of the player where I change only the file_path and the fixture_name.
The file_path points to a .json file that I created with box2d editor (site: http://www.aurelienribon.com/blog/projects/physics-body-editor/).
After the creation of the body I draw the player and the enemy with two similar functions ( I only post one):
private void drawPlayer(){
player_sprite = new Sprite(player_TR);
player_sprite.setSize(player.getWidth(), player.getHeight());
player_sprite.setPosition(player.getX(), player.getY());
player_sprite.setOrigin(0, 0);
player_sprite.draw(sb);
}
If I start the game everything is drawn where it should be. Obviously if the player touches the enemy nothing happen.
So i started trying to search how to make the two bodies collides but I don't really understand how to use ContactListener and beginContact.
beginContact wants as input a Contact but what is a Contact?
I have found this code online which appears to solve my problem but I don't know how to use it:
worldbox.setContactListener(new ContactListener() {
#Override
public void beginContact(Contact contact) {
if(contact.getFixtureA().getBody().getUserData()== "body1" &&
contact.getFixtureB().getBody().getUserData()== "body2")
Colliding = true;
System.out.println("Contact detected");
}
Can you help me (if it is possible through some code) to solve my problem?
Thanks in advance,
Francesco
Update of my question
Here is my render method:
public class GameRenderer{
private GameWorld myWorld;
private ShapeRenderer shapeRenderer;
private SpriteBatch sb;
private Camera camera;
private Constants constant;
private Rectangle viewport;
//dichiaro le variabili per caricare gli asset
private Player player;
private ScrollHandler scroller;
private Bordo frontBordoSX_1, backBordoSX_1, frontBordoSX_2, backBordoSX_2;
private Bordo frontBordoDX_1, backBordoDX_1, frontBordoDX_2, backBordoDX_2;
/*
private Ostacolo ob1_sx, ob2_sx, ob3_sx;
private Ostacolo ob4_dx, ob5_dx, ob6_dx;
*/
private TextureRegion player_TR;
private TextureRegion bordoSX_1, bordoSX_2;
private TextureRegion bordoDX_1, bordoDX_2;
private TextureRegion obstacleSX, obstacleSX_flip;
private TextureRegion obstacleDX, obstacleDX_flip;
private TextureRegion enemyS;
private TextureRegion blackBar;
//box2dpart
private World worldbox;
private Sprite fbDx_1,fbDx_2,fbSx_1,fbSx_2;
private Sprite player_sprite;
private Body player_body, bordo_destro;
private MyContactListener contactListener;
public GameRenderer(GameWorld world) {
myWorld = world;
constant = new Constants();
camera = new OrthographicCamera(constant.getWidth(), constant.getHeight());
shapeRenderer = new ShapeRenderer();
shapeRenderer.setProjectionMatrix(camera.combined);
sb = new SpriteBatch();
sb.setProjectionMatrix(camera.combined);
contactListener = new MyContactListener();
worldbox= new World(new Vector2(0,-10),true);
worldbox.setContactListener(contactListener);
//initialize objects and assets
initGameObjects();
initAssets();
}
private void initGameObjects(){
player = myWorld.getPlayer();
scroller = myWorld.getScroller();
frontBordoSX_1 = scroller.getFrontBordoSX_1();
backBordoSX_1 = scroller.getBackBordoSX_1();
frontBordoSX_2 = scroller.getFrontBordoSX_2();
backBordoSX_2 = scroller.getBackBordoSX_2();
frontBordoDX_1 = scroller.getFrontBordoDX_1();
backBordoDX_1 = scroller.getBackBordoDX_1();
frontBordoDX_2 = scroller.getFrontBordoDX_2();
backBordoDX_2 = scroller.getBackBordoDX_2();
/* other objects
ob1_sx = scroller.getOb1_sx();
ob2_sx = scroller.getOb2_sx();
ob3_sx = scroller.getOb3_sx();
ob4_dx = scroller.getOb4_dx();
ob5_dx = scroller.getOb5_dx();
ob6_dx = scroller.getOb6_dx();
*/
}
private void initAssets(){
player_TR = AssetLoader.player;
bordoSX_1 = AssetLoader.bordoSX;
bordoSX_2 = AssetLoader.bordoSX;
bordoDX_1 = AssetLoader.bordoDX;
bordoDX_2 = AssetLoader.bordoDX;
obstacleDX = AssetLoader.obstacleDX;
obstacleSX = AssetLoader.obstacleSX;
obstacleDX_flip = AssetLoader.obstacleDX_flip;
obstacleSX_flip = AssetLoader.obstacleSX_flip;
enemyS = AssetLoader.enemyS;
blackBar = AssetLoader.blackBar;
//box2d part
}
private void drawMargin(){
//bordo SX
/*
sb.draw(bordoSX_1, frontBordoSX_2.getX(), frontBordoSX_2.getY(), frontBordoSX_2.getWidth(),
frontBordoSX_2.getHeight());
sb.draw(bordoSX_2, frontBordoSX_1.getX(), frontBordoSX_1.getY(), frontBordoSX_1.getWidth(),
frontBordoSX_1.getHeight());
*/
fbSx_1 = new Sprite(bordoSX_1);
fbSx_1.setSize(frontBordoSX_1.getWidth(),frontBordoSX_1.getHeight());
fbSx_1.setPosition(frontBordoSX_1.getX(), frontBordoSX_1.getY());
fbSx_1.setOrigin(0, 0);
fbSx_1.draw(sb);
fbSx_2 = new Sprite(bordoSX_2);
fbSx_2.setSize(frontBordoSX_2.getWidth(),frontBordoSX_2.getHeight());
fbSx_2.setPosition(frontBordoSX_2.getX(), frontBordoSX_2.getY());
fbSx_2.setOrigin(0, 0);
fbSx_2.draw(sb);
fbDx_1 = new Sprite(bordoDX_1);
fbDx_1.setSize(frontBordoDX_1.getWidth(),frontBordoDX_1.getHeight());
fbDx_1.setPosition(frontBordoDX_1.getX(), frontBordoDX_1.getY());
fbDx_1.setOrigin(0, 0);
fbDx_1.draw(sb);
fbDx_2 = new Sprite(bordoDX_2);
fbDx_2.setSize(frontBordoDX_2.getWidth(),frontBordoDX_2.getHeight());
fbDx_2.setPosition(frontBordoDX_2.getX(), frontBordoDX_2.getY());
fbDx_2.setOrigin(0, 0);
fbDx_2.draw(sb);
sb.draw(blackBar,-constant.getWidth()/2,-constant.getHeight()/2,
(float) (0.573913)*(constant.getWidth()/6),constant.getHeight());
sb.draw(blackBar,(float)(constant.getWidth()/2-(0.573913)*(constant.getWidth()/6)),-constant.getHeight()/2,
(float)(0.573913)*(constant.getWidth()/6),constant.getHeight());
}
private void drawPlayer(){
player_sprite = new Sprite(player_TR);
player_sprite.setSize(player.getWidth(), player.getHeight());
player_sprite.setPosition(player.getX(), player.getY());
player_sprite.setOrigin(0, 0);
player_sprite.draw(sb);
}
/*
private void drawOstacoli(){
sb.draw(obstacleSX_flip,ob1_sx.getX(),ob1_sx.getY(),ob1_sx.getWidth(),ob1_sx.getHeight());
sb.draw(obstacleSX,ob2_sx.getX(),ob2_sx.getY(),ob2_sx.getWidth(),ob2_sx.getHeight());
sb.draw(obstacleSX_flip,ob3_sx.getX(),ob3_sx.getY(),ob3_sx.getWidth(),ob3_sx.getHeight());
sb.draw(obstacleDX,ob4_dx.getX()+constant.getWidth()/2-ob4_dx.getWidth(),ob4_dx.getY(),ob4_dx.getWidth(),ob4_dx.getHeight());
sb.draw(obstacleDX_flip,ob5_dx.getX()+constant.getWidth()/2-ob5_dx.getWidth(),ob5_dx.getY(),ob5_dx.getWidth(),ob5_dx.getHeight());
sb.draw(obstacleDX,ob6_dx.getX()+constant.getWidth()/2-ob6_dx.getWidth(),ob6_dx.getY(),ob6_dx.getWidth(),ob6_dx.getHeight());
}
*/
public void render(float runTime) {
Box2D.init();
int width = constant.getWidth();
int height = constant.getHeight();
float ratio = constant.getRatio();
//viewport
float aspectRatio = (float) width / (float) height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > ratio)
{
scale = (float)height/(float)height;
crop.x = (width - width * scale) / 2f;
} else if (aspectRatio < ratio) {
scale = (float)width/(float)width;
crop.y = (height - height*scale)/2f;
}
else
{
scale = (float) width / (float) width;
}
float w = (float) width * scale;
float h = (float) height * scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
// update camera
camera.update();
// clear previous frame
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
// Draw Background color
shapeRenderer.setColor(255 / 255.0f, 255 / 255.0f, 250 / 255.0f, 1);
shapeRenderer.rect(-constant.getWidth() / 2, -constant.getHeight() / 2, constant.getWidth(),
constant.getHeight());
// End ShapeRenderer
shapeRenderer.end();
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
// Begin SpriteBatch
sb.begin();
// The player needs transparency, so we enable that again.
sb.enableBlending();
// Draw player at its coordinates.
drawPlayer();
//draw right and left side
drawMargin();
// End SpriteBatch
sb.end();
worldbox.step(1 / 60f, 6, 2);
}
}
And if I start the program my view is my player in the middle and to margins ,one on the left and one on the right. (unfortunatly I cannot post images of my view because I don't have enough rep).
Everithing is fine. I move my player with the accelerometer and it works fine without any problem. The only problem is that if I move the player near the margin the two entities overlap instead of colliding and I don't understand why.
I also fixed the line:
loader.attachFixture(body, fixture_name, fd, 1);
to
loader.attachFixture(body, fixture_name, fd, player_width);
but nothing changes.
First, from here, the object Contact manages contact between two shapes, and from here, the listener ContactListener will be called when two fixtures begin to touch.
So, to make your code work, you should set a custom object to your bodies with the method: setUserData(Object userData). Usually this method is used to link the sprite or the actor with the physic body, but for example purpose you could just send a simple ID (like a string).
So in this part:
// 3. Create a Body, as usual.
body= world.createBody(bd);
//body.setBullet(true);
You could add an identificator to your object like this:
body.setUserData("player");
to idenfity your object, and then, when the listener get fired, you could retrieve this value:
#Override
public void beginContact(Contact contact) {
String userDataA = contact.getFixtureA().getBody().getUserData().toString();
String userDataB = contact.getFixtureB().getBody().getUserData().toString();
if(userDataA.equals("player") && userDataB.equals("otherEntity")){
colliding = true;
//do stuffs when collision has started
} else if(userDataB.equals("player") && userDataA.equals("otherEntity")){
colliding = true;
//do stuffs when collision has started
}
System.out.println("Contact detected");
}
After that, you could be able to do whatever you want to do with this collision.
Hope you find this useful!

ApplyLinearForce to dynamic body causes NullPointerException/ Libgdx box2d

I am developing an Android game using the libgdx box2d library in Eclipse. In the game, there's a ball that falls after touching the start button. But I get a nullpointerexception when the ball contacts the dynamic body.
On contact I want to applyLinearForce to that dynamic body. But I keep getting nullpointerexception on contact of the ball and dynamic body.
ContactHandler class:
public class ContactHandler implements ContactListener {
InputHandler input;
#Override
public void beginContact(Contact contact) {
if(contact.getFixtureA().getBody().getUserData() == "do1" && contact.getFixtureB().getBody().getUserData() == "ball"){
System.out.println("beginContact");
input = new InputHandler();
input.getBody1().applyLinearImpulse(10, 0, 0, 0, true);
}
}
InputHandler class:
public class InputHandler implements InputProcessor {
private OrthographicCamera camera;
private Ball ball;
private DragObject dragObject;
private boolean start = false;
private Vector3 touch = new Vector3();
private Vector3 dragTo = new Vector3();
public InputHandler(){
}
public InputHandler(OrthographicCamera camera, Ball ball,
DragObject dragObject) {
this.camera = camera;
this.ball = ball;
this.dragObject = dragObject;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
if (!start) {
for (Body body : dragObject.getBody()) {
if (touch.x > body.getPosition().x - dragObject.getWidth() - 1
&& touch.x < body.getPosition().x
+ dragObject.getWidth() + 1) {
if (touch.y > body.getPosition().y - dragObject.getHeight()
- 1
&& touch.y < body.getPosition().y
+ dragObject.getHeight() + 1) {
dragTo.set(screenX, screenY, 0);
camera.unproject(dragTo);
body.setTransform(dragTo.x, dragTo.y, 0);
touch.set(screenX, screenY, 0);
camera.unproject(touch);
}
}
}
}
return false;
}
public Body getBody1(){
return dragObject.getBody().get(0);
}
DragObject class:
public static Array<Body> bodies = new Array<Body>();
public static int count = 0;
public DragObject(){
}
public DragObject(World world, float x, float y, float width, float height) {
this.world = world;
this.width = width;
this.height = height;
initialize();
body1 = world.createBody(bodyDef1);
body1.createFixture(fixtureDef);
body1.setUserData("do1");
bodies.add(body1);
}
public Array<Body> getBody() {
return bodies;
}
Your constructor for the input handler is wrong, these lines should be removed:
public InputHandler(){
}
Because when you call this constructor here:
public void beginContact(Contact contact) {
if(contact.getFixtureA().getBody().getUserData() == "do1" && contact.getFixtureB().getBody().getUserData() == "ball"){
System.out.println("beginContact");
//You are using the wrong contructor, therefore body1 or dragObject is never initialised
input = new InputHandler();
//The null pointer exception is here, no body1 has been initialised yet
input.getBody1().applyLinearImpulse(10, 0, 0, 0, true);
}
You need to make the contructor match and create a new DragObject within the InputHandler class and as a side note it isn't very efficient initialising the class every time the body collides I am sure you can think of a better way to organise it.

Libgdx: Actor as body

I'm beginner with libgdx and i looking for answer how to link actor and body(box2d) for a lot time, so please help me :(
I have following code:
/// CLASS ACTOR
public class MyActor extends Actor
{
Texture texture;
float actorX = 0, actorY = 0;
public boolean clicked = false;
public String id;
public MyActor(float x, float y, String id, String tekstura)
{
this.texture = new Texture(Gdx.files.internal(tekstura));
this.id = id;
actorX = x;
actorY = y;
setBounds(actorX, actorY, texture.getWidth(), texture.getHeight());
addListener(new InputListener()
{
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button)
{
MyActor co = ((MyActor) event.getTarget());
co.clicked = true;
System.out.println(co.id);
co.remove();
return true;
}
});
}
#Override
public void draw(SpriteBatch batch, float alpha)
{
batch.draw(texture, actorX, actorY);
}
}
/*....................
.......................
........................
..........................*/
//CREATING SIMPLE OBJECT
MyActor samolot1 = new MyActor(100, 300, "samolot1", "data/jet.png");
samolot1.setTouchable(Touchable.enabled);
stage.addActor(samolot1);
// //////////////// WORLD /////////////////////////////////////////////
// 1
BodyDef bodydef_mojapostac = new BodyDef();
bodydef_mojapostac.type = BodyType.DynamicBody;
bodydef_mojapostac.position.set(400, 100);
CircleShape shape_mojapostac = new CircleShape();
shape_mojapostac.setRadius(30);
FixtureDef fixturedef_mojapostac = new FixtureDef();
fixturedef_mojapostac.density = 0.1f;
fixturedef_mojapostac.friction = 0.8f;
fixturedef_mojapostac.restitution = 0.7f;
fixturedef_mojapostac.shape = shape_mojapostac;
Body BodyMojaPostac = world.createBody(bodydef_mojapostac);
BodyMojaPostac.createFixture(fixturedef_mojapostac);
BodyMojaPostac.setUserData(samolot1);
and render()
......
batch.begin();
world.getBodies(tmpBodies);
for (Body body : tmpBodies)
if (body.getUserData() != null)
{
System.out.println(body.getUserData());
MyActor dupa = (MyActor) body.getUserData();
batch.draw(dupa.texture, dupa.actorX, dupa.actorY);
}
batch.end();
.....
I can link body with sprite but i don't know how with actor :(
After having trouble with this combination as well I'd like to share my solution:
public class PhysicsActor extends Image {
private Body body;
private Fixture fixture;
public PhysicsActor(World world, BodyDef bodyDef, FixtureDef fixtureDef, TextureRegion textureRegion) {
super(textureRegion);
body = world.createBody(bodyDef);
setFixture(getBody().createFixture(fixtureDef));
}
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
}
public Body getBody() {
return body;
}
public Fixture getFixture() {
return fixture;
}
I use it like this:
bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(Toolkit.Screen2World(x), Toolkit.Screen2World(y));
pShape = new PolygonShape();
pShape.setAsBox(Toolkit.Screen2World(width/2), Toolkit.Screen2World(height/2)); //In Toolkit I have my methods to scale the world
fixtureDef = new FixtureDef();
fixtureDef.shape = pShape;
//Set some more attributes i.e. density
//Add the PhysicsActor
PhysicsActor leftBar = new PhysicsActor(world, bodyDef, fixtureDef, new TextureRegion(Resources.barLeftTexture, 0, 0, width, height));
leftUpperBar.setSize(width, height);
this.addActor(leftUpperBar);
You only must set your width and height manually (in my case I use the resolution of my Texture).
Resources.barLeftTexture:
public static Texture barLeftTexture;
barLeftTexture = new Texture(Gdx.files.internal("data/barLeft.png"));
I noticed that your question may be outdated for you (the OP) but maybe it helps somebody stumbling across this question.

Categories

Resources