Archive for the ‘Development’ Category

Where to Start

Posted: September 17, 2010 in Development
Tags: , , ,

One of the most frequently asked questions I get from beginners in programming, is that of where to start. This is very common amongst beginners, that they are given the tools to do almost anything, but they lack the inspiration of what these tools can be used for. As with anything, practice makes perfect, and programming is no different, so anything you can think of is really good exercise.

Besides practicing the use of the tools you are given though, I recommend a gradual move into practicing techniques, rather than syntactical practice. I look at programming as problem-solving, and each time you solve a problem you learn a technique for a given task, with practice you learn more and more techniques — some even for the exact same problem, just more efficient than the last. So, I suggest setting yourself goals, modest goals to begin with, practice the goal until you have a thorough understanding of the problem and solution, even try different ways of accomplishing the same goal — this way you will not only have understood the problem, but also gain a deep knowledge of various techniques to solve it, which will come in handy later on.

From Beginner To Intermediate
These are a few suggestions for you to practice, that get increasingly difficult to solve. If you finish all, go back to the first project and try to solve it with any new technique learned as you progressed. And if you are learning an object oriented programming language, such as C++, make sure you make everything an object in the project, as it will ensure a very good understanding of how OOP (Object Oriented Programming) works. Once you get familiar with OOP and comfortable working with it, you will not be wanting to go back to procedural programming — and then you can call yourself an intermediate programmer.

  • Hello World — Printing a string to the console.
  • Guessing Game (eg. guess a number) — Generate a random number, have the player try to guess the number.
  • Tic-Tac-Toe — Slightly more complicated game, will challenge you on several aspects of basic programming.
  • Pong — Very simple game, but requires animation, which can be quite difficult at first. Will get you familiar with time-based programming, real-time input interpretation and event handling.

Anytime you feel like you don’t know exactly how to solve a problem, write it out in pseudo-code, as such:

create keyboardInputVariable
generate aRandomNumber

while keyboardInputVariable does not equal aRandomNumber
     ask user for input
     set keyboardInputVariable equal to keyboardInput

// once outside this loop, the number has been guessed
print game-over string

By writing out pseudo-code, things become much easier to solve, as you have the solution in —almost— plain english.

I hope this helped you get started on your first projects. If i neglected to mention something, that you as a beginner, would like to know on the subject of getting started, let me know by commenting and I’ll update the post accordingly.

Advertisements

I’ve never really used the Interface Builder all that much when developing, and frankly I don’t like the “magic” it does for me. I prefer being able to visualize what my application does in the code by avoiding the NIB altogether — and I’m going to show you how I go about doing this.

Why ?
Well, there are projects where it just doesn’t make sense to use Interface Builder, rendering the NIB obsolete to the project itself. This is true for projects that have little or no GUI based on the AppKit, like fullscreen games. Games in particular usually incorporate their own GUI, which is managed by the engine.

How ?
As far as I know, there is no Apple-sanctioned method of approach of doing nibless development under cocoa, and the method I will show you is probably not the only way — or the best, for that matter.

The standard main.m looks something like this:

#import <Cocoa/Cocoa.h>

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

    return NSApplicationMain(argc,  (const char **) argv);
}

The return NSApplicationMain(argc, (const char **) argv) instantiates your application by creating the singleton object NSApplication, loading the MainMenu.xib (the nib) and calling the run method on your NSApp. In order to avoid the nib, we need to circumvent this by initiating the application ourselves.

The first thing we do, is to get rid of the NSApplicationMain function call. In it’s place we simply return zero, as cocoa will call exit() before reaching the return instruction of the main function, so this never gets executed anyway. Now that our main function looks like a generic C program, we can begin recreating what the NSApplicationMain did for us.

We will need to wrap everything in an autorelease pool, and make sure we have an instantiated application — we do this as such:

#import <Cocoa/Cocoa.h>

int main(int argc, char *argv[])
{
    // create an autorelease pool
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    // make sure the application singleton has been instantiated
    NSApplication * application = [NSApplication sharedApplication];
    
    // drain the autorelease pool
    [pool drain];
	
    // execution never gets here ..
    return 0;
}

Now that we have made sure we have an application to run, we can go on and create an application delegate — if not already present in your project.

Create a new Objective-C NSObject subclass, name it AppDelegate. In the @interface section found in the header of your new NSObject subclass, add the NSApplicationDelegate protocol to it as such: @interface AppDelegate : NSObject <NSApplicationDelegate>

Import the AppDelegate’s header to your main.m as such: #import "AppDelegate.h"

Now that your AppDelegate implements the NSApplicationDelegate protocol and your main.m knows about it, we can create an instantiation of the application delegate and assign it to the NSApplication, and then all we really need to do is to call the run method:

#import <Cocoa/Cocoa.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])
{
    // create an autorelease pool
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    
    // make sure the application singleton has been instantiated
    NSApplication * application = [NSApplication sharedApplication];
    
    // instantiate our application delegate
    AppDelegate * applicationDelegate = [[[AppDelegate alloc] init] autorelease];
    
    // assign our delegate to the NSApplication
    [application setDelegate:applicationDelegate];
    
    // call the run method of our application
    [application run];
    
    // drain the autorelease pool
    [pool drain];
    
    // execution never gets here ..
    return 0;
}

This takes care of the main function. Now all we need to do, is implement how our application delegate handles our application. You can handle this however you want, I’m just going to show you how to create a window with a content view. Keep in mind, that for the sake for keeping the demonstration short and to the point, I do not use custom classes for these, in real projects I would definitely write a class for the content view.

Inside of the class declaration of the AppDelegate, we put an NSWindow and a NSView as such:

@interface AppDelegate : NSObject  {

    NSWindow * window;
    NSView * view;
}

Because the AppDelegate implements the NSApplicationDelegate protocol, there are quite a few methods that it will now respond to and that will get called during run-time. So in the definition of our application delegate, we add the following methods and implementations as such:

@implemention AppDelegate

- (id)init {
    
    if ( self = [super init] ) {
        
        // create a reference rect
        NSRect contentSize = NSMakeRect(0.0f, 0.0f, 480.0f, 320.0f);
	
        // allocate window
        window = [[NSWindow alloc] initWithContentRect:contentSize styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:YES];
        
        // allocate view
        view = [[NSView alloc] initWithFrame:contentSize];
    }
    return self;
}


- (void)applicationWillFinishLaunching:(NSNotification *)notification {
    
    // attach the view to the window
    [window setContentView:view];
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
    
    // make the window visible.
    [window makeKeyAndOrderFront:self];
}

- (void)dealloc {
    
    // don’t forget to release allocated objects!
    [view release];
    [window release];
    
    [super dealloc];
}

@end

.. and that concludes my approach of doing nibless development. Notice that I did not implement the main menu, so when you run this the main menu will not work. But there is a solution for that as well, I might write an article about that some time — please do let me know if this is something you would like to see.

Phew, that got a little lengthier than I originally expected it to.

Hopefully you found this useful. If you have any questions or thoughts on this, please leave a comment — Thank you.

Download Xcode Project
I’ve made an xcode project available for download at, just click the link above to get it. It has been build, tested and it works.

UPDATE Fixed a typo; in AppDelegate.m it said ‘@implemention’, while it should have been ‘@implementation’. Thank you albert7546, for pointing out the source wouldn’t compile.

The C Programming Tutorial is now done. I spend most of yesterday and this morning writing on this, hoping to finish it some time this evening. However, it seems that I almost completed it this morning. There are only a few lessons missing, but don’t worry, I expect these to be the conclusion of it, so it is all set for you to start learning C. These last lessons will be concluding what you have learned and bringing it all together in a project — a game, your very first game.

I hope you will enjoy the series, as I put a lot of effort into making the lessons as understandable and straight-to-the-point as I could. Hopefully you’ll be writing C fluently in no time. If this tutorial yields success, I will continue to add more lessons, getting into more advanced topics.

If you do follow along with the lessons, please comment on the lessons if you had trouble understanding it, if you have questions or pretty much anything you would want to share or ask. I will make changes if necessary and provide you with answers, should question arise.

Happy coding, have fun! 🙂