Implementing "begin contact" in box2d - c++

I am working on a game in box2d. I have the following code:
for (int contact_num = 0; contact_num<contact_count; ++contact_num)
{
if (contact->IsTouching())
{
// get the colliding bodies
b2Body* bodyA = contact->GetFixtureA()->GetBody();
b2Body* bodyB = contact->GetFixtureB()->GetBody();
// check if one of the colliding objects is a censor
bool sensorA = contact->GetFixtureA()->IsSensor();
bool sensorB = contact->GetFixtureB()->IsSensor();
// do stuff, mainly handling variables
}
}
// Get next contact point
contact = contact->GetNext();
}
All of this is being called in the update function of my main class (which also contains most of the games variables). The problem is that I want the code to only be called when the two objects first collide, because otherwise something like score++ will end up skyrocketing in value as it gets updated for the collisions duration. I am aware of a "contact listener" class in box2d with the function "begin contact", but there is no good documentation that could help a beginer learn how to implement it. For example, if I add a contact listener to my main class, how do I get it to handle my score, for example, if the contact listener doesn't have access to those variables? Or where do I call "begin contact" in the first place? Sorry if these are obvious questions, but i was hoping someone could clarify these. Thank you in advance.

Here's a couple suggestions which hopefully will answer your question:
Take a look at Box2D C++ tutorials - Collision callbacks. Personally, I think it's a great tutorial on using the b2ContactListener class.
Just make your class which contains the score information inherit from b2ContactListener. That way your BeginContact method will have direct access to the score data. Presumably that'll be your "main" class. Be sure to also notify your b2World instance to use this by calling your world instance's SetContactListener method with a pointer to the score containing instance (that you'd subclassed from b2ContactListener).
If you still need more help with this, please add a comment to that effect or update your question to reflect what remains unclear.

Related

Touch Event on Sprite with Cocos2d-x 3.x?

In my scene I have a vector with multiple custom sprites. When I tap on one of them, I want an action to be fired on another element on the scene, can be another sprite in the vector, or another node. I have been researching the best way to do this, but I'm not quite sure how to implement it. The options are:
Add a touch listener to the scene, and verify if it was tapped inside the bounds of the sprite with rect. containsPoint(point). And after that, I have to get the sprite that was tapped to do the action I want. For me, it doesn't seems very clean to do it this way. And if two sprites are overlaped, I have to verify if the sprite is behind or in the front in order to retrieve the desired sprite. I followed this example: Touch Event example
Add a touch listener in the subclass of the sprite (my custom sprite). And add onTouchBegan and onTouchEnded inside it. But this way, I don't know how to modify an attribute of another sprite, or another element in the scene (Is it possible to use Delegates like Objective-C does?). I followed this example: Subclass Sprite Example
My main problem is that I don't understand very well how to make a node interact with another node in the scene. I have seen a lot of tutorials, but in all of them, when you interact with a node, it only changes its attributes, not other nodes' attributes.
Thanks in advance.
I shall propose "EventCustom" way :)
You can add in your touchBegan / touchEnded methods (wherever you put them... you got the point...) additional code for passing an EventCusto to the _eventDispatcher and get it announced to the world ;)
EventCustom *e = new EventCustom("MyAwesomeEvent");
e->setUserData(ptrMyFantasticData); //This function takes a void pointer. cheers :)
_eventDispatcher->dispatchEvent(e);
You may subclass the EventCustom class but that is hardly necessary. You can always hang an object to it with setUserData().
Now the objects which need to react to the event can listen to it by
_myCustomListener = EventListenerCustom::create(
"MyAwesomeEvent",
CC_CALLBACK_1(
ListeningClass::onMyAwesomeEvent,
this
)
);
_eventDispatcher->addEventListenerWithXXXXXPriority(_myCustomListener, XXX);
//ScreenGraphPriority / FixedPriority depends on situation. Either should work.
It's always a good practice to remove your listeners when you go off, so somewhere, perhaps in onExit(), where you removed touch listeners remove this listener too, as
_eventDispatcher->removeEventListener(_myCustomListener);
Going a bit off the track, a clarification:
CC_CALLBACK_X are a bit tricky names. The X indicates the no. of args the target function will get. Here, event dispatcher will pass 1 arg i.e. ptr to object of EventCustom you handed it, so we use CC_CALLBACK_1. The next arg - here "this" - is the object on which the method will be invoked.
In short, we may say that this callback is going to result into a function call this->onMyAwesomeEvent(e);
For CC_CALLBACK_2 onwards, we can specify additional args, 3rd arg onwards.
Coming back to the issue at hand, ListeningClass::onMyAwesomeEvent will look something like
void ListeningClass::onMyAwesomeEvent(EventCustom *e)
{
MyFantasticData *d = (MyFantasticData *) e->getUserData();
CCLOG("[ListeningClass::onMyAwesomeEvent] %d", d->getMyPreciousInt());
}
Hope it helps :)
Set your elements tags or names with setTag and setName. Then if element x is touched, get them with getChildByTag or getChildByName and do what you need to do.
With the second option you list above.
To make a node interact with another node in the scene you can add touch callback function to your custom sprite object like that:
https://github.com/Longpc/RTS/tree/master/Classes/base/dialogBase
and in main scene you can define function to handle this callback. So you can do every thing to unit in you scene

Using Cocos2d-x SEL_CallFunc

I'm trying to make a custom sprite, which could receive touch and handle the function as callback.
Okay, first step, receive the touch, easy, we can search it online everywhere.
The one I couldn't do is, I want to make it receive SOMETHING in the class the sprite is created, a function that will be called when the sprite is touched.
I was searching on internet and I think (not really sure) that SEL_Callfunc can do what I want, but I couldn't understand how this one work, so can you guys give me an example please?
For example, my custom class is BSprite, so when I create new object in HelloWorld.cpp, it should be
BSprite* sprite = BSprite::create("HelloWorld.png",HelloWorld::TouchCallback);
Thanks for reading :)
sprite->addTouchEventListener(CC_CALLBACK_0(HelloWorld::onTouchSprite, this));
void HelloWorld::onTouchSprite() {
}
Note: onTouchSprite method should not have any parameters

Correct way in OOP. Game example. Player::walk or Map::playerWalk?

Let's suppose there is a game. There is a map class and a player class. Map stores fields and fields stores players.
Which would be a proper way to do in OOP. When method responsible for player walking would be Player::walk or Map::playerWalk?
Concerning first example (Player::walk), it seems that it is correct way to do and its like in real life - its player who walks,
however it would have to access destination field through map instance, check if it can walk there, remove its from start field and add its on destination field, I have impression that Player would "know too much".
Ultimately this is a design question, both could fit well within the OOP paradigm.
I tend to place methods on the class that makes the most sense semantically. In this scenario, that means Player::walk, unless the map does something to make "players" move (I.e. in a flippers game, the game board makes the ball [aka 'player'] move) and then it may be more semantic to have that entity call for instance Board::movePlayer.
You should pass the map instance to the player if you go for the Player::walk design. So you end up with Player::walk(Map &map /*more parameters here, maybe a direction or vector speed?*/).
The other thing to point out is that you should try to tell more than you ask. What this means is that rather than:
//in Player::walk
if (map.cells[wantToWalkTo] == 0) {
map.cells[wantToWalkTo] = this.playerId;
}
//TODO: handle failed moves
You should do something like:
bool moved = map.moveTo(position, this); //encapsulate the logic for moving a player to a position
//TODO: handle failed moves
Your player instance doesn't have to "know" all those things. It can communicate with the Map instance through an interface. A person can look out at their surroundings and see some things, but not others (e.g. can see a wall, but not what's behind it). The Map instance can be in control of what is visible and what isn't.
Python-ish pseudo-code:
class Player:
def __init__(self, Map, location):
"""Create a player, and tell them what Map they live on."""
self.Map = Map
self.location = location
def walk(self, destination):
"""Try to walk to the destination."""
path = self.Map.path_visible(location, destination)
if path:
self.location = destination
class Map:
def path_visible(self, location, destination):
"""Can a player at location see how to get to the destination?"""
Correct OOP approach would be for the map to present some kind of interface which would allow to:
Check whether some field is empty / what object is on that field
Place objects on the map / remove them
The logic of moving the player should be entirely in the Player class. So checking whether target field is reachable by the player, whether is empty, etc... should be handled by the Player using information provided by the Map interface or other classes. Consider for example situation when you would like to allow player to walk through walls, walk on water or similar stuff - it's the player who changes, not the map!

How to layout a program?

I'm making an Arkanoid clone. This is the program layout I came up with:
source.cpp // few lines
App class // has constants APP_WIDTH and APP_HEIGHT
Ball class // has constant RADIUS
Brick class
Paddle class
Now I want to place the ball at the center of the window at the beginning of the game. Normally I would accomplish it like this:
Ball::Ball (App &app)
{
circle.setPos(app->WINDOW_WIDTH/2-RADIUS/2,app->WINDOW_HEIGHT/2-RADIUS/2)
}
But the ball class doesn't know anything about the App!
Do I need to make APP_WIDTH and APP_HEIGHT global variables?
Or do I need to turn the current app layout upside down, so that Ball class has #include "app.hpp" statement?
EDIT: Or do I need to declare ball, brick and paddle classes inside the app class? But then where I define them? Inside the same app class? Then the header gets too big!
And maybe there are some good tutorials on program layout topic on the internet? I haven't found any...
QUESTION 2:
Why do classes need protected variables if "there is no reason that ball would know anything about app class"
Since the issue seems to be that "Ball doesn't have any access to the private members of app class.", than maybe you want to make a getter.
A getter is a public method that returns the value of a private field.
If you do that, you can access the values of those members like so
circle.setPos(app->GetWidth()....
Your getter might look similar to the following
public int GetWidth()
{
return this.APP_WIDTH;
}
There is no reason for the game objects to know anything about the App they are part of. When it needs any information from App, it should receive them from App directly. This can happen either through setter-methods (recommended when properties can be changed by the App later, like the position of the ball) or in the constructor (recommended for things which don't change, like the positions of blocks).
Ball should have a SetPosition(x,y) which app invokes with the above calculation. Internally, this SetPosition would set the circle like above, so ball knows nothing about app.

C++ parallel loops

I'm making a console game called alien spaceships as a homework. It should look something like this http://img74.imageshack.us/img74/8362/alieninvadersfdcl192720mu1.jpg .
So far so good I ain't allowed to use classes nor objects => only functions and arrays.
I have one while loop that checks the buttons I press on the keyboard and according to the button applies some functions.
The problem comes when I try to shoot a missle because it's done with a "for" loop and when I shoot I can't move. Can someone give me an idea how the model is supposed to look like and how can I make something like this work. I don't think it's needed to post my code, but if you want I'll post it.
I assume that you're not willing to play with multiple threads. It is not mandatory for a simple game like this and would add a bit of complexity.
So generic loop for monothreaded game is:
state new_state = createInitialState();
do
{
input = readInput(); // non blocking !
new_state = modifyState(input, new_state);
updateScreen(new_state);
}
while (!exitCondition(input));
None of these functions should loop for long.
In your case, the missile position should be updated in modifyState taking into account the time since the last modifyState.
I assume you use a matrix to store all the data, and periodically you print the content of the matrix (that's how you create a console game).
So, your code should look something like this:
render()
{
update_position(x,y);
if(missile_fired)
update_missile_position();
}
main()
{
for(;;)
{
read_input(&x,&y);
render();
draw_image();
}
}