solved libgdx rotation (Sprite, Animation) array issues

hi people,
well i am a noob at java and libgdx. i got the homing bullet working with the help of “BurntPizza” great programmer and helps alot.
now i am smashing my head as to how i can make it rotate so it faces the ball (which is the main character) when it goes around it or when it is coming towards it. the bullet is facing <— (left) and the code below is what i have done so far. also i used sprites for the bullet and also animation method.

Also how do i make it an array/arraylist which is best so i can have multiple bullets at random or placed places. i tried many things nothing worked :frowning:

examples would be great and will be repped.

thank you for the help.

// below is the bullet or enemy if you want to call it.


public class Bullet extends Sprite {

public static final float BULLET_HOMING = 6000; 
public static final float BULLET_SPEED = 300; 
private Vector2 velocity;
private float lifetime;


public Bullet(float x, float y) {
 velocity = new Vector2(0, 0);
 setPosition(x, y);
}

public void update(float delta) {
 float targetX = GameWorld.getBall().getX();
 float targetY = GameWorld.getBall().getY();
 float dx = targetX - getX();
 float dy = targetY - getY();

 float distToTarget = (float) Math.sqrt(dx * dx + dy * dy); 
 dx /= distToTarget;
 dy /= distToTarget;
 dx *= BULLET_HOMING;
 dy *= BULLET_HOMING;
 velocity.x += dx * delta;
 velocity.y += dy * delta;

 float vMag = (float) Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
 velocity.x /= vMag;
 velocity.y /= vMag;
 velocity.x *= BULLET_SPEED;
 velocity.y *= BULLET_SPEED;

 Vector2 v = velocity.cpy().scl(delta);
 setPosition(getX() + v.x, getY() + v.y);
 setOriginCenter(); 
 setRotation(velocity.angle());
 lifetime += delta;
 setRegion(AssetLoader.bulletAnimation.getKeyFrame(lifetime));
 }
}

// this is where i load the images.


public class AssetLoader {
public static Animation bulletAnimation;
public static Sprite bullet1, bullet2;

public static void load() {

texture = new Texture(Gdx.files.internal("SpriteN1.png"));
texture.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);

bullet1 = new Sprite(texture, 380, 350, 45, 20);
bullet1.flip(false, true);

bullet2 = new Sprite(texture, 425, 350, 45, 20);
bullet2.flip(false, true);

Sprite[] bullets = { bullet1, bullet2 };
bulletAnimation = new Animation(0.06f, aims);
bulletAnimation.setPlayMode(Animation.PlayMode.LOOP);
}

public static void dispose() {
// We must dispose of the texture when we are finished.
texture.dispose();
}

// this is for the rendering of the images etc


public class GameRenderer {
private Bullet bullet;
private Ball ball;

public GameRenderer(GameWorld world) {
myWorld = world;
cam = new OrthographicCamera();
cam.setToOrtho(true, 480, 320);

batcher = new SpriteBatch();
// Attach batcher to camera
batcher.setProjectionMatrix(cam.combined);

shapeRenderer = new ShapeRenderer();
shapeRenderer.setProjectionMatrix(cam.combined);

// Call helper methods to initialize instance variables
initGameObjects();
initAssets();
}

private void initGameObjects() {
ball = GameWorld.getBall();
bullet = myWorld.getBullet();
scroller = myWorld.getScroller();
}

private void initAssets() {
ballAnimation = AssetLoader.ballAnimation;
bulletAnimation = AssetLoader.bulletAnimation;
}

public void render(float runTime) {

Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);

batcher.begin();
// Disable transparency 
// This is good for performance when drawing images that do not require
// transparency.
batcher.disableBlending();

// The ball needs transparency, so we enable that again.
batcher.enableBlending();


batcher.draw(AssetLoader.ballAnimation.getKeyFrame(runTime), ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());

batcher.draw(AssetLoader.bulletAnimation.getKeyFrame(runTime), bullet.getX(), bullet.getY());

// End SpriteBatch
batcher.end();
}
}

// this is to load the image etc on the screen i guess


public class GameWorld {

public static Ball ball;
private Bullet bullet;
private ScrollHandler scroller;

public GameWorld() {
ball = new Ball(480, 273, 32, 32);
bullet = new Bullet(10, 10);
scroller = new ScrollHandler(0);
}

public void update(float delta) {
ball.update(delta);
bullet.update(delta);
scroller.update(delta);
}

public static Ball getBall() {
return ball;
}

public ScrollHandler getScroller() {
return scroller;
}

public Bullet getBullet() { 
return bullet;
}
}

so there is the whole thing. the images are loaded via the AssetLoader then to the GameRenderer and GameWorld via the Bullet class. i am guessing that is how it is. sorry newbie so still learning.

thank you in advace for the help or any advice.

i know this might be a silly question but any help will be nice
and also a CHALLENGE for the top programmers who are Titans amonst us

As English is not my main language I’m not sure if is this what you are asking, but to get the rotation angle to point to other vector you can use

double angle=MathUtils.atan2(vector1.y - vector2.y, vector1.x - vector2.x)

The angle is returned in radians, if you need it in degrees, MathUtils has a method to transform it.

For the other question about having multiple bullets, enemies,… , use the Pool class in libgdx.

Follow what Endos said, then you can use that angle and call [icode]bullet.setRotation(MathUtils.toDegrees(angle))[/icode];

If you’re just learning Java, then don’t try to make a game yet, just learn the language first.

this solved my problem two days ago :




yourBulletAngle = target.sub(position).angle();

//target is a Vector2 which contain the target position
//position is also a Vector2 that contain your bullet position

but i don’t have a bullet angle or Vector2 position???
so now do i have to create them and amend my code?
thanks

The LibGDX class Sprite, which your bullet class extends, contains a position vector and an angle variable.

float x,y;

Vector2 position = new Vector2(x,y);

You don’t need a vector, I put it only as a reference to help you understand how it works.
“vector1.y - vector2.y” is “dy”, and “vector1.x - vector2.x” is “dx” in your code.

So, at the end, is something like this:


float targetX = GameWorld.getBall().getX();
float targetY = GameWorld.getBall().getY();
float dx = targetX - getX();
float dy = targetY - getY();
float angle=MathUtils.toDegrees(MathUtils.atan2(dy,dx)); // <-----
...
setRotation(angle);

I suggest you to learn Java better before attempting to make a game like this. You are a bit lost in basic things.

i just checked the code and the problem is not what i thought.

its the sprite. it is not being drawn on the screen if i do this


bullet.draw(batcher);

even if i do this


batcher.draw(AssetLoader.bulletAnimation.getKeyFrame(runTime), bullet.getX(), bullet.getY(), bullet.getOriginX() / 2, bullet.getOriginY() / 2, bullet.getWidth(), bullet.getHeight(), 1, 1, bullet.getRotation());

i have tried amending the code but for some reason the only way it draws the bullet is


batcher.draw(AssetLoader.bulletAnimation.getKeyFrame(runTime), bullet.getX(), bullet.getY());

that is it??? for some reason the bullet wont draw unless i use that method and that is the reason for it not to turn.
i used the bullet1 and bullet2 in the AssetLoader class for a Sprite[] and used Animation to make it loop.
could that be it?

is there another way aroung that maybe?

thank you

ps. sorry just i am very slow in processing information so hence i might come of as stupid.
just saying
please dont take me wrong.
thank you

isn’t this because your bullets sprite array is a local variable of the Load class ?

but as you can see i make a new bullet object and bulletAnimation and use that in the batcher.draw() method.
that is in the GameRenderer class.

i dont mind re doing all my code if this makes it work.

any suggestions.

thank you

But you are not calling the load method of the AssetsLoader class anywhere, so you are using an empty variables

i have tried that it does not work as if you call the method then the GameRenderer class will call everything in the load method.
i tried many forms.
i cannot access the fields via the load() method.
only the declared ones as objects.

anyone got any other thoughts or solutions???

thank you

i went through your code again and it seems that you are also not calling the bullet update method, and also the “structure” of some of your classes seems to be “wrong” (other members will confirm) for example in your bullet Class, why there is Final fields ? and why there is no getters/setters ?

the bullet update is being called in game world class which is being called via a get method to game Renderer class.

i tried it with one single pic sprite and still the same thing.

so i have concluded that it is the bullet class and there is no rotate method or any way the bullet will rotate so now i have to find a way to make the bullet rotate within that class and call it somehow.

i now have try and rotate it as a texture rather than a sprite.

no one has any way of doing this.

all those who tried to help a MASSIVE THANK YOU from me as you tried.

i will try and see if i can get an expert to look into this as only a professional can sort this out.

if anyone has any suggestion please feel free.

thanks

ok so got some results as now the bullet is rotating :o

just now it is backwards, as the sprite is originaly drawn facing Left <---- so now i have to figure out how to make the bullet face the target.

if anyone is good at flipping sprites when is goes towards a target that will be nice.

thank you

the code is working it’s you who is having a wrong image, by default the sprite should be headed to the right so you can just avoid all troubles and simply revert your sprite in photoshop, or you you can set your sprite xScale to -1

done ;D
i just flip it so it works now
Thank you everyone for helping and i hope i can sleep now

more issues to come…

You can also use [icode]bullet.flip(true, false);[/icode]

Why can he not use final fields? Some variables will never change and the final keyword ensures they don’t. No issue there. Getters and setters are not necessary and have nothing to do with the code working/not working. Its a design pattern that Java developers use heavily, its not necessary to use though.