ParallaxBackground AndEngine - android

I'm new to game development andengine. I want to add ParallaxBackground but I don't know how to change background on player move. I'm using arrow for moving a player. Now my question is where I write the code parallaxBackground.setParallaxValue(5); I was written this line in onAreaTouched method of arrow but it not work. please help me. Thanks.
Code
private Camera mCamera;
private static int CAMERA_WIDTH = 800;
private static int CAMERA_HEIGHT = 480;
private BitmapTextureAtlas bgTexture;
private ITextureRegion bgTextureRegion;
#Override
protected void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
bgTexture = new BitmapTextureAtlas(getTextureManager(),2160,480,TextureOptions.REPEATING_BILINEAR);
bgTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(bgTexture, this, "background.png", 0, 0);
bgTexture.load();
}
#Override
protected Scene onCreateScene() {
this.getEngine().registerUpdateHandler(new FPSLogger());
Scene scene = new Scene();
scene.setBackground(new Background(Color.BLACK));
final ParallaxBackground parallaxBackground = new ParallaxBackground(0, 0, 0);
final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();
parallaxBackground.attachParallaxEntity(new ParallaxEntity(0.0f, new Sprite(0, CAMERA_HEIGHT - this.bgTextureRegion.getHeight(), this.bgTextureRegion, vertexBufferObjectManager)));
scene.setBackground(parallaxBackground);
Robot robot = new Robot();
// add Player
final AnimatedSprite animatedRobotSprite = new AnimatedSprite(robot.centerX, robot.centerY, 122, 126, (ITiledTextureRegion) robotTextureRegion, getVertexBufferObjectManager());
scene.attachChild(animatedRobotSprite);
animatedRobotSprite.animate(new long[]{1250,50,50});
// add right arrow button
Sprite rightArrowSprite = new Sprite(0, CAMERA_HEIGHT-70, rightArrowTextureRegion, getVertexBufferObjectManager()){
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,float pTouchAreaLocalX, float pTouchAreaLocalY) {
switch (pSceneTouchEvent.getAction()) {
case TouchEvent.ACTION_DOWN:
moveRight = true;
parallaxBackground.setParallaxValue(5);
break;
case TouchEvent.ACTION_MOVE:
moveRight = true;
break;
case TouchEvent.ACTION_UP:
moveRight = false;
break;
default:
break;
}
return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
}
};
scene.attachChild(rightArrowSprite);
scene.registerTouchArea(rightArrowSprite);
scene.setTouchAreaBindingOnActionDownEnabled(true);
scene.setTouchAreaBindingOnActionMoveEnabled(true);
scene.registerUpdateHandler(new IUpdateHandler() {
#Override
public void reset() {
}
#Override
public void onUpdate(float pSecondsElapsed) {
if ( moveRight ){
animatedRobotSprite.setPosition(animatedRobotSprite.getX()+speedX, animatedRobotSprite.getY());
}
}
});
return scene;
}

I see at least on possible problem: You have only one ParallaxEntity attached. The visual effect of parallax is created by multiple entities moving at different speeds.
But I think what you are seeing is that your background is not scrolling. If you do not use the AutoParallaxBackground class, you have to update the paralax amount on each update.
Inside the autoparallax class, this is what it does onUpdate():
#Override
public void onUpdate(final float pSecondsElapsed) {
super.onUpdate(pSecondsElapsed);
this.mParallaxValue += this.mParallaxChangePerSecond * pSecondsElapsed;
}
Looking at this you can see that the setParallaxValue() is an absolute number, so to make it continually scroll, you will need to feed it a new number on each update. For example, in you main game update loop, you could feed in your player.getX() into parallaxBackground.setParallaxValue() like so:
parallaxBackground.setParallaxValue(rightArrowSprite.getX());
While this may not be the exact effect you want, you should now see the background moving when your character moves.

There are different modifiers foe updating your entity(AnimatedSprite) you can use them for movement like
final Entity playerEntity = ...;//Get player entity here.
final float jumpDuration = 2;
final float x= playerEntity.getX();
final MoveXModifiermoveModifier = new MoveXModifier(jumpDuration / 2, x+ 100, y);
playerEntity.registerEntityModifier(moveModifier );

It's not necessary to have two background moving at different speeds. With one fixed background and one "moving" background you will notice the effect when the player moves. However, I've tried setting an absolute value in
parallaxBackground.setParallaxValue(10f);
And the effect was not continuous. What it worked for me was a recipe found in Android Cookbook which is based on overriding the onUpdate of the background to change only when the camera has moved.
ParallaxBackground background = new ParallaxBackground(0.3f, 0.3f,0.9f) {
/* We'll use these values to calculate the parallax value of the background*/
float cameraPreviousX = 0;
float parallaxValueOffset = 0;
/* onUpdates to the background, we need to calculate new
* parallax values in order to apply movement to the background
* objects (the hills in this case) */
#Override
public void onUpdate(float pSecondsElapsed) {
/* Obtain the camera's current center X value */
final float cameraCurrentX = mCamera.getCenterX();
/* If the camera's position has changed since last update... */
if (cameraPreviousX != cameraCurrentX) {
/* Calculate the new parallax value offset by subtracting the previous update's camera x coordinate from the current update's camera x coordinate */
parallaxValueOffset += cameraCurrentX - cameraPreviousX;
/* Apply the parallax value offset to the background, which will in-turn offset the positions of entities attached to the background */
this.setParallaxValue(parallaxValueOffset);
/* Update the previous camera X since we're finished with this update */
cameraPreviousX = cameraCurrentX;
}
super.onUpdate(pSecondsElapsed);
}
};
background.attachParallaxEntity(new ParallaxEntity(5, hillFurthest));
Note than depending on the camera configuration, the "5" value included in the "attachParallaxEntity" may need to be negative. Otherwise, the background will move in the opposite direction of the player.

Related

LibGDX using Animations with a skin (for drag n' drop)

I have set up a game where Actor fireflies randomly fly across the screen, while glowing on and off — and a user can drag them into a mason jar. Pretty happy I've got this working, but I'd like to add a bit more detail. I'd like to add a two-step animation so that it looks like their wings are flapping.
I know how to do this with the Animation class, making use of TextureAtlas and TextureRegion. But that was prior to me heading in this Drag n Drop direction.
My issue, I think, is that I'm using skins, and they might not play nice with Animations.
///////////////////
Portions of my code.
///////////////////
Some of the items I declare up top:
private TextureAtlas textureAtlas;
private Texture texture;
private TextureRegion[] regions = new TextureRegion[3];
private Animation ffFlapping;
Setting up my TextureAtlas:
textureAtlas = new TextureAtlas(Gdx.files.internal("Player Animation/player_animation.png.atlas"));
texture = new Texture(Gdx.files.internal("Player Animation/player_animation.png.png"));
Setting up the skin:
final Skin skin = new Skin();
skin.addRegions(textureAtlas);
Doing the animation:
TextureRegion[] ffAnimation = new TextureRegion[2];
ffAnimation[0] = (textureAtlas.findRegion("firefly-0"));
ffAnimation[1] = (textureAtlas.findRegion("firefly-1"));
ffFlapping = new Animation(0.01f, ffAnimation);
For loop to create all my fireflies:
// ********************************************
// iterate through the number of fireflies
// we want to draw out using fireflyCount
// ********************************************
for (int fireflyIndex = 0; fireflyIndex < fireflyCount; fireflyIndex++) {
// YELLOW FIREFLY HERE
String fireflyName = "firefly" + fireflyIndex;
// if I replace ffFlapping below with object, I get no errors,
// but also no animation
skin.add(fireflyName, ffFlapping);
final Firefly ff = new Firefly(skin, fireflyName);
System.out.println("Fireflies objects:" + fireflyIndex);
// Not sure this affected the color, but it starts the alpha at 0
ff.setColor(150, 150, 150, 0);
ff.setOrigin(ff.getWidth()/2, ff.getHeight()/2);
stage.addActor(ff);
// This was set up in the attempt to continue movement if user misses target
final MoveToAction actionRight = new MoveToAction();
final MoveToAction actionLeft = new MoveToAction();
// setting up right and left targets, with a random Y position
float toRight = Gdx.graphics.getWidth() + 60;
float toLeft = (Gdx.graphics.getWidth() -Gdx.graphics.getWidth())-60f;
// sets up speed of glow, and the random time firefly is off, and also on
float glow = MathUtils.random(.5f, 1f);
float delayRandomOff = MathUtils.random(2.3f, 4.5f);
float delayRandomOn = MathUtils.random(.5f, .9f);
// sets up first variable to randomly choose between toRight and toLeft
// assigns direction to that value
float randomDirection = MathUtils.random.nextBoolean() ? toRight : toLeft;
float direction = randomDirection;
SequenceAction sequence = new SequenceAction();
AlphaAction aa = new AlphaAction();
Action alphaStartOn = Actions.delay(delayRandomOn, Actions.fadeOut(glow));
Action alphaStartOff = Actions.delay(delayRandomOff, Actions.fadeIn(glow));
// toRight is the x value ... it goes (x, y, duration)
Action startRight = Actions.moveTo(toRight, MathUtils.random(50, Gdx.graphics.getHeight() - 40), MathUtils.random(10f, 45f));
// toLeft is the x value ... it goes (x, y, duration)
// 170 makes sure they don't fly on top of mason jar
Action startLeft = Actions.moveTo(toLeft, MathUtils.random(170, Gdx.graphics.getHeight() - 40), MathUtils.random(10f, 45f));
Action faceOpposite = Actions.rotateBy(180f);
Action faceOpposite2 = Actions.rotateBy(180f);
// THIS ENDLESSLY LOOPS THEM ON THE SCREEN
Action loopRight = Actions.forever(Actions.sequence(faceOpposite, startRight, faceOpposite2, startLeft));
Action loopLeft = Actions.forever(Actions.sequence(startLeft, faceOpposite, startRight, faceOpposite2));
Action loopGlow1 = Actions.forever(Actions.sequence(alphaStartOn, alphaStartOff));
Action loopGlow2 = Actions.forever(Actions.sequence(alphaStartOff, alphaStartOn));
// THIS IS DEFINITELY TRIGGERING THE MOVEMENT
if(direction == toRight) {
ff.addAction(loopRight);
ff.addAction(loopGlow1);
} else {
ff.addAction(loopLeft);
ff.addAction(loopGlow2);
}
// MAKE EACH FIREFLY DRAGGABLE, and SET LARGER SIZE as you drag
dragAndDrop.addSource(new DragAndDrop.Source(ff) {
public DragAndDrop.Payload dragStart (InputEvent event, float x, float y, int pointer) {
DragAndDrop.Payload payload = new DragAndDrop.Payload();
payload.setObject("Firefly captured");
payload.setDragActor(ff);
ff.clearActions();
getActor().setSize(80, 80);
// Firefly freezes on drag, and enlarges ... disappears if dropped in jar
// Does not visually drag with cursor since it was part of animation.
return payload;
}
// IF YOU DON'T DROP FIREFLY ON TARGET, MAKE SURE IT STAYS ON STAGE
// AND GOES BACK TO THE NORMAL SIZE
#Override
public void dragStop(InputEvent event, float x, float y, int pointer, DragAndDrop.Payload payload, DragAndDrop.Target target) {
if(target == null)
stage.addActor(ff);
ff.addAction(actionLeft);
getActor().setSize(50, 50);
}
});
// MAKE EACH FIREFLY DRAGGABLE, and SET LARGER SIZE as you drag
dragAndDrop.addSource(new DragAndDrop.Source(ff) {
public DragAndDrop.Payload dragStart (InputEvent event, float x, float y, int pointer) {
DragAndDrop.Payload payload = new DragAndDrop.Payload();
payload.setObject("Firefly captured");
payload.setDragActor(ff);
ff.clearActions();
getActor().setSize(80, 80);
// Firefly freezes on drag, and enlarges ... disappears if dropped in jar
// Does not visually drag with cursor since it was part of animation.
return payload;
}
// IF YOU DON'T DROP FIREFLY ON TARGET, MAKE SURE IT STAYS ON STAGE
// AND GOES BACK TO THE NORMAL SIZE
#Override
public void dragStop(InputEvent event, float x, float y, int pointer, DragAndDrop.Payload payload, DragAndDrop.Target target) {
if(target == null)
stage.addActor(ff);
ff.addAction(actionLeft);
getActor().setSize(50, 50);
}
});
} // ***** END OF FOR LOOP ***********
And here's my Firefly code:
public class Firefly extends Image {
private float x = MathUtils.random(20, Gdx.graphics.getWidth() -40);
private float y = MathUtils.random(200, Gdx.graphics.getHeight() - 40);
private float width = 70;
private float height = 70;
public Firefly(Skin skin, String drawableName) {
super(skin, drawableName);
this.setBounds(x, y, width, height);
}
} // firefly
The error I'm getting is:
com.badlogic.gdx.utils.GdxRuntimeException: No Drawable, NinePatch, TextureRegion, Texture, or Sprite registered with name: firefly-2
///////////////////////////////
Any tips are very much appreciated.
In the meantime, I'm creating a new feature branch and keeping at it.
My guess is that I need to somehow make my two-step animation into some kind of Drawable.
Thanks!
— Bill

How do I set visibility of each shape in the array for a given amount of time?

So I am using the libgdx framework and am new to android games development. I have an array of yellow circle objects stored in each index which are shown on the game screen when I run them, all the circle objects are in different x positions but on the same y axis. I want to basically set the visibility of each circle for a given amount of time before the next one becomes visible for say 1000 ms per circle. So for example circle 1 will be visible for 1000 ms then it will become invisible and circle 2 will then become visible for 1000ms so on and so forth, till I reach the end of the list.
public class Spot {
private float x;
private float y;
private float radius;
private Circle spot;
private Circle spotList[];
public Spot(float x, float y, float radius, int amount){
this.x = x;
this.y = y;
this.radius = radius;
spot = new Circle(x,y,radius);
spotList = new Circle[amount];
for(int i = 0; i < spotList.length; i++){
spotList[i] = new Circle(this.x+(i*15), this.y, this.radius);
}
}
public void update(float delta){
}
public Float getX(){
return x;
}
public Float getY(){
return y;
}
public float getRadius(){
return radius;
}
public Circle[] getSpots(){
return spotList;
}
public Circle getSpot(){
return spot;
}
}
The rendering of the shape has been outsourced to a different class I want to be able to handle the visibility of the circles etc in the update method.
Since you're not using Actors (https://github.com/libgdx/libgdx/wiki/Scene2d), you need to keep track of time yourself and make the circles visible/not visible.
You will want to add
private float elapsedTime = 0.0f;
private float currentCircle = 0;
two fields, one for keeping track of elapsed time and one for the currently visible circle.
public void update(float delta){
elapsedTime += delta;
if (elapsedTime >= 1.0f) { // more than one second passed
spot[currentCircle].setVisible(false);
if (currentCircle + 1 < spotList.size()) {
currentCircle++;
spot[currentCircle].setVisible(true);
elapsedTime -= 1.0f; // reset timer (don't just set to 0.0f to avoid time shifts)
}
}
}
In the update method, count elapsedTime and if more then one seconds passed, make old circle not visible and new circle visible. Also make sure that initially the first circle is visible and that the timer is 0.
A possible solution is to use the Universal Tween Engine which works well with the libGDX framework. Visit the link to see how to include it in your project and for documentation.
As a quick demonstration on how to use it:-
Create and instantiate a TweenManager and your array of Spots in your class responsible for rendering.
protected TweenManager tweenManager = new TweenManager();
Spot spots[] = new Spot[...];
...
Create your timer by implementing the TweenCallback()
final int numberOfSpots = 5;
int spotArrayIndex = 0;
float timeDelay = 1000f; /*1000 milliseconds*/
Tween.call(new TweenCallback() {
#Override
public void onEvent(int type, BaseTween<?> source) {
/*set or unset the visibility of your Spot objects here i.e. */
spots[spotArrayIndex++].setVisible(false); /*Set current spot invisible*/
spots[spotArrayIndex].setVisible(true); /*Set next spot to be visible*/
}
}).repeat(numberOfSpots, timeDelay).start(tweenManager);
Update the tweenManager in your render method
public void render(float delta) {
...
tweenManger.update(delta);
...
}
Please check the code for errors if you use it, as I am not sure of the rest of your code.

Pause/Resume a Simple Libgdx Game for android

Presently I'm trying to implement simple game using libgdx for Android Platform. I have implemented the game but don't know how to pause and resume game based on user input.Kindly suggest idea as well as some practical code to implement the same.I am using simple game code demonstrated in libgdx library. Thank you.
Here is the code :
public class Drop implements ApplicationListener {
Texture dropImage;
Texture bucketImage;
Sound dropSound;
Music rainMusic;
SpriteBatch batch;
OrthographicCamera camera;
Rectangle bucket;
Array<Rectangle> raindrops;
long lastDropTime;
#Override
public void create() {
// load the images for the droplet and the bucket, 64x64 pixels each
dropImage = new Texture(Gdx.files.internal("droplet.png"));
bucketImage = new Texture(Gdx.files.internal("bucket.png"));
// load the drop sound effect and the rain background "music"
dropSound = Gdx.audio.newSound(Gdx.files.internal("drop.wav"));
rainMusic = Gdx.audio.newMusic(Gdx.files.internal("rain.mp3"));
// start the playback of the background music immediately
rainMusic.setLooping(true);
rainMusic.play();
// create the camera and the SpriteBatch
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
batch = new SpriteBatch();
// create a Rectangle to logically represent the bucket
bucket = new Rectangle();
bucket.x = 800 / 2 - 64 / 2; // center the bucket horizontally
bucket.y = 20; // bottom left corner of the bucket is 20 pixels above the bottom screen edge
bucket.width = 64;
bucket.height = 64;
// create the raindrops array and spawn the first raindrop
raindrops = new Array<Rectangle>();
spawnRaindrop();
}
private void spawnRaindrop() {
Rectangle raindrop = new Rectangle();
raindrop.x = MathUtils.random(0, 800-64);
raindrop.y = 480;
raindrop.width = 64;
raindrop.height = 64;
raindrops.add(raindrop);
lastDropTime = TimeUtils.nanoTime();
}
#Override
public void render() {
// clear the screen with a dark blue color. The
// arguments to glClearColor are the red, green
// blue and alpha component in the range [0,1]
// of the color to be used to clear the screen.
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// tell the camera to update its matrices.
camera.update();
// tell the SpriteBatch to render in the
// coordinate system specified by the camera.
batch.setProjectionMatrix(camera.combined);
// begin a new batch and draw the bucket and
// all drops
batch.begin();
batch.draw(bucketImage, bucket.x, bucket.y);
for(Rectangle raindrop: raindrops) {
batch.draw(dropImage, raindrop.x, raindrop.y);
}
batch.end();
// process user input
if(Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
bucket.x = touchPos.x - 64 / 2;
}
if(Gdx.input.isKeyPressed(Keys.LEFT)) bucket.x -= 200 * Gdx.graphics.getDeltaTime();
if(Gdx.input.isKeyPressed(Keys.RIGHT)) bucket.x += 200 * Gdx.graphics.getDeltaTime();
// make sure the bucket stays within the screen bounds
if(bucket.x < 0) bucket.x = 0;
if(bucket.x > 800 - 64) bucket.x = 800 - 64;
// check if we need to create a new raindrop
if(TimeUtils.nanoTime() - lastDropTime > 1000000000) spawnRaindrop();
// move the raindrops, remove any that are beneath the bottom edge of
// the screen or that hit the bucket. In the later case we play back
// a sound effect as well.
Iterator<Rectangle> iter = raindrops.iterator();
while(iter.hasNext()) {
Rectangle raindrop = iter.next();
raindrop.y -= 200 * Gdx.graphics.getDeltaTime();
if(raindrop.y + 64 < 0) iter.remove();
if(raindrop.overlaps(bucket)) {
dropSound.play();
iter.remove();
}
}
}
#Override
public void dispose() {
// dispose of all the native resources
dropImage.dispose();
bucketImage.dispose();
dropSound.dispose();
rainMusic.dispose();
batch.dispose();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
The most simple thing is, that you add an Enum:
public enum State
{
PAUSE,
RUN,
RESUME,
STOPPED
}
And modify your rendermethod
private State state = State.RUN;
#Override
public void render()
{
switch (state)
{
case RUN:
//do suff here
break;
case PAUSE:
//do stuff here
break;
case RESUME:
break;
default:
break;
}
}
Use the callback from android too. For example use the callbacks from libgdx to change the state:
#Override
public void pause()
{
this.state = State.PAUSE;
}
#Override
public void resume()
{
this.state = State.RESUME;
}
Also add something like a setMethod for the state so you can change it on userevent.
public void setGameState(State s){
this.state = s;
}
You can use states, with enums or constants. and only update in the Running state. Something like this:
public enum State{
Running, Paused
}
State state = State.Running;
#Override
public void render(){
switch(state){
case Running:
update();
break;
case Paused:
//don't update
break;
}
draw();
}
public void update(){
//your update code
}
public void draw(){
//your render code
}
I don't have the rep to reply to comments, but the flickering of items is something I ran into before.
You are no longer clearing the screen and redrawing the sprites in your render when its paused right? If I am not mistaken if you glClear and redraw the srpites in every render i think it will stop
Even more simple, see here: https://github.com/libgdx/libgdx/wiki/Continuous-&-non-continuous-rendering
In your ApplicationListener's create method, just put
Gdx.graphics.setContinuousRendering(false);
Gdx.graphics.requestRendering();
Set up a boolean
public boolean paused = false;
Then for example a button listener to pause/resume on a button press
buttonPause.addListener(new ChangeListener() {
public void changed (ChangeEvent event, Actor actor) {
// set paused true or false here
}
});
Then right at the end of your render method, just add:
if (!paused) {
Gdx.graphics.requestRendering();
}
The render method is now paused/resumed.
I tried using this approach:
I made GAME_PAUSED a boolean , If it is true don't update your screen or camera . Otherwise update Camera .
boolean GAME_PAUSED = false;
if (GAME_PAUSED) {
//Do not update camera
batch.begin();
resumeButton.draw(batch);
batch.end();
} else {
//Update Camera
Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(1/60f, 8, 3);
camera.update();
debugRenderer.render(world, camera.combined);
//Do your game running
}

Andengine - Shooting bullets in front of a rotating sprite (Turret / Ship)

I'm making a game with Andengine and i'm stuck for 2 days on shooting from a rotating sprite. I'm not a hero at geometry and already ask a teacher but he could also not provide me the correct answer. So who is a mathematics hero and help me out :).
The problem is that i cannot figure out where the bullet has to spawn in front of the turret. Rotating and finding the destination where the bullet has to go is no problem. It only about the spawn point.
I removed a lot of not-interesting-code for this question.
Okay so here is the rotating code from the turret-rotation:
public class AlienShip extends Ship {
public static final float BASE_ROTATION_SPEED = 0.25f;
public static final int DEFAULT_IMAGE_ROTATION = 90; //90 degrees
protected PlayerShip ship;
public AlienShip(float pX, float pY, TextureRegion pTextureRegion,
VertexBufferObjectManager pVertexBufferObject,FixedStepPhysicsWorld pw, int baseDurability) {
super(pX, pY, pTextureRegion, pVertexBufferObject, pw, baseDurability);
}
public void rotateToPlayer()
{
if (ship != null) {
float dX = this.getX() - ship.getX();
float dY = this.getY() - ship.getY();
float angle = (float) Math.atan2(-dY, dX);
float rotation = MathUtils.radToDeg(angle) + DEFAULT_IMAGE_ROTATION;
RotationModifier rotMod = new RotationModifier(BASE_ROTATION_SPEED, this.getRotation(), rotation);
this.registerEntityModifier(rotMod);
}
}
public void rotateToInitPos() {
RotationModifier rotMod = new RotationModifier(BASE_ROTATION_SPEED, this.getRotation(), 0);
this.registerEntityModifier(rotMod);
}
}
The code above is working fine.
Here is the code from the laser that the ship is shooting.
Read the comments to find out witch part is not working.
public class GameScene extends Scene {
protected PlayerShip playerShip;
private SpawnCallback createShootCallback(boolean player) {
return new SpawnCallback() {
#Override
public void spawn(SpawnTimer spawnTimer) {
PhysicsSprite laser = null;
AlienShip alienShip = (AlienShip) spawnTimer.getPhysicsSprite();
// laser = alienMissilePool.getMissileFromPool(x,y)
//spawn the laser in front of the rotating ship [Not working :( ]
laser = alienMissilePool.getMissileFromPool( ( alienShip.getX() * FloatMath.cos(MathUtils.degToRad(rotation)) - ((1280 - alienShip.getY() - alienShip.getY()/2) * FloatMath.sin(MathUtils.degToRad(rotation)) ) ) ,
( alienShip.getX() * FloatMath.sin(MathUtils.degToRad(rotation)) + ((1280 - alienShip.getY() - alienShip.getY()/2) * FloatMath.cos(MathUtils.degToRad(rotation)) ) ) );
//Set the rotation from the laser same to the ship rotation [Is working perfectly].
float rotation = alienShip.getRotation();
laser.setRotation(rotation);
//Set laser speed and direction [Is working perfectly]
float pX = 0.01f * (playerShip.getX() - laser.getX());
float pY = 0.01f * (playerShip.getY() - laser.getY());
laser.getSpriteBody().setLinearVelocity(pX, pY);
spawnPhysicsSprite(laser);
}
};
}
}
Here is a link to a drawing that shows the x-axis and y-axis values.
http://s24.postimg.org/citz29339/gamescene.png
Thank you!
Instead of getting into maths, why don't you put an object (Entity) positioned on the place of the turret and use it's position as the spawn point for the laser ?
so your turret would have an Entity attached to it on the place of the gun.
tell me if you need an example code

Only want one sprite to animate, instead they all do. Andengine

I'm creating an android app using Andengine. One part of the app requires users to select a few sprites from a group of sprites on the screen, which causes the selected sprites to turn a different color (ie, moving to the next tile). I declared them all as animated sprites and I'm using the same texture for each one. The problem is that once I select a sprite, every sprite moves to the next tile, not just the one I selected. How do I make just the one sprite change?
Here's where I setup the textures and whatnot:
private Texture mGreenTextureAtlas;
private TiledTextureRegion mGreenBallFaceTextureRegion;
#Override
public void onLoadResources() {
/* Textures. */
...
this.mGreenTextureAtlas = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
...
TextureRegionFactory.setAssetBasePath("gfx/");
/* TextureRegions. */
...
this.mGreenBallFaceTextureRegion = TextureRegionFactory.createTiledFromAsset(this.mGreenTextureAtlas, this, "green_ball.png", 0, 16, 2, 1); // 64x32
this.mEngine.getTextureManager().loadTextures(this.mCueTextureAtlas, this.mGreenTextureAtlas , this.mBackgroundTexture, this.mPocketTexture);
}
Here's where I actually create the sprites and apply the textures:
face = new AnimatedSprite(pX, pY, this.mGreenBallFaceTextureRegion);
body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, FIXTURE_DEF);
encapsed = new Encapsulator(body, face, Encapsulator.AVOID_BALL, mFaceCount);
ballsList.add(encapsed);
I encapsulate each sprite, it's body, and some other data into an object that I made, and then add that object into an ArrayList.
Here is the onTouch event handler.
#Override
public boolean onAreaTouched( final TouchEvent pSceneTouchEvent, final ITouchArea pTouchArea,final float pTouchAreaLocalX, final float pTouchAreaLocalY) {
if(pSceneTouchEvent.isActionDown()) {
final AnimatedSprite face = (AnimatedSprite) pTouchArea;
for(int i=0; i<ballsList.size(); i++)
{
if(face.equals(ballsList.get(i).animatedFace))
{
ballsList.get(i).toggleType(face);
System.out.println("Ball " + ballsList.get(i).id + " is now " + ballsList.get(i).type);
}
}
return true;
}
return false;
}
Finally, here is the toggleType method in the Encapsulator class that's responsible for moving to the next tile:
public void toggleType(AnimatedSprite face)
{
if(this.type == AVOID_BALL)
{
this.type = HIT_BALL;
face.nextTile();
}
else if(this.type == HIT_BALL)
{
this.type = AVOID_BALL;
face.setCurrentTileIndex(0);
}
}
Sorry if this is a bit long-winded. Any help is appreciated.
I did some more googling and came across a solution. I had to use the textureregion.clone() method when creating the sprites. I found the solution at this link:
http://www.andengine.org/forums/development/two-sprites-sharing-the-same-tiledtextureregion-t4339.html

Categories

Resources