PhysicsHandler not working as expected - AndEngine - android

Guys am a complete newbie to AndEngine. I wanted to use the physics handler and went through the examples of andengine. So in my case i have a "ball" sprite which i can move by touching and a second "square" animated sprite which i expect to bounce of the walls. But it is just leaving the screen. Help me out...
package com.Escapo;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.handler.physics.PhysicsHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import android.view.Display;
public class EscapoActivity extends BaseGameActivity {
private Camera mCamera;
private Scene mMainScene;
//main ball variables
private BitmapTextureAtlas mBitmapTextureAtlas;
private TextureRegion mPlayerTextureRegion;
private Sprite player;
//square
private BitmapTextureAtlas mBitmapTextureAtlas2;
private static final float DEMO_VELOCITY = 100.0f;
private TiledTextureRegion mFaceTextureRegion;
private static int cameraWidth;
private static int cameraHeight;
private Sprite square;
#Override
public void onLoadComplete() {
}
#Override
public Engine onLoadEngine() {
final Display display = getWindowManager().getDefaultDisplay();
cameraWidth = display.getWidth();
cameraHeight = display.getHeight();
mCamera = new Camera(0, 0, cameraWidth, cameraHeight);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(cameraWidth, cameraHeight), mCamera));
}
#Override
public void onLoadResources() {
mBitmapTextureAtlas = new BitmapTextureAtlas(512, 512,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
//square
mBitmapTextureAtlas2 = new BitmapTextureAtlas(512, 512,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, this, "ball.png",
0, 0);
//square
this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas2, this, "square.png", 0, 0, 1, 1);
mEngine.getTextureManager().loadTextures(mBitmapTextureAtlas,mBitmapTextureAtlas2);
}
#Override
public Scene onLoadScene() {
mEngine.registerUpdateHandler(new FPSLogger());
mMainScene = new Scene();
mMainScene
.setBackground(new ColorBackground(0.09804f, 0.6274f, 0.8784f));
final int PlayerX =(int) ((mCamera.getWidth() - mPlayerTextureRegion
.getWidth()) / 2);
final int PlayerY = (int) ((mCamera.getHeight() - mPlayerTextureRegion
.getHeight()) / 2);
player = new Sprite(PlayerX, PlayerY, mPlayerTextureRegion) {
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,float pTouchAreaLocalX, float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX()- this.getWidth() / 2, pSceneTouchEvent.getY()- this.getHeight() / 2);
return true;
}
};
mMainScene.registerTouchArea(player);
mMainScene.setTouchAreaBindingEnabled(true);
mMainScene.attachChild(player);
//square
final Ball ball = new Ball(2, 2, this.mFaceTextureRegion);
final PhysicsHandler physicsHandler = new PhysicsHandler(ball);
ball.registerUpdateHandler(physicsHandler);
physicsHandler.setVelocity(DEMO_VELOCITY, DEMO_VELOCITY);
mMainScene.getLastChild().attachChild(ball);
return mMainScene;
}
private static class Ball extends AnimatedSprite {
private final PhysicsHandler mPhysicsHandler;
public Ball(final float pX, final float pY, final TiledTextureRegion pTextureRegion) {
super(pX, pY, pTextureRegion);
this.mPhysicsHandler = new PhysicsHandler(this);
this.registerUpdateHandler(this.mPhysicsHandler);
}
#Override
protected void onManagedUpdate(final float pSecondsElapsed) {
if(this.mX < 0) {
this.mPhysicsHandler.setVelocityX(DEMO_VELOCITY);
} else if(this.mX + this.getWidth() > cameraWidth) {
this.mPhysicsHandler.setVelocityX(-DEMO_VELOCITY);
}
if(this.mY < 0) {
this.mPhysicsHandler.setVelocityY(DEMO_VELOCITY);
} else if(this.mY + this.getHeight() > cameraHeight) {
this.mPhysicsHandler.setVelocityY(-DEMO_VELOCITY);
}
super.onManagedUpdate(pSecondsElapsed);
}
}
}
I have just tried to integrate the moving ball example http://code.google.com/p/andengineexamples/source/browse/src/org/anddev/andengine/examples/MovingBallExample.java
Where am i going wrong?

I'm not sure PhysicsHandler will solve your problems, because I think it's just supposed to help you move your Entity.
Try the Box2d extension to AndEngine.
From the AndEngine Examples, there's PhysicsJumpExample.java (called "Combining Physics and Touch" in the launcher) which basically makes an object jump if you touch it, so I guess it's near to what you want.
Here's some code from that file, to make walls:
//onCreateScene
final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
final Rectangle ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2, vertexBufferObjectManager);
final Rectangle roof = new Rectangle(0, 0, CAMERA_WIDTH, 2, vertexBufferObjectManager);
final Rectangle left = new Rectangle(0, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);
final Rectangle right = new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);
final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
this.mScene.attachChild(ground);
this.mScene.attachChild(roof);
this.mScene.attachChild(left);
this.mScene.attachChild(right);
To make the object jump, just set a set the velocity to negative gravity. Gravity pulls it back after it eventually reaches 0:
final Vector2 velocity = Vector2Pool.obtain(this.mGravityX * -50, this.mGravityY * -50);
faceBody.setLinearVelocity(velocity);
Vector2Pool.recycle(velocity);

Related

Newton's cradle on andengine, box2d

i'm trying to create something like Newton's cradle. But when one ball hits another, all balls move simultaneously in same direction. How can I decide this problem? Should i create another physical options of balls in createFixtureDef? Or I need to use some specific algorithm to transfer impuls between balls?
public class MainActivity extends SimpleBaseGameActivity implements IAccelerationListener,
IOnAreaTouchListener
{
private static final int CAMERA_WIDTH = 720;
private static final int CAMERA_HEIGHT = 480;
private BitmapTextureAtlas mBitmapTextureAtlas;
final String TAG = "States";
private Scene mScene;
protected ITiledTextureRegion mBoxFaceTextureRegion;
protected ITiledTextureRegion mCircleFaceTextureRegion;
protected PhysicsWorld mPhysicsWorld;
#Override
public EngineOptions onCreateEngineOptions() {
final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
}
#Override
protected void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 64, 64, TextureOptions.BILINEAR);
this.mBoxFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_box_tiled.png", 0, 0, 2, 1); // 64x32
this.mCircleFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_circle_tiled.png", 0, 32, 2, 1); // 64x32
this.mBitmapTextureAtlas.load();
}
#Override
protected Scene onCreateScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
this.mScene = new Scene();
this.mScene.setBackground(new Background(0, 0, 0));
//this.mScene.setOnSceneTouchListener(this);
this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
this.initJoints(mScene);
this.mScene.registerUpdateHandler(this.mPhysicsWorld);
this.mScene.setOnAreaTouchListener(this);
return this.mScene;
}
private void initJoints(final Scene pScene) {
final float centerY = CAMERA_HEIGHT / 2;
final float spriteWidth = this.mBoxFaceTextureRegion.getWidth();
final float spriteHeight = this.mBoxFaceTextureRegion.getHeight();
final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(30, 0.2f, 0.2f);
for(int i = 0; i < 10; i++) {
final float anchorFaceX = 100 + i * spriteWidth ;
final float anchorFaceY = centerY;
final AnimatedSprite anchorFace = new AnimatedSprite(anchorFaceX, anchorFaceY,
this.mBoxFaceTextureRegion, this.getVertexBufferObjectManager());
final Body anchorBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld,
anchorFace, BodyType.StaticBody,
objectFixtureDef);
final AnimatedSprite movingFace = new AnimatedSprite(anchorFaceX, anchorFaceY + 150,
this.mCircleFaceTextureRegion, this.getVertexBufferObjectManager()) ;
// movingFace.setScale(1.2f);
final Body movingBody = PhysicsFactory.createCircleBody(this.mPhysicsWorld,
movingFace, BodyType.DynamicBody, objectFixtureDef);
movingFace.setUserData(movingBody);
// anchorFace.setScale(1.2f);
anchorFace.animate(200);
anchorFace.animate(200);
final Line connectionLine = new Line(anchorFaceX + spriteWidth / 2,
anchorFaceY + spriteHeight / 2,
anchorFaceX + spriteWidth / 2,
anchorFaceY + spriteHeight / 2,
this.getVertexBufferObjectManager());
pScene.registerTouchArea(movingFace);
pScene.attachChild(connectionLine);
pScene.attachChild(anchorFace);
pScene.attachChild(movingFace);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(anchorFace,
anchorBody, true, true){
#Override
public void onUpdate(final float pSecondsElapsed) {
super.onUpdate(pSecondsElapsed);
final Vector2 movingBodyWorldCenter = movingBody.getWorldCenter();
connectionLine.setPosition(connectionLine.getX1(), connectionLine.getY1(),
movingBodyWorldCenter.x * PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT,
movingBodyWorldCenter.y * PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT);
}
});
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(movingFace, movingBody, true, true));
final RevoluteJointDef revoluteJointDef = new RevoluteJointDef();
revoluteJointDef.initialize(anchorBody, movingBody, anchorBody.getWorldCenter());
this.mPhysicsWorld.createJoint(revoluteJointDef);
}
}
#Override
public void onAccelerationAccuracyChanged(final AccelerationData pAccelerationData) {
}
#Override
public void onAccelerationChanged(final AccelerationData pAccelerationData) {
final Vector2 gravity = Vector2Pool.obtain(pAccelerationData.getX(), pAccelerationData.getY());
this.mPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
}
public boolean onAreaTouched( final TouchEvent pSceneTouchEvent,
final ITouchArea pTouchArea,final float pTouchAreaLocalX,
final float pTouchAreaLocalY) {
if(pSceneTouchEvent.isActionMove())
{
float touchX = pSceneTouchEvent.getX();
float touchY = pSceneTouchEvent.getY();
Log.d(TAG, "move to in X" +touchX + "n Y " +touchY);
final AnimatedSprite anchorFace = (AnimatedSprite) pTouchArea;
final Body tochedBody = (Body)anchorFace.getUserData();
//move sprite to xy
final float x = pSceneTouchEvent.getX();
final float y = pSceneTouchEvent.getY();
final float widthD2 = anchorFace.getWidth() / 2;
final float heightD2 = anchorFace.getHeight() / 2;
final float angle = tochedBody.getAngle(); // keeps the body angle
final Vector2 v2 = Vector2Pool.obtain((x + widthD2) / 32, (y + heightD2) / 32);
tochedBody.setTransform(v2, angle);
Vector2Pool.recycle(v2);
return true;
}
return false;
}
}
Unfortunately Box2D is not really suitable for this.
In my experience, you can get one or two swing-thrus to work as long as the balls are not touching each other to start with. That is, each ball starts with a very small gap between it and the neighbor on each side. This means that when they collide each collision is solved using just two balls at a time, for a total of 4 separate collisions for the impact to travel to the other side (for 5 balls), instead of solving all 5 balls as a single 'island'.
Trouble is, the positioning needs to be very precise, and after a few swings the balls stray from that, so that you end up with collisions involving more than two balls at a time. I only ever saw at most 2-3 swings work as desired...

How to move a player sprite By onScreenDigitalControl on autoparallexbackground in andengine

I am developing a game in andengine.i want to move a player sprite by onScreenDigitalControl on an autoparallex background.Can anyone tell me how to do that ???? thanks
Using this code you can make player sprite moving by DigitalOnScreenControl. Also you can find many tutorials on this at http://www.andengine.org/forums/tutorials/
public class TileActivity extends BaseGameActivity {
private TMXTiledMap mTMXTiledMap;
private BoundCamera mBoundChaseCamera;
private static final int CAMERA_WIDTH = 480;
private static final int CAMERA_HEIGHT = 320;
private Scene mScene;
private static final long[] ANIMATE_DURATION = new long[]{200, 200, 200};
private static final int PLAYER_VELOCITY = 2;
private BitmapTextureAtlas mTexturePlayer;
private Body mPlayerBody;
private TiledTextureRegion mPlayerTextureRegion;
private BitmapTextureAtlas mOnScreenControlTexture;
private TextureRegion mOnScreenControlBaseTextureRegion;
private TextureRegion mOnScreenControlKnobTextureRegion;
private DigitalOnScreenControl mDigitalOnScreenControl;
private PhysicsWorld mPhysicsWorld;
private enum PlayerDirection{
NONE,
UP,
DOWN,
LEFT,
RIGHT
}
private PlayerDirection playerDirection = PlayerDirection.NONE;
#Override
public Engine onLoadEngine() {
this.mBoundChaseCamera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mBoundChaseCamera));
}
#Override
public void onLoadResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
// Control texture
this.mOnScreenControlTexture = new BitmapTextureAtlas(256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_base.png", 0, 0);
this.mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_knob.png", 128, 0);
// Player sprite texture
this.mTexturePlayer = new BitmapTextureAtlas(128, 128, TextureOptions.DEFAULT);
this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mTexturePlayer, this, "hero.png", 0, 0, 3, 4);
// Load the textures
this.mEngine.getTextureManager().loadTextures(this.mTexturePlayer, this.mOnScreenControlTexture);
}
#Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
// Create physics world
this.mPhysicsWorld = new FixedStepPhysicsWorld(30, new Vector2(0, 0), false, 8, 1);
// Create the scene and register the physics world
mScene = new Scene();
mScene.registerUpdateHandler(this.mPhysicsWorld);
// Load the TMX map
try {
final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine.getTextureManager(), TextureOptions.NEAREST, null);
this.mTMXTiledMap = tmxLoader.loadFromAsset(this, "test.tmx");
} catch (final TMXLoadException tmxle) {
Debug.e(tmxle);
}
// Add the non-object layers to the scene
for (int i = 0; i < this.mTMXTiledMap.getTMXLayers().size(); i++){
TMXLayer layer = this.mTMXTiledMap.getTMXLayers().get(i);
if (!layer.getTMXLayerProperties().containsTMXProperty("wall", "true"))
mScene.attachChild(layer);
}
// Read in the unwalkable blocks from the object layer and create boxes for each
this.createUnwalkableObjects(mTMXTiledMap);
// Make the camera not exceed the bounds of the TMXEntity.
final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
this.mBoundChaseCamera.setBounds(0, tmxLayer.getWidth(), 0, tmxLayer.getHeight());
this.mBoundChaseCamera.setBoundsEnabled(true);
// Add outer walls
this.addBounds(tmxLayer.getWidth(), tmxLayer.getHeight());
// Calculate the coordinates for the player, so it's centred on the camera.
final int centerX = (CAMERA_WIDTH - this.mPlayerTextureRegion.getTileWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mPlayerTextureRegion.getTileHeight()) / 2;
// Create the player sprite and add it to the scene.
final AnimatedSprite player = new AnimatedSprite(centerX, centerY, this.mPlayerTextureRegion);
this.mBoundChaseCamera.setChaseEntity(player);
final FixtureDef playerFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 0.5f);
mPlayerBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, player, BodyType.DynamicBody, playerFixtureDef);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(player, mPlayerBody, true, false){
#Override
public void onUpdate(float pSecondsElapsed){
super.onUpdate(pSecondsElapsed);
mBoundChaseCamera.updateChaseEntity();
}
});
mScene.attachChild(player);
// Add the control
this.mDigitalOnScreenControl = new DigitalOnScreenControl(0, CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight(), this.mBoundChaseCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, new IOnScreenControlListener() {
#Override
public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
// Set the correct walking animation
if (pValueY == 1){
// Up
if (playerDirection != PlayerDirection.UP){
player.animate(ANIMATE_DURATION, 0, 2, true);
playerDirection = PlayerDirection.UP;
}
}else if (pValueY == -1){
// Down
if (playerDirection != PlayerDirection.DOWN){
player.animate(ANIMATE_DURATION, 9, 11, true);
playerDirection = PlayerDirection.DOWN;
}
}else if (pValueX == -1){
// Left
if (playerDirection != PlayerDirection.LEFT){
player.animate(ANIMATE_DURATION, 3, 5, true);
playerDirection = PlayerDirection.LEFT;
}
}else if (pValueX == 1){
// Right
if (playerDirection != PlayerDirection.RIGHT){
player.animate(ANIMATE_DURATION, 6, 8, true);
playerDirection = PlayerDirection.RIGHT;
}
}else{
if (player.isAnimationRunning()){
player.stopAnimation();
playerDirection = PlayerDirection.NONE;
}
}
// Set the player's velocity
mPlayerBody.setLinearVelocity(pValueX * PLAYER_VELOCITY, pValueY * PLAYER_VELOCITY);
}
});
this.mDigitalOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
this.mDigitalOnScreenControl.getControlBase().setAlpha(0.5f);
this.mDigitalOnScreenControl.getControlBase().setScaleCenter(0, 128);
this.mDigitalOnScreenControl.getControlBase().setScale(1.25f);
this.mDigitalOnScreenControl.getControlKnob().setScale(1.25f);
this.mDigitalOnScreenControl.getControlKnob().setAlpha(0.5f);
this.mDigitalOnScreenControl.refreshControlKnobPosition();
mScene.setChildScene(this.mDigitalOnScreenControl);
return mScene;
}
#Override
public void onLoadComplete() {
// TODO Auto-generated method stub
}
private void createUnwalkableObjects(TMXTiledMap map){
// Loop through the object groups
for(final TMXObjectGroup group: this.mTMXTiledMap.getTMXObjectGroups()) {
if(group.getTMXObjectGroupProperties().containsTMXProperty("wall", "true")){
// This is our "wall" layer. Create the boxes from it
for(final TMXObject object : group.getTMXObjects()) {
final Rectangle rect = new Rectangle(object.getX(), object.getY(),object.getWidth(), object.getHeight());
final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, rect, BodyType.StaticBody, boxFixtureDef);
rect.setVisible(false);
mScene.attachChild(rect);
}
}
}
}
private void addBounds(float width, float height){
final Shape bottom = new Rectangle(0, height - 2, width, 2);
bottom.setVisible(false);
final Shape top = new Rectangle(0, 0, width, 2);
top.setVisible(false);
final Shape left = new Rectangle(0, 0, 2, height);
left.setVisible(false);
final Shape right = new Rectangle(width - 2, 0, 2, height);
right.setVisible(false);
final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, bottom, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, top, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
this.mScene.attachChild(bottom);
this.mScene.attachChild(top);
this.mScene.attachChild(left);
this.mScene.attachChild(right);
}
}

Shooting a bullet from wrong starting point

I created a racing game in andengine.There is a player which is size 100x30px,like a rectangle.And there is fire() function to shoot bullet, code is below.It works fine.but problem is when player is rotating.player is a car image.so they rotating by directionButton().When I shoot a bullet,it starting 0x0px of car.But i want it must be start to move in front of car like 100x15px of car.How can I do?
public void fire() {
float startBulletX=player.getX();
float startBulletY=player.getY();
Sprite bullet=new Sprite(startBulletX,startBulletY,bulletRegion);
final float xComp = (float) Math.cos(MathUtils.degToRad(this.player.getRotation() + 90));
final float yComp = (float) Math.sin(MathUtils.degToRad(this.player.getRotation() + 90));
final Vector2 velocity = Vector2Pool.obtain(xComp * 10, yComp * 10);
bullet.setRotation(this.player.getRotation());
final FixtureDef bulletFixtureDef1 = PhysicsFactory.createFixtureDef(0, 0, 0);
this.mBulletBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, bullet, BodyType.KinematicBody, bulletFixtureDef1);
this.mBulletBody.setLinearVelocity(velocity);
Vector2Pool.recycle(velocity);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(bullet, this.mBulletBody, true, false));
this.scene.attachChild(bullet);
}
//on screen control button
public void addDirectionButton() {
player = new AnimatedSprite(centerX, centerY, this.playerTextureRegion);
final AnalogOnScreenControl analogOnScreenControl = new AnalogOnScreenControl(0, CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight(), this.mBoundChaseCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, 200, new IAnalogOnScreenControlListener() {
public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
final Body carBody = DeffenseActivity.this.mCarBody;
final Vector2 velocity = Vector2Pool.obtain(pValueX * 5, pValueY * 5);
carBody.setLinearVelocity(velocity);
Vector2Pool.recycle(velocity);
final float rotationInRad = (float)Math.atan2(-pValueX, pValueY);
player.setRotation(MathUtils.radToDeg(rotationInRad));
}
public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
}
});
analogOnScreenControl.getControlBase().setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
analogOnScreenControl.getControlBase().setAlpha(0.5f);
analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
analogOnScreenControl.getControlBase().setScale(1.25f);
analogOnScreenControl.getControlKnob().setScale(1.25f);
analogOnScreenControl.refreshControlKnobPosition();
this.scene.setChildScene(analogOnScreenControl);
this.mBoundChaseCamera.setChaseEntity(player);
a=new Sprite(0,0,bulletRegion);
player.attachChild(a);
final FixtureDef carFixtureDef = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
this.mCarBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, player, BodyType.DynamicBody, carFixtureDef);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(player, this.mCarBody, true, false));
this.scene.attachChild(player);
}

setAngularVelocity reduces in onGameResume, onPause

I am setting a linear impulse on an object, it moves fine but when I press power button and then again come to game I noticed that my object rotation speed is lessened.
package com.algo;
import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.Camera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.anddev.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;
import org.anddev.andengine.util.MathUtils;
import org.anddev.andengine.util.constants.TimeConstants;
import android.hardware.SensorManager;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
public class PhysicsTest1 extends BaseGameActivity implements IAccelerometerListener, IOnSceneTouchListener{
private final float CAMERA_WIDTH = 800;
private final float CAMERA_HEIGHT = 480;
private final float MAX_DISTANCE_FLING = 80f;
private final float MAX_VELOCITY_CONST = 250f;
private final float DEFAULT_VELOCITY = 50f;
private BitmapTextureAtlas mBitmapTextureAtlas;
private Scene mScene;
protected TiledTextureRegion mBoxFaceTextureRegion;
protected TiledTextureRegion mCircleFaceTextureRegion;
protected PhysicsWorld mPhysicsWorld;
private int mFaceCount = 0;
private float X = 0;
private float Y = 0;
private Body body = null;
#Override
public void onLoadComplete() {
}
#Override
public Engine onLoadEngine() {
final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
engineOptions.getTouchOptions().setRunOnUpdateThread(true);
return new Engine(engineOptions);
}
#Override
public void onLoadResources() {
this.mBitmapTextureAtlas = new BitmapTextureAtlas(64, 64, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mBoxFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_box_tiled.png", 0, 0, 2, 1); // 64x32
this.mCircleFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_circle_tiled.png", 0, 32, 2, 1); // 64x32
this.mEngine.getTextureManager().loadTexture(this.mBitmapTextureAtlas);
}
#Override
public Scene onLoadScene() {
this.mScene = new Scene();
this.mScene.setBackground(new ColorBackground(0, 0, 0));
this.mScene.setOnSceneTouchListener(this);
this.mScene.setOnSceneTouchListenerBindingEnabled(true);
this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
final Shape ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2);
final Shape roof = new Rectangle(0, 0, 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);
final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.3f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
this.mScene.attachChild(ground);
this.mScene.attachChild(roof);
this.mScene.attachChild(left);
this.mScene.attachChild(right);
this.mScene.registerUpdateHandler(this.mPhysicsWorld);
addFace(0,0);
return this.mScene;
}
#Override
public void onResumeGame() {
super.onResumeGame();
this.enableAccelerometerSensor(this);
}
#Override
public void onPauseGame() {
super.onPauseGame();
this.disableAccelerometerSensor();
}
#Override
public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
// final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getX(), pAccelerometerData.getY());
// this.mPhysicsWorld.setGravity(gravity);
// Vector2Pool.recycle(gravity);
}
private float Xlocal = 0.0f;
private float Ylocal = 0.0f;
private long timeDown = 0;
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
// if(this.mPhysicsWorld != null) {
// if(pSceneTouchEvent.isActionDown()) {
// this.addFace(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
// return true;
// }
if (pSceneTouchEvent.isActionDown()) {
timeDown = System.currentTimeMillis();
System.out.println("Time down is "+timeDown);
Xlocal = pSceneTouchEvent.getX();
Ylocal = pSceneTouchEvent.getY();
} else if (pSceneTouchEvent.isActionUp()) {
X = (pSceneTouchEvent.getX() - Xlocal);
Y = (pSceneTouchEvent.getY() - Ylocal);
float distance = getDistance(Xlocal, Ylocal, pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
if( distance >= MAX_DISTANCE_FLING){
long timeUp = System.currentTimeMillis();
System.out.println("Time up is "+timeUp);
shootBall(X, Y, distance, (float) (timeUp - timeDown) / TimeConstants.MILLISECONDSPERSECOND);
}
}
// }
return true;
}
private void addFace(final float pX, final float pY) {
this.mFaceCount++;
Debug.d("Faces: " + this.mFaceCount);
final AnimatedSprite face;
final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(0.3f, 0.2f, 0.3f);
final FixtureDef objectFixtureDefKinetic = PhysicsFactory.createFixtureDef(0.5f, 0.4f, 0f);
// if(this.mFaceCount % 2 == 0) {
face = new AnimatedSprite(pX, pY, this.mCircleFaceTextureRegion){
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
// if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN){
// Xlocal = pSceneTouchEvent.getX();
// Ylocal = pSceneTouchEvent.getY();
//
// }else if(pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP){
// float x = pSceneTouchEvent.getX();
// float y = pSceneTouchEvent.getY();
//
// x = Math.abs(x - Xlocal);
// y = Math.abs(y - Ylocal);
//
// shootBall(x, y);
// }
//
// return mVisible;
return false;
}
};
face.setScale(2);
AnimatedSprite face2 = new AnimatedSprite((CAMERA_WIDTH * 0.5f) - mBoxFaceTextureRegion.getWidth(), (CAMERA_HEIGHT * 0.5f) - mBoxFaceTextureRegion.getHeight(), this.mBoxFaceTextureRegion.clone());
Body bodyKinetic = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face2, BodyType.KinematicBody, objectFixtureDefKinetic);
bodyKinetic.setAngularVelocity(15f);
AnimatedSprite face3 = new AnimatedSprite(400f, 100f, this.mBoxFaceTextureRegion.clone());
Body body2 = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face3, BodyType.DynamicBody, objectFixtureDef);
body2.setLinearDamping(2f);
body2.setAngularDamping(10f);
// } else {
// face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion);
// face.setScale(MathUtils.random(0.5f, 1.25f));
// body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
// }
body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
body.setBullet(true);
this.mScene.attachChild(face);
this.mScene.registerTouchArea(face);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));
this.mScene.attachChild(face2);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face2, bodyKinetic));
this.mScene.attachChild(face3);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face3, body2));
}
private void shootBall(final float pX, final float pY, final float pDistance, final float pTime) {
System.out.println("Time Final seconds "+pTime);
float angleRad =(float)Math.atan2(pY, pX);
float velocity = this.getVelocity(pTime);//(pDistance * 12.5f) / 100f;
if(body != null){
float Vx = velocity * (float)Math.cos(angleRad);
float Vy = velocity * (float)Math.sin(angleRad);
body.applyLinearImpulse(new Vector2(Vx,Vy), body.getWorldCenter());
body.setAngularDamping(0.8f); //to decrease velocity slowly. no linear no floaty :)
body.setLinearDamping(0.5f);
body.applyTorque(100f);
}
}
private float getDistance(float x1, float y1, float x2, float y2){
float X2_ = (float)Math.pow(x2 - x1, 2);
float Y2_ = (float)Math.pow(y2 - y1, 2);
float distance = (float)Math.sqrt(X2_ + Y2_);
return distance;
}
private float getVelocity(float pTime) {
float velocity = MAX_VELOCITY_CONST - (pTime * 100f);
if (velocity < DEFAULT_VELOCITY) {
velocity = DEFAULT_VELOCITY;
}
System.out.println("velocity "+velocity);
return velocity;
}
}
please see bodyKinetic.setAngularVelocity(15f);
Update
#Override
public void onResumeGame() {
super.onResumeGame();
if(bodyKinetic != null){
System.out.println("set angular veclocity resume ");
bodyKinetic.setAngularVelocity(25f);
}
this.enableAccelerometerSensor(this);
}
Its strange that when I run it in dubug mode it runs ok and without debug it has no effect
Update
I have also unreg and re-reg body but still of no use :(
#Override
public void onResumeGame() {
super.onResumeGame();
if(bodyKinetic != null){
System.out.println("OnResumeGame Angular Velocity "+bodyKinetic.getAngularVelocity());
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector((IShape) bodyKinetic.getUserData(), bodyKinetic));
bodyKinetic.setAngularVelocity(25f);
}
this.enableAccelerometerSensor(this);
}
#Override
public void onPauseGame() {
super.onPauseGame();
if(bodyKinetic != null){
System.out.println("OnPauseGame Angular Velocity "+bodyKinetic.getAngularVelocity());
bodyKinetic.setAngularVelocity(0f);
this.mPhysicsWorld.unregisterPhysicsConnector(this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape((IShape) bodyKinetic.getUserData()));
}
this.disableAccelerometerSensor();
}
You can try saving the bodies' velocities in onPauseGame() and setting them back in onResume(). You can also try setting linear and angular damping to 0 when pausing the game and reseting the values when resuming. The damping sometimes behaved weirdly in the project I work on.
The fact that you're experiencing a heisenbug suggests that it might be a bug in the engine.

how to move body of sprite using andEngine?

I want to move body of the sprite along with line in some portion of line, just i able to move sprite only but body is not moving.
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(2);
scene.setBackground(new ColorBackground(0.09804f, 0.00274f, 0.0784f));
this .enableAccelerometerSensor(this );
this.sPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
final Shape ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH,2);
final Shape roof = new Rectangle(0, 0, 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.sPhysicsWorld, ground,
BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.sPhysicsWorld, roof,
BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.sPhysicsWorld, left,
BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.sPhysicsWorld, right,
BodyType.StaticBody, wallFixtureDef);
scene.getFirstChild().attachChild(ground);
scene.getFirstChild().attachChild(roof);
scene.getFirstChild().attachChild(left);
scene.getFirstChild().attachChild(right);
final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
final AnimatedSprite face = new AnimatedSprite(centerX - 100, centerY, this.mFaceTextureRegion);
final Body bodyRedBall = PhysicsFactory.createCircleBody(this.sPhysicsWorld, face,
BodyType.DynamicBody, wallFixtureDef);
this.sPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, bodyRedBall, true, true));
scene.attachChild(face);
final AnimatedSprite face2 = new AnimatedSprite(100, 100, this.mFaceTextureRegion);
final Body bodyRedBall2 = PhysicsFactory.createCircleBody(this.sPhysicsWorld, face2,
BodyType.KinematicBody, wallFixtureDef);
final Path path4 = new Path(3).to(682, 223).to(482, 223).to(682, 223);
face2.registerEntityModifier(new LoopEntityModifier(new PathModifier(30, path4, null, new IPathModifierListener() {
#Override
public void onWaypointPassed(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex) {
}
})));
this.sPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face2, bodyRedBall2, true, true){
#Override
public void onUpdate(final float pSecondsElapsed) {
super.onUpdate(pSecondsElapsed);
face2.setPosition(face2.getX(), face2.getY());
}
});
scene.attachChild(face2);
scene.registerUpdateHandler(this.sPhysicsWorld);
return scene;
}
#Override
public void onLoadComplete() {
}
#Override
public void onAccelerometerChanged(AccelerometerData pAccelerometerData) {
// TODO Auto-generated method stub
final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getY(), pAccelerometerData.getX());
this.sPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
}
You can use body.setLinearVelocity(); to move the body, the sprite will automatically follow the body because you have specified a physics connector.
public class MoveBodyModifier extends MoveModifier {
private Body mBody;
public MoveBodyModifier(float pDuration, float pFromX, float pToX, float pFromY, float pToY, Body body) {
super(pDuration, pFromX, pToX, pFromY, pToY);
mBody = body;
}
#Override
protected void onSetInitialValues(IEntity pEntity, float pX, float pY) {
mBody.setTransform(pX/ PhysicsConnector.PIXEL_TO_METER_RATIO_DEFAULT,
pY/ PhysicsConnector.PIXEL_TO_METER_RATIO_DEFAULT, mBody.getAngle());
}
#Override
protected void onSetValues(IEntity pEntity, float pPercentageDone, float pX, float pY) {
mBody.setTransform(pX/ PhysicsConnector.PIXEL_TO_METER_RATIO_DEFAULT,
pY/ PhysicsConnector.PIXEL_TO_METER_RATIO_DEFAULT, mBody.getAngle());
}
}
to move the body must use the setTransform
yourBody.setTransform(new Vector2(x/32,y/32), 0);
and remember that you have to divide x and y default by 32
you can also go
yourBody.setTransform(x/32,y/32), 0);
and you need to divide by 32 because box2d does not operates in pixels so to get it to pixels you need to divide by 32

Categories

Resources