I am developing a Game in which sprite have to jump forward .
I already explore it and used MoveYModifier for up and then MoveYModifier for down again it is working right except on more then one tap on the screen.But I want to move him forward as well while jump.
final Entity playerEntity = move;
final float jumpDuration = 3;
final float startX = playerEntity.getX();
final float jumpHeight = 100;
final MoveXModifier moveUpModifier = new MoveXModifier(jumpDuration / 2, startX, startX - jumpHeight); // - since we want the sprite to go up.
final MoveXModifier moveDownModifier = new MoveXModifier(jumpDuration / 2,startX - jumpHeight, startX);
final SequenceEntityModifier modifier = new SequenceEntityModifier(moveUpModifier, moveDownModifier);
playerEntity.registerEntityModifier(modifier);
return true;
Instead of using MoveXModifier why not just use the MoveModifier?
https://github.com/nicolasgramlich/AndEngine/blob/GLES2/src/org/andengine/entity/modifier/MoveModifier.java
final MoveModifier jumpForward = new MoveModifier(pDuration, pFromX, pToX, pFromY, pToY);
Related
I found this question: body falls slowly in any gravity
made the changes but still not working.
here is the relevant code:
for the camera
float w = (float) Gdx.graphics.getWidth();
float h = (float) Gdx.graphics.getHeight();
//Initialize variables
camera = new OrthographicCamera();
viewport = new FitViewport(w/ PPM,h/ PPM,camera);
//set the position of the camera to the center of the world
camera.position.set(viewport.getWorldWidth()/2, viewport.getWorldHeight()/2,0);
Creating the world
world = new World(new Vector2(0,-24),true);
Creating the body
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(300
/JungleMasters.PPM,3000/JungleMasters.PPM);
b2body = world.createBody(bodyDef);
code for the world step
world.step(1 / 60f, 6, 2);
The is issue is resolved by changing the timestep. Thanks to the comments I was able to figure it out.
private static final float STEP_TIME = 1/60f;
private float accumulator = 0;
private void stepWorld() {
float delta = Gdx.graphics.getDeltaTime();
accumulator += Math.min(delta, 0.25f);
while (accumulator >= STEP_TIME) {
accumulator -= STEP_TIME;
world.step(STEP_TIME, 10, 8);
}
}
This is an article that explains in details what happens and how to fix this type of issues which is something very common.
I'm trying to scale view from start rectangle (e.g. defined by another view) to it's final position.
I tried to use the following code to setup animations which looks straight forward:
float scaleX = 0f;
float scaleY = 0f;
Rect startRect = new Rect(10, 10, 100, 100); // taken from real view position with getLocationOnScreen
final Collection<Animator> animators = new ArrayList<>();
if (animatedView.getMeasuredHeight() != 0) {
scaleX = (float)startRect.width() / animatedView.getMeasuredWidth();
}
if (animatedView.getMeasuredHeight() != 0) {
scaleY = (float)startRect.height() / animatedView.getMeasuredHeight();
}
animatedView.getLocationInWindow(location);
animatedView.setPivotX(startRect.left);
animatedView.setPivotY(startRect.top);
animatedView.setScaleX(scaleX);
animatedView.setScaleY(scaleY);
animators.add(ObjectAnimator.ofFloat(animatedView, View.SCALE_X, 1.0f).setDuration(1000));
animators.add(ObjectAnimator.ofFloat(animatedView, View.SCALE_Y, 1.0f).setDuration(1000));
The animatedView is child of RelativeLayout (layout parameters set to below some title view of layout) and measured width and height and location are valid values at the moment of animation setup.
Depending on startRect I observe different animations - sometimes animated view get displayed below or above startRect.
Seems RectEvaluator is one of possible solutions, but it's available only from API 18.
What is the proper way to animate view from start rectangle position to final (not modified one)?
As per comments on the question, it's possible to copy RectEvaluator code from Android source, and then apply the following logic:
RectViewAnimator mRectAnimator;
/**
* Creates animator which can be played. From some start position
* to final (real position).
* From final position to start position can be achieved using reverse interpolation.
*/
private Collection<Animator> createMoveAnimators(View targetView, Rect startRect) {
final Collection<Animator> animators = new ArrayList<>();
final int[] location = new int[2];
targetView.getLocationOnScreen(location);
final Rect finalRect = new Rect(location[0], location[1],
location[0] + targetView.getMeasuredWidth(),
location[1] + targetView.getMeasuredHeight());
// Must keep this reference during animations, since Animator keeps only WeakReference to it's targets.
mRectAnimator = appendRectEvaluatorAnimation(animators, targetView, 500, startRect, finalRect);
return animators;
}
private RectViewAnimator appendRectEvaluatorAnimation(final Collection<Animator> animators, final View view, final int duration,
final Rect startRect, final Rect finalRect) {
final float scaleX = (float) startRect.width() / finalRect.width();
final float scaleY = (float) startRect.height() / finalRect.height();
view.setTranslationY(startRect.top - (finalRect.top + (1 - scaleY) * finalRect.height() / 2));
view.setTranslationX(startRect.left - (finalRect.left + (1 - scaleX) * finalRect.width() / 2));
view.setScaleX(scaleX);
view.setScaleY(scaleY);
final RectViewAnimator rectViewAnimator = new RectViewAnimator(view, finalRect);
final Animator animator = ObjectAnimator.ofObject(rectViewAnimator, RectViewAnimator.RECT,
new RectEvaluator(), startRect, finalRect);
animators.add(animator);
return rectViewAnimator;
}
private static class RectViewAnimator {
static final String RECT = "rect";
private final View target;
private final Rect finalRect;
RectViewAnimator(final View target, final Rect finalRect) {
this.target = target;
this.finalRect = finalRect;
}
#Keep
public void setRect(final Rect r) {
final float scaleX = (float)r.width() / finalRect.width();
final float scaleY = (float)r.height() / finalRect.height();
target.setScaleX(scaleX);
target.setScaleY(scaleY);
target.setTranslationX(r.left - (finalRect.left + (1 - scaleX) * finalRect.width() / 2));
target.setTranslationY(r.top - (finalRect.top + (1 - scaleY) * finalRect.height() / 2));
}
}
I am just starting using AndEngine,
I am moving a sprite like this:
if(pValueY < 0 && !jumping) {
jumping = true;
// User is currently holding the UP direction
// get the player entity (used to apply entity modifier, and get the current X position
final Entity playerEntity = (Entity) physicsHandler.getEntity();
// set the jump duration, set the starting x position, and how high the jump will be
final float jumpDuration = 8;
final float startX = playerEntity.getX();
final float jumpHeight = 40;
// set the move modifiers and set it as a sequence
final MoveYModifier moveUpModifier = new MoveYModifier(jumpDuration / 2, startX, startX - jumpHeight);
final MoveYModifier moveDownModifier = new MoveYModifier(jumpDuration / 2, startX + jumpHeight, startX);
final SequenceEntityModifier modifier = new SequenceEntityModifier(moveUpModifier, moveDownModifier);
// apply modifier
playerEntity.registerEntityModifier(modifier);
}
else {
// basically if the user presses left or right this should occur
physicsHandler.setVelocityX(pValueX * 10);
distance += pValueX;
}
My question is how can I set jumping to false after the registerEntityModifier function has completed? (after the player has finished jumping)
Thanks!
Use onModifierFinished() method of andengine
#Override
protected void onModifierFinished(IEntity pItem)
{
super.onModifierFinished(pItem);
// Your action after finishing modifier
}
Use this link for more detail..,.
I want to limit the area to move the sprite object only on this area (for example a area dimensions 200x200).
I would to create a box2D 200x200 where the sprites can moved only on this area
How do you do that please?
#Override
public Scene onCreateScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene();
scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegionLetterOne
.getWidth()) / 2;
final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegionLetterOne
.getHeight()) / 2;
final Sprite letterOne = new Sprite(centerX - centerX / 2, centerY
- centerY / 2, this.mFaceTextureRegionLetterOne,
this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
return true;
}
};
final Sprite letterTwo = new Sprite(centerX - centerX / 2, centerY,
this.mFaceTextureRegionLetterTwo,
this.getVertexBufferObjectManager()) {
#Override
public boolean onAreaTouched(final TouchEvent pSceneTouchEvent,
final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
this.setPosition(pSceneTouchEvent.getX() - this.getWidth() / 2,
pSceneTouchEvent.getY() - this.getHeight() / 2);
//int count = scene.getChildCount();
//for(int i = 0; i < count; i++) {
IEntity entity = scene.getChildByIndex(1);
if (entity instanceof Sprite) {
if (entity.getUserData().equals("sprite"))
if (((Sprite) entity).collidesWith(letterOne))
Log.v("colission", "face_box is collised on google plus -> letterTwo on letterOne");
}
//}
return true;
}
};
letterTwo.setUserData("sprite");
final Sprite boxArea = new Sprite(centerX, centerY,
this.mFaceTextureRegionBox, this.getVertexBufferObjectManager());
letterOne.setScale(2);
scene.attachChild(letterOne);
scene.registerTouchArea(letterOne);
letterTwo.setScale(2);
scene.attachChild(letterTwo);
scene.registerTouchArea(letterTwo);
boxArea.setScale(2);
scene.attachChild(boxArea);
scene.setTouchAreaBindingOnActionDownEnabled(true);
return scene;
}
Thank you.
I don't know box2D, but normally you would check the edges of the sprite on each movement, if they do not overlap the edges of the area.
If your sprite is represented by a Rectangle, and the area where you can move also represented by a Rectangle, this could be done easy.
But first, check the box2D API, maybe it has already some helper methods to ease this task, something like:
obect.overlaps(object)
You should create a Rectangle of 200X200 and then you should use create a body of the rectangle using the Box2D Physics. And for Fixture definition for rectangle you can set density, Elasticity and Friction so that your sprites will be treated accordingly when they collide with the boundary of the Rectangle.
To create a Rectangle you can refer the Examples of the Andengine.
With your code, you seem to try to do collision checking with your sprites ?!
It would be complicated and not nice when you try to do things without physics bodies. So lets use the physics bodies with your sprites.
But note that, DO NOT create a solid box body for your area (containing your sprites), lets use 4 separated body walls (left, top, right, bottom) to form a closed box; because game engine can only check collision with solid shapes.
The following is the code for reference:
/**
* #param pScene
* Sence of the game, get from class member
* #param pWorld
* physics world of the game, get from class member
*/
public void CreateSprites(final Scene pScene, final PhysicsWorld pWorld)
{
final FixtureDef mFixtureDef = PhysicsFactory.createFixtureDef(10, 1.1f, 0.0f);//should be placed as member of class
final Sprite letterTwo = new Sprite(centerX - centerX / 2, centerY,
this.mFaceTextureRegionLetterTwo,
this.getVertexBufferObjectManager());
final Body letterTwoBody = PhysicsFactory.createBoxBody(pWorld, letterTwo, BodyType.DynamicBody, mFixtureDef);
letterTwo.setUserData(letterTwoBody); // for later sprite-body attachment access
pScene.attachChild(letterTwo);
pWorld.registerPhysicsConnector(new PhysicsConnector(letterTwo, letterTwoBody, true, true));
}
/** Create the walls, in these boudaries sprites will move */
public void InitBoxWalls(Scene pScene, PhysicsWorld pWorld)
{
final float WALL_MARGIN_WIDTH = 5f;
final float WALL_MARGIN_HEIGHT = 10f;
final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
mWallGround = new Rectangle(-WALL_MARGIN_WIDTH, mCameraHeight + WALL_MARGIN_HEIGHT - 2, mCameraWidth + 2*WALL_MARGIN_WIDTH, 2, vertexBufferObjectManager);
mWallRoof = new Rectangle(-WALL_MARGIN_WIDTH, -WALL_MARGIN_HEIGHT, mCameraWidth + 2*WALL_MARGIN_WIDTH, 2, vertexBufferObjectManager);
mWallLeft = new Rectangle(-WALL_MARGIN_WIDTH, -WALL_MARGIN_HEIGHT, 2, mCameraHeight + 2*WALL_MARGIN_HEIGHT, vertexBufferObjectManager);
mWallRight = new Rectangle(mCameraWidth + WALL_MARGIN_WIDTH - 2, -WALL_MARGIN_HEIGHT, 2, mCameraHeight + 2*WALL_MARGIN_HEIGHT, vertexBufferObjectManager);
PhysicsFactory.createBoxBody(pWorld, mWallGround, BodyType.StaticBody, mWallFixtureDef);
PhysicsFactory.createBoxBody(pWorld, mWallRoof, BodyType.StaticBody, mWallFixtureDef);
PhysicsFactory.createBoxBody(pWorld, mWallLeft, BodyType.StaticBody, mWallFixtureDef);
PhysicsFactory.createBoxBody(pWorld, mWallRight, BodyType.StaticBody, mWallFixtureDef);
pScene.attachChild(mWallGround);
pScene.attachChild(mWallRoof);
pScene.attachChild(mWallLeft);
pScene.attachChild(mWallRight);
}
And the last thing you should do is to look up example of Physics/MouseJoint in AndEngine examples.
Ok, this should be simple enough, but I'm tripping myself up on the math. Using AndEngine BTW>
I'm using some of the tutorials out there... hero on the left of the screen (landscape) shooting right. Everything works wonderfully. Now I'd like to have the hero on the right side of the screen shooting left. I'm going in circles and would great appreciate some help. Here is the code I'm using for left hero, shooting right.
/** shoots a projectile from the player's position along the touched area */
private void shootProjectile(final float pX, final float pY) {
int offX = (int) (pX - (hero.getX()));
int offY = (int) (pY - (hero.getY() + hero.getHeight()/2));
if (offX <= 0) return;
// position the projectile on the player and set up path
projectile = pPool.obtainPoolItem();
int realX = (int) (mCamera.getWidth() - (hero.getX() ) );
float ratio = (float) realX / (float) offX;
int realY = (int) ((offY * ratio));
float length = (float) Math.sqrt((realX * realX) + (realY * realY));
float velocity = 280.0f / .5f; // 480 pixels per (sec)f on screen
float realMoveDuration = length / velocity;
// defining a moveBymodifier from the projectile's position to the
// calculated one
//this code angles the projectile sprite
double PI = 3.14159265;
float dx = pX - hero.getX();
float dy = pY - hero.getY()-50;
double Radius = Math.atan2(dy,dx);
double Angle = Radius * 180 / PI;
projectile.setRotation((float)Angle); // sets the angle of the projectile
//Move modifier for projectile
MoveByModifier movMByod = new MoveByModifier(realMoveDuration, realX, realY);
final ParallelEntityModifier par = new ParallelEntityModifier(movMByod);
DelayModifier dMod = new DelayModifier(0.001f);
dMod.addModifierListener(new IModifierListener<IEntity>() {
#Override
public void onModifierStarted(IModifier<IEntity> arg0, IEntity arg1) {
}
#Override
public void onModifierFinished(IModifier<IEntity> arg0, IEntity arg1) {
// TODO Auto-generated method stub
shootingSound.play();
projectile.setVisible(true);
projectile.setPosition(hero.getX(), hero.getY() + hero.getHeight() / 2);
projectilesToBeAdded.add(projectile);
projectile.animate(50);
}
});
SequenceEntityModifier seq = new SequenceEntityModifier(dMod, par);
projectile.registerEntityModifier(seq);
projectile.setVisible(false);
mMainScene.attachChild(projectile, 1);
I've got the hero positioned fine on the right side. What do I need to do to get the projectile to move to the left correctly?
Thanks a ton for any help.
MWM
You shouldn't use DelayModifier the way you do. Instead create a PhysicsHandler for your sprites and then set velocity to the PhysicsHandler. Something like:
PhysicsHandler phys = new PhysicsHandler();
projectile.registerUpdateHandler(phys);
phys.setVelocityX(50);
and this will take care of moving your projectile. You can also set acceleration on the physics handler the same way. So if you set the initial velocity to point up and left and then set the acceleration pointing down, the projectile will first fly left and up and then gradually fall down. And you don't have to do any calculations yourself.
This code looks like the one from http://jimmaru.wordpress.com/2011/09/28/andengine-simple-android-game-tutorial/
if it is, try this:
private void shootProjectile(final float pX, final float pY) {
int side = 1;
int offX = (int) (pX - (hero.getX()));
int offY = (int) (pY - (hero.getY() + hero.getHeight()/2));
if (offX <= 0){
side=-1
}
// position the projectile on the player and set up path
projectile = pPool.obtainPoolItem();
int realX = (int) (mCamera.getWidth() - (hero.getX() ) ) * side;
....
I got the same problem with the code from link, with this change i could shoot fot both sides with a player in the middle of screen.