I have one dynamic sprite and few static. My dynamic body:
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(180, 20);
bodyMonkey = world.createBody(bodyDef);
PolygonShape abcBox = new PolygonShape();
bodyMonkey.setUserData(monkey1);
bodyMonkey.setFixedRotation(true);
abcBox.setAsBox(10.0f, 10.0f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = abcBox;
fixtureDef.density = 0.5f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution = 0.9f;
Fixture fixture = bodyMonkey.createFixture(fixtureDef);
abcBox.dispose();
bodyMonkey.setLinearVelocity(new Vector2(1f, 0.5f));
bodyMonkey.setLinearDamping(1.0f);
I have to implement ContactListener. My class:
#Override
public void beginContact(Contact contact) {
Object a = contact.getFixtureA().getBody().getUserData();
Object b = contact.getFixtureB().getBody().getUserData();// null
Gdx.app.log("1", ""+a);
Gdx.app.log("2", ""+b);
if(a!=null&&b!=null) {
Gdx.app.log("ok", "");
screen2dBox.restartGame();
}
}
#Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
}
#Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
}
#Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
}
But object b is alaways null (a no, b is dynamic, I saw it in my logs). I have try to use try, catch, finally to overcome this (in finally block - screen2dBox.restartGame();) but I had error that contact can not be null. I don't know how does it solve? thanks for help.
static body:
BodyDef bodyDefPlatform1 = new BodyDef();
bodyDefPlatform1.type = BodyType.StaticBody;
bodyDefPlatform1.position.set(50, 280);
bodyPlatform1 = world.createBody(bodyDefPlatform1 );
PolygonShape platformBox1 = new PolygonShape();
bodyPlatform1.setUserData(platform);
platformBox1.setAsBox(20.0f, 10.0f);
FixtureDef fixtureDefPlatform1 = new FixtureDef();
fixtureDefPlatform1.shape = platformBox1;
Fixture fixturePlatform = bodyPlatform1.createFixture( fixtureDefPlatform1);
platformBox1.dispose();
I check your code, I can't see any error. Maybe the object monkey1 is null.
bodyMonkey.setUserData(monkey1); //check if monkey1 is null.
Note: I have low reputacion, I can't post this as comment.
Related
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
I am a newbie in libgdx. I am working on a game which has a player body and I have given controls but I want to create enemies at specific time in my game. I have tried creating it but only the player body is been created and but not enemy body.
This is my code
public class Player
implements Screen, InputProcessor {
private Body polybody;
private Player player;
private World world;
private Body enemybody;
private Sprite polysprite;
public final float width, height;
private Vector2 movement = new Vector2();
private float speed = 580;
public Player(World world, float x, float y, float width) {
this.width = width; //IMP
height = width * 2;
BodyDef polygon = new BodyDef();
polygon.type = BodyType.DynamicBody;
polygon.position.set(x, y); //
PolygonShape poly = new PolygonShape();
poly.setAsBox(width / 2, height / 2); //
//fixture defn
FixtureDef polyfixture = new FixtureDef();
polyfixture.shape = poly;
polyfixture.friction = 0.8f; //
polyfixture.restitution = 0.1f; //
polyfixture.density = 3; //
//creating actual body
polybody = world.createBody(polygon);
polybody.createFixture(polyfixture);
// polybody.applyAngularImpulse(52, true);
polysprite = new Sprite(new Texture("img/car.jpg"));
polysprite.setSize(0.5f, 1); //size of mario
polysprite.setOrigin(polysprite.getWidth() / 2, polysprite.getHeight() / 2);
polybody.setUserData(polysprite);
poly.dispose();
}
public void update() {
polybody.applyForceToCenter(movement, true);
}
public Body getBody() {
return polybody;
}
#Override
public void show() {
// TODO Auto-generated method stub
}
final float step = 0.1f;
float timeElapsed = 0f;
#Override
public void render(float delta) {
timeElapsed += delta;
while (timeElapsed > step) {
timeElapsed -= step;
Enemy();
}
}
public void Enemy() {
BodyDef enemy = new BodyDef();
enemy.type = BodyType.DynamicBody;
enemy.position.set(6, 3);
PolygonShape enemypoly = new PolygonShape();
enemypoly.setAsBox(2, 2);
FixtureDef enemyfixture = new FixtureDef();
enemyfixture.shape = enemypoly;
enemyfixture.friction = 0.75f;
enemyfixture.restitution = 0.1f;
enemyfixture.density = 5;
enemybody = world.createBody(enemy);
enemybody.createFixture(enemyfixture);
enemypoly.dispose();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#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
}
#Override
public boolean keyDown(int keycode) {
// TODO Auto-generated method stub
switch (keycode) {
case Keys.W:
movement.y = speed;
break;
case Keys.S:
movement.y = -speed;
break;
case Keys.D:
movement.x = speed;
break;
case Keys.A:
movement.x = -speed;
}
return true;
}
#Override
public boolean keyUp(int keycode) {
// TODO Auto-generated method stub
switch (keycode) {
case Keys.W:
movement.y = 0;
break;
case Keys.S:
movement.y = 0;
break;
case Keys.D:
movement.x = 0;
break;
case Keys.A:
movement.x = 0;
}
return true;
}
#Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
movement.x = speed;
Gdx.app.log("Example", "touch done ");
return true;
}
}
This is the player class that gets called first and after this on render method the enemy method gets called. The player body is working fine but I couldn't see any enemy body. Please help .Thanks in advance !!
Apparently, your Player class is responsible for:
Handling inputs for controlling the game
the construction of enemy objects
rendering the entire world (handling time) and displaying the world and all objects
creating Textures (that is supposed to be created only once, not every time you make a Sprite!)
Aaaand you don't have any other class.
I think you should fix this problem.
Also, I'm a bit weary of that you're calling dispose() each time after you create an object.
By the way, the render() method only gets called if you set the active screen for the Game, so
public class MyGame extends Game {
...
MyScreen myScreen = new MyScreen();
...
public void goToMyScreen() {
this.setScreen(myScreen);
}
}
Something like that is necessary for render() to work.
And please check How to track time in Libgdx(android) on how to handle elapsed time.
I suggest a refactoring of your application. That class Player doesn't look like the right place for creating enemies (which you seem to do in every step). Instead you should create the Enemy in the same place where you create your Player and give your Enemy an own class.
Furthermore you could write debug messages to the console or use your IDE's debugger to check what your code is actually doing.
I don't know what to do, the contactlistener isn't working anymore.
The thing is I first used the Simpleleveloader to load my sprites - during that time the Contactlistener worked without a problem.
But later I wanted to change the Simpleleveloader to something that I wrote by myself (because I want endless level and not premade xml ones) and here the Contact listener don't work!
Here is the Leveloader before:
Code:
private void loadiLevel(int levelID)
{
final SimpleLevelLoader levelLoader = new SimpleLevelLoader(vbom);
final FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.01f, 0.5f);
camera.setBounds(0, 480, 2500, 40); // here we set camera bounds
camera.setBoundsEnabled(true);
levelLoader.registerEntityLoader(new EntityLoader<SimpleLevelEntityLoaderData>(LevelConstants.TAG_LEVEL)
{
public IEntity onLoadEntity(final String pEntityName, final IEntity pParent, final Attributes pAttributes, final SimpleLevelEntityLoaderData pSimpleLevelEntityLoaderData) throws IOException
{
final int width = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_WIDTH);
final int height = SAXUtils.getIntAttributeOrThrow(pAttributes, LevelConstants.TAG_LEVEL_ATTRIBUTE_HEIGHT);
return GameScene.this;
}
});
levelLoader.registerEntityLoader(new EntityLoader<SimpleLevelEntityLoaderData>(TAG_ENTITY)
{
public IEntity onLoadEntity(final String pEntityName, final IEntity pParent, final Attributes pAttributes, final SimpleLevelEntityLoaderData pSimpleLevelEntityLoaderData) throws IOException
{
final int x = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_X);
final int y = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_Y);
final String type = SAXUtils.getAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_TYPE);
final Sprite levelObject;
if (type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLATFORM1))
{
levelObject = new Sprite(x, y, resourcesManager.platform1_region, vbom);
PhysicsFactory.createBoxBody(physicsWorld, levelObject, BodyType.StaticBody, FIXTURE_DEF).setUserData("platform1");
}
else if (type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLATFORM2))
{
levelObject = new Sprite(x, y, resourcesManager.platform2_region, vbom);
final Body body = PhysicsFactory.createBoxBody(physicsWorld, levelObject, BodyType.StaticBody, FIXTURE_DEF);
body.setUserData("platform2");
physicsWorld.registerPhysicsConnector(new PhysicsConnector(levelObject, body, true, false));
}
else if (type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLAYER))
{
player = new Player(x, y, vbom, camera, physicsWorld)
{
#Override
public void onDie()
{
scoreText.detachSelf();
BackButton.detachSelf();
}
};
levelObject = player;
}
else if (type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_ZOMBIE))
{
zombie = new Zombie(x, y, vbom, camera, physicsWorld);
levelObject = zombie;
}
else
{
throw new IllegalArgumentException();
}
levelObject.setCullingEnabled(true);
return levelObject;
}
});
levelLoader.loadLevelFromAsset(activity.getAssets(), "level/1.lvl");
}
And here is the current one ('which perfectly works except the Contactlistener!'):
Code:
private void createLevel(){
loadLevel("player",0,200);
loadLevel("platform1",0,40 );
loadLevel("platform1",350,40);
loadLevel("platform1",700,40);
loadLevel("platform2",1050,40);
loadLevel("platform2",1400,40);
loadLevel("platform1",1750,40);
//loadLevel("zombie",700,200);
}
private void loadLevel( final String tipus, final int number,final int numer){
camera.setBounds(0, 480, 250000, 40);
camera.setBoundsEnabled(true);
final FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.01f, 0.5f);
final int y = 0 + numer;
final int x = 0 +number;
final String type = tipus;
final Sprite levelObject;
if (type.equals("platform1"))
{
levelObject = new Sprite(x, y, resourcesManager.platform1_region, vbom);
PhysicsFactory.createBoxBody(physicsWorld, levelObject, BodyType.StaticBody, FIXTURE_DEF).setUserData("platform1");
}
else if (type.equals("platform2"))
{
levelObject = new Sprite(x, y, resourcesManager.platform2_region, vbom);
final Body body = PhysicsFactory.createBoxBody(physicsWorld, levelObject, BodyType.StaticBody, FIXTURE_DEF);
body.setUserData("platform2");
physicsWorld.registerPhysicsConnector(new PhysicsConnector(levelObject, body, true, false));
}
else if (type.equals("player"))
{
player = new Player(x, y, vbom, camera, physicsWorld)
{
#Override
public void onDie()
{
scoreText.detachSelf();
BackButton.detachSelf();
}
};
levelObject = player;
}
else if (type.equals("zombie"))
{
zombie = new Zombie(x, y, vbom, camera, physicsWorld);
levelObject = zombie;
}
else
{
throw new IllegalArgumentException();
}
levelObject.setCullingEnabled(true);
attachChild(levelObject);
}
Btw here is how I create my physicsWorld:
private void createPhysics()
{
physicsWorld = new PhysicsWorld(new Vector2(0, -25.5f), true);
physicsWorld.setContactListener(contactListener());
registerUpdateHandler(physicsWorld);
engine.registerUpdateHandler(new FPSLogger());
}
private ContactListener contactListener()
{
ContactListener contactListener = new ContactListener()
{
public void beginContact(Contact contact)
{
final Fixture x1 = contact.getFixtureA();
final Fixture x2 = contact.getFixtureB();
if (x1.getBody().getUserData() != null && x2.getBody().getUserData() != null)
{
if (x2.getBody().getUserData().equals("player"))
{
player.increaseFootContacts();
if(firstTouch){
player.Run();
}
}
if (x1.getBody().getUserData().equals("platform2") && x2.getBody().getUserData().equals("player"))
{
engine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback()
{
public void onTimePassed(final TimerHandler pTimerHandler)
{
pTimerHandler.reset();
engine.unregisterUpdateHandler(pTimerHandler);
x1.getBody().setType(BodyType.DynamicBody);
}
}));
}
}
}
public void endContact(Contact contact)
{
final Fixture x1 = contact.getFixtureA();
final Fixture x2 = contact.getFixtureB();
if (x1.getBody().getUserData() != null && x2.getBody().getUserData() != null)
{
if (x2.getBody().getUserData().equals("player"))
{
player.decreaseFootContacts();
}
}
}
public void preSolve(Contact contact, Manifold oldManifold)
{
}
public void postSolve(Contact contact, ContactImpulse impulse)
{
}
};
return contactListener;
}
Hope you can help me!
THANK YOU!
I am using a ContactListener to listen for any contact, and if collision is detected between the ball and ground, the ball should get an impulse in the upward direction, which is provided in the void endContact() function of the ContactListener class. But this impulse is having no effect at all, for any impulse value. The ball just bounces off the same distance for any impulse value. What am I doing wrong. Here's the full code:
public class Game implements ApplicationListener {
World world ;
Box2DDebugRenderer debugRenderer;
OrthographicCamera camera;
static final float BOX_STEP=1/60f;
static final int BOX_VELOCITY_ITERATIONS=8;
static final int BOX_POSITION_ITERATIONS=3;
static final float WORLD_TO_BOX=0.01f;
static final float BOX_WORLD_TO=100f;
Rectangle ball;
Body body;
#Override
public void create() {
world = new World(new Vector2(0, -100), true);
camera = new OrthographicCamera();
camera.viewportHeight = 480;
camera.viewportWidth = 800;
camera.position.set(camera.viewportWidth * .5f, camera.viewportHeight * .5f, 0f);
camera.update();
//Ground body
BodyDef groundBodyDef =new BodyDef();
groundBodyDef.position.set(new Vector2(0, 10));
Body groundBody = world.createBody(groundBodyDef);
PolygonShape groundBox = new PolygonShape();
groundBox.setAsBox((camera.viewportWidth) * 2, 10.0f);
groundBody.createFixture(groundBox, 0.0f);
//Dynamic Body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(camera.viewportWidth / 8, camera.viewportHeight / 2);
body = world.createBody(bodyDef);
// create a Rectangle to logically represent the ball
CircleShape dynamicCircle = new CircleShape();
dynamicCircle.setRadius(40f);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = dynamicCircle;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.0f;
fixtureDef.restitution =1f;
body.createFixture(fixtureDef);
debugRenderer = new Box2DDebugRenderer();
listener listener1=new listener();
world.setContactListener(listener1);
}
#Override
public void render() {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
debugRenderer.render(world, camera.combined);
world.step(BOX_STEP, BOX_VELOCITY_ITERATIONS, BOX_POSITION_ITERATIONS);
}
class listener implements ContactListener
{
#Override
public void beginContact(Contact contact) {
// TODO Auto-generated method stub
}
#Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
body.applyLinearImpulse(0, 500000f, body.getWorldCenter().x, body.getWorldCenter().y, true);
//body.setLinearVelocity(0,50000000);
System.out.println("Collision detected");
}
#Override
public void preSolve(Contact contact, Manifold oldManifold) {
// TODO Auto-generated method stub
}
#Override
public void postSolve(Contact contact, ContactImpulse impulse) {
// TODO Auto-generated method stub
}
};
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}
In the original C++ version, EndContact is called inside the Step function, which is a time when you cannot alter anything in the world because the engine is still using it. I would think that the Java version is the same. You will probably need to make a note of the fact that the ball has bounced, and apply the impulse after the Step has finished.
The reason that there is no impact on of impulse is you are try to apply impulse in the endcontact method.
In box2d ContactListener methods you cannot change the property or position of body.
You can do like this
boolean b;
#Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
//body.applyLinearImpulse(0, 500000f, body.getWorldCenter().x, body.getWorldCenter().y, true);
//body.setLinearVelocity(0,50000000);
b = true;
System.out.println("Collision detected");
}
In you update method.....
if(b)
{
body.applyLinearImpulse(0, 500000f, body.getWorldCenter().x, body.getWorldCenter().y, true);
}
So I have this method that when i touch the screen my sprite will jump. Now the problem is when I continuously touch the screen the sprite will jump again and again. What I want to do is if it jumps, the jump method cannot be called unless my sprite hits the ground.
Here is the code.
public class PhyiscsActivity extends BaseGameActivity implements IAccelerometerListener, IOnSceneTouchListener{
private static final int CAMERA_WIDTH = 720;
private static final int CAMERA_HEIGHT = 480;
private Camera mCamera;
private BitmapTextureAtlas mBitmapTextureAtlas;
private TiledTextureRegion mTextureRegion;
private Scene mScene;
private FixtureDef mFixtureDef = PhysicsFactory.createFixtureDef(1,-10f, 0.5f);
private PhysicsWorld mPhysicsWorld;
private Body body;
private AnimatedSprite facebox;
private FixtureDef wallfixture = PhysicsFactory.createFixtureDef(-1,0.5f, 0.5f);
#Override
public Engine onLoadEngine() {
// TODO Auto-generated method stub
this.mCamera = new Camera(0,0,CAMERA_WIDTH, CAMERA_HEIGHT);
final EngineOptions mEngineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),this.mCamera);
mEngineOptions.getTouchOptions().setRunOnUpdateThread(true);
return new Engine(mEngineOptions);
}
#Override
public void onLoadResources() {
// TODO Auto-generated method stub
this.mBitmapTextureAtlas = new BitmapTextureAtlas(128,128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mBitmapTextureAtlas, this, "gfx/face_box_tiled.png", 0, 0, 2, 1);
this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
}
#Override
public Scene onLoadScene() {
// TODO Auto-generated method stub
this.mEngine.registerUpdateHandler(new FPSLogger());
this.mScene = new Scene();
this.mScene.setBackground(new ColorBackground(1,1,1));
this.mPhysicsWorld = new PhysicsWorld(new Vector2(0,SensorManager.GRAVITY_EARTH),false);
// This is the walls
final Shape roof = new Rectangle(0, 0, CAMERA_WIDTH, 2);
final Shape ground = new Rectangle(0,CAMERA_HEIGHT - 2,CAMERA_WIDTH,2);
final Shape left = new Rectangle(0,0,2,CAMERA_HEIGHT);
final Shape right = new Rectangle(CAMERA_WIDTH -2, 0,2,CAMERA_HEIGHT);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallfixture);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallfixture);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallfixture);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallfixture);
// This is the Sprite
facebox = new AnimatedSprite(30,(CAMERA_HEIGHT - 2) - this.mTextureRegion.getHeight() ,this.mTextureRegion);
body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, facebox, BodyType.DynamicBody, mFixtureDef);
this.mScene.attachChild(facebox);
this.mScene.registerUpdateHandler(this.mPhysicsWorld);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(facebox,body,true,true));
this.mScene.setOnSceneTouchListener(this);
return this.mScene;
}
#Override
public void onLoadComplete() {
// TODO Auto-generated method stub
}
//Accelerometer
#Override
public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
// TODO Auto-generated method stub
final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getX()* 3, 10);
this.mPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
this.enableAccelerometerSensor(this);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
this.disableAccelerometerSensor();
}
//This is where i make the sprite jump
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
pSceneTouchEvent.isActionDown();{
this.jump(facebox);
}
return false;
}
public void jump(AnimatedSprite sprite){
boolean jumping = false;
if(!jumping ){
body.setLinearVelocity(new Vector2(body.getLinearVelocity().x,-8f));
}
}
public void jump(AnimatedSprite sprite){
if(!jumping){
body.setLinearVelocity(new Vector2(body.getLinearVelocity().x,-10));
jumping = true;
}
}
#Override
public void beginContact(Contact contact) {
// TODO Auto-generated method stub
jumping = true;
}
#Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
jumping = false;
}
I don't know why the beginContact and endContact isn't initialzing. are there things that i should do to initialize this? example like updating a handler? contactlistener?
You need to have a method wich tell you if your player is jumping or not.
public void jump(AnimatedSprite sprite){
if( isJumping(sprite)){
body.setLinearVelocity(new Vector2(body.getLinearVelocity().x,-8f));
}
In this method you should put the way to compute if the player is jumping. Like if he is touching a wall (if player's body (x,y) is in a wall (rectangle))
Ok you are using box2d to make physics =)
You have to create a ContactListener, you have to implement this class and the function ou want to add.
http://code.google.com/p/andenginephysicsbox2dextension/source/browse/src/com/badlogic/gdx/physics/box2d/ContactListener.java?r=1605f6e82f710ef9ebbe07632d6b055239d3b520
public void beginContact (Contact contact);
public void endContact (Contact contact);
The contact object will countain your objects (Fixture) that are touching. You just have to check and set jumping to false when the body is touching and true when you call jump and you can jump, set jumping to true;
Ok?
#Override
public void beginContact(Contact contact) {
// TODO Auto-generated method stub
jumping = true;
}
#Override
public void endContact(Contact contact) {
// TODO Auto-generated method stub
jumping = false;
}
This is false.. I would think of it like that only:
#Override
public void beginContact(Contact contact) {
jumping = false; //you touched ground so you aren't jumping anymore
}
#Override
public void endContact(Contact contact) {
jumping = true; //you leave ground so you're jumping
}
and one jump method (not two):
public void jump(AnimatedSprite sprite){
if(!jumping ){
jumping = true;
body.setLinearVelocity(new Vector2(body.getLinearVelocity().x,-8f));
}
}
You see?;