I have a basic class for detecting collisions but I can't figure out how to see what bodies are colliding to trigger the appropriate event. Lets say I have a pong game and in it a ballBody and topwallBody. How would I figure out if these are colliding or not. Here is the class I'm using just to give you an idea.
class MyListener : public b2ContactListener
{
void BeginContact(b2Contact* contact)
{
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
b2Body* body1 = fixtureA->GetBody();
b2Body* body2 = fixtureB->GetBody();
cout << "started";
}
void EndContact(b2Contact* contact)
{
cout << "ended\n";
}
};
MyListener listener;
world.SetContactListener(&listener);
It looks like I can get the bodies in the pointers but I have no idea how to compare them to other bodies.
When you create the bodies, set the userdata to something meaningful, but be consistent :) A good tip is to always have the same kind and type of data in there, an entity id or reference to an actor.
Straight from the documentation:
b2BodyDef bodyDef;
bodyDef.userData = &myActor;
So if you went this road you would get the actor from the b2Body and inform it of the collision, or do something else.
Also from the docs:
b2Fixture* fixtureA = myContact->GetFixtureA();
b2Body* bodyA = fixtureA->GetBody();
MyActor* actorA = (MyActor*)bodyA->GetUserData();
In the code above you would have the actor/entity and could do whatever you would like... actorA.explode().
Being consistent will likely save you from insanity. If one sticks all kinds of data in there it'll become really hard knowing what data is in what body. Plus you can't really handle the contacts in any generic way.
The answer Skurmedel gave helped me immensely on this. I thought I would add a little bit of information from what I was doing to solve this.
I, like the OP, wanted to check what was hitting what. I have hearts bouncing around inside the walls of the game screen and wanted to know if they are hitting other hearts, or the walls.
I used this code to view the contact
world.setContactListener(new ContactListener() {
#Override
public void beginContact(Contact contact) {
Gdx.app.log("GameScreen", "Contact Made! Fixture A: " + contact.getFixtureA().getBody().getUserData().toString());
Gdx.app.log("GameScreen", "Contact Made! Fixture B: " + contact.getFixtureB().getBody().getUserData().toString());
}
And within my heart object I overrode the toString method to simply return 'Hear' for now. I am setting the userData for the body as the whole sprite object, so I have flexibility with the body in the object itself.
Not having my actual class references for the floor, walls, and ceiling I simply set the userData as 'Floor' etc.
GameScreen: Contact Made! Fixture A: Ground
GameScreen: Contact Made! Fixture B: Heart
Using this method, and beefing it up later, I will be able to change how the objects react based on who they are contacting.
Related
I'm writing a roboter controller class Controller in which I'm using a struct Axis for each of the 4 controllable motors.
For each test I want to reset everything, so I created a pointer in the class which is changed to a new Controller before each test method. The initialisation works fine in TEST_METHOD_INITIALIZE, but once any TEST_METHOD is called the program seems reset the Axis pointers.
Thanks for your help!
Edit: After further analysis I have the theory, that the initialised Axis objects Axis init_mx are deleted after the method is finished.
Edit2: I think this a slightly more complex problem like this: Pointer to local variable in C++
Nevertheless, I didn't find a way to reset the Axis variables at for every method without actually resetting each variable in it.
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
...
namespace UnitTest
{
TEST_CLASS(UnitTestController)
{
public:
Controller* controller;
struct Axis *mx, *my, *mz, *mg;
TEST_METHOD_INITIALIZE(methodName)
{
Axis init_mx(50), init_my(50), init_mz(50), init_mg(5);
mx = &init_mx;
my = &init_my;
mz = &init_mz;
mg = &init_mg;
Controller init_controller(mx, my, mz, mg);
controller = &init_controller;
}
...
TEST_METHOD(id_3_next_mode)
{
mx->position = 5;
controller->getAxisPositionMx();
//Axis in pointers got reset and therefore have no pointers to the
//provided structs from TEST_METHOD_INITIALIZE
}
}
};
}
Controller.h(excerpt):
private:
struct Axis *mx, *my, *mz, *mg;
Controller.cpp (excerpt)
Controller::Controller(Axis *mx_in, Axis *my_in, Axis *mz_in, Axis *mg_in)
{
mx = mx_in;
my = my_in;
mz = mz_in;
mg = mg_in;
}
You found your original bug, but I think it's worth pointing out some details of how test modules, classes, methods, and the special initialize/cleanup methods are intended to work.
The most important thing to note is that a new instance of the class is instantiated every time a test method is executed, so each test will have a fresh set of class variables. This means that your example test class could look like:
TEST_CLASS(UnitTestController)
{
public:
struct Axis mx, my, mz, mg;
Controller controller;
// Define a constructor to initialize the class variables
UnitTestController() :
mx(50), my(50), mz(50), mg(50),
controller(mx, my, mz, mg)
{
}
TEST_METHOD(id_3_next_mode)
{
mx.position = 5;
controller.getAxisPositionMx();
}
};
If you wanted to have a variable persist between tests, you could put it outside the test class.
namespace UnitTest {
SomeClass moduleVar1;
TEST_CLASS(UnitTestClass)
{
public:
TEST_METHOD(TestMethod1)
{
Assert::IsTrue(moduleVar1.SomeMethod());
}
TEST_METHOD(TestMethod2)
{
Assert::IsFalse(moduleVar1.SomeOtherMethod());
}
};
}
The framework also provides the following Initialize and Cleanup functions which can be used to manipulate the test environment and fixtures:
TEST_METHOD_INITIALIZE - Called once before running each test method.
TEST_METHOD_CLEANUP - Called once after running each test method.
TEST_CLASS_INITIALIZE - Called once per module before running any tests belonging to this class.
TEST_CLASS_CLEANUP - Called once per module after running all tests belonging to this class.
TEST_MODULE_INITIALIZE - Called once per module before running any tests or class initalizers.
TEST_MODULE_CLEANUP - Called once per module after running all tests and class cleanups.
Unity3D 2018.2
So I have a canvas that gets deactivated and reactivated at users choice. I have a List filled with transforms in which I populated the Grid with. I also have another List to hold all the images that will be used to populate the Grid with, since what the grid is being populated with are buttons containing the transform. For example if I click the button and run Debug.Log("transform.name"), I should see all my different transforms.
Problem 1: Every time this canvas gets enabled or disabled, the grid
keeps adding 1 element under the initial one, and after being
enabled/disabled again, another element is instantiated under that
one.
+
Problem 2: Also none of these instantiated buttons get called. Maybe
the problem here is due to the 1st problem?
Here is the code I have for inside the button I have
public class SatelliteButton : MonoBehaviour {
[SerializeField]
private Image myIcon;
public void SetIcon(Sprite mySprite)
{
myIcon.sprite = mySprite;
}
public void OnMouseEnter()
{
Debug.Log(transform.name);
}
}
Here is the code for populating the grid
public class SatelliteGridControl : MonoBehaviour {
private List<Transform> satelliteListFromPlanet;
[SerializeField]
private GameObject buttonTemplate;
[SerializeField]
private GridLayoutGroup gridGroup;
[SerializeField]
private List<Sprite> iconSprites;
// Use this for initialization
void OnEnable()
{
getSatellitesInPlanet();
genInventory();
}
// Get Satellites
private void getSatellitesInPlanet()
{
satelliteListFromPlanet = new List<Transform>();
// Get current planet
Transform currentPlanet = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<HandleCamera>().targetToLookAt;
// Check inside for satellites
foreach (Transform satellite in currentPlanet)
{
// Check transform for tag
if (satellite.CompareTag("Satellite"))
{
// Add each transform from planet to array
satelliteListFromPlanet.Add(satellite);
}
}
}
// Handle Grid
private void genInventory()
{
if (satelliteListFromPlanet.Count < 6)
{
gridGroup.constraintCount = satelliteListFromPlanet.Count;
}
else
{
gridGroup.constraintCount = 5;
}
foreach (Transform sat in satelliteListFromPlanet)
{
GameObject newButton = Instantiate(buttonTemplate) as GameObject;
newButton.SetActive(true);
newButton.GetComponent<SatelliteButton>().SetIcon(iconSprites[Random.Range(0, iconSprites.Count)]);
newButton.transform.SetParent(buttonTemplate.transform.parent, false);
}
}
}
I appreciate the help! Learning about grid layouts with List<>!
In genInventory() you Instantiate a new button for every Transform in satelliteListFromPlanet. Since only 1 is added it seems that your list only contains 1 element.
But you never destroy/remove this Instantiated GameObjects, so the next time you re-enable the object, OnEnable will be called again and new prefabs are Instantiated.
Solution:
Make sure to store the Instantiated objects somewhere e.g.
private List<GameObject> instances = new List<GameObject>();
//....
foreach (Transform sat in satelliteListFromPlanet)
{
GameObject newButton = Instantiate(buttonTemplate) as GameObject;
newButton.SetActive(true);
newButton.GetComponent<SatelliteButton>().SetIcon(iconSprites[Random.Range(0, iconSprites.Count)]);
newButton.transform.SetParent(buttonTemplate.transform.parent, false);
instances.Add(newButton);
}
And than you can destroy them when you disable the object:
private void OnDisable()
{
foreach(var instance in instances)
{
Destroy(instance);
}
}
Problem 1: Every time this canvas gets enabled or disabled, the grid keeps adding 1 element under the initial one, and after being enabled/disabled again, another element is instantiated under that one.
Right now you're calling getSatellitesInPlanet() on SatelliteGridControl's OnEnabled() method. This method is called every time the object is set to active. If you just want to call your method once, use Start.
Problem 2: Also none of these instantiated buttons get called. Maybe
the problem here is due to the 1st problem?
I don't think the problems are related. Can you confirm that your buttonTemplate prefab has an Image element and its RaycastTarget is enabled?
Just one tip, I would set the type of buttonTemplate to SatelliteButton, not GameObject. That way you can instantiate it as type SatelliteButton and avoid the need to call:
newButton.GetComponent<SatelliteButton>()
Consider there are two classes, named User and Player. These classes, superficially, refer to users (accounts) in a game and players of them. Each user has one player, whereas each player could be owned by single user.
When user wants to join a game, a Player instance is created and the game abstraction will own the including players.
The instances of class Player should not be created by anyone other than a User. To be more precise, User has a method Player *createPlayer(...) in order to create a Player.
How this could be achieved? I considered User class could inherit from Player, so with a protected constructor of Player it will be okay. However, you know, this is ultimately odd. We would like to inherit Player from User, not the opposite.
Pseudocode of classes (as suggested by AndyG):
class User {
String username
String password
func createPlayer(type: GameType, owner: Game) {
var player = Player(type: type, owner: owner)
return player
}
}
class Player {
private(set) Game owner
private(set) GameType type
Set<Weapon> loadout
UInt kills
UInt deaths
init(type: GameType, owner: Game) {
self.type = type
self.owner = owner
}
}
Usage:
var user = User() // consider this gives you user
var game = Game() // consider there is a game
var player = user.createPlayer(.Deathmatch, game) // the way we should create it
var anotherPlayer = Player(.Deathmatch, game) // oops, compiler error.
You make Player's constructor private, and Player declares User to be a friend. Then createPlayer can call Player's constructor normally, but no other class can. Try not to declare any other friends for Player, using friend is ok in certain situations but overuse is generally a bad sign.
I have a singleton class named GameManager.
GameManager.h
#include "cocos2d.h"
using namespace cocos2d;
class GameManager : private CCObject
{
public:
GameManager(void);
virtual ~GameManager(void);
virtual bool init(void);
static GameManager* sharedGameManager(void);
CC_SYNTHESIZE(CCString*, email, Email);
CC_SYNTHESIZE(CCString*, nickName, NickName);
CC_SYNTHESIZE(int, currentGame, CurrentGame);
CCArray* gamesArray;
};
GameManager.cpp
#include "GameManager.h"
static GameManager* _sharedGameManager = NULL;
GameManager* GameManager::sharedGameManager(void)
{
if (!_sharedGameManager)
{
_sharedGameManager = new GameManager;
_sharedGameManager->init();
}
return _sharedGameManager;
}
GameManager::GameManager(void)
{
}
GameManager::~GameManager(void)
{
email->release();
nickName->release();
gamesArray->release();
}
bool GameManager::init()
{
CCLOG("GameManager Created");
email = CCString::create("");
email->retain();
nickName = CCString::create("");
nickName->retain();
currentGame = 0;
gamesArray = CCArray::create();
gamesArray->retain();
return true;
}
and I create the GameManager in my login page with
GameManager::sharedGameManager();
the flow of my app goes:
Login.cpp -> GameList.cpp -> GameScreen.cpp
In the login page I store the account email and nickname and also the gamesArray which is created within that page:
//store user info to gamemanager
GameManager::sharedGameManager()->setEmail((CCString*) parseOne->objectAtIndex(3));
GameManager::sharedGameManager()->setNickName((CCString*) parseOne->objectAtIndex(7));
GameManager::sharedGameManager()->gamesArray = gameObjectArray;
once the user has logged in, the GameList is created using the GameManager info.
so the info from the singleton exists at this point.
the GameList page creates a GameObject for each game in the gamesArray. each GameObject has a child button attached to it which is used to goto the GameScreen and saves that GameObjects id to the GameManager
GameManager::sharedGameManager()->setCurrentGame(gameNumber);
CCDirector * pDirector = CCDirector::sharedDirector();
CCScene* pScene = GameScreenScene::scene();
pDirector->replaceScene(pScene);
Now the weird part, when I get to the GameScreenScene the data from the GameManager is gone, except for the currentGame which is still showing the right values.
I have put in some logs to diagnose the problem but I can't seem to figure it out.
I can read the values right before the GameListScene changes to the GameScreenScene, but once it changes the values are gone.
I also tried reading the data in the GameObject button call, but the data also doesn't exist there also.
I can add more code if it can help figure this out, I just didn't want to flood this if it was something easy.
Any help would be awesome.
You are not retaining your autorelease objects (i.e, email and name strings) resulting in deletion of its data when it is released. The reason currentGame is still there is that it is an int (not an autorelease pointer).
You can use CC_SYNTHESIZE_RETAIN instead of CC_SYNTHESIZE to retain these two string to automatically retain them.
If i am right,
Constructor of CCObject (maybe Init() function) calls autorelease() and instances which are not attached to scenes automately destroy after one frame even if it is singleton instance.
I think your GameManager class have no reason to inherit from CCObject.
My team is designing a library that is wrapping calls to Active Directory to search and return a list of people.
We have a person class that wraps up the information for a person found. We then use the List to wrap them up. When we call the search it uses the internal System.Directory library and returns a SearchResultCollection object. We then iterate through it to build up the list<> and return that.
We have designed the person class to only have read only (get) properties since we don't want the callee to change the person info. We pass in the SearchResult object from the System.Directory library on the constructor of the person.
My issue is we can't test this easily.
My thoughts so far have been:
Pass variables into the person constructor for each property needing to be set.
Unfortunately, this will make for a very long constructor parameter list.... Smells bad to me.
Allow the person class to have setters on the properties.
Again, smells bad to me since we can't control the callee from using this.
Refactor:
I have looked at the extract to interface and adapt parameter techniques. It seems the adapt parameter has the most promise? Adapt parameter seems nice because it does help break the dependency I have on the Directory Library's SearchResult object. So if in the future I wanted to do some other kind of search we are in good shape. At least I think we are?
Sub class the person object and create a test Person with setters....
Seems like it would work but not sure if it's the right way to go?
Mock it
Haven't done any mocking yet so again not sure on this one.
EDIT: If mocking is best idea please let me know... However, I would be interested to know how this would be done without mocking also (or perhaps it really isn't do able without mocking)....
I would appreciate guidance on this one.
Here's a snippet of the code:
public class PeopleSearcher
{
.... declarations left out....
public List<Person> FindPerson(string FirstName, string LastName, string Login)
{
...filter setup left out for brevity....
_peopleFound = _directoryToSearch.FindAll();
//Convert to list of persons....
int cnt = 0;
_listOfPeople = new List<Person>();
while (cnt < _peopleFound.Count)
{
Person p = new Person(_peopleFound[0]);
_listOfPeople.Add(p);
cnt++;
}
return _listOfPeople;
}
}
public class Person
{
private string sn;
....further declarations left out for brevity....
public Person(SearchResult PersonFound)
{
sn = PersonFound.Properties["sn"].Count == 0 ? string.Empty : PersonFound.Properties["sn"][0].ToString();
givenName = PersonFound.Properties["givenName"].Count == 0 ? string.Empty : PersonFound.Properties["givenName"][0].ToString();
sAMAccountName = PersonFound.Properties["sAMAccountName"].Count == 0 ? string.Empty : PersonFound.Properties["sAMAccountName"][0].ToString();
adsPath = PersonFound.Path == null ? string.Empty : PersonFound.Path;
}
public string LastName
{
get
{
return sn;
}
}
.... more getters...
}
}
"Mocking" is a word that is usually used for all kinds of test doubles. And most times people or not "mocking", they're faking or stubbing. Anyway, your 4th option (subclass and add setters) sounds to me like the easiest way to go given your codebase assuming you want Person objects to pass toother methods. Because I don't think you're talking about testing that the person object gets the properties set correct by the constructor, right?
Mock it. This is the sort of situation that mocking was invented for. I've only done mocking in Ruby, so I'm not sure of the state of the art for .net, but it should work well.
When mocking it you might realize some areas that should be refactored. This is also a good plan.
In your mock (by framework or otherwise), you're still going to end up having to create Person objects with values, which leads you right back to your original problem.
Fortunately, there are two excellent solutions:
1) Go ahead and add setters to the Person class, but make them protected. This means your mock and test code would have to be in the same package, but would block other users from mutating your Persons. (and we don't want mutants running around - there's been enough of that in the movies lately).
2) Use a Builder class (as Joshua Bloch describes in Effective Java). You'd create a public static PersonBuilder class inside Person, which would export a build method and chainable parameter specifiers (like setters, but not separately callable):
public class Person ....
public static class PersonBuilder {
public PersonBuilder (String firstName, String lastName) {...} // my sample has two required values
public Person build() { ... }
public PersonBuilder ssn (String value) { ... }
public PersonBuilder adsPath (String value) { ... }
...
}
...
}
The chainable value specifiers look like this:
public PersonBuilder ssn (String value) {
this.sn = value;
return this;
}
Then a call to create a Person looks like this:
Person thisPerson = new Person.PersonBuilder ("John", "Smith").ssn("123-45-6789").adsPath("whatever");
This method completely hides the methods which can set the values (indeed, you have no "setters"), but keeps you from having to deal with long constructor argument lists (which makes it easier to deal with optional values).
Incidentally, you also probably want to make Person's constructor private.