how to stopped the forces acting AFTER the collision of a dynamic body with a dynamic body?
I expect that at the moment of collision, one body will be able to move body2, and after the collision, body2 will stop.
I tried really many times to solve this with ContactListener, ground friction and player active states. Unfortunately, I have not been able to solve this. Does anyone know how this should work?
I don't see the point in attaching the code, but I'll do it anyway:
public class GameScreen implements Screen {
...
Player player;
Player player2;
#Override
public void show() {
...
world = new World(new Vector2(0, 0f), true);
player = new Player(world);
player2 = new Player(world);
moveDirection = new MoveDirection(player);
shotDirection = new ShotDirection(player);
...
}
#Override
public void render(float delta) {
world.step(1f/60f, 6, 2);
player.update();
player2.update();
...
}
...
}
public class Player {
private final float PIXELS_TO_METERS = 100f;
private Sprite sprite;
private World world;
private Body body;
...
public Body getBody()
public void createBody() {
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.fixedRotation = true;
bodyDef.position.set(
sprite.getX() / PIXELS_TO_METERS,
sprite.getY() / PIXELS_TO_METERS
);
body = world.createBody(bodyDef);
CircleShape shape = new CircleShape();
shape.setRadius((long) (20) / PIXELS_TO_METERS);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
body.createFixture(fixtureDef);
shape.dispose();
}
public void update() {
if(!isBodyCreated) {
createBody();
isBodyCreated = true;
}
//Previously used:
/*if(!isActive()) {
body.setLinearVelocity(0, 0);
}*/
...
}
...
}
Thanks for reading.
EDIT: Ok, I found a solution, but it works with a delay, what can I do to fix it?
public class GameScreen implements Screen {
...
#Override
public void render(float delta) {
world.step(1f/60f, 6, 2);
player.update();
player2.update();
...
}
...
}
public class MoveDirection extends Actor {
...
addListener(new InputListener() {
...
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
...
player.setActive(true);
...
}
...
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
...
player.setActive(false);
player.getBody().setLinearVelocity(0, 0);
}
...
}
public class Player {
private boolean active = false;
...
public void createBody() {
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.fixedRotation = true;
bodyDef.position.set(
(sprite.getX()) / PIXELS_TO_METERS,
(sprite.getY()) / PIXELS_TO_METERS
);
body = world.createBody(bodyDef);
CircleShape shape = new CircleShape();
shape.setRadius((long) (20) / PIXELS_TO_METERS);
fixtureDef = new FixtureDef();
fixtureDef.shape = shape;
fixtureDef.density = 0.1f;
//fixtureDef.restitution = 0;
body.createFixture(fixtureDef);
shape.dispose();
body.setBullet(true);
body.setUserData("player");
}
public void setActive(boolean bool) {
this.active = bool;
}
public boolean isActive() {
return this.active;
}
public boolean isContact() {
boolean isContact = false;
for(Contact contact : world.getContactList()) {
if((contact.getFixtureA().getBody() == this.body || contact.getFixtureB().getBody() == this.body) && (contact.getFixtureA().getBody().getUserData() == "player" && contact.getFixtureB().getBody().getUserData() == "player")) {
isContact = true;
break;
}
}
return isContact;
}
public void update() {
...
if(!isContact() && !isActive()) {
body.setLinearVelocity(0, 0);
}
}
}
I haven't got any experience with box2d, so I can not give a detailed answer. But perhaps this is where the EndContact and PostSolve methods are ment to be implemented.
https://www.iforce2d.net/b2dtut/collision-anatomy
Related
I have a animation which i want to flip to the left if key LEFT is pressed, but it doesnt stay flipped. It only flips like 1 frame then turns back again.
Here is my GameScreen where i draw everything:
public class GameScreen extends ScreenManager{
//For the view of the game and the rendering
private SpriteBatch batch;
private OrthographicCamera cam;
//DEBUG
private Box2DDebugRenderer b2dr;
//World, Player and so on
private GameWorld world;
private Player player;
private Ground ground;
//player animations
private TextureRegion currFrame;
public static float w, h;
public GameScreen(Game game) {
super(game);
//vars
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
//view and rendering
batch = new SpriteBatch();
cam = new OrthographicCamera();
cam.setToOrtho(false, w/2, h/2);
//debug
b2dr = new Box2DDebugRenderer();
//world, bodies ...
world = new GameWorld();
player = new Player(world);
ground = new Ground(world);
}
#Override
public void pause() {
}
#Override
public void show() {
}
#Override
public void render(float delta) {
//clearing the screen
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//updating
update(Gdx.graphics.getDeltaTime());
player.stateTime += Gdx.graphics.getDeltaTime();
//render
batch.setProjectionMatrix(cam.combined);
currFrame = Player.anim.getKeyFrame(Player.stateTime, true);
batch.begin();
batch.draw(currFrame, Player.body.getPosition().x * PPM - 64, Player.getBody().getPosition().y * PPM- 72);
batch.end();
//debug
b2dr.render(GameWorld.getWorld(), cam.combined.scl(PPM));
}
#Override
public void resize(int width, int height) {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
#Override
public void onKlick(float delta) {
}
public void update(float delta){
world.update(delta);
updateCam(delta);
Player.keyInput(delta);
System.out.println("X-POS" + Player.getBody().getPosition().x);
System.out.println("Y-POS" + Player.getBody().getPosition().y);
}
public void updateCam(float delta){
Vector3 pos = cam.position;
pos.x = Player.getBody().getPosition().x * PPM;
pos.y = Player.getBody().getPosition().y * PPM;
cam.position.set(pos);
cam.update();
}
}
and this is the Player class where the animation is:
public class Player {
public static Body body;
public static BodyDef def;
private FixtureDef fd;
//textures
public static Texture texture;
public static Sprite sprite;
public static TextureRegion[][] region;
public static TextureRegion[] idle;
public static Animation<TextureRegion> anim;
public static float stateTime;
//set form
private PolygonShape shape;
private GameScreen gs;
public Player(GameWorld world){
texture = new Texture(Gdx.files.internal("player/char_animation_standing.png"));
region = TextureRegion.split(texture, texture.getWidth() / 3, texture.getHeight() / 2);
idle = new TextureRegion[6];
int index = 0;
for(int i = 0; i < 2; i++){
for(int j = 0; j < 3; j++){
sprite = new Sprite(region[i][j]);
idle[index++] = sprite;
}
}
anim = new Animation<TextureRegion>(1 / 8f, idle);
stateTime = 0f;
def = new BodyDef();
def.fixedRotation = true;
def.position.set(gs.w / 4, gs.h / 4);
def.type = BodyType.DynamicBody;
body = world.getWorld().createBody(def);
shape = new PolygonShape();
shape.setAsBox(32 / 2 / PPM, 64/ 2 / PPM);
fd = new FixtureDef();
fd.shape = shape;
fd.density = 30;
body.createFixture(fd);
shape.dispose();
}
public static Body getBody() {
return body;
}
public static BodyDef getDef() {
return def;
}
public static Texture getTexture() {
return texture;
}
public static void keyInput(float delta){
int horizonForce = 0;
if(Gdx.input.isKeyJustPressed(Input.Keys.UP)){
body.applyLinearImpulse(0, 300f, body.getWorldCenter().x, body.getWorldCenter().y, true);
//body.applyForceToCenter(0, 1200f, true);
System.out.println("PRESSED");
}
if(Gdx.input.isKeyPressed(Input.Keys.LEFT)){
horizonForce -= 1;
sprite.flip(!sprite.isFlipX(), sprite.isFlipY());
}
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)){
horizonForce += 1;
}
body.setLinearVelocity(horizonForce * 20, body.getLinearVelocity().y);
}
}
thank you in advance and any answer is appreciated :D
Your sprite variable contain only one frame at the time of pressing left key. So, it flip that current sprite of your animation frame.
To solve the Problem you have to flip all the animation frame on pressing the left key.
You're only flipping last frame of Animation by sprite reference, You need to flip all frames of your Animation anim. You can flip in this way :
if(keycode== Input.Keys.RIGHT) {
for (TextureRegion textureRegion:anim.getKeyFrames())
if(!textureRegion.isFlipX()) textureRegion.flip(true,false);
}
else if(keycode==Input.Keys.LEFT) {
for (TextureRegion textureRegion:anim.getKeyFrames())
if(textureRegion.isFlipX()) textureRegion.flip(true,false);
}
the texture region I am using for my player wont draw to my screen
here is the player class where the player is defined and the texture region is attached to a box 2d body
public Player (World world, PlayScreen screen){
super(screen.getAtlas().findRegion("player"));
this.world= world;
currentState = State.STANDING;
previousState = State.STANDING;
stateTimer=0;
runningRight=true;
Array<TextureRegion> frames = new Array<TextureRegion>();
for(int i=5; i<9; i++){
frames.add(new TextureRegion(getTexture(),i*50,0,50,50));
}
playerRun= new Animation(0.1f , frames);
defineplayer();
playerStand = new TextureRegion(getTexture(),0,0,50,50);
setBounds(0,0,50,50);
setRegion(playerStand);
}
public void update(float dt){
setPosition(b2dbody.getPosition().x-getWidth()/2,b2dbody.getPosition ().y-getHeight()/2);
setRegion(getFrame(dt));
}
public TextureRegion getFrame(float dt){
currentState = getState();
TextureRegion region;
switch(currentState){
case RUNNING:
region=(TextureRegion) playerRun.getKeyFrame(stateTimer, true);
break;
case STANDING:
default:
region = playerStand;
break;
}
if((b2dbody.getLinearVelocity().x<0 || !runningRight) && !region.isFlipX() ){
region.flip(true, false);
runningRight=false;
}
if((b2dbody.getLinearVelocity().x>0 || runningRight) && region.isFlipX()){
region.flip(true, false);
runningRight=true;
}
stateTimer = currentState == previousState ? stateTimer +dt : 0;
previousState = currentState;
return region;
}
public State getState(){
if(b2dbody.getLinearVelocity().x!=0){
return State.RUNNING;
}
else{
return State.STANDING;
}
}
public void defineplayer(){
BodyDef bdef = new BodyDef();
bdef.position.set(32,32);
bdef.type = BodyDef.BodyType.DynamicBody;
b2dbody = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(5);
fdef.shape=shape;
b2dbody.createFixture(fdef);
}
}
here is the play screen where my player is being displayed and moved
public class PlayScreen implements Screen {
private final FinalGame game;
Texture texture;
private OrthographicCamera gamecam;
private Viewport gameport;
private Hud hud;
private TmxMapLoader loader;
private TiledMap map;
private OrthogonalTiledMapRenderer render;
private Player player;
private TextureAtlas atlas;
private Music music;
int Vx;
int Vy;
//Box 2D
private World world;
private Box2DDebugRenderer b2dr;
public PlayScreen(FinalGame game , String name){
atlas = new TextureAtlas("Player_And_Enemies.pack");
hud=new Hud(game.sb, name);
this.game=game;
gamecam=new OrthographicCamera();
gameport=new StretchViewport(FinalGame.width ,FinalGame.height,gamecam);
loader = new TmxMapLoader();
map=loader.load("level1.tmx");
render=new OrthogonalTiledMapRenderer(map);
gamecam.position.set(gameport.getWorldWidth()/2,gameport.getWorldHeight()/2,0);
world = new World(new Vector2(0,0),true);
b2dr = new Box2DDebugRenderer();
player=new Player(world,this);
music = FinalGame.manager.get("Horror field.mp3", Music.class);
music.setLooping(true);
music.setVolume(0.1f);
music.play();
}
#Override
public void show() {
// TODO Auto-generated method stub
}
public TextureAtlas getAtlas(){
return atlas;
}
public void handleinput(float dt){
Vy=0;
Vx=0;
if(Gdx.input.isKeyPressed(Input.Keys.W)){
Vy=40;
}
if(Gdx.input.isKeyPressed(Input.Keys.S)){
Vy=-40;
}
if(Gdx.input.isKeyPressed(Input.Keys.D)){
Vx=40;
}
if(Gdx.input.isKeyPressed(Input.Keys.A)){
Vx=-40;
}
player.b2dbody.setLinearVelocity(new Vector2(Vx,Vy));
}
public void update(float dt){
handleinput(dt);
world.step(1/60f,6,2);
player.update(dt);
gamecam.update();
render.setView(gamecam);
}
#Override
public void render(float delta) {
//renders the play screen map
update(delta);
Gdx.gl.glClearColor(1,0,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
render.render();
game.sb.setProjectionMatrix(gamecam.combined);
game.sb.begin();
player.draw(game.sb);
game.sb.end();
game.sb.setProjectionMatrix(hud.stage.getCamera().combined);
//draws all the hud information to the screen
Hud.stage.draw();
}
#Override
public void resize(int width, int height) {
gameport.update(width, height);
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
}
I want to create moving platform that changes its orientation when its position equals width of screen, I'm doing it like this:
if(bucket.getPosition().x <= Gdx.graphics.getWidth()/PPM){
do{
bucket.setLinearVelocity(dt*PPM,0);
}while (bucket.getPosition().x <= Gdx.graphics.getWidth()/PPM);
}else{
do{
bucket.setLinearVelocity(-dt*PPM,0);
}while (bucket.getPosition().x != 0);
}
But when I run it, I see just black screen;
But when I wrote like this:
if(bucket.getPosition().x <= Gdx.graphics.getWidth()/PPM){
bucket.setLinearVelocity(dt*PPM,0);
}else{
bucket.setLinearVelocity(-dt*PPM,0);
}
All is works, but "bucket" doesn't change its orientation :((
You can use setTransform(vector2,angle) on body for your requirement and move your bucket left and right.
I've try to completed your requirement, check it.
public class GdxTest extends InputAdapter implements ApplicationListener {
private SpriteBatch batch;
private ExtendViewport extendViewport;
private OrthographicCamera cam;
private float w=20;
private float h=22;
private World world;
private Box2DDebugRenderer debugRenderer;
private Array<Body> array;
private Vector3 vector3;
private Body bucket;
Vector2 vector2;
boolean isLeft;
#Override
public void create() {
vector2=new Vector2();
isLeft=true;
cam=new OrthographicCamera();
extendViewport=new ExtendViewport(w,h,cam);
batch =new SpriteBatch();
Gdx.input.setInputProcessor(this);
world=new World(new Vector2(0,-9.8f),true);
array=new Array<Body>();
debugRenderer=new Box2DDebugRenderer();
vector3=new Vector3();
BodyDef bodyDef=new BodyDef();
bodyDef.type= BodyDef.BodyType.KinematicBody;
bodyDef.position.set(0,0);
bucket=world.createBody(bodyDef);
ChainShape chainShape=new ChainShape();
chainShape.createChain(new float[]{1,5,1,1,5,1,5,5});
FixtureDef fixtureDef=new FixtureDef();
fixtureDef.shape=chainShape;
fixtureDef.restitution=.5f;
bucket.createFixture(fixtureDef);
chainShape.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(0,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1/60f,6,2);
batch.setProjectionMatrix(cam.combined);
batch.begin();
world.getBodies(array);
for (Body body:array){
if(body.getUserData()!=null) {
Sprite sprite = (Sprite) body.getUserData();
sprite.setPosition(body.getPosition().x-sprite.getWidth()/2, body.getPosition().y-sprite.getHeight()/2);
sprite.setRotation(body.getAngle()*MathUtils.radDeg);
sprite.draw(batch);
}
}
batch.end();
debugRenderer.render(world,cam.combined);
Vector2 pos=bucket.getTransform().getPosition();
vector2.set(pos.x+(isLeft?0.05f:-0.05f),pos.y);
bucket.setTransform(vector2,0);
if(pos.x>20-5)
isLeft=false;
if(pos.x<-1)
isLeft=true;
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void resize(int width, int height) {
extendViewport.update(width,height);
cam.position.x = w /2;
cam.position.y = h/2;
cam.update();
}
private void createPhysicsObject(float x,float y){
float sizeX=0.5f,sizeY=0.5f;
BodyDef bodyDef=new BodyDef();
bodyDef.position.set(x,y);
bodyDef.type= BodyDef.BodyType.DynamicBody;
Body body=world.createBody(bodyDef);
PolygonShape polygonShape=new PolygonShape();
polygonShape.setAsBox(sizeX,sizeY);
FixtureDef fixtureDef=new FixtureDef();
fixtureDef.shape=polygonShape;
fixtureDef.restitution=.2f;
fixtureDef.density=2;
body.createFixture(fixtureDef);
body.setFixedRotation(false);
polygonShape.dispose();
Sprite sprite=new Sprite(new Texture("badlogic.jpg"));
sprite.setSize(2*sizeX,2*sizeY);
sprite.setPosition(x-sprite.getWidth()/2,y-sprite.getHeight()/2);
sprite.setOrigin(sizeX,sizeY);
body.setUserData(sprite);
}
#Override
public void dispose() {
batch.dispose();
debugRenderer.dispose();
world.dispose();
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
vector3.set(screenX,screenY,0);
Vector3 position=cam.unproject(vector3);
createPhysicsObject(vector3.x,vector3.y);
return false;
}
}
I want to add to the score of my game +1 when an enemy was touched, I tried two methods addListener and touchDown but not worked for me or I didn't use them right.
How can I do that my (enemy object is linked to an userData and Actor classes, I regroup many different sizes for my enemy in an enum class also those enemies move from the top of the screen to bot. How to detect if an enemy was touched?
public class GameStage extends Stage {
// This will be our viewport measurements while working with the debug renderer
private static final int VIEWPORT_WIDTH = 13;
private static final int VIEWPORT_HEIGHT = 20;
private World world;
private Ground ground;
private Enemy enemy;
private final float TIME_STEP = 1 / 300f;
private float accumulator = 0f;
private Rectangle bounds;
private Vector3 touchPoint = new Vector3();;
private int score;
private String yourScoreName;
BitmapFont yourBitmapFontName;
private SpriteBatch batch;
private OrthographicCamera camera;
private Box2DDebugRenderer renderer;
public GameStage() {
world = WorldUtils.createWorld();
renderer = new Box2DDebugRenderer();
Gdx.input.setInputProcessor(this);
batch = new SpriteBatch();
score = 0;
yourScoreName = "score: 0";
yourBitmapFontName = new BitmapFont();
setUpWorld();
setUpCamera();
}
public void setUpWorld(){
world = WorldUtils.createWorld();
setUpGround();
createEnemy();
}
private void setUpGround(){
ground = new Ground (WorldUtils.createGround(world));
addActor(ground);
}
private void createEnemy() {
enemy = new Enemy(WorldUtils.createEnemy(world));
// (1) *****using addListener method
enemy.addListener(new InputListener()
{
#Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button)
{
score++;
yourScoreName = "score: " + score;
return true;
}
});
/*enemy.addListener(new ClickListener() {
public void clicked() {
world.destroyBody(enemy.getBody());
}});*/
//bounds = new Rectangle(enemy.getX(), enemy.getY(), enemy.getWidth(), enemy.getHeight());
addActor(enemy);
}
private void setUpCamera() {
camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0f);
camera.update();
}
#Override
public void act(float delta) {
super.act(delta);
checkEnemy();
// Fixed timestep
accumulator += delta;
while (accumulator >= delta) {
world.step(TIME_STEP, 6, 2);
accumulator -= TIME_STEP;
}
//TODO: Implement interpolation
}
private void checkEnemy(){
final Body body = enemy.getBody();
UserData userData = enemy.getUserData();
bounds = new Rectangle(enemy.getBody().getPosition().x, enemy.getBody().getPosition().y, enemy.getUserData().getWidth(), enemy.getUserData().getHeight());
// bounds = new Rectangle(body.getPosition().x, body.getPosition().y,userData.getWidth() ,userData.getHeight());
if (!BodyUtils.enemyInBounds(body,userData)){
world.destroyBody(body);
createEnemy();}
}
public World getWorld(){
return world;
}
// (2) ****using TouchDown method
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
// Need to get the actual coordinates
translateScreenToWorldCoordinates(x, y);
// score++;
// yourScoreName = "score: " + score;
if(enemyTouched(touchPoint.x,touchPoint.y)){
// world.destroyBody(enemy.getBody());
score++;
yourScoreName = "score: " + score;
}
return super.touchDown(x, y, pointer, button);
}
private boolean enemyTouched(float x, float y) {
return bounds.contains(x, y);
}
private void translateScreenToWorldCoordinates(int x, int y) {
getCamera().unproject(touchPoint.set(x, y, 0));
}
#Override
public void draw() {
super.draw();
batch.begin();
yourBitmapFontName.setColor(1.0f, 1.0f, 1.0f, 1.0f);
yourBitmapFontName.draw(batch, yourScoreName, 25, 100);
batch.end();
enemy.setBounds(enemy.getBody().getPosition().x,enemy.getBody().getPosition().y,enemy.getUserData().getWidth(),enemy.getUserData().getHeight());
renderer.render(world, camera.combined);
}
}
A screen from my game:
It should work the way you did it (with the addListener() method). But you have to set the correct bounds of the actor (width, height, position): actor.setBounds(x, y, width, height). I would use the body to get these values. You can also use a ClickListener instead of the InputListener.
I have my Box2D project almost completely done, however, when I try the first obstacle to appear randomly and repeat itself infinitely using the while loop, the while loop doesn't work and instead it just appears once, I would like my game to appear like this as shown in this video, "https://www.youtube.com/watch?v=X-jEZHDN-gw"The while loop is not working, what am I doing wrong? could somebody please help me?
Box2D class:
package com.circlecrashavoider.scene2d;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Vector;
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.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.Contact;
import com.badlogic.gdx.physics.box2d.ContactImpulse;
import com.badlogic.gdx.physics.box2d.ContactListener;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.Manifold;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.circlecrashavoider.BaseScreen;
import com.circlecrashavoider.MainGame;
/**
* Created by Felipe on 2/19/2016.
*/
public class Box2DScreen extends BaseScreen {
public Box2DScreen(MainGame game) {
super(game);
}
private World world;
private Box2DDebugRenderer renderer;
private OrthographicCamera camera;
private Body playerBody, floorBody, obstacleBody, obstacle2Body;
private Fixture playerFixture, floorFixture, obstacleFixture, obstacle2Fixture;
private boolean mustJump, playerJumping, playerAlive = true;
#Override
public void show() {
world = new World(new Vector2(0, -10), true);
renderer = new Box2DDebugRenderer();
camera = new OrthographicCamera(16, 9);
camera.translate(0, 1);
world.setContactListener(new ContactListener() {
#Override
public void beginContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA(), fixtureB = contact.getFixtureB();
if ((fixtureA.getUserData().equals("player") && fixtureB.getUserData().equals("floor")) ||
(fixtureA.getUserData().equals("floor") && fixtureB.getUserData().equals("player"))) {
if (Gdx.input.isTouched()) {
mustJump = true;
}
playerJumping = false;
}
if ((fixtureA.getUserData().equals("player") && fixtureB.getUserData().equals("obstacle")) ||
(fixtureA.getUserData().equals("obstacle") && fixtureB.getUserData().equals("player"))) {
playerAlive = false;
}
if ((fixtureA.getUserData().equals("player") && fixtureB.getUserData().equals("obstacle2")) ||
(fixtureA.getUserData().equals("obstacle2") && fixtureB.getUserData().equals("player"))) {
playerAlive = false;
}
}
#Override
public void endContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA(), fixtureB = contact.getFixtureB();
if (fixtureA == playerFixture && fixtureB == floorFixture) {
playerJumping = true;
}
if (fixtureA == floorFixture && fixtureB == playerFixture) {
playerJumping = true;
}
}
#Override
public void preSolve(Contact contact, Manifold oldManifold) {
}
#Override
public void postSolve(Contact contact, ContactImpulse impulse) {
}
});
playerBody = world.createBody(createplayerBodyDef());
floorBody = world.createBody(createfloorBodyDef());
obstacleBody = world.createBody(createobstacleBodyDef(0.5f));
obstacle2Body = world.createBody(createobstacle2BodyDef(-0.5f));
CircleShape playerShape = new CircleShape();
playerShape.setRadius(0.5f);
playerFixture = playerBody.createFixture(playerShape,1);
playerShape.dispose();
PolygonShape floorShape = new PolygonShape();
floorShape.setAsBox(500,1);
floorFixture = floorBody.createFixture(floorShape, 1);
floorShape.dispose();
obstacleFixture = createobstacleFixture(obstacleBody);
obstacle2Fixture = createobstacle2Fixture(obstacle2Body);
playerFixture.setUserData("player");
floorFixture.setUserData("floor");
obstacleFixture.setUserData("obstacle");
obstacle2Fixture.setUserData("obstacle2");
}
private BodyDef createobstacleBodyDef(float x) {
while (true) {
BodyDef def = new BodyDef();
def.position.set(0, 0.5f);
return def;
}
}
private BodyDef createobstacle2BodyDef(float x) {
BodyDef def = new BodyDef();
def.position.set(6,2.5f);
return def;
}
private BodyDef createfloorBodyDef() {
BodyDef def = new BodyDef();
def.position.set(0,-1);
return def;
}
private BodyDef createplayerBodyDef() {
BodyDef def = new BodyDef();
def.position.set(-5 ,0);
def.type = BodyDef.BodyType.DynamicBody;
return def;
}
private Fixture createobstacleFixture(Body obstacleBody) {
while (true) {
Vector2[] vertices = new Vector2[3];
vertices[0] = new Vector2(-0.5f, -0.5f);
vertices[1] = new Vector2(0.5f, -0.5f);
vertices[2] = new Vector2(0, 0.5f);
PolygonShape shape = new PolygonShape();
shape.set(vertices);
Fixture fix = obstacleBody.createFixture(shape, 1);
shape.dispose();
return fix;
}
}
private Fixture createobstacle2Fixture(Body obstacle2Body) {
Vector2[] vertices = new Vector2[3];
vertices[2] = new Vector2(-0.5f, 0.5f);
vertices[1] = new Vector2(0.5f, 0.5f);
vertices[0] = new Vector2(0, -0.5f);
PolygonShape shape = new PolygonShape();
shape.set(vertices);
Fixture fix = obstacle2Body.createFixture(shape, 1);
shape.dispose();
return fix;
}
#Override
public void dispose() {
playerBody.destroyFixture(playerFixture);
obstacleBody.destroyFixture(obstacleFixture);
world.destroyBody(playerBody);
world.destroyBody(obstacleBody);
world.dispose();
renderer.dispose();
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(mustJump) {
mustJump = false;
jump();
}
if (Gdx.input.justTouched()) {
mustJump = true;
}
if (playerAlive) {
float velocityY = playerBody.getLinearVelocity().y;
playerBody.setLinearVelocity(8, velocityY);
}
world.step(delta, 6, 2);
camera.update();
renderer.render(world, camera.combined);
}
private void jump () {
Vector2 position = playerBody.getPosition();
playerBody.applyLinearImpulse(0, 6, position.x, position.y, true);
}
}
return fix; will return; exiting the first iteration on the while loop.