Trigonometry for Game Programming: Part 2/2

Discussion of the official tutorials published on raywenderlich.com. Please only discuss the official tutorials here - for general questions, use the General Discussion forum instead.

Trigonometry for Game Programming: Part 2/2

Postby rwenderlich » Thu Apr 25, 2013 11:00 am

This is the official thread to discuss the following blog post: Trigonometry for Game Programming: Part 2/2
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ray Wenderlich
Blog: http://www.raywenderlich.com
Twitter: http://twitter.com/rwenderlich
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
User avatar
rwenderlich
Team Member
Site Admin
 
Posts: 2218
Joined: Thu Dec 23, 2010 4:14 pm
Has thanked: 28 times
Been thanked: 359 times

Re: Trigonometry for Game Programming: Part 2/2

Postby Phoenix » Fri Apr 26, 2013 11:39 pm

Excellent work! Great tutorial! Not to brag, but I pretty much remember most of the Math I learned in High School!
Phoenix
Uber Haxx0r
 
Posts: 214
Joined: Wed Jun 29, 2011 7:20 pm
Has thanked: 7 times
Been thanked: 12 times

Re: Trigonometry for Game Programming: Part 2/2

Postby Will » Wed May 08, 2013 4:02 pm

Quick question although not 100% aligned with the topic of the tutorial, I have been playing around adding features like sneaky joystick instead of touch, etc to learn more about Cocos2D and trying to improve the game for it to be more fun.

I have been trying to add the capability to fire more than 1 shot at a time. To that effect I have created an array of 5 player missiles, and I check that array every time for collisions, etc. Everything compiles but keeps operating 1 shot at a time. I must have a flaw in the logic but I fail to detect where it is.

How do you normally implement a feature of keeping track of several shots at a time ? This is what I am doing:

Declaration:
Code: Select all
CCSprite *_playerMissileSprite[4];


in init:
Code: Select all
for (int i =0; i<5; i++) {
            _playerMissileSprite[i] = [CCSprite spriteWithFile:@"PlayerMissile.png"];
            _playerMissileSprite[i].visible = NO;
            [self addChild:_playerMissileSprite[i]];
        }


Checking for a hit:
Code: Select all
for (int i=0; i<5; i++) {
        if (_playerMissileSprite[i].visible)
        {
            float deltaX = _playerMissileSprite[i].position.x - _turretSprite.position.x;
            float deltaY = _playerMissileSprite[i].position.y - _turretSprite.position.y;
           
            float distance = sqrtf(deltaX*deltaX + deltaY*deltaY);
            if (distance < CannonHitRadius)
            {
                [[SimpleAudioEngine sharedEngine] playEffect:@"Hit.wav"];
               
                _cannonHP = MAX(0, _cannonHP - 10);
               
                _playerMissileSprite[i].visible = NO;
                [_playerMissileSprite[i] stopAllActions];
            }
        }
    }


Firing using sneaky button:
Code: Select all
if (attackButton.active == YES) {
       
        for (int i=0; i<5; i++) {
           
            if (!_playerMissileSprite[i].visible) {
                float angle = _playerAngle;
                _playerMissileSprite[i].rotation = 90.0f - CC_RADIANS_TO_DEGREES(angle);
               
                _playerMissileSprite[i].position = _playerSprite.position;
                _playerMissileSprite[i].visible = YES;
               
                float adjacent, opposite;
                CGPoint destination;
               
                if (angle <= -M_PI_4 && angle > -3.0f * M_PI_4) {
                    // Shoot down
                    angle = M_PI_2 - angle;
                    adjacent = _playerMissileSprite[i].position.y + Margin;
                    opposite = tanf(angle) * adjacent;
                    destination = ccp(_playerMissileSprite[i].position.x - opposite, -Margin);
                }
                else if (angle > M_PI_4 && angle <= 3.0f * M_PI_4) {
                    // Shoot up
                    angle = M_PI_2 - angle;
                    adjacent = _winSize.height - _playerMissileSprite[i].position.y + Margin;
                    opposite = tanf(angle) * adjacent;
                    destination = ccp(_playerMissileSprite[i].position.x + opposite, _winSize.height + Margin);
                }
                else if (angle <= M_PI_4 && angle > -M_PI_4){
                    // Shoot right
                    adjacent = _winSize.width - _playerMissileSprite[i].position.x + Margin;
                    opposite = tanf(angle) * adjacent;
                    destination = ccp(_winSize.width + Margin, _playerMissileSprite[i].position.y + opposite);
                }
                else  // angle > 3.0f * M_PI_4 || angle <= -3.0f * M_PI_4
                {
                    // Shoot left
                    adjacent = _playerMissileSprite[i].position.x + Margin;
                    opposite = tanf(angle) * adjacent;
                    destination = ccp(-Margin, _playerMissileSprite[i].position.y - opposite);
                }
               
               
                float hypotenuse = sqrtf(adjacent*adjacent + opposite*opposite);
                ccTime duration = hypotenuse / PlayerMissileSpeed;
               
                id action = [CCSequence actions: [CCMoveTo actionWithDuration:duration position:destination],
                             [CCCallBlock actionWithBlock:^
                              {
                                  _playerMissileSprite[i].visible = NO;
                              }],
                             nil];
               
                [_playerMissileSprite[i] runAction:action];
                [[SimpleAudioEngine sharedEngine] playEffect:@"Shoot.wav"];
               
               
            }
           
        } // for
       
    }
Will
Baby Hacker
 
Posts: 5
Joined: Wed Dec 14, 2011 2:13 pm
Has thanked: 0 time
Been thanked: 0 time

Re: Trigonometry for Game Programming: Part 2/2

Postby Hollance » Wed May 08, 2013 4:10 pm

Will wrote:I must have a flaw in the logic but I fail to detect where it is.

At first glance your code looks OK. What I would do it place some NSLog() statements here and there. For example, in the code that is supposed to first a new missile, print out the value of "i" for the missile that it fires.

Do the same thing in your update loop. This will tell you whether the sprites are really being used or not.
Like card games? Play my new game Mahjong Cards for iPad.
User avatar
Hollance
Team Member
iOS Tutorial Team Member
 
Posts: 5049
Joined: Wed Mar 09, 2011 8:33 pm
Location: The Netherlands
Has thanked: 0 time
Been thanked: 751 times

Re: Trigonometry for Game Programming: Part 2/2

Postby Will » Thu May 09, 2013 8:39 pm

Thank you !

That helped. I had a flaw in the logic.

I was firing all 5 missiles simultaneously one on top of the other. That is why it seemed just 1. It went through the loop so fast it seemed only 1.

When I fired a missile I went through the loop checking missile visibility, so 1st time through all 5 were fired, and the same happened every time.

Need to figure a more clever way to check if missile has been fired or not. Thank you again for your great tutorial
Will
Baby Hacker
 
Posts: 5
Joined: Wed Dec 14, 2011 2:13 pm
Has thanked: 0 time
Been thanked: 0 time

Re: Trigonometry for Game Programming: Part 2/2

Postby TheRealms » Sat Sep 13, 2014 6:44 pm

Brilliant tutorial thanks.

I have a question though as ive come into the tutorial mid way through. Im using a joystick which has degress from 0 to 360. Im picking up the joystick value at the point of the fire button being pressed as the angle variable, but it messes up the direction the projectile fires.

This is as far as ive got but something is seriously messed up!!


Code: Select all
      if (angle <= 135 && angle > 45)
        {
            // Shoot up

            angle = M_PI_2 - angle;
            adjacent = self.contentSize.height - _Weapon.position.y + Margin;
            opposite = tanf(angle) * adjacent;
            destination = CGPointMake(_Weapon.position.x + opposite, self.contentSize.height + Margin);
            //destination = CGPointMake(_Weapon.position.x + opposite, self.contentSize.height);
           
           
           
        }
        else if (angle > 135 && angle <= 225)
        {
            // Shoot left

            adjacent = _Weapon.position.x + Margin;
            opposite = tanf(angle) * adjacent;
            destination = CGPointMake(-Margin, _Weapon.position.y - opposite);
            //destination = CGPointMake(0,self.contentSize.height/2);

           
           
           
        }
        else if (angle > 225 &&  angle <= 315)
        {
            // Shoot down
           
            angle = M_PI_2 - angle;
            adjacent = _Weapon.position.x + Margin;
            opposite = tanf(angle) * adjacent;
            destination = CGPointMake(_Weapon.position.x - opposite, -Margin);
            //destination = CGPointMake(self.contentSize.width/2,0);

           
           
        }
        else //right
        {
            adjacent = self.contentSize.width - _Weapon.position.x + Margin;
            opposite = tanf(angle) * adjacent;
            destination = CGPointMake(self.contentSize.width + Margin, _Weapon.position.y + opposite);
            //destination = CGPointMake(self.contentSize.width,self.contentSize.height/2);


           
           
           
        }
TheRealms
n00b
 
Posts: 1
Joined: Sat Sep 13, 2014 6:43 pm
Has thanked: 0 time
Been thanked: 0 time


Return to Official Tutorials

Who is online

Users browsing this forum: No registered users and 5 guests