Doubt about physics. A rotating triangle against walls

  ... discussions about development with the GLES1 branch of AndEngine.

Doubt about physics. A rotating triangle against walls

Postby bernardo » Tue Aug 31, 2010 10:16 pm

Hello guys,

I have a rotating triangle colliding against the 4 walls of the device. It always "reflect" on the walls with the same angle, even though it collides with different angles at the wall. Is this the expected the behavior, physics wise? I'd expect it to bounce in different directions according to it's angle. Maybe I have something configured wrong?

For the walls and triangle:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(0f, 1f, 0f);
Parsed in 0.030 seconds, using GeSHi 1.0.8.4


Thanks a lot

Edit: I've experimented making the triangle with 1f for density. The body then starts to rotate with a different velocity, but it's still bouncing in the same direction, which I find weird. It also seems to conservate energy, because when it's spinning too fast it gets very slow. Is there a way to make the linear velocity constant and be able to change the spinning speed indenpently on collisions?

Here's the whole source code
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package org.anddev.andengine.examples;
  2.  
  3. import static org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
  4.  
  5. import org.anddev.andengine.engine.Engine;
  6. import org.anddev.andengine.engine.camera.Camera;
  7. import org.anddev.andengine.engine.options.EngineOptions;
  8. import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
  9. import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
  10. import org.anddev.andengine.entity.primitive.Rectangle;
  11. import org.anddev.andengine.entity.scene.Scene;
  12. import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
  13. import org.anddev.andengine.entity.scene.background.ColorBackground;
  14. import org.anddev.andengine.entity.shape.Shape;
  15. import org.anddev.andengine.entity.sprite.AnimatedSprite;
  16. import org.anddev.andengine.entity.util.FPSLogger;
  17. import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
  18. import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;
  19. import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
  20. import org.anddev.andengine.input.touch.TouchEvent;
  21. import org.anddev.andengine.opengl.texture.Texture;
  22. import org.anddev.andengine.opengl.texture.TextureOptions;
  23. import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
  24. import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
  25. import org.anddev.andengine.sensor.accelerometer.AccelerometerData;
  26. import org.anddev.andengine.sensor.accelerometer.IAccelerometerListener;
  27. import org.anddev.andengine.util.Debug;
  28.  
  29. import android.hardware.SensorManager;
  30. import android.view.MotionEvent;
  31. import android.widget.Toast;
  32.  
  33. import com.badlogic.gdx.math.Vector2;
  34. import com.badlogic.gdx.physics.box2d.Body;
  35. import com.badlogic.gdx.physics.box2d.FixtureDef;
  36. import com.badlogic.gdx.physics.box2d.PolygonShape;
  37. import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
  38.  
  39. /**
  40.  * @author Nicolas Gramlich
  41.  * @since 18:47:08 - 19.03.2010
  42.  */
  43. public class PhysicsExample extends BaseExample implements IAccelerometerListener, IOnSceneTouchListener {
  44.         // ===========================================================
  45.         // Constants
  46.         // ===========================================================
  47.  
  48.         private static final int CAMERA_WIDTH = 720;
  49.         private static final int CAMERA_HEIGHT = 480;
  50.  
  51.         // ===========================================================
  52.         // Fields
  53.         // ===========================================================
  54.  
  55.         private Texture mTexture;
  56.  
  57.         private TiledTextureRegion mBoxFaceTextureRegion;
  58.         private TiledTextureRegion mCircleFaceTextureRegion;
  59.         private TiledTextureRegion mTriangleFaceTextureRegion;
  60.         private TiledTextureRegion mHexagonFaceTextureRegion;
  61.  
  62.         private PhysicsWorld mPhysicsWorld;
  63.  
  64.         private int mFaceCount = 0;
  65.  
  66.         // ===========================================================
  67.         // Constructors
  68.         // ===========================================================
  69.  
  70.         // ===========================================================
  71.         // Getter & Setter
  72.         // ===========================================================
  73.  
  74.         // ===========================================================
  75.         // Methods for/from SuperClass/Interfaces
  76.         // ===========================================================
  77.  
  78.         @Override
  79.         public Engine onLoadEngine() {
  80.                 Toast.makeText(this, "Touch the screen to add objects.", Toast.LENGTH_LONG).show();
  81.                 final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
  82.                 return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera));
  83.         }
  84.  
  85.         @Override
  86.         public void onLoadResources() {
  87.                 this.mTexture = new Texture(64, 128, TextureOptions.BILINEAR);
  88.                 TextureRegionFactory.setAssetBasePath("gfx/");
  89.                 this.mBoxFaceTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mTexture, this, "face_box_tiled.png", 0, 0, 2, 1); // 64x32
  90.                 this.mCircleFaceTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mTexture, this, "face_circle_tiled.png", 0, 32, 2, 1); // 64x32
  91.                 this.mTriangleFaceTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mTexture, this, "face_triangle_tiled.png", 0, 64, 2, 1); // 64x32
  92.                 this.mHexagonFaceTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mTexture, this, "face_hexagon_tiled.png", 0, 96, 2, 1); // 64x32
  93.                 this.mEngine.getTextureManager().loadTexture(this.mTexture);
  94.  
  95.                 this.enableAccelerometerSensor(this);
  96.         }
  97.  
  98.         @Override
  99.         public Scene onLoadScene() {
  100.                 this.mEngine.registerUpdateHandler(new FPSLogger());
  101.  
  102.                 final Scene scene = new Scene(2);
  103.                 scene.setBackground(new ColorBackground(0, 0, 0));
  104.                 scene.setOnSceneTouchListener(this);
  105.  
  106.                 this.mPhysicsWorld = new PhysicsWorld(new Vector2(0, 0), false);
  107.  
  108.                 final Shape ground = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2);
  109.                 final Shape roof = new Rectangle(0, 0, CAMERA_WIDTH, 2);
  110.                 final Shape left = new Rectangle(0, 0, 2, CAMERA_HEIGHT);
  111.                 final Shape right = new Rectangle(CAMERA_WIDTH - 2, 0, 2, CAMERA_HEIGHT);
  112.  
  113.                 final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(1f, 1f, 0f);
  114.                 PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef); //left
  115.                 PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);
  116.                 PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
  117.                 PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
  118.  
  119.                 scene.getBottomLayer().addEntity(ground);
  120.                 scene.getBottomLayer().addEntity(roof);
  121.                 scene.getBottomLayer().addEntity(left);
  122.                 scene.getBottomLayer().addEntity(right);
  123.  
  124.                 scene.registerUpdateHandler(this.mPhysicsWorld);
  125.  
  126.                 return scene;
  127.         }
  128.  
  129.         public void onLoadComplete() {
  130.  
  131.         }
  132.  
  133.         @Override
  134.         public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) {
  135.                 if(this.mPhysicsWorld != null) {
  136.                         if(pSceneTouchEvent.getAction() == MotionEvent.ACTION_DOWN) {
  137.                                 this.runOnUpdateThread(new Runnable() {
  138.                                         @Override
  139.                                         public void run() {
  140.                                                 PhysicsExample.this.addFace(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
  141.                                         }
  142.                                 });
  143.                                 return true;
  144.                         }
  145.                 }
  146.                 return false;
  147.         }
  148.  
  149.         @Override
  150.         public void onAccelerometerChanged(final AccelerometerData pAccelerometerData) {
  151.                 //this.mPhysicsWorld.setGravity(new Vector2(pAccelerometerData.getY(), pAccelerometerData.getX()));
  152.         }
  153.  
  154.         // ===========================================================
  155.         // Methods
  156.         // ===========================================================
  157.  
  158.         private void addFace(final float pX, final float pY) {
  159.                 final Scene scene = this.mEngine.getScene();
  160.  
  161.                 this.mFaceCount++;
  162.                 Debug.d("Faces: " + this.mFaceCount);
  163.  
  164.                 final AnimatedSprite face;
  165.                 final Body body;
  166.  
  167.                 final FixtureDef objectFixtureDef = PhysicsFactory.createFixtureDef(1f, 1f, 0f);
  168.  
  169.                 if(this.mFaceCount % 4 == 0) {
  170.                         face = new AnimatedSprite(pX, pY, this.mBoxFaceTextureRegion);
  171.                         body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
  172.                 } else if (this.mFaceCount % 4 == 1) {
  173.                         face = new AnimatedSprite(pX, pY, this.mCircleFaceTextureRegion);
  174.                         body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
  175.                 } else if (this.mFaceCount % 4 == 2) {
  176.                         face = new AnimatedSprite(pX, pY, this.mTriangleFaceTextureRegion);
  177.                         body = PhysicsExample.createTriangleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
  178.                 } else {
  179.                         face = new AnimatedSprite(pX, pY, this.mHexagonFaceTextureRegion);
  180.                         body = PhysicsExample.createHexagonBody(this.mPhysicsWorld, face, BodyType.DynamicBody, objectFixtureDef);
  181.                 }
  182.  
  183.                 //face.animate(200);
  184.                 //face.setVelocity(100, 0);
  185.                 //face.setAcceleration(8, 8);
  186.                 body.setLinearVelocity(new Vector2(50, 0));
  187.                 body.setAngularVelocity(1f);
  188.                 face.setUpdatePhysics(true);
  189.  
  190.                 scene.getTopLayer().addEntity(face);
  191.                 this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true, false, false));
  192.         }
  193.  
  194.         /**
  195.          * Creates a {@link Body} based on a {@link PolygonShape} in the form of a triangle:
  196.          * <pre>
  197.          *  /\
  198.          * /__\
  199.          * </pre>
  200.          */
  201.         public static Body createTriangleBody(final PhysicsWorld pPhysicsWorld, final Shape pShape, final BodyType pBodyType, final FixtureDef pFixtureDef) {
  202.                 /* Remember that the vertices are relative to the center-coordinates of the Shape. */
  203.                 final float halfWidth = pShape.getWidthScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
  204.                 final float halfHeight = pShape.getHeightScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
  205.  
  206.                 final float top = -halfHeight;
  207.                 final float bottom = halfHeight;
  208.                 final float left = -halfHeight;
  209.                 final float centerX = 0;
  210.                 final float right = halfWidth;
  211.  
  212.                 final Vector2[] vertices = {
  213.                                 new Vector2(centerX, top),
  214.                                 new Vector2(right, bottom),
  215.                                 new Vector2(left, bottom)
  216.                 };
  217.  
  218.                 return PhysicsFactory.createPolygonBody(pPhysicsWorld, pShape, vertices, pBodyType, pFixtureDef);
  219.         }
  220.  
  221.         /**
  222.          * Creates a {@link Body} based on a {@link PolygonShape} in the form of a hexagon:
  223.          * <pre>
  224.          *  /\
  225.          * /  \
  226.          * |  |
  227.          * |  |
  228.          * \  /
  229.          *  \/
  230.          * </pre>
  231.          */
  232.         public static Body createHexagonBody(final PhysicsWorld pPhysicsWorld, final Shape pShape, final BodyType pBodyType, final FixtureDef pFixtureDef) {
  233.                 /* Remember that the vertices are relative to the center-coordinates of the Shape. */
  234.                 final float halfWidth = pShape.getWidthScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
  235.                 final float halfHeight = pShape.getHeightScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
  236.  
  237.                 /* The top and bottom vertex of the hexagon are on the bottom and top of hexagon-sprite. */
  238.                 final float top = -halfHeight;
  239.                 final float bottom = halfHeight;
  240.  
  241.                 final float centerX = 0;
  242.  
  243.                 /* The left and right vertices of the heaxgon are not on the edge of the hexagon-sprite, so we need to inset them a little. */
  244.                 final float left = -halfWidth + 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
  245.                 final float right = halfWidth - 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
  246.                 final float higher = top + 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;
  247.                 final float lower = bottom - 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;
  248.  
  249.                 final Vector2[] vertices = {
  250.                                 new Vector2(centerX, top),
  251.                                 new Vector2(right, higher),
  252.                                 new Vector2(right, lower),
  253.                                 new Vector2(centerX, bottom),
  254.                                 new Vector2(left, lower),
  255.                                 new Vector2(left, higher)
  256.                 };
  257.  
  258.                 return PhysicsFactory.createPolygonBody(pPhysicsWorld, pShape, vertices, pBodyType, pFixtureDef);
  259.         }
  260.  
  261.         // ===========================================================
  262.         // Inner and Anonymous Classes
  263.         // ===========================================================
  264. }
  265.  
Parsed in 0.069 seconds, using GeSHi 1.0.8.4
bernardo
 
Posts: 9
Joined: Fri Aug 27, 2010 2:20 am

Return to GLES1

Who is online

Users browsing this forum: No registered users and 9 guests