1
\$\begingroup\$

I'm currently learning to code 2d games in Libgdx. Right now I'm making a kind of worms clone. I am using Box2d and have just my main sprite and a flat ground object so far.

What im stuck on is making the crosshair for the main character which I would like to rotate around him at a distance of say 90px when the player presses UP or DOWN key.

Here is the code I have so far but I havent even been able to attempt the rotation code at all:

package com.supermegabrobro.apoca.Sprites;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.supermegabrobro.apoca.Screens.PlayScreen;

    public class ArmyDude extends Sprite {
PlayScreen playScreen;
BodyDef bodyDef;
Body body;
FixtureDef fixtureDef;

boolean crossHairShowing = false;

Texture crossHairTexture;
float crossHairDistance = 30f;
float crossHairAngle = 45f;
Vector2 crossHairPosition;


public ArmyDude(PlayScreen playScreen){
    super(new Texture("armydude.png"));
    this.playScreen = playScreen;
    bodyDef = new BodyDef();
    bodyDef.type = BodyDef.BodyType.DynamicBody;
    bodyDef.position.set(0,0);   // TODO: Make this random

    body = playScreen.world.createBody(bodyDef);
    CircleShape circleShape = new CircleShape();
    circleShape.setRadius(getWidth() / 2);
    fixtureDef = new FixtureDef();
    fixtureDef.shape = circleShape;
    body.createFixture(fixtureDef);

    crossHairTexture = new Texture("crosshair.png");
    crossHairPosition = new Vector2(0,0);





}

public void update(float dt){
    setPosition(body.getPosition().x - getWidth() / 2, body.getPosition().y - getHeight() / 2);

    if(Gdx.input.isKeyPressed(Input.Keys.UP)){
        crossHairShowing = true;
    }
}


@Override
public void draw(Batch batch) {
    super.draw(batch);
    if (crossHairShowing){

    }
}
}

Any help is massively appreciated thanks. (nb. I have read up on, and implemented in previous projects, normal rotation of sprites. But I beleive this is very different since I am trying to not rotate the actual sprite but instead draw a texture (of a crosshair) that rotates around this sprite.

I'm really stuck though my poor brain can't figure it out alone :(

\$\endgroup\$
1
\$\begingroup\$

Usually problems like this can be solved by using vector geometry. With the basic ideas of vectors, problems relating to the coordinate system can be much easier solved.

For your game the steps would be:

  1. Create angle and crosshairVector at the constructor

    float angle = 45f;
    Vector2 crosshairVector = new Vector2;
    
  2. In your method to get the crosshair position get the vector position of the player.

    Vector2 playerVector = new Vector2(getX(), getY());
    
  3. Create a vector with a length of the desired distance between player and crosshair.

    Vector2 distanceVector = new Vector2(90, 0);
    
  4. Rotate the vector by the value of the angle variable.

    distanceVector.setAngle(angle);
    
  5. Add both vectors together to get the position vector of the crosshair.

    crosshairVector = playerVector.add(distanceVector);
    

Now you have the position of the crosshair in the Vector crosshairVector. With crosshairVector.x and crosshairVector.y you get the x and y values. To rotate the crosshair simply change the angle variable.

If you want to know more about the basics of vectors you can have a look on: https://www.mathsisfun.com/algebra/vectors.html

\$\endgroup\$
  • \$\begingroup\$ Note that if you work with a language/framework that doesn't support setting an angle to a vector, use the cos and sin of the angle to get the position: crosshairVector = playerVector + new Vector2(Cos(angle),Sin(angle)) * crosshairDistance \$\endgroup\$ – Felsir Nov 11 '16 at 10:39
  • \$\begingroup\$ thank you for the indepth answer. I am not at home now but will try to implement this when i am back. One thing though, I had already managed (since posting question) to create them variables and make the crosshair position relative to the player vector. But Im unsure of the code to use when person presses UP or DOWN key. Im using libgdx java and I think it does support angle and has some rotation method but i can only know how to make the sprite itseld rotate at the moment. \$\endgroup\$ – Big T Larrity Nov 11 '16 at 16:28
  • \$\begingroup\$ Thanks also Felsir as I will try to use Cos and Sin together with Hunter99 answer above and I think it may just have clicked in my head. Hopefully when i get home I can find out :) \$\endgroup\$ – Big T Larrity Nov 11 '16 at 16:30
  • \$\begingroup\$ My answer is written for LibGDX so you don't necessarily need to use Felsirs line of code because LibGDX will do the same with distanceVector.setAngle(angle); \$\endgroup\$ – Hunter99 Nov 11 '16 at 18:43
  • \$\begingroup\$ by the way, thank you again for the answer Hunter99. I have now got it working and your answer was basically a full walkthrough. \$\endgroup\$ – Big T Larrity Nov 13 '16 at 23:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.