Projectile angled movement
armond

This is for a sidescrolling shooting game. I admit I'm such an idiot in Trig so if someone could please tell me what's wrong with this formula?

1void Vulcan::update()
2{
3 fixed fAngle = itofix(angle);
4 fixed fX = itofix(x);
5 fixed fY = itofix(y);
6
7 if (this->x < SCREEN_W)
8 {
9 switch(direction)
10 {
11 case RIGHT:
12 std::cout << "xp: " << fixtoi( fX + fcos(fAngle) + speed );
13 std::cout << "xy: " << fixtoi( fY + fsin(fAngle) + speed );
14 move( fixtoi( fX + fcos(fAngle) + speed ), fixtoi( fY + fsin(fAngle) + speed) );
15 break;
16 case LEFT:
17 move(x - speed, y);
18 break;
19 default:
20 break;
21 }
22
23 animation->animate();
24 }
25}

I'm calling the code like this...

currentWeapon->fire(RIGHT, 45);

The bullets won't appear in the screen anymore... I'm trying to make an angled shot.

EDIT:

I can't seem to make another post so I'll make the updates here.

I seem to get it working now. But why is the angle 45 now shooting at 45 degrees? As I recall from my trigonometry class, it shouldn't be going down!

Here's the not so fixed code...

1void Vulcan::update()
2{
3 fixed fAngle = itofix(angle);
4
5 int newX = 0;
6 int newY = 0;
7
8 if (this->x < SCREEN_W)
9 {
10 switch(direction)
11 {
12 case RIGHT:
13 newX = x + ( fixtoi( fcos(fAngle) ) * speed );
14 newY = y + ( fixtoi( fsin(fAngle) ) * speed );
15 std::cout << "angle: " << angle << std::endl;
16 std::cout << "oldX: " << x << std::endl;
17 std::cout << "oldY: " << y << std::endl;
18 std::cout << "newX: " << newX << std::endl;
19 std::cout << "newY: " << newY << std::endl;
20 move(newX, newY);
21 break;
22 case LEFT:
23 move(x - speed, y);
24 break;
25 default:
26 break;
27 }
28
29 animation->animate();
30 }
31}

void Ship::fireWeapon()
{
     if (currentWeapon != NULL)
     {
         currentWeapon->fire(RIGHT, 90);                       
     }
}

Ceagon Xylas

Dammit... Had my entire post typed out and then Firefox decided it wanted to go back for some reason. :'(

Okay, pretty much, use Radians instead of fixed. Get rid of the 'direction,' the angle will take care of that all by itself.

It would help much if you posted your class or struct.

void Vulcan::update() {
  //make sure angle's in range
  if(angle<0)      angle+=M_PI*2;
  if(angle>M_PI*2) angle-=M_PI*2;
  
  float newX=speed*fcos(angle); //I recommend storing your x and y
  float newY=speed*fsin(angle); //values as float too.

  move(newX,newY);

  animation->animate();
}

void Weapon::fire(float angle,float speed);

If you're worried about shooting left and right, it's only a matter of specifying the angle correctly.

if(player.fire) {
  if(player.direction==LEFT)
    currentWeapon->fire(3.14,90);
  else if(player.direction==RIGHT)
    currentWeapon->fire(0,90);
}

armond

Thank you for your suggestions! I will incorporate your ideas with my code once I solve the other problem I'm having right now with page flipping. Thanks!

ImLeftFooted
Quote:

  //make sure angle's in range
  if(angle<0)      angle+=M_PI*2;
  if(angle>M_PI*2) angle-=M_PI*2;

  //make sure angle's in range
  while(angle<0)      angle+=M_PI*2;
  while(angle>M_PI*2) angle-=M_PI*2;

Ceagon Xylas

I have been thinking about changing that all night.

armond

Hi! When I use the if version posted by Dustin Dettmer, my projectiles just go straight. When I use the while version posted by Ceagon Xylas, some of the bullets go straight and some would circle around before going straight. I just need them to be fixed on a certain angle. Let's say projectile one would move in the 45 degree angles, projectile 2 on the zero degree(or 360) angle and the third one on the 315 angle.

I reverted back the code but you could see the ones I've tried commented out.

1void Vulcan::update()
2{
3 /*
4 while (angle < 0)
5 {
6 angle += (int)(MAX_PI * 2);
7 }
8
9 while ( angle > (int)(MAX_PI * 2) )
10 {
11 angle -= (int)(MAX_PI * 2);
12 }
13 */
14
15
16 fixed fAngle = itofix(angle);
17
18 int newX = 0;
19 int newY = 0;
20
21 if (this->x < SCREEN_W)
22 {
23 newX = x + ( speed * fixtoi( fcos(fAngle) ) );
24 newY = y + ( speed * fixtoi( fsin(fAngle) ) );
25 move(newX, newY);
26
27 animation->animate();
28 }
29
30}

and the projectiles would be initialized like this(...

1void VulcanGun::fire(int a)
2{
3 if (waitCount <= 0)
4 {
5 int pfPoolSize;
6
7 switch(weaponLevel)
8 {
9 case 1:
10 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, a, hostile) );
11
12 pfPoolSize= ProjectileFactory::projectilePool.size();
13
14 ProjectileFactory::projectilePool[pfPoolSize - 1]->move(x, y);
15
16 waitCount = fireRate;
17
18 play_sample( SoundManager::getSample(VULCAN_GUN_FIRE_SFX), 255, 0, 2000, 0);
19
20 break;
21 case 2:
22 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, 45, hostile) );
23 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, a, hostile) );
24 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, 315, hostile) );
25
26 pfPoolSize= ProjectileFactory::projectilePool.size();
27
28 ProjectileFactory::projectilePool[pfPoolSize - 1]->move(x, y - 10);
29 ProjectileFactory::projectilePool[pfPoolSize - 2]->move(x, y);
30 ProjectileFactory::projectilePool[pfPoolSize - 3]->move(x, y + 20);
31
32 waitCount = fireRate;
33
34 play_sample( SoundManager::getSample(VULCAN_GUN_FIRE_SFX), 255, 0, 2000, 0);
35 break;
36 case 3:
37 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, 45, hostile) );
38 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, a, hostile) );
39 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, a, hostile) );
40 ProjectileFactory::projectilePool.push_back( ProjectileFactory::getProjectile(VULCAN, 315, hostile) );
41
42 pfPoolSize= ProjectileFactory::projectilePool.size();
43
44 ProjectileFactory::projectilePool[pfPoolSize - 1]->move(x, y - 10);
45 ProjectileFactory::projectilePool[pfPoolSize - 2]->move(x + 10, y);
46 ProjectileFactory::projectilePool[pfPoolSize - 3]->move(x + 10, y + 10);
47 ProjectileFactory::projectilePool[pfPoolSize - 4]->move(x, y + 20);
48
49 waitCount = fireRate;
50
51 play_sample( SoundManager::getSample(VULCAN_GUN_FIRE_SFX), 255, 0, 2000, 0);
52 break;
53 default:
54 break;
55 }

Are the codes you posted meant to go around in circles? Thanks!

CursedTyrant
Ceagon Xylas said:

if(player.fire) {
  if(player.direction==LEFT)
    currentWeapon->fire(3.14,90);
  else if(player.direction==RIGHT)
    currentWeapon->fire(0,90);
}

3.14 is so inaccurate...

Ceagon Xylas
if(player.fire) {
  if(player.direction==LEFT)
    currentWeapon->fire(M_PI,90);
  else if(player.direction==RIGHT)
    currentWeapon->fire(0,90);
}

Better? :-*

Quote:

When I use the while version posted by Ceagon Xylas, some of the bullets go straight and some would circle around before going straight.

Could you possibly attatch a compiled version that uses the code I posted? (So I can see what you mean)

armond

Ceagon Xylas

Sorry but I can't seem to repeat the screnario after having tweaking my code. Instead, please allow me to thank you guys by showing the effect I really wanted to have. I still don't use the real angles that I should be using but I will take a look into this thread from time to time to improve my code. Thank you guys! ;)

Please see attachment to see my progress in my game.

At the title screen:
Controls: UP, DOWN

1 = Quit Game
2 = Play

In Game:
Controls: W, A, S, D for moment and K to shoot

There is no ending for the game yet... And the first level is still very much under construction.

Ceagon Xylas

Works great for me. Good luck!

Thread #590313. Printed from Allegro.cc