Box2d - Changing contact filter on the fly - objective-c

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.

Related

ngui dynamic text advice (from a noob)

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.

What is the most efficient way to store the location of 4 properties (NSPoints)?

So I am passing a view into a method, and I want to find the properties of some values from a CGRect that is contained within the view.
- (void)blahblah:(someView*)view
int originX = view.myCGRect.origin.x;
int originY = view.myCGRect.origin.y;
int width = view.myCGRect.size.width;
int height = view.myCGRect.size.height;
would this be a better way of writing it?
- (void)blahblah:(someView*)view
CGRect sameCGRect = view.myCGRect;
int originX = sameCGRect.origin.x;
int originY = sameCGRect.origin.y;
int width = sameCGRect.size.width;
int height = sameCGRect.size.height;
Or is there an even more efficient way of doing this?
Also, I'm new to objective-C so could somebody explain if there even is a difference between these two implementations; and if so, what is it?
In reference to the older, previously accepted answer:
In this case the compiler would not be able to perform the subexpression elimination automatically. The reason is that view.myCGRect is actually a dynamically dispatched message.
Since the compiler does not know in advance which method will be called and what side effects it might have it cannot just drop the redundant calls because there might be a semantic difference.
The second code snippet will be more performant.
See Comments:
What you're talking about doing is manual "common subexpression elimination", where a common value (view.myCGRect in this case) is "hoisted" ahead of several references to it. This is especially effective for loops, when the common code is placed outside the loop. But for most (but not all) cases the compiler (or JITC for Java) will be able to recognize these CSEs and "hoist" them automatically. However, I still find that the code is often easier to follow (and maintain) if you do the manual operation.

AS3, Simple: Changing movieclip properties from inside its Time Line

Another one noobie question.
I have movieclip spaceship_mc on Main Timelime.
Its instance name is spaceship1_mc (added from library manually).
In Library this symbol has 2 layers: Objects layer and Action layer.
I put inside Action layer such simple code:
var spaceship1_mc:MovieClip = new MovieClip;
spaceship1_mc.blendMode = BlendMode.SCREEN;
spaceship1_mc.scaleX = 2;
spaceship1_mc.scaleY= 2;
I suppose, that at run time this code must work automatically, and all those parameters will be set at the very beginning.
However, nothing changes. As if this code doesn't work.
QUESTION1: Please, tell me what is wrong?
Maybe I should use some more complicated dot-syntax?
QUESTION2: What is the name of Main Time Line?
I tried to use stage, root, MainTimeLine, in the code above, but it doesn't work.
Using google I've found one decision.
Perhaps, It is somewhat redundant and (..Hey...WTF? It's helicopter at the skyline, dudes!...Cool...)... Okay.
And here it is:
var ship1:MovieClip = parent.getChildByName("spaceship1_mc") as MovieClip;
ship1.blendMode = BlendMode.SCREEN;
ship1.scaleX = 2;
ship1.scaleY= 2;
Well... I suppose it is somewhat too indirect.
So we must read the name of some Instance and determine it as variable. I guess there must be some more laconic way.

Handling player on turn with Objective C

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.

How to properly return a value from a method and have it available immediately after application loads?

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.