cocos2dx with box2d contactlistener doesnt work - cocos2d-x

im using box2d 2.3.1physics engine in my cocos2dx v4 project. My polygon shapes are created using physics editor. all colliding itself properly but contact listener doesnt log contacts.
this is my contactlistener header defined in helloworld.h
class MyContactListener : public b2ContactListener
{
private :
void BeginContact(b2Contact* contact);
void EndContact(b2Contact* contact);
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
};
this is my contactlistener implementation in helloworld.cpp
void MyContactListener::BeginContact(b2Contact* contact) {
std::cout << "BeginContactn\n";
}
void MyContactListener::EndContact(b2Contact* contact) {
std::cout << "EndContact\n";
}
void MyContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) {
std::cout << "PreSolve\n";
}
void MyContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) {
std::cout << "PostSolve\n";
}
MyContactListener myContactListenerInstance;
and my contactlistener assignment to world (in helloworld.cpp init )
_rootWorld->getb2World()->SetContactListener(&myContactListenerInstance);
all works but it doesnt log collion contacts
my bodies category and bitmask values are
body A : bitmask : 63, category: 1
body B : bitmask : 63, category: 2
body C : bitmask : 63, category: 4
body D : bitmask : 63, category: 8
body E : bitmask : 63, category: 16
body F : bitmask : 63, category: 32
can anyone help?

i solved problem by changing std::cout to log("..."), i guess cocos2dx engine changes std::cout behaviour so I doesnt print anything

Related

Hi everyone. I need a little help on how to do this code. I have a main that I'm not allowed to change, but I have to make it work

this is how my main looks
b = 3;
cout << "Affectation OK\n";
const Uint c = 13;
cout << uint64_t(c) << " = 13: explicit cast to uint64_t\n";
this is how my class looks
class Uint {
private:
string nb;
public:
Uint();
Uint(size_t a);//Overload constructeur
operator uint64_t() {
return static_cast<uint64_t>(123456789UL);
}
};//LABO21_UINT_H
#endif
i tried so many ways to do that, but no succes. If anyone could help me, on how to use the operators on this , it would be a greatp help
The ctor:
Uint(size_t a){
//convert a to string
nb=...
}
If you can't change the main, you should add a friend function:
friend operator uint64_t(Uint c) {
return static_cast<uint64_t>(c.nb);
}
friend function give you the option to access the private fields of class eventhough it's not a member function.

Cocos2d-x RenderTexture the image is black(empty) on Android's gallery

In my app , i'm using a RenderTexture as a Canvas.
I would like to save this canvas to android photo gallery , like this:
The cpp side :
void Canvas::saveCanvasCallback(cocos2d::Ref *sender)
{
time_t t = time(0);
struct tm * timeinfo= localtime (&t);
char buffer[120];
strftime(buffer,120,"image_%d%m%Y%I%M%S.png",timeinfo);
auto callback = [&](RenderTexture* rt, const std::string& path)
{
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
addImageToGallery(path.c_str());
#else
CGameManager_iOSBridge::addImageToGallery(path.c_str());
#endif
};
_target->saveToFile(buffer, Image::Format::PNG, true, callback);
CCLOG("Image saved %s \n", buffer);
}
The java side :
static void addImageToGallery (String path) {
ContentValues values = new ContentValues();
values.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE, "image/png");
values.put(MediaStore.MediaColumns.DATA, Environment.getExternalStorageDirectory().getPath()+path);
getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
me.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(me.getApplicationContext(), "Image saved ",
Toast.LENGTH_LONG).show();
}
});
}
The saved image it's black(empty) in the gallery ( for iOS it works fine) .
I'm working with cocos2d-x V3.3
Please help me
Thanks

Refering within the class to constructor with the this pointer

#include "stdafx.h"
ref class station{
public:
station(){
};
void wrapper_1()
{
this->somefunct(); /*happy*/
};
void wrapper_2()
{
this->station(); /*not happy*/
};
void somefunct(){
System::Console::WriteLine(L"abcde");
};
};
int main(array<System::String^>^ args)
{
station^ temp_1 = gcnew station();
temp_1->wrapper_1();
System::Console::ReadLine();
};
I want to use the this pointer to call my constructor within my station class, it doesn't like this and throws the following error:
error C2273: 'function-style cast' : illegal as right side of '->'
operator.
Can someone explain to me how the constructor differs to other functions when using the pointer this to point to the function. I don't want to take the easy way out using station::station();
example of what I meant to #hans-passant
#include "stdafx.h"
ref class station{
public:
station(int par_1,int par_2)
{
int sum = par_1 + par_2;
System::Console::WriteLine(System::Convert::ToString(sum));
//default value output 13
};
station(){
int pass_1 = 5;
int pass_2 = 8;
station(pass_1,pass_2); /* But why couldn't I use this->station(pass_1,pass_2);*/
};
};
int main(array<System::String^>^ args)
{
station^ obj = gcnew station();
System::Console::ReadLine();
};

Passing C++/CLI Class Method as C function pointer

I have a third-party C library that provides this header:
//CLibrary.h
#include <Windows.h>
#include <process.h>
typedef void (WINAPI *CLibEventCallback)(int event, void *data);
__declspec(dllexport) bool CLibStart (CLibEventCallback callback, void *data);
// CLibrary.c -- sample implementation
static CLibEventCallback cb;
void _cdecl DoWork (void *ptr)
{
for (int i = 0; i < 10; ++i)
{
cb (i*i, ptr);
Sleep (500);
}
}
__declspec(dllexport) bool CLibStart (CLibEventCallback callback, void *data)
{
cb = callback; // save address for DoWork thread...
_beginthread (DoWork, 0, data);
return true;
}
I need to create a C++/CLI class that can call CLibStart and provide a class method as the function pointer. As suggested below, this needs to be done with GetFunctionPointerForDelegate. Because the delete constructor includes 'this' and doesn't require a static method, I don't need to pass 'this' into CLibStart.
using namespace System;
using namespace System::Runtime::InteropServices;
namespace Sample {
public ref class ManagedClass
{
delegate void CLibraryDelegate (int event, void *data);
private:
CLibraryDelegate^ managedDelegate;
IntPtr unmanagedDelegatePtr;
int someInstanceData;
public:
ManagedClass()
{
this->managedDelegate = gcnew CLibraryDelegate(this, &ManagedClass::ManagedCallback);
this->unmanagedDelegatePtr = Marshal::GetFunctionPointerForDelegate(this->managedDelegate);
this->someInstanceData = 42;
}
void Start ()
{
// since the delegate includes an implicit 'this' (as static function is not needed)
// I no longer need to pass 'this' in the second parameter!
CLibStart ((CLibEventCallback) (void *) unmanagedDelegatePtr, nullptr);
}
private:
void Log (String^ msg)
{
Console::WriteLine (String::Format ("someInstanceData: {0}, message: {1}", this->someInstanceData, msg));
}
void ManagedCallback (int eventType, void *data)
{
// no longer need "data" to contain 'this'
this->Log (String::Format ("Received Event {0}", eventType));
}
};
}
All of this compiles and runs fine using this C# tester:
using System;
using Sample;
namespace Tester
{
class Program
{
static void Main(string[] args)
{
var mc = new ManagedClass();
mc.Start();
Console.ReadKey();
}
}
}
Sample output:
Received Event 0
Received Event 1
Received Event 4
Received Event 9
Received Event 16
Received Event 25
Received Event 36
Received Event 49
Received Event 64
Received Event 81
Outstanding questions:
I have this feeling that I need to use gcroot and/or pin_ptr? If
so, how? where?
Thanks.
gcroot should be in place where ref class stores delegate, like:
gcroot<CLibraryDelegate^> managedDelegate;

How to use std::find/std::find_if with a vector of custom class objects?

I have a class representing a user called Nick and I want to use std::find_if on it, where I want to find if the userlist vector has an object included with the same username I pass in. I did a few attempts by trying to create a new Nick object for the username I want to test and overloading the == operator and then trying to use find/find_if on the object:
std::vector<Nick> userlist;
std::string username = "Nicholas";
if (std::find(userlist.begin(), userlist.end(), new Nick(username, false)) != userlist.end())) {
std::cout << "found";
}
I have overloaded the == operator so comparing Nick == Nick2 should work, but the function returns error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Nick' (or there is no acceptable conversion).
Here is my Nick class for reference:
class Nick {
private:
Nick() {
username = interest = email = "";
is_op = false;
};
public:
std::string username;
std::string interest;
std::string email;
bool is_op;
Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) {
Nick();
username = d_username;
interest = d_interest;
email = d_email;
is_op = d_is_op;
};
Nick(std::string d_username, bool d_is_op) {
Nick();
username = d_username;
is_op = d_is_op;
};
friend bool operator== (Nick &n1, Nick &n2) {
return (n1.username == n2.username);
};
friend bool operator!= (Nick &n1, Nick &n2) {
return !(n1 == n2);
};
};
If you are using C++0X you can use a simple lambda expression
std::string username = "Nicholas";
std::find_if(userlist.begin(), userlist.end(), [username](Nick const& n){
return n.username == username;
})
You have to define operator== with two Objects outside your class, as a tool function, not a member.
Then to make it friend just put the declaration of the function inside the class.
try something like this:
class Nick {
public:
friend bool operator== ( const Nick &n1, const Nick &n2);
};
bool operator== ( const Nick &n1, const Nick &n2)
{
return n1.username == n2.username;
}
Also your find should look like this:
std::find(userlist.begin(), userlist.end(), Nick(username, false) );
No need of "new".
I know that you wanted to overload the == operator, but the same thing can easily be done with a predicate:
struct UsernameIs {
UsernameIs( string s ) : toFind(s) { }
bool operator() (const Nick &n)
{ return n.username == toFind; }
string toFind;
};
int main()
{
vector<Nick> vn(10);
string nameToFind = "something";
find_if(vn.begin(), vn.end(), UsernameIs(nameToFind));
}
Note that in C++0x, you can do the same thing with a lambda expression much more concisely.
You are passing a pointer to the find function. Drop the new:
std::find(userlist.begin(), userlist.end(), Nick(username, false))
Also, your operators should accept their arguments by const reference, they don't modify them.
bool operator== (const Nick &n1, const Nick &n2)
I am noticing you are trying to call one constructor from another in this manner:
Nick(std::string d_username, bool d_is_op) {
Nick();
...
Well, sorry, but this doesn't work. The line Nick() just creates a temporary and doesn't affect this. Constructor forwarding is only possible in C++0x (the upcoming standard)
As to your problem - this question asked a couple of days ago about binary_search covers the same grounds. The top answer is just awesome.
Mystical restriction on std::binary_search
HTH.
P.S. Ideally this should have been a comment, but it's just too verbose
You can use boost::bind
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::isFound,
_1 ) );
just implement bool Nick::isFound()
You can also pass the criteria
std::find_if( userlist.begin(), userlist.end(),
boost::bind( & Nick::compare,
_1,
nick ) );
implement
bool Nick::compare( const Nick & nick )
{
return this->username == nick.username;
}
This works for me:
Nick.h
#include <string>
class Nick {
private:
Nick() {
username = interest = email = "";
is_op = false;
};
public:
std::string username;
std::string interest;
std::string email;
bool is_op;
Nick(std::string d_username, std::string d_interest, std::string d_email, bool d_is_op) {
Nick();
username = d_username;
interest = d_interest;
email = d_email;
is_op = d_is_op;
};
Nick(std::string d_username, bool d_is_op) {
Nick();
username = d_username;
is_op = d_is_op;
};
bool operator==(const Nick& refNick) const
{
if (username != refNick.username)
return false;
if (interest != refNick.interest)
return false;
if (email != refNick.email)
return false;
if (is_op != refNick.is_op)
return false;
return true;
}
bool operator!=(const Nick& refNick) const
{
if (username == refNick.username)
return true;
if (interest == refNick.interest)
return true;
if (email == refNick.email)
return true;
if (is_op == refNick.is_op)
return true;
return false;
}
};
main.cpp
#include <iostream>
#include <string>
#include <vector>
#include "Nick.h"
int main()
{
std::vector<Nick> userlist;
std::string username = "Nicholas";
Nick Nicholas(username, false);
Nick John("John", true);
userlist.push_back(Nicholas);
std::vector<Nick>::iterator it;
it = std::find(userlist.begin(), userlist.end(), Nick("Nicholas", false));
if(it != userlist.end())
std::cout << "\n" << Nicholas.username << " was found.";
else
std::cout << "\n" << Nicholas.username << " was not found.";
it = std::find(userlist.begin(), userlist.end(), John);
if (it != userlist.end())
std::cout << "\n" << John.username << " was found.";
else
std::cout << "\n" << John.username << " was not found.";
}
Result
Nicholas was found.
John was not found.