4
\$\begingroup\$

I have a (turn-based) tile-based game, in which you can shoot at entities.

You can move around with mouse and keyboard, it's all tile-based, except that bullets move "freely".

I've got it all working just fine except that when I move, and the creatures shoot towards the player, they shoot towards the previous tiles.. resulting in ugly looking "miss hits" or lag.

I think I need to implement some kind of predictive firing based on the bullet speed and the distance, but I don't quite know how to implement such a thing...

Here's a simplified snip of my firing code.

class Weapon {

public void fire(int x, int y) {
  ...
  ...
  ...
  Creature owner = getOwner();
  Tile targetTile = Zone.getTileAt(x, y);

  float dist = Vector.distance(owner.getCenterPosition(), targetTile.getCenterPosition());

  Bullet b = new Bullet();
  b.setPosition(owner.getCenterPosition());

  // Take dist into account in the duration to get constant speed regardless of distance
  float duration = dist / 600f;

  // Moves the bullet to the centre of the target tile in the given amount of time (in seconds)
  b.moveTo(targetTile.getCenterPosition(), duration);

  // This is what I'm after
  // Vector v = predict the position
  // b.moveTo(v, duration);

  Zone.add(bullet); // Now the bullet gets "ticked" and moveTo will be implemented
  }
}

Movement of creatures is as simple as setting the position variable.

If you need more information, just ask.

\$\endgroup\$
1
  • \$\begingroup\$ an alternative option would be to have it fire a burst shot sometimes, so that it will at least be firing one of the shots closer to you \$\endgroup\$
    – Tom Prats
    Commented Sep 12, 2012 at 15:42

2 Answers 2

6
\$\begingroup\$

At its core you are going to have to predict which tile the target will be on.

A simple solution would be to take the current velocity of the target, figure out where the target would be in the amount of time it would take the bullet to traverse to the player (to get a rough estimate you could use the current distance to the target), and then aim at that tile.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Some games cheat by altering (a diagonal offset) the instantaneous velocity of the bullet. One of them is Age of Empires (although not tile based), where a javelin was thrown and it followed a moving character till it hit almost dead on. It was annoying to see it, but at least one wouldn't complain that the arrow fell 3 meters back and then their unit died. \$\endgroup\$
    – teodron
    Commented Sep 12, 2012 at 15:42
  • \$\begingroup\$ Your answer sounds like a nice and simple solution... but I must admit my math skills are, well... a bit rusty! A pseudo-code, or a more detailed explanation behind the - probably quite straightforward math - would be very helpful. Thanks for your time and answer! \$\endgroup\$
    – TX-256
    Commented Sep 12, 2012 at 20:45
  • 2
    \$\begingroup\$ Calculate distance from you to the player. You have the speed of the bullet, from that determine the time it'll take to reach the player (distance/speed). You have the velocity of the player. Predicted position = current player position + ( player velocity * time for bullet to hit player ). Aim at predicted position. \$\endgroup\$
    – Tetrad
    Commented Sep 12, 2012 at 21:10
  • \$\begingroup\$ OK, I got it almost working now... one more silly question though, how do I actually calculate the velocity of the player for predicting to work correctly? I currently have a simple move(Direction)-method in my player class. The turn gets processed afterwards. The player moves Tile.SIZE at a time. I tried some things, off the top my head, but they didn't work quite right; the best result got the predicting to hit 1-4 tiles ahead of the wanted tile. The predicting itself should work now, though! \$\endgroup\$
    – TX-256
    Commented Sep 13, 2012 at 22:47
  • \$\begingroup\$ I dont think the shooting angle depends on the distance. It depends only on the velocities of bullet, player and the relative angle of player with respect to the enemy. \$\endgroup\$
    – Shashwat
    Commented Sep 14, 2012 at 7:23
4
\$\begingroup\$

Sounds like ballistics technology in Age of Empires. You need to find the correct angle of fire.

         A
        | \\
        |  \ \
        |   \  \
        | vb \   \
        |     \   \
        |      \    \
        D------ B--->C
                vp

Here A = enemy
B = player current position
C = player future position
vb = speed of bullet
vp = speed of player

Hope you understood the graph. If I got the problem correct, then your enemy is shooting at B, but you want it to shoot at C.

Let angle(DAB) = o
angle(DAC) = p

Clearly,

vb*sin(o) + vp = vb*sin(p)
p = inv_sin( sin(o) + vp/vb )

Here is the angle you needed to shoot.

NOTE

I does not depend on the distance between enemy and player

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .