moving UIImageView using UIButton

Apprentice
Posts: 8
Joined: 2010.11
Post: #1
Hi Group!

I am new to this group and to programming.
Your help is greatly appreciated!

I am getting confused with trying to move a UIImageView when a UIButton is pressed. I am Using a CADisplayLink:

Code:
- (void) initializeTimer
{
    if ( theTimer == nil )
        theTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(leftButtonPressed:)];
    theTimer.frameInterval = 2;
    [theTimer addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
}

Then, create a BOOL thats says button is down:

Code:
- (IBAction) leftButtonPressed: (id) sender
{
    BOOL leftButtonDown = YES;
    
    NSLog(@"leftButtonPressed");
}

Also, in the gameLoop see if the button is down to move the image:

Code:
- (void) gameLogic
{
    if (gameState == kGameStateRunning)
    {
        [self gameStatePlayNormal];
        if (leftButtonDown)
        {
            needle.center = CGPointMake( needle.center.x - needleMovement.x, needle.center.y);

        }
    }
    else if (gameState == kGameStatePaused)
    {
        
    }
}

It moves continuously regardless of whether the button is pressed or not. If you can help me understand how this would work, you will make my day!
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #2
In the code you posted, leftButtonDown is declared in the scope of the -leftButtonPressed: method, which wouldn't make it accessible from -gameLogic where you're reading it. If this is what's in your actual code, either it won't compile, or there's another definition of leftButtonDown somewhere.

Assuming leftButtonDown is declared as a single variable accessible to both methods, do you set it to NO on initialization and when the button is released?
Quote this message in a reply
Apprentice
Posts: 8
Joined: 2010.11
Post: #3
Thanks for your reply.

I get a few warnings that 'leftButtonDown is an unused variable'.

I've added leftButtonDone here:

Code:
- (void)viewDidLoad
{
    [super viewDidLoad];
    gameState = kGameStateRunning;
    BOOL leftButtonDown = NO;
    needleMovement = CGPointMake(4, 0);
    [self startPlaying];
}

and added an IBAction for when the button is released:

Code:
- (IBAction) leftButtonReleased: (id) sender
{
    BOOL leftButtonDown = NO;
    NSLog(@"leftButtonReleased");
}

and changed the timer selector to 'gameLogic':

Code:
- (void) initializeTimer
{
    if ( theTimer == nil )
        theTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLogic)];
    theTimer.frameInterval = 2;
    [theTimer addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
}

and now the UIImageView doesn't move.

P.S. Is there a better way for me to post code?
Quote this message in a reply
Moderator
Posts: 449
Joined: 2003.08
Post: #4
Two things, there is a way to post code in a formatted code segment. If you make a new reply it should be the # button. Or you can type [ code ] and then [ /code ] without the spaces.
Code:
Like this

As for your issue, the variable leftButtonDown is still being declared in the local scope of the viewDidLoad method. Try declaring it in the header file (.h), and then modifying it in the implementation (.m) file.

Alex
Quote this message in a reply
Apprentice
Posts: 8
Joined: 2010.11
Post: #5
EvolPenguin,
Thanks for taking the time to help me. It is very much appreciated.

This is in the .h file:
Code:
@interface SomeViewController : UIViewController
{
    BOOL leftButtonDown;
}

Is this what you meant?
To make the UIImageView to move, do I need to do something more in the gameLogic method?

Sorry about my rookieness
Quote this message in a reply
Apprentice
Posts: 8
Joined: 2010.11
Post: #6
I guess I should put it all it one place for clarity:
Code:
// .h:
#import <UIKit/UIKit.h>
#import <QuartzCore/CADisplayLink.h>

@interface PopperViewController : UIViewController
{
        ...
    BOOL leftButtonDown;
        ...
}

// .m:
- (void)viewDidLoad
{
    [super viewDidLoad];
    gameState = kGameStateRunning;
    BOOL leftButtonDown = NO;
    needleMovement = CGPointMake(4, 0);    
    [self startPlaying];
}

- (void) gameLogic
{
    if (gameState == kGameStateRunning)
    {
        [self gameStatePlayNormal];
        if (leftButtonDown)
        {
            needle.center = CGPointMake( needle.center.x - needleMovement.x, needle.center.y);

        }
    }
    else if (gameState == kGameStatePaused)
    {
        
    }
}

- (void) initializeTimer
{
    NSLog(@"initializeTimer called");
    
    if ( theTimer == nil )
        theTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(gameLogic)];
    theTimer.frameInterval = 2;
    [theTimer addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
    
}

- (IBAction) leftButtonPressed: (id) sender
{
    BOOL leftButtonDown = YES;    
    NSLog(@"leftButtonPressed");
}

- (IBAction) leftButtonReleased: (id) sender
{
    BOOL leftButtonDown = NO;
    NSLog(@"leftButtonReleased");
}

- (void) startPlaying
{
    [[self view] setNeedsDisplay];
    [self initializeTimer];
}

- (void) pauseGame
{
    [theTimer invalidate];
    theTimer = nil;
}

I have been struggling with this for a while, thanks!
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #7
The statement BOOL leftButtonDown = NO; in -viewDidLoad (and similar in other methods) declares (and initializes to NO) a new local variable named leftButtonDown, which is separate from the now-hidden leftButtonDown instance variable. This is perfectly valid in C, so it compiles and runs, but changing the local variable has no effect on the instance variable. If you remove "BOOL" from the statements where you're assigning to leftButtonDown, you'll be referencing the instance variable rather than declaring a new local variable of the same name, and your code should work.
Quote this message in a reply
Apprentice
Posts: 8
Joined: 2010.11
Post: #8
Makes sense.

That is GREAT! Thank you so much!
Quote this message in a reply
Post Reply