A couple questions relevant to games
-
Hi. I'm planning to make a game, and I have a couple of questions
since I'm new to cocoa.
1) Is there some functionality to stack views, such that only one is
visible at a time in the outer window? If you look at most games,
they're usually presented as a set of screens, such as the tile screen
or the map screen, all within a single window. Certain actions within
these screens makes the application switch to a new screen. Does
cocoa/Interface Builder have something like that built in?
2) I intend to have a view that shows a grid of tiles. Its actual
dimensions should depend on the dimensions of the grid and the
dimensions of the images drawn on it (I assume the tile images are of
equal size). I may allow dynamic resizing of the view, but it should
be constrained so that the images retain their proportions and there
are no extra gaps or "partial tiles." So, if the images are square
and the grid is square, the view should always be square. I'm asking
because in Interface Builder it seems you define the dimensions of a
view directly instead of letting it be defined by user parameters at
runtime (in this case, the grid and tile dimensions). Is there a way
around this?
Thank you,
Aaron J. M. -
On Feb 17, 2008, at 7:44 AM, Aaron MacDonald wrote:> 1) Is there some functionality to stack views, such that only one is
> visible at a time in the outer window? If you look at most games,
> they're usually presented as a set of screens, such as the tile
> screen or the map screen, all within a single window. Certain
> actions within these screens makes the application switch to a new
> screen. Does cocoa/Interface Builder have something like that built
> in?
In Cocoa you would typically use a NSTabView (with the actual tabs
hidden) for this purpose. Or, alternatively, you would just insert /
remove subviews manually from your root view.> 2) I intend to have a view that shows a grid of tiles. Its actual
> dimensions should depend on the dimensions of the grid and the
> dimensions of the images drawn on it (I assume the tile images are
> of equal size). I may allow dynamic resizing of the view, but it
> should be constrained so that the images retain their proportions
> and there are no extra gaps or "partial tiles." So, if the images
> are square and the grid is square, the view should always be
> square. I'm asking because in Interface Builder it seems you define
> the dimensions of a view directly instead of letting it be defined
> by user parameters at runtime (in this case, the grid and tile
> dimensions). Is there a way around this?
In IB you set the default size & position for your views, but you can
always change them at runtime.
With regards to your concerns about keeping square proportions, take a
look at "-[NSWindow setResizeIncrements:]", or alternatively "-
[NSWindow(Delegate) windowWillResize:toSize:]".
j o a r -
On 17 Feb '08, at 7:44 AM, Aaron MacDonald wrote:> Hi. I'm planning to make a game, and I have a couple of questions
> since I'm new to cocoa.
I'd highly recommend looking at CoreAnimation if you're going to
design a game. Its drawing model is very well suited to 2D sprite
animation. There's an Apple sample app called GeekGameBoard that
demonstrates using CA for games like checkers and solitaire:
http://developer.apple.com/samplecode/GeekGameBoard/index.html
It includes a small framework for generic board/card games, that you
can reuse and extend.
(Disclaimer: I wrote this sample. I'd be chuffed if someone wants to
use it, and I'll be glad to answer questions about it...)
I also have an unpublished/incomplete project that glues together
CoreAnimation and the open-source "Box2D" physics engine, letting you
add realistic 2D physics to your CA animations.
âJens -
On 17-Feb-08, at 1:21 PM, j o a r wrote:> In Cocoa you would typically use a NSTabView (with the actual tabs
> hidden) for this purpose. Or, alternatively, you would just insert /
> remove subviews manually from your root view.
Thanks. The tabless option for NSTabView is exactly what I needed.> In IB you set the default size & position for your views, but you
> can always change them at runtime.
>
> With regards to your concerns about keeping square proportions, take
> a look at "-[NSWindow setResizeIncrements:]", or alternatively "-
> [NSWindow(Delegate) windowWillResize:toSize:]".
Are you sure? I only want to control the resizing of the tile view
(that's what I'll call it) itself.
This is what I've tried so far. I have a function bestRect() that
takes an NSRect and the desired grid dimensions and returns a trimmed
NSRect. I use this in initWithFrame, and have also tried this in
setFrame to handle resizing.
----------
- (id) initWithFrame: (NSRect) frame
{
self = [super initWithFrame: bestRect(frame, 15, 10) ];
if (self)
{
gridWidth = 15;
gridHeight = 10;
}
return self;
}
- (void) setFrame: (NSRect) frameRect
{
[super setFrame: bestRect(frameRect, gridWidth, gridHeight) ];
}
----------
This works when the window is first shown, but it doesn't handle
resizing well. When I have it set to not expand and I shrink the
window to smaller than the tile view's initial size, its tiles get
squished out of proportion (so far I'm trying to get square tiles).
There's also the issue of the grid dimensions been magic numbers. I
want an initialization method where I provide the grid width, grid
height, and tile size. It's just that I can't see where I'd be able to
call that since it appears I can only access my tile view through
Interface Builder. This is especially troublesome if I want to have
more than one tile view, such where I have a main view screen and a
mini-map.
Thank you,
Aaron J. M. -
On Feb 17, 2008, at 7:20 PM, Aaron MacDonald wrote:>> With regards to your concerns about keeping square proportions,
>> take a look at "-[NSWindow setResizeIncrements:]", or alternatively
>> "-[NSWindow(Delegate) windowWillResize:toSize:]".
>
> Are you sure? I only want to control the resizing of the tile view
> (that's what I'll call it) itself.
Most of the time, changes to the width/height ratio of the view would
correspond directly with changes to the width/height ratio of the
window. Are you sure that's not the case in your app? That said, if
this option doesn't work out for you, you can always just
programmatically keep the view at the right size in response to
whatever other event that suits you.> This works when the window is first shown, but it doesn't handle
> resizing well. When I have it set to not expand and I shrink the
> window to smaller than the tile view's initial size, its tiles get
> squished out of proportion (so far I'm trying to get square tiles).
It sounds like you have some sort of bug in your resizing code. Add
logging statements to see how the size of your view correlates to the
size of your window as it is resized.> There's also the issue of the grid dimensions been magic numbers. I
> want an initialization method where I provide the grid width, grid
> height, and tile size. It's just that I can't see where I'd be able
> to call that since it appears I can only access my tile view through
> Interface Builder. This is especially troublesome if I want to have
> more than one tile view, such where I have a main view screen and a
> mini-map.
Make sure that the view is assigned to an "outlet" (instance variable)
of your window controller. This will give you a reference to the view
to be used at runtime.
j o a r -
On 17 Feb '08, at 7:20 PM, Aaron MacDonald wrote:> This works when the window is first shown, but it doesn't handle
> resizing well. When I have it set to not expand and I shrink the
> window to smaller than the tile view's initial size, its tiles get
> squished out of proportion (so far I'm trying to get square tiles).
Here's some old code of mine that ensures its window's main view
remains square, by always preserving the difference between the
window's height and width. This goes in the window's delegate object:
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
{
// This will get called _before_ awakeFromNib if frame default
has been set!
if( _extraHeight == 0.0 ) {
NSRect frame = [_window frame];
_extraHeight = frame.size.height - frame.size.width;
} else {
frameSize.height = frameSize.width + _extraHeight;
}
return frameSize;
}> There's also the issue of the grid dimensions been magic numbers. I
> want an initialization method where I provide the grid width, grid
> height, and tile size. It's just that I can't see where I'd be able
> to call that since it appears I can only access my tile view through
> Interface Builder. This is especially troublesome if I want to have
> more than one tile view, such where I have a main view screen and a
> mini-map.
Yeah, you can't use initialization methods with objects in nibs. You
can implement -awakeFromNib on the view subclass, or on an app/window
controller that will then tell the view to set itself up.
âJens -
On Feb 17, 2008, at 10:48 PM, Jens Alfke wrote:>
> On 17 Feb '08, at 7:20 PM, Aaron MacDonald wrote:
>
>> This works when the window is first shown, but it doesn't handle
>> resizing well. When I have it set to not expand and I shrink the
>> window to smaller than the tile view's initial size, its tiles get
>> squished out of proportion (so far I'm trying to get square tiles).
>
> Here's some old code of mine that ensures its window's main view
> remains square, by always preserving the difference between the
> window's height and width. This goes in the window's delegate object:
The significantly easier way is to use:
[window setContentAspectRatio: 1.0];
(Available from 10.3 on)
Glenn Andreas <gandreas...>
<http://www.gandreas.com/> wicked fun!
quadrium | prime : build, mutate, evolve, animate : the next
generation of fractal art -
On Feb 18, 2008, at 10:23 AM, glenn andreas wrote:> The significantly easier way is to use:
>
> [window setContentAspectRatio: 1.0];
>
> (Available from 10.3 on)
I think the aspect ratio setting is not enforced precisely enough or
in enough cases. I've had trouble with it not always working. If I
remember correctly it has shortcomings when it comes to zooming a
window, and perhaps is ignored when setting the frame programatically.
I can't remember all the reasons, but in my crossword solving
application it's important to keep the window a size that allows the
puzzle grid to be an even pixel multiple. I ended up enforcing it in
windowWillResize and windowWillUseStandardFrame.
Daniel -
On Feb 18, 2008, at 11:22 AM, Daniel Jalkut wrote:> On Feb 18, 2008, at 10:23 AM, glenn andreas wrote:
>
>> The significantly easier way is to use:
>>
>> [window setContentAspectRatio: 1.0];
>>
>> (Available from 10.3 on)
>
> I think the aspect ratio setting is not enforced precisely enough or
> in enough cases. I've had trouble with it not always working. If I
> remember correctly it has shortcomings when it comes to zooming a
> window, and perhaps is ignored when setting the frame programatically.
>
I've not seen that personally, though setAspectRatio suffers from such
a fate (since it includes the title bar in the aspect ratio, making it
basically useless).>
> I can't remember all the reasons, but in my crossword solving
> application it's important to keep the window a size that allows the
> puzzle grid to be an even pixel multiple. I ended up enforcing it in
> windowWillResize and windowWillUseStandardFrame.
>
> Daniel
Since you needed pixel multiples, you'd also need to use
setContentResizeIncrements:
There may be a bug that the zooming doesn't use
setContentResizeIncrements (I've never needed that functionality) but
from what I remember, setAspectRatio worked fine with zooming.
Glenn Andreas <gandreas...>
<http://www.gandreas.com/> wicked fun!
quadrium | flame : flame fractals & strange attractors : build,
mutate, evolve, animate -
On Feb 18, 2008, at 9:22 AM, Daniel Jalkut wrote:> I think the aspect ratio setting is not enforced precisely enough or
> in enough cases. I've had trouble with it not always working. If I
> remember correctly it has shortcomings when it comes to zooming a
> window, and perhaps is ignored when setting the frame programatically.
This is true for most of Cocoa: All the different API:s for
restricting things (max/min size of windows, control of the selection
in table views, etc.) only applies for user actions. The restrictions
doesn't apply for programmatic control of these properties.
j o a r


