Я устанавливаю линейный импульс на объект, он движется нормально, но когда я нажимаю кнопку питания и затем снова захожу в игру, я заметил, что скорость вращения моего объекта уменьшена.
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;
}
}
см. BodyKinetic.setAngularVelocity (15f);
Обновление
@ Override
public void onResumeGame () {
super.onResumeGame ();
if(bodyKinetic != null){
System.out.println("set angular veclocity resume ");
bodyKinetic.setAngularVelocity(25f);
}
this.enableAccelerometerSensor(this);
}
Странно, что когда я запускаю его в режиме дублирования, он работает нормально и без отладки не действует
Обновление
У меня также есть незарегистрированный и повторный регистр тела, но он по-прежнему бесполезен: (
@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();
}