Cocoa: Tile Question - Printable Version
+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: Cocoa: Tile Question (/thread-6712.html)
Pages: 1 2
Cocoa: Tile Question - Criollo - Oct 1, 2003 07:51 PM
Hey everyone. I'm trying to create a simple tile-based game in Cocoa, but I'm having some problems. Basically, I have a custom view in which all the tiles are drawn in the drawRect method. The problem is that everytime I move my character, the entire view updates, which is slowing down my program. Is there any way that I could just update the portions of the view that need updating, and not the entire view? Thanks.
Cocoa: Tile Question - Steven - Oct 1, 2003 08:36 PM
One way to do that would be to keep an array of tiles which need to be updated. Every time the player touched a tile, it would be added to that list. Every frame, the renderer renders each tile in the list and then clears the list.
Cocoa: Tile Question - arekkusu - Oct 1, 2003 09:30 PM
Figure out which portion of your drawing is taking up "too much" time and optimize it or redesign your tiling approach.
Any recent Mac should have no problem drawing a few hundred tiles filling the display at several hundred frames per second.
Cocoa: Tile Question - Bachus - Oct 1, 2003 10:29 PM
Are you using NSImages and Quartz to draw the tiles? If so, then you shouldn't be. Switch to OpenGL. Quartz is far too slow for games.
Cocoa: Tile Question - Criollo - Oct 1, 2003 10:33 PM
Quote:One way to do that would be to keep an array of tiles which need to be updated. Every time the player touched a tile, it would be added to that list. Every frame, the renderer renders each tile in the list and then clears the list.
How would I render just the tiles that need to be rendered, though? When I set setNeedsDisplay to YES, it redraws the entire view.
Quote:Any recent Mac should have no problem drawing a few hundred tiles filling the display at several hundred frames per second.
Well, the program is noticeably slow drawing a matrix of 16X12 on my computer(blueberry iMac).
Cocoa: Tile Question - Criollo - Oct 1, 2003 10:37 PM
Quote:Are you using NSImages and Quartz to draw the tiles? If so, then you shouldn't be. Switch to OpenGL. Quartz is far too slow for games.
Yes, I am using NSImages with gif and tiff files. I understand that Quartz is slower than OpenGL, but do I really need 3D acceleration just to create a simple tile based game? The current speed would be acceptable if I could only update the portion of the view that needed updating, instead of redrawing the view everytime. Is there any way to do this? Thanks.
Cocoa: Tile Question - junyx - Oct 1, 2003 10:50 PM
Quote:Originally posted by Criollo
I think you can simply make an NSView subclass and override drawRect:
Btw, when I was looking for a way to implement my tile-based uDG entry (Bubble Blast!), I noticed that OpenGL is the best. If you don't want to learn it, you can use the amazing CocoaBlitz framework, as I did.
Cocoa: Tile Question - FCCovett - Oct 1, 2003 11:25 PM
I've been trying to do something similar, a vertical scrolling shoot'em-up. I put together a base structure to load the pic files from the main bundle or from a resource file - in Carbon, not in Cocoa - and three blocks of code to draw the pics with QuickDraw, Quartz, or OpenGL.
From what I've seen, you can have 20 sprites (32 bits) moving on the screen in a old iMac 333 (no hardware acceleration) and get 40+ fps, but then you start scrolling the background (16 bits), the framerate drops drastically to about 7 fps. The same 20 sprites with a scrolling background (320 x 480 pixels) averages 30 fps on a new 12" Powerbook 1GHz (that's with Quickdraw or Quartz).
With Quickdraw, you can get good results if you reduce the number of colors of your bitmaps and tell the program which rectangles to update. That's kind of trick to do with Quartz because the graphics context depends on the current screen setting and it only accepts 8, 16 or 32 bits images. I have the impression that scaling the bit depth of your pics is easier with Cocoa.
Now, with OpenGL, you are sure to get better frame rates on newer Macs, but I understand that the textures need to be at least 64 x 64 pixels, with dimensions always a power of 2, etc. It's not that hard to load TGA pics with an embedded alpha channel (to create transparency effects - colorkeying) to create your OpenGL textures. I am loading bitmaps from the main bundle and converting the actual bitmap data from the TGA files into OpenGL textures. No sweat there - check the NeHe web-site for sample code in Cocoa.
Cocoa: Tile Question - arekkusu - Oct 2, 2003 03:21 AM
If you read the docs for NSView, right next to setNeedsDisplay you'll find setNeedsDisplayInRect. Be warned that the view system may stupidly coalesce disparate rects into one large dirty rect on pre-Panther systems, though. Another useful place for QuartzDebug.
A blueberry iMac is questionably "recent", in terms of Quartz Extreme.
OpenGL is not just 3D acceleration. It is graphics acceleration, 2D or 3D.
GL textures can be any size (up to a hardware limit, such as 2048x2048) and do not need to be a power of two. They may consume a power of two section of VRAM if you don't (or can't) use the rectangle texture extension, though.
Don't use TGA format. Ever.
Cocoa: Tile Question - Damian - Oct 2, 2003 03:48 AM
Quote:Originally posted by Steven
Criollo, you can do this without any subclassing.
In your drawInRect method, only render the tiles that are marked as needing to be drawn:
[[tileArray objectAtIndex:tileN] compositeToPoint... etc];
Cocoa: Tile Question - FCCovett - Oct 2, 2003 12:36 PM
Why not use TGA files? They conveniently store the alpha channel data, so it's a snap to create a texture from a TGA bitmap, without the need to load a separate file with a mask for colokeying. Am I missing something?
My application can also load textures from JPG or PNG files, but I couldn't see any difference from doing that or loading textures from a TGA file.
Older video cards won't accept textures in sizes which are not power of 2. You can assign sections of a texture to a quad, for instance, with you are working with older cards.
Or you may just disregard older iMacs, of course. If you use Quartz or Quickdraw, you won't have to worry that much about which kind of video card the end user has got in his computer.
Cocoa: Tile Question - arekkusu - Oct 2, 2003 01:01 PM
What's your size on disk for your TGA file, compared to PNG or TIFF?
See my older post.
Cocoa: Tile Question - FCCovett - Oct 2, 2003 03:00 PM
Indeed, if the final download file size is critical to you, and you are not getting a good compression rate from your compressor of choice, then JPG and PNG would be the way to go.
As noted in that other thread, I've notice that PNGs get somewhat darker when displayed on screen. Also, I don't know if there's a way to embedded the alpha channel data into the JPG file, and the alternative of having the alpha mask in a separate file is not ideal.
One can always create a proprietary file fomat, or generate the alpha channel on-the-fly upon loading the JPG (based on a background color value), but I wouldn't do it either way unless the difference in download size were really significant. For this particular application I am building, the size of the audio files is far more of an issue than the size of the pic files.
I am not advocating the use of TGAs; it's just that the implementation of the alternatives seemed a little more involved to me, or less than ideal for a speedy production.
Cocoa: Tile Question - Criollo - Oct 2, 2003 04:59 PM
Thanks for the suggestions everyone. I'll try them out in my application, and see how it goes.
FCCovett: No idea what a TGA file is or how to make one, but TIFFs and GIFs also have alpha channels.
Cocoa: Tile Question - FCCovett - Oct 2, 2003 06:41 PM
Yeah, if you are working with Cocoa, it should be easier to keep on working with those formats.
The uncompressed TGA comes with a header of 12 bytes that describe the bit depth (24 or 32 bits/pixel) and the size of the actual bitmap (bytes). You just need to swap the Red and Blue bytes to get a RGB or RGBA for the OpenGL texture-create function.
Anyway, if you decide to work with OpenGL, you can find valuable pieces of source code (in Cocoa) at http://nehe.gamedev.net/