Problem With Motion in NSView
I'm trying to get a sprite to be controlled by keyboard input. The input finally works (only took me a half hour to get) but now it draws it in a really odd fashion where it only flashes the character every once in a while. Anyone know why this might be occuring? It it'll help, I can post the .app on my site for download but I'm hoping that won't be necessary. Here's the code that I suppose matters. I only have the MyView.h and MyView.m so that's where all of this is located. There's only the view in my app so there isn't much else needing to be elaborated on.
This last one is just the keyDown: and keyUp: methods but maybe they have something to do with it:
Code:
- (id)initWithFrame:(NSRect)frameRect
{
if ((self = [super initWithFrame:frameRect]) != nil)
{
// Add initialization code here
spriteLoc = NSMakePoint(0,0);
sprite = [NSImage imageNamed:@"sprite.png"];
}
return self;
}
- (void)awakeFromNib
{
[[self window] makeFirstResponder:self];
controlTimer = [[NSTimer scheduledTimerWithTimeInterval:.001
target:self
selector:@selector(checkKeys)
userInfo:nil
repeats:YES] retain];
[[NSRunLoop currentRunLoop] addTimer:controlTimer
forMode:NSEventTrackingRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:controlTimer
forMode:NSModalPanelRunLoopMode];
}Code:
- (void)drawRect:(NSRect)rect
{
[[NSColor blueColor] set];
NSRectFill([self bounds]);
NSRect myRect;
myRect.size = [sprite size];
[sprite drawAtPoint:spriteLoc
fromRect:myRect
operation:NSCompositeSourceOver
fraction:1];
}Code:
- (void)checkKeys
{
if(up)
spriteLoc.y++;
if(down)
spriteLoc.y--;
if(left)
spriteLoc.x--;
if(right)
spriteLoc.x++;
[self setNeedsDisplay:YES];
}Code:
- (void)keyDown:(NSEvent*)theEvent
{
unichar key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
if(key == NSUpArrowFunctionKey || key == 'w' || key == 'W')
{
up = YES;
return;
}
if(key == NSDownArrowFunctionKey || key == 's' || key == 'S')
{
down = YES;
return;
}
if(key == NSLeftArrowFunctionKey || key == 'a' || key == 'A')
{
left = YES;
return;
}
if(key == NSRightArrowFunctionKey || key == 'd' || key == 'D')
{
right = YES;
return;
}
}
- (void)keyUp:(NSEvent*)theEvent
{
unichar key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
if(key == NSUpArrowFunctionKey || key == 'w' || key == 'W')
{
up = NO;
return;
}
if(key == NSDownArrowFunctionKey || key == 's' || key == 'S')
{
down = NO;
return;
}
if(key == NSLeftArrowFunctionKey || key == 'a' || key == 'A')
{
left = NO;
return;
}
if(key == NSRightArrowFunctionKey || key == 'd' || key == 'D')
{
right = NO;
return;
}
}
Is your timer firing at the correct interval?
There was a long silence...
'I claim them all,' said the Savage at last.
Is there a good way to check that? Is that the problem, you think?
Asking for a timer that fires 1000 times per second is pretty excessive. I've never seen a need for one that goes any faster than 120 times per second. It's an easy thing to try; increase your timer interval and see if the problem goes away.
- Alex Diener
- Alex Diener
most hollywood movies (film) are shot at 24 FPS, while TV (NTSC) is 29.97 FPS. So ~30 FPS should do you just fine. In other words, try setting your timer interval around 0.033.
Andrew Wrote:most hollywood movies (film) are shot at 24 FPS, while TV (NTSC) is 29.97 FPS. So ~30 FPS should do you just fine. In other words, try setting your timer interval around 0.033.
But both movies & TV have motion blur. You need higher frame rates to fake smooth motion on a game, 60 is the maximum FPS you can get with Apple's LCDs, but CRTs & LCDs from other vendors can have higher refresh rates.
Also, it would probably be a good idea to use frame rate independent animation (basically, dont just ++ or -- the x or y position of your sprite, use some constant value multiplied by the time elapsed since the last frame, that is, the difference between the current time and the previous frame time).
Well I'm sure I'll do the frame-rate independent stuff later, I was just trying to get the keys and everything to work.
I tried increasing the timer to .015 and .1 but neither fixed the problem. I'm going to post the app on my site and I'll return with a URL.
I tried increasing the timer to .015 and .1 but neither fixed the problem. I'm going to post the app on my site and I'll return with a URL.
Weird... Could you post the project folder?
There was a long silence...
'I claim them all,' said the Savage at last.
Sure. Here's the folder.
Hey Nick,
This seemed to fix the issue for me.
All the best,
Lyndon.
This seemed to fix the issue for me.
Code:
- (void)drawRect:(NSRect)rect
{
[[NSColor blueColor] set];
NSRectFill([self bounds]);
//NSRect myRect;
//myRect.size = [sprite size];
[sprite drawAtPoint:spriteLoc
fromRect:NSZeroRect
operation:NSCompositeSourceOver
fraction:1];
}All the best,
Lyndon.
Try adding this to drawRect:
Also, probably a good idea to add this to initWithFrame:
Edit: Shaddy beat me to this post... His solution for drawRect is better
Code:
myRect.origin.x = 0.0f;
myRect.origin.y = 0.0f;Also, probably a good idea to add this to initWithFrame:
Code:
up = down = left = right = NO;Edit: Shaddy beat me to this post... His solution for drawRect is better
I went with PowerMac's suggestion and it worked perfectly. Thanks a ton.
On a related note, how would I do the frame-rate independent motion in Cocoa? I did it once in SDL but that was with some SDL function for getting the time.
On a related note, how would I do the frame-rate independent motion in Cocoa? I did it once in SDL but that was with some SDL function for getting the time.
Quote:Also, probably a good idea to add this to initWithFrame:
Code:
up = down = left = right = NO;
This is unnecessary since up, down, etc. are instance variables. In objective-C, they automatically are initialized to zero.
Nick Wrote:how would I do the frame-rate independent motion in Cocoa?
I think PowerMacX already answered your question

PowerMacX Wrote:use some constant value multiplied by the time elapsed since the last frame, that is, the difference between the current time and the previous frame time).
Possibly Related Threads...
| Thread: | Author | Replies: | Views: | Last Post | |
| Motion Sensor Query for 3D game | iphone-query | 1 | 3,947 |
Sep 2, 2011 09:26 PM Last Post: PoseMotion |
|
| Device motion detection using Acceleration data. | RockyDilse | 4 | 6,972 |
Feb 16, 2011 12:57 AM Last Post: RockyDilse |
|
| Mouse Events in NSView | Chandhu | 1 | 3,536 |
Feb 28, 2008 02:08 AM Last Post: kuon_ |
|
| NSView loaded from bundle won't draw... | Joseph Duchesne | 1 | 3,102 |
Feb 12, 2006 03:33 AM Last Post: Cochrane |
|
| NSImage and NSView problems | Joseph Duchesne | 1 | 3,282 |
Aug 19, 2005 07:36 AM Last Post: unknown |
|

