views:

142

answers:

4

I am trying to make a UIImageView move when I tap a button. I have set a UIIAction to start an NSTimer. When tap the button, the character(UIImageView) moves fine. When I tap the same button again, the character speeds up and so forth so eventually he is moving a billion mph. How do I solve this? Here is the code:

(void)animateCharRight:(NSTimer *)theTimer 
{

    float speed;

    if (speed > 10.0f) 
    {

        speed = 10.0f;

    } 
    else 
    {

        speed = 10.0f;

    }

    CGRect rect = [character frame];
    rect.origin.x += speed;
    [character setFrame:rect];
}

Also, when you press the opposite button after you already pressed one it bugs up because there is no cancelation of the other timer. How do I do that?

How do I access the key up event? I cant seem to find it.

A: 

I think you problem is that you are not setting the speed back to zero when you release the key to move. You should either reset as soon as the keyup event fires or if you'd like the character to keep moving for a little while after you release the key you can set the speed to zero after the time has expired with a timer.

Caleb Thompson
+1  A: 

Well you declare speed in your method and do not set it to anything. So it is always going to the else setting the speed to 10.0f. Because in both your if and else you are setting it to 10, so what is the point of the if statement?

Then you rect.origin.x += speed; or add 10 the origin all the time, no exceptions. It is the same as doing rect.origin.x += 10; The image will constantly move.

The speed is always going to be 10, and always add to the rect.origin.x do you want to make speed a instance variable rather than just in the method?

EDIT

Because speed is declared in the method each time it has 0 as a value. Then it is set to 10. If you create speed as a member variable, then each time animateCharRight is called you can do something like

speed += speedIncrementAmount;

or

speed += 1.0f;

Meaning each time the speed is increased by 1 unit or what you need for your game.

Then the you would need a couple of checks depending on your logic.

if (speed > 10.0f) 
{
    // This will clamp the speed at 10.0f;
    speed = 10.0f;
}

if (speed < - 10.0f) 
{
    // This will make sure you will never go left to quickly
    speed = - 10.0f;
}

The above if statements may work or might not. Depends on the use. If the game is a side scooler and you only want to move to the right then you might want to make sure the speed is never less than 0.

Think about the design you want.

Since you are new to game programming I would start with a Tutorial and build upon the skills learned in the tutorial. Here is a link to one I found in a quick Google search.

Remember nobody makes Doom as there first game. Everybody starts with a Brick Breaker rip off or Tetris, it is the 'Hello World' of game programming.

David Basarab
I'm new to game programming so this may be garbage, but everytime you tap the button the character gains speed. I assume that 10.0f is being added to the speed variable every tap. So I am checking to see if "speed" is more than 10 and if so, set it back down to 10. And if it's not make it 10. Please correct me if this is totally wrong because like I said, I'm pretty new to all of this.
allthewayapps
@Tate Allen: See my edit.
David Basarab
Thank you david. That helped. But now how would I invalidate the opposite timer when the other timer is activated to prevent the character from jumping around?
allthewayapps
+2  A: 

Sounds like you might be starting a new timer on each button tap. So after 2 taps you now have 2 timers, each of which will call -animateCharRight: to move your view 10, for a total of 20. More taps, faster, and so on. Is that what's going on?

Jim
Yes that is what is going on I believe. Where would I put the [timer invalidate] method and what would I replace "timer" with?
allthewayapps
A: 

That method will always move your character by 10. However, it seems that you are starting a new timer every time the button is pressed. So if you press the button 3 times, the character moves 3x10=30. You need to cancel the existing timer so there is always only one running.

You can cancel an NSTimer instance using [timer invalidate]. (See here)

Colin Gislason