0

I'll try to keep it short. I want to create a 3D FPS game, just for myself, that can run on multiple platforms, but I figured that to keep it simple, perhaps it is best to start off with something that is exclusively for macOS. I opted for Objective-C because

(a) Window Application projects in Xcode can only be coded either in Obj-C or Swift (since we are dealing with Cocoa API) and

(b) Obj-C is closer to old-school then Swift.

But before I learn to draw/render 2D-shapes on the window's canvas by writing code, I have to learn to invoke an application window with its properties set to my liking. I've spent hours doing research and experimenting with chunks of code. This is what I've tried: I open with

#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {

Then I go with ...

1)

        NSWindow *window = [[[NSApplication sharedApplication] windows] firstObject];
        NSRect frame = [window frame];
        frame.origin.x = 100;
        frame.origin.y = 200;
        frame.size.width = 100;
        frame.size.height = 500;
        [window setFrame: frame display: YES];

... and close with ...


        NSApplicationMain(argc, argv); // runs the win display function.
    }

    return (0) ;
}

But no visible changes. Nothing really gets reset. So instead of (1) I tried ...

2)

        NSWindow *window = [[[NSApplication sharedApplication] windows] firstObject];
        NSPoint newOrigin;
        newOrigin.x = 400;
        newOrigin.y = 100;
        [window setFrameOrigin : newOrigin];

Still nothing. Then instead of (2) I tried:

3)

 NSWindowController* controller = [[NSWindowController alloc]
            initWithWindowNibName:@"MainMenu"];
        [controller showWindow:nil];

Great. Now it's spitting out something I don't understand, especially since I'm new to Obj-C:

2020-02-08 21:53:49.782197-0800 
        tryout_macApp2[14333:939233] [Nib Loading] Failed 
        to connect (delegate) outlet from 
        (NSWindowController) to (AppDelegate): missing 
        setter or instance variable

I remember dicing around with an ApplicationDelegate, with CGSizeMake(), etc., but it just made the experience really inundating and frustrating. Nothing happened. Then there are NSView, NSViewController, and other classes, which is really mindboggling and begs the question: why are there so many classes when all I want to do is override the preset origin of the window and the dimensions preset by the MainMenu.xib file? (By the way, this project is derived from a Window Application project provided by Xcode.)

I really can't think of anything else to add to give you the entire picture of my predicament, so if you feel that something is missing, please chime in.

[Edit:] Moving forward to phase 2 of my project here: How do I paint/draw/render a dot or color a pixel on the canvas of my window with only a few lines in Obj-C on Mac OS X using Xcode?.

2 Answers2

2

The short answer is that main() is too early to be trying to do this. Instead, implement -applicationDidFinishLaunching: on your app delegate class, and do it there. Leave main() as it was originally created by Xcode's template.

After that, I would say to obtain the window (if there's only going to be one main one), it's better to add an outlet to your app delegate and then, in the NIB, connect that outlet to the window. Then, you can use that outlet whenever you want to refer to the window.

Also, make sure that Visible at Launch is disabled for the window in the NIB. That's so you configure it as you want before showing it.

For a more complex app, it's probably better to not put a window into the Main Menu NIB. Instead, make a separate NIB for the window. Then, load it using a window controller object and ask that for its window.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • One small step for this man. I implemented chunk (1) in the implementation file AppDelegate.m instead of main.m and omitted the custom allocation for window ```NSWindow *window = [[[NSApplication sharedApplication] windows] firstObject]; ``` since the delegate already comes with an IBOutlet connected to ```*window```. Thank you so much. – AndrewGreen Feb 09 '20 at 18:43
-2

I love Objective-C but also feel your pain, it has this testy ability to frustrate you endlessly.

I have not really developed a game but let me try and point you in the right direction. I think you need a UIViewController.

Now each UIViewController has a built in UIView that sort of represents the visible portion of it. You can use this or add a UIView and use that, whichever depends on your implementation. For now I'd suggest add a separate UIView and use that rather. Once you're comfortable you can then move the implementation to the UIViewController's view if you need to.

Anyhow, for now, create a UIView subclass, say MyGame or something, as for now all your code will end up there.

To do all of the above is not easy, especially if its the first time. If you can follow some tutorial it will be great. Even if the tutorial just adds a button, you can use it and replace the button with your view.

Anyhow, now that you've got that running and the view you've added shows up in green or some other neon colour just to verify that you can indeed change its properties, you're good to go.

Now you start. In MyGame, implement the -(void)drawRect:(CGRect)rect message, grab the context through UIGraphicsGetCurrentContext and start drawing lines and stuff on it, basically the stuff I understand you are interested in doing. You can also, through the same context, change the origin of what you are doing.

Hope this helps.

skaak
  • 2,988
  • 1
  • 8
  • 16
  • My Xcode project does not know UI-classes; it will only accept their NS-counterparts. I don't suppose that is a big deal since all object classes inherit from NSObject ... unless there are things that the UI libraries have that NextSTEP libraries don't. And if that's the case, do I have to import some kind of a master UI library? And if so, what is it called? Because my IDE cannot find UIResponder.h . – AndrewGreen Feb 09 '20 at 18:15
  • #import ? – skaak Feb 10 '20 at 03:59
  • Apologies - now I realise you are writing desktop, not mobile app ... – skaak Feb 10 '20 at 04:17