AndEngine gravity doesn't work - android

Hello everybody I'm trying to make a sprite fall in my game. I searched all over the web and I did this:
scene = new Scene();
main = new Sprite(sX, sY, mainTextureRegion);
main.setScale(1);
main.setFlippedHorizontal(true);
scene.attachChild(main);
mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
final Body body = PhysicsFactory.createBoxBody(mPhysicsWorld, main, BodyType.DynamicBody, objectFixtureDef);
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(main, body, true, true));
final Vector2 gravity = new Vector2(0, 5f);
mPhysicsWorld.setGravity(gravity);
scene.registerUpdateHandler(new IUpdateHandler() {
#Override
public void onUpdate(float pSecondsElapsed) {
mPhysicsWorld.onUpdate(pSecondsElapsed);
}
#Override
public void reset() {}
});
But the when i launch the game the sprite doesn't fall !! Why ?? Please I'm desperate !!

Sprite doesn't use physics, but body does. You should use Physics connector (which is connecting your sprite with your body):
Set the body variable:
Body yourBody = PhysicsFactory.createBoxBody(mPhysicsWorld, main, BodyType.DynamicBody, objectFixtureDef);
and then use this physics connector:
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(main, yourBody, true, true));
Sorry for my English.

Related

andengine applyLinearImpulse don't work

I have a Dynamic body. On tap to screen I try to jump body by apply LinearImpulse for body, but after execution its didn't get effect. Just nothing changes
this my tap to screen method:
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if (pSceneTouchEvent.isActionDown()){
Debug.d("jump test");
int index = mPlayer.getCurrentTileIndex()-1;
mPlayer.setCurrentTileIndex(Math.abs(index));
//mPlayerBody.applyForce(new Vector2(10, -10), mPlayerBody.getWorldCenter());
mPlayerBody.applyLinearImpulse(99990, -999999, mPlayerBody.getPosition().x,
mPlayerBody.getPosition().y);
//mPlayerBody.applyLinearImpulse(10, 10, mPlayerBody.getPosition().x, mPlayerBody.getPosition().y);
}
return false;
}
and this how I create physics for body:
final FixtureDef PLAYER_FIX = PhysicsFactory.createFixtureDef(0,
0, 1, false);
mPlayerBody = PhysicsFactory.createBoxBody(physicsWorld, mPlayer,
BodyType.DynamicBody, PLAYER_FIX);
mScene.attachChild(mPlayer);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(mPlayer,
mPlayerBody, true, false));
and on create scene i use:
physicsWorld = new PhysicsWorld(new Vector2( 0, SensorManager.GRAVITY_EARTH), false);
Whats wrong? Why linear impulse didn't apply? also I try to use apply LinearVelocity but this also has no effect.
please note: sorry for my English
PhysicsFactory.createFixtureDef(flaot density , float elasticity ,float friction)
the mass of the the body is 0 if density = 0.

Random number condition anomaly with AndEngine - Android

I'm currently using AndEngine, to do a little box game with faces in it, so that the player spawns faces when touching the screen. So here I already declared the variable "onch" as a double and I made it a random number between 1 and 4 so that each time addFace is called, it generates a new number and so a new face. However I'm getting always the last face. I'm getting only this :
face = new AnimatedSprite(pX, pY, this.mort, this.getVertexBufferObjectManager());
body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
Here is the full code :
private void addFace(final float pX, final float pY) {
onch = Math.floor((Math.random()*4)+1);
final AnimatedSprite face;
final Body body;
if(onch == 4) {
body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
} else if (onch == 3) {
face = new AnimatedSprite(pX, pY, this.noel, this.getVertexBufferObjectManager());
body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
} else if (onch == 2) {
face = new AnimatedSprite(pX, pY, this.sournois, this.getVertexBufferObjectManager());
body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
} else {
face = new AnimatedSprite(pX, pY, this.mort, this.getVertexBufferObjectManager());
body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
}
face.animate(200);
this.mScene.attachChild(face);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));
}
Why do I only receive the one value?
i think it is because you set your variables with the
final
modifier, once you set an instance of a final variable it cannot be changed, so your random code works fine but since the variables have the final modifier, once they are set the first time they are stuck like that, you cannot change them
There are some problems with the code.
This line body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF); appears in the code four times. You could take it out of your if statements because it's the same in all four.
As JRowan said, final should not be use in this case.
Now, if you are sure that the face is exactly identical at the end of this method, the problem is in one of these calls: AnimatedSprite()constructor might give you the same face no matter what arguments you put in, or animate() method of AnimatedSprite class changes the face and makes it look the same in the end.
This appears incorrect:
onch = Math.floor((Math.random()*4)+1);
Try:
onch = Math.floor((Math.random()%4)+1);

jointed body not following the real body

I use this two body jointed. Player body and his foot body.But footBody don't follow player body.?
final FixtureDef fixtureDef = PhysicsFactory.createFixtureDef(0, 0, 0.1f);
this.body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, this, BodyType.DynamicBody, fixtureDef);
this.body.setUserData("player");
this.body.setFixedRotation(true);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(this, this.body, true, true));
this.setCurrentTileIndex(8); //Başlangıç resmi
this.foot = new Rectangle(this.getX()-20, this.getY(), 10, 50);
final FixtureDef footFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 0, true);
footFixtureDef.isSensor = true;
this.footBody=PhysicsFactory.createBoxBody(this.mPhysicsWorld, this.foot, BodyType.DynamicBody, footFixtureDef);
this.footBody.setUserData("foot");
this.foot.setColor(0.9f, 0.3f, 0.6f);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(this.foot, this.footBody, true, true));
final WeldJointDef joint = new WeldJointDef();
joint.initialize(this.body, this.footBody, this.body.getWorldCenter());
this.mPhysicsWorld.createJoint(joint);
You have 10 questions for a 10min, and every one of them are - two words and a big block of code with no clear definition. Nobody will answer you if you don't modify the questions.

I need Collision to make an object sit on another in AndEngine

I have a game, where with the gyroscope, i control a couple of blocks. Now the problem is that i have inplemented box2d in my andengine code, but the bodies do not seem to react one at another, causing them to overlap, instead of actually doing the physics stuff.
In my onCreateScene i have this:
#Override
protected Scene onCreateScene() {
this.mMainScene = new Scene();
backgroundSprite = new Sprite(0, 0, this.mBackgroundTextureRegion, getVertexBufferObjectManager());
physicsWorld = new PhysicsWorld(new Vector2(0, 0), false);
final Player oPlayer = new Player(centerX, centerY, this.goodTiledTextureRegion, this.getVertexBufferObjectManager(), MainActivity.this, playerID, 0);
player_fix = PhysicsFactory.createFixtureDef(10.0f, 0.2f, 1.0f);
body = PhysicsFactory.createBoxBody(physicsWorld, oPlayer, BodyType.DynamicBody, player_fix);
oPlayer.setBody(body);
playerID++;
players.add(oPlayer);
for (Player player : players) {
player.setPlayers(players);
mMainScene.attachChild(player);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(player, body, true, false));
mMainScene.registerTouchArea(player);
}
this.mMainScene.registerUpdateHandler(physicsWorld);
this.mMainScene.registerUpdateHandler(new TimerHandler(0.1f, true, new ITimerCallback() {
#Override
public void onTimePassed(final TimerHandler pTimerHandler) {
Player player = new Player(random, 5, goodTiledTextureRegion, getVertexBufferObjectManager(), MainActivity.this, playerID, 0);
body = PhysicsFactory.createBoxBody(physicsWorld, player, BodyType.DynamicBody, player_fix);
player.setBody(body);
players.add(player);
mMainScene.detachChildren();
mMainScene.attachChild(backgroundSprite);
for (Player player : players) {
player.setPlayers(players);
mMainScene.attachChild(player);
player.body.setLinearVelocity(AccelerometerHelper.TILTX * 5, AccelerometerHelper.TILTY * 5);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(player, body, true, false));
mMainScene.registerTouchArea(player);
}
}
return this.mMainScene;
}
Now, I create the scene, I create the physics world.
Then i create my first "player", (this is a sprite, that i move). I create a body for it, and also set that body in my Player.class (entity). to have access to every players body, from it's entity. Then on every a couple of updates (the code is a bit longer, but i took out the stuff that doesn't have anything to do with physics) I create a new player. and then for every player in my arraylist (players), i set the linear velocity after the accelerometer, to make it move. The problem is that if a player hits another one, they overlap, and do not react at the impact.
the player fixture is the same everywhere player_fix = PhysicsFactory.createFixtureDef(10.0f, 0.2f, 1.0f); And the BodyType is always DynamicBody. Can somebody tell me what I am missing?
You can download it from http://code.google.com/p/andenginephysicsbox2dextension/.
I use Eclipse, and added it as a project. I then included it into my project.
I also recommend the project AndEngineExamples, it shows you all kinds of nice tools.
Here is how i add Walls:
final Rectangle wall = new Rectangle(pX, pY, pWidth, pHeight, pVman); // pvman is the ObjectVertexBufferManager
wall.setIgnoreUpdate(true);
Body body = PhysicsFactory.createBoxBody(
pParent.mPhysicsWorld,
wall,
BodyType.StaticBody,
Environment.WALL_FIXTURE_DEF
);
pScene.getFirstChild().attachChild(wall);
pParent.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(wall, body, true, true));
// pParent is of type GameActivity.
The WALL_FIXTURE_DEF is:
/* The categories. */
public static final short CATEGORYBIT_WALL = 1;
public static final short CATEGORYBIT_MONNING = 2;
public static final short CATEGORYBIT_WHEEL = 4;
/* And what should collide with what. */
public static final short MASKBITS_WALL = CATEGORYBIT_WALL + CATEGORYBIT_MONNING + CATEGORYBIT_WHEEL;
public static final short MASKBITS_MONNING = CATEGORYBIT_WALL;
public static final short MASKBITS_WHEEL = CATEGORYBIT_WALL;
public static final FixtureDef WALL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0f, 0.9f, false, CATEGORYBIT_WALL, MASKBITS_WALL, (short)0);
public static final FixtureDef MONNING_FIXTURE_DEF = PhysicsFactory.createFixtureDef(10, 0f, 0f, false, CATEGORYBIT_MONNING, MASKBITS_MONNING, (short)0);
public static final FixtureDef WHEEL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(20, 0f, 10f, false, CATEGORYBIT_WHEEL, MASKBITS_WHEEL, (short)0);
public static final float GRAVITY_MONNINGS = 2*SensorManager.GRAVITY_EARTH;
This also handles collisions using the MASK_BITS. Monnings and Wheels should not collide with each other, but they should collide with Walls.
The Physics world is created as this in the createScene function:
this.mPhysicsWorld = new FixedStepPhysicsWorld(Environment.FPS, new Vector2(0, Environment.GRAVITY_MONNINGS), false);
Again the AndEngineExamples project (http://code.google.com/p/andengineexamples/) is a must to have installed.
This might be the code you need. Note that i have not run the code so its might contain error but i hope you can get the idea: (Sorry for indent)
#Override
protected Scene onCreateScene() {
this.mMainScene = new Scene();
backgroundSprite = new Sprite(0, 0, this.mBackgroundTextureRegion, getVertexBufferObjectManager());
physicsWorld = new PhysicsWorld(new Vector2(0, 0), false);
final Player oPlayer = new Player(centerX, centerY, this.goodTiledTextureRegion, this.getVertexBufferObjectManager(), MainActivity.this, playerID, 0);
player_fix = PhysicsFactory.createFixtureDef(10.0f, 0.2f, 1.0f);
oPlayer.setBody(body);
playerID++;
players.add(oPlayer);
for (Player player : players) {
Body body = PhysicsFactory.createBoxBody(physicsWorld, oPlayer, BodyType.DynamicBody, player_fix);
player.setPlayers(players);
mMainScene.attachChild(player);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(player, body, true, false));
mMainScene.registerTouchArea(player);
}
this.mMainScene.registerUpdateHandler(physicsWorld);
this.mMainScene.registerUpdateHandler(new TimerHandler(0.1f, true, new ITimerCallback() {
#Override
public void onTimePassed(final TimerHandler pTimerHandler) {
Player player = new Player(random, 5, goodTiledTextureRegion, getVertexBufferObjectManager(), MainActivity.this, playerID, 0);
Body body = PhysicsFactory.createBoxBody(physicsWorld, player, BodyType.DynamicBody, player_fix);
player.setBody(body);
players.add(player);
player.setPlayers(players);
mMainScene.attachChild(player);
/* This might have to be in the loop */
player.body.setLinearVelocity(AccelerometerHelper.TILTX * 5, AccelerometerHelper.TILTY * 5);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(player, body, true, false));
mMainScene.registerTouchArea(player);
}
}
return this.mMainScene;
}

Spring wall in AndEngine and Box2D

I use Box2D in my game, but I would like to have a nicely looking spring - wall to push the player when touched. It would look like this (in 3 frames):
Question: how to implement it? Can I attach a wall effect to an animated sprite?
The answer is: Prismatic Joint. I divided the image into 2 parts: static and dynamic (the moving bar). The below code is for creation of a prismatic joint in orientation like in the image in my question:
//prismatic joint
final Sprite springFrameT = new Sprite(pX, pY, mSpringFrameTRegion, getVertexBufferObjectManager());
final Sprite springBarT = new Sprite(pX, pY + mSpringFrameTRegion.getHeight()-mSpringBarTRegion.getHeight(),
mSpringBarTRegion, getVertexBufferObjectManager());
mMainScene.attachChild(springFrameT);
mMainScene.attachChild(springBarT);
mMapSprites.add(springFrameT);
mMapSprites.add(springBarT);
final Body springFrameBody = PhysicsFactory.createBoxBody(mPhysicsWorld, springFrameT, BodyType.StaticBody, FIXTURE_DEF);
final Body springBarBody = PhysicsFactory.createBoxBody(mPhysicsWorld, springBarT, BodyType.DynamicBody, SPRING_FIXTURE_DEF);
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(springFrameT, springFrameBody, false, false));
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(springBarT, springBarBody, true, true));
final PrismaticJointDef prismaticJointDef = new PrismaticJointDef();
prismaticJointDef.initialize(springFrameBody, springBarBody, springFrameBody.getWorldCenter(), // new Vector2(springFrameT.getWidth(), springFrameT.getHeight()/2),
new Vector2(0, 1.0f));
prismaticJointDef.lowerTranslation = -0.5f;
prismaticJointDef.upperTranslation = 0.5f;
prismaticJointDef.enableLimit = true;
prismaticJointDef.enableMotor = true;
prismaticJointDef.maxMotorForce = 100.0f;
prismaticJointDef.motorSpeed = 100000f;
prismaticJointDef.collideConnected = false;
this.mPhysicsWorld.createJoint(prismaticJointDef);

Categories

Resources