Create a Layer in Cocoa from a picture

Simon
Unregistered
 
Post: #1
I am quite new to programing with Cocoa(only a few Weeks).
And I want to do a begining to a simple game.
I make a NSView with the class "Picture"(a subbclasse from NSView).
First( game):
I just want to set a picture on the the NSView.
So that I can choose it¥s position.

This is not yet a real game but it will be.


Second (game):
Now I want to set some pictures on the NSView.
I want to have a grid in a array. And You will enter a Letter In the array for the right picture.
Something like this:
NSArray(("G","G","G","G")
("G","T","G","C")
("G","T","T","G"))
(In this case G will be Grass and T will be Tree)
Every picture is the size of 32*32.

I don¥t know how to set anything in NSView and I have just start to learn Object C. I have the basis for C( i have work with Php, basic, litle Java, MySQL).
Please help me how to do the first game
Quote this message in a reply
AJ Infinity
Unregistered
 
Post: #2
To center an image in the view use something like
[SOURCECODE]
/*I think this is right*/
[myNSView centerImageInView:myImage];
[/SOURCECODE]

Haven't worked with Cocoa in a while but I seem to remember something like that.
Quote this message in a reply
Member
Posts: 78
Joined: 2002.06
Post: #3
To get an image, include an image file in PB, so that it's included in your program.

Then use

[SOURCECODE]NSImage *myImage = [NSImage imageNamed:@"Tree"];[/SOURCECODE]

Note: no need to include extension, picture could be Tree.gif or Tree.jpg or even Tree.pdf Smile

Then to draw it use:

[SOURCECODE][myImage compositeToPoint:myPoint operation:NSCompositeSourceOver];

//or if you want more control
NSSize imageSize = [myImage size];
NSRect srcRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
[myImage drawInRect:myRect fromRect:srcRect operation:NSCompositeSourceOver fraction:1.0];[/SOURCECODE]

Then to draw an array you can do this, btw I think its probably best to use a standard c array, since you'll probably not use any of the benefits of multiple NSArrays.

[SOURCECODE]int x,y;
for(x=0;x<width;x++)
{
for(y=0;y<height;y++)
{
if([[[map objectAtIndex:x] objectAtIndex:y] isEqualTo:Tree])
{
[treeImage compositeToPoint:NSMakePoint(x*32, y*32) operation:NSCompositeSourceOver];
}
else if([[[map objectAtIndex:x] objectAtIndex:y] isEqualTo:Grass])
{
[grassImage compositeToPoint:NSMakePoint(x*32, y*32) operation:NSCompositeSourceOver];
}
}
}[/SOURCECODE]

Tree and Grass could be any object, such as @"T" or @"G". But it might be an idea to have aTile class that contains infomation about the tile including the image. Then you could just write for(...)for(...){ [[[[map objectAtIndex:x] objectAtIndex:y] image] compositeTo...

hth
Quote this message in a reply
Simon
Unregistered
 
Post: #4
I don¥t get it to work. I have made a NSView subbclasse named MyPicture.
I make a NSView object in the window and set it to MyPicture.
I make the files for MyPicture. I write in MyPicture.h:
[SOURCECODE]
#import <Cocoa/Cocoa.h>

@interface MyPicture : NSView
{
NSImage *myImage = [NSImage imageNamed:@"Tree"];
}
- (void)awakeFromNib;
@end
[/SOURCECODE]
MyPicture.m:
[SOURCECODE]
#import "MyPicture.h"

@implementation MyPicture
- (void)awakeFromNib
{

[MyPicture centerImageInView:myImage];

}

@end
[/SOURCECODE]
But it don¥t work. Should I make an outlet from an new class to The NSView?
Quote this message in a reply
w_reade
Unregistered
 
Post: #5
I'm no Cocoa guru, but I'm sure the bold bit of this line:

NSImage *myImage = [NSImage imageNamed:@"Tree"];

has no place in the interface. As I understand it, Obj-C objects are initialised to contain all zeroes. If you want a new object to be different from this, you'll probably want to write your own init method.

However you do it, you'll want the actual code in the implementation bit rather than the interface.
Quote this message in a reply
Simon
Unregistered
 
Post: #6
IF I don¥t write "NSImage *myImage = [NSImage imageNamed:@"Tree"];" in MyPictuer.h but insted [SOURCECODE]

- (void)awakeFromNib

{


NSImage *myImage = [NSImage imageNamed:@"Tree"];"
[MyPicture centerImageInView:myImage];


}
[/SOURCECODE] But is still not working. Can anyone send me a Projekt with a gif at 25.65 As example, plz?
Quote this message in a reply
w_reade
Unregistered
 
Post: #7
Well, you probably want:

NSImage *myImage;

in the interface, and:

myImage = [NSImage imageNamed:@"Tree"];

in the implementation.

As I said before, I'm not a Cocoa expert, but IIRC there's something you can tell NSView (or a subclass thereof) that makes it actually display whatever's in it. It almost certainly isn't [myPicture setNeedsDisplay:YES], but I think it's something along those lines.

That might not be it at all though; please post more details of how it's "not working". Does it not compile, or compile but crash, or compile and run without showing you the image?
Quote this message in a reply
Simon
Unregistered
 
Post: #8
On building I get "Warning cannot find class (factory) method" and "return type for 'centerImageInView' defaults to id".

And on debbug: "2003-02-13 21:21:49.482 Test[444] *** +[MyPicture centerImageInView:]: selector not recognized
2003-02-13 21:21:49.510 Test[444] An uncaught exception was raised
2003-02-13 21:21:49.529 Test[444] *** +[MyPicture centerImageInView:]: selector not recognized
2003-02-13 21:21:49.551 Test[444] *** Uncaught exception: <NSInvalidArgumentException> *** +[MyPicture centerImageInView:]: selector not recognized

Test.app has exited with status 255. "

It doesent even run. If it will help I can mail the projcet to you, just tell me. I really want to learn draw in NSView.
Quote this message in a reply
AJ Infinity
Unregistered
 
Post: #9
Quote:Originally posted by w_reade
Well, you probably want:

NSImage *myImage;

in the implementation, and:

myImage = [NSImage imageNamed:@"Tree"];

in the implementation.

As I said before, I'm not a Cocoa expert, but IIRC there's something you can tell NSView (or a subclass thereof) that makes it actually display whatever's in it. It almost certainly isn't [myPicture setNeedsDisplay:YES], but I think it's something along those lines.

That might not be it at all though; please post more details of how it's "not working". Does it not compile, or compile but crash, or compile and run without showing you the image?


Yeah. You're right. I haven't worked with NSImage for a while but I'm pretty good with file I/O and string parsing.
Quote this message in a reply
Feanor
Unregistered
 
Post: #10
Quote:Originally posted by w_reade
Well, you probably want:

NSImage *myImage;

in the implementation, and:

myImage = [NSImage imageNamed:@"Tree"];

in the implementation

You meant "interface" instead of "implementation" for the first one.

Simon, it seems like you maybe want to spend a little more time on some of the basics of Cocoa class definitions, and the uses of certain key methods.

You do not have to initialize your image instance at the time you declare it. You can do that anytime before you actually draw it (but not in the interface). You might consider browsing some of the Hooptie source, which I imagine does a lot of what you are interested in. Personally I've not use NSImage yet.
Quote this message in a reply
Moderator
Posts: 608
Joined: 2002.04
Post: #11
Quote:Originally posted by Simon
On building I get "Warning cannot find class (factory) method" and "return type for 'centerImageInView' defaults to id".

And on debbug: "2003-02-13 21:21:49.482 Test[444] *** +[MyPicture centerImageInView:]: selector not recognized
2003-02-13 21:21:49.510 Test[444] An uncaught exception was raised
2003-02-13 21:21:49.529 Test[444] *** +[MyPicture centerImageInView:]: selector not recognized
2003-02-13 21:21:49.551 Test[444] *** Uncaught exception: <NSInvalidArgumentException> *** +[MyPicture centerImageInView:]: selector not recognized

Test.app has exited with status 255. "

It doesent even run. If it will help I can mail the projcet to you, just tell me. I really want to learn draw in NSView.
This means that centerImageInView is not a method that NSView uses (assuming MyPicture is your NSView subclass). You can center it in your view like this, however:
Code:
- (NSPoint)centerInView:(NSView *)view
{
    return NSMakePoint([view bounds].size.width/2, [view bounds].size.height/2);
}
This will return a NSPoint that is the center of the view. I haven't tested this code, but it should work. Rolleyes Like Feanor said, however, you should probably learn to walk before you try to run. I'll stop with the bad analogies now. Rasp
Quote this message in a reply
quillbit
Unregistered
 
Post: #12
Since we're just throwing wild guesses out, I'll add my totally unqualified contribution as well. Wink

Simon, I do believe Good Master Thimbleby has the code you'll want, though there is a caveat: you should generally invoke NSImage methods within the drawRect: method of your chosen NSView so you can be sure focus is locked on the view you want to draw into. (*blink* Anyone care to parse that sentence into something a bit more readable?)

As long as you don't want to do any orientation tricks (such as rotating or flipping) with your bitmaps, you can use something along the lines of:
[sourcecode]
[myImage compositeToPoint:NSMakePoint(0,0) operation:NSCompositeCopy];
[/sourcecode]
within drawRect:, which will place myImage at the origin (0,0) of the locked view.

To composite the image somewhere else, you can either substitute your own NSPoint (as per jabber's post), or replace the (x,y) tuple in NSMakePoint with different values.

If you replace the NSCompositeCopy with NSCompositeSourceOver, alpha blending will be performed, which is useful if you have sprites overlaid upon or moving across terrain (a passing fad, I say, all these moving sprites and whatnot).

In any case, try putting together some test applications before you move on to building a tile engine. Once you're comfortable with the basic syntax of Objective-C, you may wish to peruse the following links:
NSView, NSImage, and Cocoa Drawing & Imaging.

Best of luck!
Quote this message in a reply
Moderator
Posts: 608
Joined: 2002.04
Post: #13
Quote:Originally posted by quillbit
Simon, I do believe Good Master Thimbleby has the code you'll want, though there is a caveat: you should generally invoke NSImage methods within the drawRect: method of your chosen NSView so you can be sure focus is locked on the view you want to draw into. (*blink* Anyone care to parse that sentence into something a bit more readable?)
I'll try! When drawing in Cocoa, you must have your "focus" set on something. The focus being what you want to draw to. If you do your drawing in -drawRect, you can be sure that what you are drawing to is your view. If you don't do your drawing in -drawRect, then the image(s) will never appear.

If, for some reason, you must draw outside of -drawRect, you can call -[NSView lockFocus] and then -[NSView unlockFocus] when you are done.

To recap: always try to draw in your view's -drawRect method, otherwise things get messy.
Quote this message in a reply
w_reade
Unregistered
 
Post: #14
Thanks Feanor; edited now.

A quick look at the NSView documentation tells me that all subclasses of NSView must implement their own drawRect method. So, probably best to do that... load your image in either the init method or some other one you make up (and remember to call Wink), and then draw the image when you're inside the drawRect method.

Try not to put the image loading code inside the drawRect method, though, unless you do something clever that ensures the picture only gets loaded once.
Quote this message in a reply
quillbit
Unregistered
 
Post: #15
Quote:Originally posted by jabber
I'll try!

>snip<

Thanks, jab -- a great improvement on my tortured syntax!
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Cocoa and the big picture Varias 3 2,524 Feb 1, 2010 07:34 AM
Last Post: backslash
  Picture in Interface Builder skyhawk 1 3,085 Jun 15, 2006 02:10 PM
Last Post: OneSadCookie