PDA

View Full Version : Quickly refreshing NSViews


Steven
2002.11.09, 12:59 PM
I am trying to create something akin to REALbasic's SpriteSurface in Cocoa/Java. I have a sprite moving diagonally across the screen, and I am pretty sure that the underlying code is at least ok. One problem left is that many frames are 'dropped' and the sprite moves unpredictably in 'jumps'.
Right now I'm using a NSTimer to have the view refresh itself, but this isn't working very well. Is there a faster way? (Preferably synchronous)
Thanks a bunch,
Steven

skyhawk
2002.11.09, 01:52 PM
NSTimer is very reliable and you can easily set it to 40fps, or 60fps... of course I'm assuming you did it with 0 as the parameter... if you do that, then you must make your game time based and not frame based. if your game IS frame based, I suggest:

[NSTimer scheduledTimerWithTimeInterval: (1.0/40.0)target:self selector:@selector(drawnext: ) userInfo:nil repeats:YES];

Steven
2002.11.09, 06:56 PM
Well I must be doing something wrong then, as it doesn't work right. And, as I said, I am using Java. How does that call translate to Java? I would do it myself, but I don't get how the selector thingy works.
Steven

Steven
2002.11.09, 07:25 PM
I got it; it is very similar to java.lang.reflect.Method.
Now, my problem is that nothing happens. These are the significant portions of my code...

timer = new NSTimer(1/40,this,new NSSelector("doNextFrame"),"test",true);
public void doNextFrame(){
Thanks,
Steven

Steven
2002.11.09, 08:00 PM
Ok, I refined the code a bit and put some more in to verify the validity of the selector:
public void run(){
NSSelector s;
s = new NSSelector("doNextFrame",new Class[0]);
System.out.println(s);
try{
System.out.println(s.methodOnObject(this));
}catch(Exception e){
System.out.println(e);
}
try{
s.invoke(this,null);
}catch(Exception e){
System.out.println(e);
}
timer = new NSTimer(1,this,s,"test",true);
System.out.println("Created timer..."+timer.isValid());
}

The invoke() call works fine, but the timer never fires!
Thanks for any help,
Steven

Steven
2002.11.09, 08:05 PM
In case it helps, this is the output my debug statements produce:

NSSelector doNextFrame
public void SSView.doNextFrame()
NextFrame
Moved.
DrawRect
DrawRect
Created timer...true
The NextFrame and Moved lines show that the doNextFrame() method was actually called.
Steven

Josh
2002.11.09, 08:31 PM
There was *just* a discussion about this... search the forums.

[Edit: wait... you were the author of that thread. Did OSC's solution not work?]

Steven
2002.11.10, 10:35 AM
I forgot all about that... I just tried that (having one argument, an Object) but the same results happened:
The selector was valid, calling invoke() worked; but the timer never fired.
Steven

anarchie
2002.11.10, 12:43 PM
In Cocoa-Java, it appears you have to add the NSTimer to the current NSRunLoop yourself, like so:

NSRunLoop.currentRunLoop().addTimerForMode(myTimer , DefaultRunLoopMode);

To remove the timer from the runloop, just invalidate it:

myTimer.invalidate();

Don't take my word for it, though; I have never used Cocoa-Java, and this is only what I gleaned from the documentation.

OneSadCookie
2002.11.10, 02:11 PM
I said that, in the last thread. I assume that Steven's done it...

Steven
2002.11.10, 10:26 PM
It still does nothing :mad:
I do wish that the Cocoa interfaces were more friendly...
Steven

skyhawk
2002.11.11, 02:16 AM
just so you know... 1/40 give you 0....
while 1.0/40.0 gives you 1/40...
and cocoa is VERY friendly interface... java on the other hand..:[

Steven
2002.11.11, 10:01 AM
*Whacks himself*

And, yes Java's APIs are no prettier. I wish that everything was more like REALbasic (minus the slowness, bugginess, and huge upgrade fees every six months) :[

Ok, off to fix that.

{Back}

Still doesn't work. :mad:
Thanks everyone for trying, but it still does nothing. I have the code to this:
public void run(){
NSSelector s;
s = new NSSelector("doNextFrame",new Class[] {Object.class});
System.out.println(s);
try{
System.out.println(s.methodOnObject(this));
}catch(Exception e){
System.out.println(e);
}
try{
s.invoke(this,new Object[] {null});
}catch(Exception e){
System.out.println(e);
}
timer = new NSTimer(1.0/40.0,this,s,null,true);
System.out.println("Created timer..."+timer.isValid());
NSRunLoop.currentRunLoop().addTimerForMode(timer, NSRunLoop.DefaultRunLoopMode);
System.out.println("Added to run loop "+NSRunLoop.currentRunLoop());
}

Anything else to try?
Steven

skyhawk
2002.11.11, 01:21 PM
run and flee in mercy?

Steven
2002.11.11, 07:34 PM
*Thinks, decides 'Why not?' ; screams and runs around; calms down; falls alseep*

;)
Steven

anarchie
2002.11.11, 08:05 PM
If you're not running NSApplication, or you're in a separate thread from the running NSApplication, you have to make the current run loop run...

Steven
2002.11.11, 09:05 PM
Hey thanks! It works now. Now I have to speed it up... :p I'm getting 25 fps with two sprites on the screen, only one of which moves :(
Steven

Steven
2002.11.11, 09:09 PM
Ok; I'm up to 208 FPS. The problem is that when it refreshes it this fast, the screen isn't in sync. It jumps again. Can I force the info to be dumped to the screen ASAP instead of when the OS feels like doing it? Thanks guys,
Steven

Steven
2002.11.11, 09:24 PM
Well I got it to be not jumpy by moving it out of a thread; but now I'm only getting 43 FPS. How can I get it to go faster?
Steven

anarchie
2002.11.11, 09:29 PM
Using Obj-C in place of Java would make it go a bit faster.

Steven
2002.11.12, 12:13 PM
Well I know Java but I dont' know Obj-C. :p
Steven

OneSadCookie
2002.11.12, 02:57 PM
If you know Java, it should take you a couple of hours at the most to learn 90% of ObjC...

Steven
2002.11.12, 06:46 PM
My point is that why learn both the API and the language at the same time when I could just learn the API? I don't think that coding it in Obj-C is going to make too much difference...
Steven

OneSadCookie
2002.11.12, 08:20 PM
The point isn't really that ObjC will make your game go faster, but that people will be more able to help you, and that there are excellent profiling tools available that will tell you which parts of your code are slow.

I'm using Lua for the bulk of my uDevGame entry, which is significantly slower than Java, and I'm doing more complex stuff than you are by the sounds of it, and I don't have any performance problems. It should therefore not be a problem to get your frame-rate up :)

Steven
2002.11.13, 09:30 AM
Ok; I'll work on it more after I finish up my uDG entry.
Steven