I'm creating a simple app which has a list of characters and a list of (4) players, the players is simply a reference to a playable character.
I'm stuck on how to do the following:
Make a reference to the current player on turn
Find out who the next player on turn is
Handling the last player so that it will return to the first player on turn.
Ideally, I would like to be able to do AFTER, FIRST, LAST BEFORE commands on a NSMutableArray, of these I'm able to do lastObject, but there is no firstObject, afterObject, etc.
I believe you can fake BEFORE,AFTER,FIRST commands with objectAtIndex; but ideally I do not want to rely on numeric references because it could be incorrect -- also if its mutable, the size will always change.
Typically, I would be able to do the following in Pseudocode.
Global player_on_turn.player = Null //player_on_turn is a pointer to the player object
; Handle next player on turn
If (player_on_turn.player = Null) Then Error("No player on turn assigned")
If (sizeOf[playerList]==0) Then Error("There are no players in the game")
If After player_on_turn = null Then
; We reset it
player_on_turn.player = First player
Else
; Move to the next player on turn
player_on_turn.player = After player_on_turn.player
End If
With this in mind, what is the best strategy to help handle a player on turn concept as described in the 1-2-3 example above.
Thanks
It probably doesn’t matter what data structure you’re using - at some level you will have to rely on a numerical index (except if you are using linked lists). And this is alright. If you don’t want to use it in your main game implementation that is alright, too. Just create a class that encapsulates those things. First think of the operations you need it to support. My guess here would be those:
- (PlayerObject *) currentPlayer;
- (void) startNextTurn;
If you have this you can write your game using those primitives and worry about how to best implement that later. You can change those at any time without breaking your actual game.
My recommendation would be something like this:
- (PlayerObject *) currentPlayer; {
return [players objectAtIndex: currentPlayerIndex];
}
- (void) startNextTurn; {
++currentPlayerIndex;
if (currentPlayerIndex >= [players count]) {
currentPlayerIndex = 0;
}
}
Using the index there is OK, even if the array is mutable. If you have methods that change the player array they also can take care of the necessary changes to the currentPlayerIndex.
Having this object makes it easy to write unit tests. The global variable you suggest in your pseudo-code makes it impossible to write meaningful unit tests.
Use a State Pattern for the main runloop of the software. Draw it out as a diagram and create variables to control which state the system is in.
You should use a circular list of the players to return current, next, and previous players.
This is also a great question for GameDev on the Stack Exchange.
PS
CocoaHeads puts out a relatively nice set of data objects, including a circular buffer.
Related
Sorry in advance, this is an extremely noobie question (but i'm just getting into NGUI with unityscript and can't find many answers/tutorials/docs).. Also my untiyscript skills are sub-par.
I have a TCG/Playing card game object with some basic RPG stats (strength, dexterity) that currently display on the card in GUIlabel and trying to convert this to NGUI. I'm adding a UILabel as a child to the card (which contains the stats script)
Looking for some advice on going about this, the only way I've even remotely gotten something to display correctly is, unfortunately I have to attach the stats script to the label too:
var strLbl : UILabel;
function Start() {
var strLbl = GetComponent(UILabel);
}
function OnGUI() {
strLbl.text = strength.ToString();
}
This is throwing numberous 'nullreferenceexception: object reference not set to an instance of an object (for the stats script)
Do I need to make a separate label for each stat or is there a way
to aggregate it into one label? (seems when I try to add strength
,then dexterity it overrides it)
is OnGUI the correct course for NGUI or is there a more efficient
function?
Is this script attached to the object that the UILabel is on? You should do a check for
if(strLbl != null)
strLbl.text = strength.ToString();
You could aggregate them into one label (though if individual stats update I would advise against it), assuming you want each stat on a newline then your next would be: strLbl.text += "\n" + dexterity.ToString()
No need to use OnGUI with NGUI. Especially not for setting things. You probably want to do this whole stage in Start() and have another method called for updating the label.
I'm running an update() method n times per second to "update" the keyboard input from the user so I can read it later in the logic part of the program. So I find two ways of implementing this in the SDL Docs and I'm not sure which one should I use.
1; Loop for all events using SDL_PollEvent searching for key down/up events and saving the key states in a map so I can check for each key state in the logic of the program.
Note: Alternatively, I can also use SDL_PeepEvents instead of SDL_PollEvent to take only the event types that matter; so, it would not "thrown away" the events on the queue.
std::map<int, bool> keyboard; // Saves the state(true=pressed; false=released) of each SDL_Key.
void update()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
keyboard[event.key.keysym.sym] = false;
break;
case SDL_KEYUP:
keyboard[event.key.keysym.sym] = true;
break;
}
}
}
2; Taking a snapshot from the keyboard each frame so I can read it easily.
Uint8* keyboard;
void update()
{
SDL_PumpEvents();
keyboard = SDL_GetKeyState(NULL);
}
With any of above implementations I can read keyboard just like this:
if (key_map[SDLK_Return]) printf("Return has been pressed.");
Also, is there another way to do so?
I prefer to do a variation of 1, where I fill three arrays, indicating not only the current state, but also which keys just went down and which keys just went up. This allows me to easily check for those events in code (without comparing to the previous snapshot), but, most importantly, it won't miss events that last less than a frame. For example, if your game is running at 10 fps due to a slow machine, the user might press and release an important key between two calls of your update routine, and then your system will never register it. This is extremely frustrating.
SDL also sends key events when the key is held down, which allow you to have multiple key down events for each key up. I find this particularly useful when implementing keyboard scrolling through a list of items, e.g. a keyboard-controlled menu.
You should use solution 2.
Why? As SDL_GetKeyState() docs point out, before using it you are expected to call SDL_PumpEvents() to update the state array.
When you are calling SDL_PollEvent(), it implicitly calls SDL_PumpEvents(). So, it basically updates the array for SDL_GetKeyState() anyway. By parsing these events manually, you just create a second array (well, actually a much slower map) holding the same information which SDL already collected for you.
So, I would dare say that first solution means doing the same thing twice. And if you ever decide to support things such as repeated keystrokes (SDL_EnableKeyRepeat()), you'll be reimplementing even a larger part of SDL.
I realize this question is quite old, but my answer could benefit someone. Personally, I use two arrays with SDL_GetKeyState. I store one array holding the current frame's keyboard state, and one array holding that last frame's keyboard state. (With some memcpy commands, it's really easy to update them.) Along with those two arrays, I have a map that converts strings like "A" to the SDL scancode values, but that is optional.
Then, when you need to check if something is released or pressed, you can combine the two arrays to check. (I made this a function.) For example, if you know that the key is pressed this frame, but wasn't pressed last frame, it was clearly just pressed this frame. if (currentFrame["A"] == true && lastFrame["A"] == false) {/*just pressed*/}
You would then do the opposite for the released. I find that method super easy to implement and use.
I have a question regarding nested arrays of objects.
I’m writing a simple objective c program (I’m a beginner) and I was wondering whether it is advisable to structure an array in such a way that not only are all the individual batting scores be logged (data), but also methods embedded in the nested arrays could be used to interrogate the this data.
For example the line below is easily readable (even for those who are not cricket fans!)
Team1.Over[2].BowlNumber[3].score = 6
Team 1 scored a 6 during the 3rd bowl in the 2nd Over.
I would also like to do something like the following where I can use a method to interrogate the data. The method line below would just cycle through the scores within BowNumber[] and total the scores up
Total = Over[2].TotalForAmountForOver()
I could set up and manage all the arrays from within main() , but its much easier to read if I can embed as much as possible within the structure.
Is this a common approach?
Haven't seen many examples of fairly complicated embedded arrays of data and methods….
You'd easily be able to achieve this by making Over cant Bowl classes that each wrap an NSMutableArray object. e.g.
- (void)getOverNumer:(int)index {
return [overs objectAtIndex:index];
}
You'd then access it like this:
[[team1 getOverNumber:2] getBowlNumber:2].score = 6;
int total = [[team1 getOverNumber:2] totalForAmountForOver];
You'd implement totalForAmountForOver as a method within your Over class.
Im using cocos2d (iOS) and box2d to create a game.
I have come to the point where I need to change the contact filter mid simulation and wondering how to go about this.
I need to use maskbits and categorybits, which is fine, im just unsure how to apply them to a b2body mid game.
I'm thinking I may need to retrieve the original b2fixture or b2fixturedef of the b2body on initialization, alter the values accordingly then call a method to refresh - world.Refilter()?
Does this sound somewhat accurate?
Any advice is surely appreciated
Oliver.
b2Filter filter;
for ( b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext() ) {
f->GetFilterData( &filter );
filter.categoryBits = ...;
filter.maskBits = ...;
filter.groupIndex = ...;
f->SetFilterData( &filter );
}
Obviously this would change the filter settings for all fixtures on a body - if you want to be more selective you will have to be able to tell which fixture is which somehow. Eg. if you know it's the only circle fixture you could just look at the type of the fixture to decide, otherwise you would have to make use of the fixture's user data I guess.
You can iterate over all bodies in the b2World. On each body you can iterate over it's fixture and change it's filter. To identify your bodies you can use userData.
The answer from iforce2d might be obsolete. I got the following code working properly with box2d v2.2.1, cocos2D v2.0.0 using Xcode v4.5.2 (here I assume I have a pointer to a b2Body named 'body' with only one fixture, i.e., I don't iterate over all fixtures on the body):
b2Fixture *fix = body->GetFixtureList();
b2Filter filter = fix->GetFilterData();
filter.groupIndex = -1*kPlayerGroupIndex;
fix->SetFilterData(filter);
In the above code I prevent 'body' from colliding with my player body which also has the same groupIndex value, i.e., -1*kPlayerGroupIndex, where kPlayerGroupIndex is a positive integer constant. Any bodies with this negative groupIndex never collide with one another. You could also update the categoryBits or maskBits accordingly to prevent collisions.
GetFilterData(&filter) and SetFilterData(&filter) returned errors for me given the version numbers I quoted above.
first post here so sorry for the length of it. I've been lurking and learning a lot so far but now I have to step in and ask a question. I have read numerous posts here as advised in the FAQs, but I couldn’t find exactly the answer I’m looking for.
Before anything else, let me just say that I'm a total beginner in programming (let alone Objective-C) so please excuse me for any misuse of the terminology. Same goes for any funny english as english not my native language.
I'm building an unit conversion application with a main window containing (among other stuff) two popUpButtons. I'm using indexOfSelectedItem from both popUpButtons in order to calculate a float value (I'm getting the indexes initially in the AwakeFromNib and later in the pop up buttons controller method, when the user change selection).
My problem consists of two parts: first, the code for calculation of that float is pretty massive as I'm comparing every combination of the two indexes of selected items. And second, I would need to have the calculated float value available immediately after launch as the user might want to perform a conversion before using any of the window popUpButtons (otherwise I would put the calculation code in a -(IBAction) method).
So, I'm trying with the following code for calculation of the float value:
#interface MyClass: NSObject
float calculatedFloat;
-(void)setCalculatedFloat:(float)calcFl;
-(float)calculatedFloat;
#implementation MyClass
-(void)setCalculatedFloat:(float)calcFl {
calcFl = 1.0; // I'm simplifying, this is where I'd like to perform calculation
}
-(float)calculatedFloat {
return calculatedFloat;
}
Now, for the first part of my problem, when I use the calculatedFloat in another method, say:
-(void)printIt {
NSLog(#"Calculated float equals: %.2f", calulatedFloat);
}
all I receive in Debugger is 0.00.
First question would be: if this is not working, how do I properly access this value from within another method?
For the second part of the problem, I'm using -(void)AwakeFromNib; to set up popUpButtons etc. right after the launch but I really wouldn't like to put all of the float calculation code in it only to repeat it somewhere else later.
So the second question would be: is this even possible what I'm trying to achieve? Further more, do I need to move this calculation code to another class? If so, how can I make that other class aware of the indexOfSelectedItem from a popUpButton?
Sorry for the lengthy post and possibly confusing and silly questions. I hope you didn't have to cringe your teeth too much while reading! :)
Thanks!
-(void)setCalculatedFloat:(float)calcFl {
calcFl = 1.0; // I'm simplifying, this is where I'd like to perform calculation
}
This doesn't show up when you print it later because you assigned to the variable holding the new value, not the variable for the value of the property. You need to assign to your calulatedFloat instance variable.
(You typo'ed that variable name, BTW.)
You should move the calculating into another method, and send yourself that message from awakeFromNib and from anywhere that needs to cause recalculation. That method should call setCalculatedFloat: with the calculated value—i.e., setCalculatedFloat: should be just a simple setter. Once you make that change, you could replace your custom accessors with a #synthesize statement and let the compiler write the accessors for you.
My problem consists of two parts: first, the code for calculation of that float is pretty massive as I'm comparing every combination of the two indexes of selected items.
You might see whether you can create custom objects to set as the menu items' representedObject properties, in order to cut out this massive comparison tree. It's hard to be more specific about this without knowing what your comparison tree does.