package com.andengine.using.physical;
import static org.anddev.andengine.extension.physics.box2d.util.constants.PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
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.background.ColorBackground;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.util.FPSLogger;
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.Vector2Pool;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
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 android.hardware.SensorManager;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.Toast;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
/**
* @author pham tien phong
* @since 18:47:08 - 02.04.2015
*/
public class Temp extends BaseGameActivity implements IAccelerometerListener {
// ===========================================================
// Constants
// ===========================================================
private static int CAMERA_WIDTH = 0;
private static int CAMERA_HEIGHT = 0;
private static final FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f);
// ===========================================================
// Fields
// ===========================================================
private Texture mTexture;
private TiledTextureRegion mFace;
private PhysicsWorld mPhysicsWorld;
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
protected void getScreen() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
CAMERA_WIDTH = dm.widthPixels;
CAMERA_HEIGHT = dm.heightPixels;
}
@Override
public Engine onLoadEngine() {
getScreen();
Toast.makeText(this, getTitle(), Toast.LENGTH_LONG).show();
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() {
/* Textures. */
this.mTexture = new Texture(64, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
TextureRegionFactory.setAssetBasePath("gfx/");
/* TextureRegions. */
mFace = TextureRegionFactory.createTiledFromAsset(this.mTexture, this, "face_hexagon_tiled.png", 0, 96, 2, 1); // 64x32
mEngine.getTextureManager().loadTexture(this.mTexture);
// đăng kí sự kiện thay đổi vị trí so với trọng lực của điện thoại
this.enableAccelerometerSensor(this);
}
@Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(2);
scene.setBackground(new ColorBackground(0, 0, 0));
// trong lực : GRAVITY
mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
final Shape top = new Rectangle(0, CAMERA_HEIGHT - 2, CAMERA_WIDTH, 2);
final Shape bottom = 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 Shape line = new Rectangle(CAMERA_WIDTH / 4, CAMERA_HEIGHT / 2, CAMERA_WIDTH / 2, 6);
line.setColor(23, 0, 33);
// PhysicsFactory.createFixtureDef(hightJump, ping, sự trơn trượt);
// hightJump khi đối tượng chạm vào vật chắn : tăng khi a tăng
// sự trợn trượt càng lớn khi a càng giảm (min=0) : đặt a= 2
// ping (độ đàn hổi ) : a càng lớn đàn hồi càng mạnh : đặt a = 0.8f
final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0f, 0.8f, 0.5f);
PhysicsFactory.createBoxBody(mPhysicsWorld, top, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(mPhysicsWorld, bottom, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(mPhysicsWorld, line, BodyType.StaticBody, wallFixtureDef);
scene.getFirstChild().attachChild(top);
scene.getFirstChild().attachChild(bottom);
scene.getFirstChild().attachChild(left);
scene.getFirstChild().attachChild(right);
scene.getFirstChild().attachChild(line);
scene.registerUpdateHandler(mPhysicsWorld);
return scene;
}
@Override
public void onLoadComplete() {
// when load completed scene , add a object to screen
if (this.mPhysicsWorld != null) {
addFace(CAMERA_WIDTH / 2, CAMERA_HEIGHT / 2);
addFace(0, CAMERA_HEIGHT / 4);
}
}
// hàm này để bắt sự kiện người dùng xoay điện thoại trên tay tính theo
// hướng trọng lực hấp dẫn
@Override
public void onAccelerometerChanged(final AccelerometerData pAccelerometerData) {
final Vector2 gravity = Vector2Pool.obtain(pAccelerometerData.getY(), pAccelerometerData.getX());
this.mPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
}
// ===========================================================
// Methods
// ===========================================================
private void addFace(final float pX, final float pY) {
final Scene scene = this.mEngine.getScene();
final AnimatedSprite face;
final Body body;
face = new AnimatedSprite(pX, pY, mFace);
// khởi tạo vật thể
body = Temp.createHexagonBody(mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
// time change frame 0.2s
face.animate(200);
scene.attachChild(face);
// đăng kí sự kiện vật lí cho vật
mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(face, body, true, true));
}
/**
* Creates a {@link Body} based on a {@link PolygonShape} in the form of a
* hexagon:
*
* <pre>
* /\
* / \
* | |
* | |
* \ /
* \/
* </pre>
*/
private static Body createHexagonBody(final PhysicsWorld pPhysicsWorld, final Shape pShape, final BodyType pBodyType, final FixtureDef pFixtureDef) {
/*
* Remember that the vertices are relative to the center-coordinates of
* the Shape.
*/
final float halfWidth = pShape.getWidthScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
final float halfHeight = pShape.getHeightScaled() * 0.5f / PIXEL_TO_METER_RATIO_DEFAULT;
Log.e("halfHeight = "+halfHeight, "halfWidth = "+halfWidth);
/*
* The top and bottom vertex of the hexagon are on the bottom and top of
* hexagon-sprite.
*/
final float top = -halfHeight;
final float bottom = halfHeight;
final float centerX = 0;
/*
* 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.
*/
final float left = -halfWidth + 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
final float right = halfWidth - 2.5f / PIXEL_TO_METER_RATIO_DEFAULT;
final float higher = top + 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;
final float lower = bottom - 8.25f / PIXEL_TO_METER_RATIO_DEFAULT;
final Vector2[] vertices = { new Vector2(centerX, top), new Vector2(right, higher), new Vector2(right, lower), new Vector2(centerX, bottom), new Vector2(left, lower), new Vector2(left, higher) };
return PhysicsFactory.createPolygonBody(pPhysicsWorld, pShape, vertices, pBodyType, pFixtureDef);
}
}