-1
\$\begingroup\$

I'm trying to shoot bullets where the mouse is aiming using one image as a test. I'm trying to get the mechanics like this

I have some kind of algorithm to handle that but the results arn't too good. Can anyone help me make the bullet fly towards the mouse's exact location? My code:

public class GameScreen implements Screen{

  MyGame mg;


  SpriteBatch batch;
  Sprite s;



  float timeStep=1f/60f;
  float turretX=10f;
  float turretY=10f;
  float bulletSpeed=0.1f; 

  float bulletX=turretX;
  float bulletY=turretY;

  float dirX= 100 - turretX;
  float dirY= 100 - turretY;

  public GameScreen(MyGame mg) {
     this.mg = mg;


     float dirLength= (float) Math.sqrt(dirX*dirX + dirY*dirY);
     dirX=dirX/dirLength;
     dirY=dirY/dirLength;




  }

  @Override
  public void render(float delta) {
     Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
     update(delta);

     batch.begin();
        batch.draw(s, bulletX, bulletY);
     batch.end();

  }

  public void update(float delta) {
     if(Gdx.input.isKeyPressed(Keys.SPACE)) {
     dirX= Gdx.input.getX() - turretX;
     dirY= Gdx.input.getY() - turretY;
     }

     bulletX=bulletX+(dirX*bulletSpeed*timeStep);
     bulletY=bulletY+(dirY*bulletSpeed*timeStep);



  }

  @Override
  public void resize(int width, int height) {
     // TODO Auto-generated method stub

  }

  @Override
  public void show() {
     batch = new SpriteBatch();
      s = new Sprite(new Texture(Gdx.files.internal("HUDS/button_Back.png")));

  }

  @Override
  public void hide() {
     // TODO Auto-generated method stub

  }

  @Override
  public void pause() {
     // TODO Auto-generated method stub

  }

  @Override
  public void resume() {
     // TODO Auto-generated method stub

  }

  @Override
  public void dispose() {
     // TODO Auto-generated method stub

  }

  }
\$\endgroup\$
  • \$\begingroup\$ "How do I improve my code" type of questions aren't a good fit for this site. Is there a more specific question or specific improvement you're after? Can you explain how your current results aren't good enough? \$\endgroup\$ – ashes999 Aug 7 '14 at 21:41
  • \$\begingroup\$ @ashes999 I changed up my question for you. Hopeful I make my point properly. \$\endgroup\$ – CogWheelz Aug 7 '14 at 21:57
0
\$\begingroup\$

Try: position + directon.

The method here is called raycasting. IT can be used in various ways.

(cannonPosition & cannonDirection are vector2's)

Like. vector2 bulletPosition = cannonPosition + cannonDirection * i

Just. do:

float bulletSpeed = 0.5f;
float shootRange = Gun.getShootDistance(); /*(EG: 100)*/
float gravityConstant = 0.1f;

float gravity = 0;

vector2 bulletPosition = (vector2)null;

for(float i = 1; i < shootRange; i+=bulletSpeed)
{
    bulletPosition = cannonPosition + cannonDirection * i;

    bulletPosition.y = bulletPosition.y - gravity;

    gravity += gravityConstant;
}
\$\endgroup\$
0
\$\begingroup\$

It is actually very simple, I have this exact thing in my game. I will solve it in a pseudo code manner.

  1. Obtain the coordinates of the gun that is firing. var gunPosition;
  2. Obtain the coordinates of the target. var targetPosition;
  3. Subtract the targetPosition FROM the gunPosition and store it in a new variable. var difference;
  4. Now you can either compute the firing angle like this: atan2(difference.y/difference.x) or normalize the difference vector and use that.

    float dirLength=(float) Math.sqrt(difference.x*difference.x + difference.y*difference.y);
    dirX=difference.x/dirLength;
    dirY=difference.y/dirLength;
    

That should be the correct direction. If you would like to know how this is working, I suggest you learn a little Trigonometry. There are tons of tutorials on it on youtube.

\$\endgroup\$
-2
\$\begingroup\$

Without screenshots or an idea about where the origin and target are, and what kind of coordinates you're registering for your mouse, it's really just blind guessing on my side.

I think your problem is here:

float dirLength= (float) Math.sqrt(dirX*dirX + dirY*dirY);
dirX=dirX/dirLength;
dirY=dirY/dirLength;

You're using distance between points to get the euclidian distance between the mouse and the turret.

This is not what you want to do. You want to use either sine law or cosine law to calculate the vector's components (horizontal and vertical).

There's a good, visual example here, albeit one that uses forces. In your case, you're using distance, not force.

Once you solve that, you will have correct values for dirX and dirY. You can also scale them proportionally down if they are too large (eg. moves too fast).

\$\endgroup\$
  • \$\begingroup\$ There's nothing wrong with the code you've quoted — it's a fine way to normalize a vector, which can be used to turn a relative position into a direction. No angles need to be used. However, it does appear to be in the wrong place in that it's only executed once, not as the mouse moves. \$\endgroup\$ – Kevin Reid Aug 9 '14 at 2:34

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