我环顾四周,发现了类似的问题,但在java环境中(我完全没有准备)。 我在我的世界中创造了一些身体,现在我正在制作鼠标关节以使它们移动,但即使身体似乎被选中并且创建了关节,我根本无法抓住它;
这是我的.mm文件中的代码
class myQueryCallback: public b2QueryCallback
{
public:
myQueryCallback(const b2Vec2& point)
{
mouse_p = point;
body = nil;
}
bool ReportFixture(b2Fixture* fixture)
{
body = fixture->GetBody();
body = nil;
if (fixture->GetBody()->GetType() != b2_staticBody || nil)
{
bool inside = fixture->TestPoint(mouse_p);
if (inside)
{
body = fixture->GetBody();
trackerBody = body;
if (trackerBody != nil ){touchedCheck = 1;
//myfunctionhere();
}
m_fixture = fixture;
return false;
}
}
m_fixture = fixture;
trackerBody = body;
return true;
}
b2Body* body;
b2Vec2 mouse_p;
b2Fixture* m_fixture;
};
...
/*-(void) registerWithTouchDispatcher
{
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:NO];
}*/
我在教程中找到了这个部分,但是当它处于活动状态时程序崩溃并退出
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event // grab objects
{
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
b2Vec2 myTouchPos;
myTouchPos.Set(location.x/PTM_RATIO, location.y/PTM_RATIO);
b2AABB aabb;
b2Vec2 correction;
correction.Set(0.001f, 0.001f);
aabb.lowerBound = myTouchPos - correction;
aabb.upperBound = myTouchPos + correction;
// Query the world for overlapping shapes.
myQueryCallback ReportFixture(myTouchPos);
world->QueryAABB(&ReportFixture, aabb);
if (ReportFixture.m_fixture)
{
b2Body* myBody = ReportFixture.m_fixture->GetBody();
b2MouseJointDef md;
md.bodyA = ground1;//currentGround;
md.bodyB = myBody;
md.target = myTouchPos;
md.maxForce = 2000.0f * myBody->GetMass();
mouseJoint = (b2MouseJoint*)world->CreateJoint(&md);
myBody->SetAwake(true);
NSValue *mouseJointVal = [NSValue valueWithPointer:mouseJoint];
NSLog(@"mouseJoint %@",mouseJointVal);
直到这里NSLog显示我的指针,但我无法抓住我选择的b2Body
}
}
}
- (void)ccTouchEnded:(UITouch*)touch withEvent:(UIEvent *)event
{
if(mouseJoint)
{
world->DestroyJoint(mouseJoint);
mouseJoint = nil;
NSValue *mouseJointVal = [NSValue valueWithPointer:mouseJoint];
NSLog(@"mouseJoint ended %@",mouseJointVal);
}
}
这部分似乎不起作用,NSLog在控制台中不显示任何内容
我做错了什么?
提前感谢您的帮助!
答案 0 :(得分:1)
您没有显示ccTouchesMoved的代码,但我会假设您知道鼠标关节必须在触摸移动时移动其目标位置,否则不会发生任何事情。
我不确定问题的根本原因是什么,但我确实看到了一些问题。也许它有助于指出它们。
首先,您正在循环使用ccTouchesBegan中可能存在的多个触摸点。如果同时开始多次触摸,您将创建多个鼠标关节,并且只有最后创建的关节将存储在“mousejoint”变量中。
第二个是在ccTouchesEnded中,当任何触摸结束时你正在破坏关节 - 你应该检查触摸是否与创建鼠标关节的触摸相同。
第三个是回调中的ReportFixture函数为所有报告的灯具设置'm_fixture'成员,无论它们是否是动态的。鼠标关节应该有一个动态体,所以不应该检查身体是否是静态的(它也可能是运动学的),你应该检查 是否是动态的。
最后,查询回调中'm_fixture'的值未初始化为任何内容,因此如果没有报告任何数据,您将最终在该指针中使用垃圾数据,并且在尝试取消引用时可能会崩溃。
我能想到ccTouchesBegan中的NSLog显示的唯一原因,但ccTouchesEnded中的NSLog没有显示,是变量'mousejoint'不相同(例如变量阴影)。
我还假设您以某种方式渲染触摸位置以检查您触摸的位置是否实际上正确地转换为物理坐标。否则,您的触摸可能会检测到与您认为不同的夹具(例如,另一个屏幕外夹具),这可能解释了为什么您没有看到任何发生的事情。
答案 1 :(得分:0)
好的,我解决了所有问题,这要归功于正确的建议,但我正在写下这些内容,希望他们可以帮助像我这样的新手关于xcode + box2d并需要一些代码示例:
起初我避免使用“for”循环,这只是弄乱了东西,正如建议的那样,加上我将ccTouchBegan方法从“void”更改为“bool”,我将其设置为:
-(BOOL)ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event // grab objects
{
//select body at location
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
b2Vec2 myTouchPos;
myTouchPos.Set(location.x/PTM_RATIO, location.y/PTM_RATIO);
if (mouseJoint != NULL)
{
return NO;
}
b2AABB aabb;
b2Vec2 correction;
correction.Set(0.001f, 0.001f);
aabb.lowerBound = myTouchPos - correction;
aabb.upperBound = myTouchPos + correction;
// Query the world for overlapping shapes.
myQueryCallback ReportFixture(myTouchPos);
world->QueryAABB(&ReportFixture, aabb);
if (ReportFixture.m_fixture)
{
b2Body* myBody = ReportFixture.m_fixture->GetBody();
trackerBody = myBody;
b2MouseJointDef md;
md.bodyA = ground1;
md.bodyB = trackerBody;
md.target = myTouchPos;
md.maxForce = 2000.0f * trackerBody->GetMass();
mouseJoint = (b2MouseJoint*)world->CreateJoint(&md);
trackerBody->SetAwake(true);
NSLog(@"mouseJoint created, myBody %f x, %f y",trackerBody->GetPosition().x,trackerBody->GetPosition().y);
return YES;
}
return YES;
}
之后,touchDispatcher不再发生任何崩溃,所以我可以成功实现它,并且mouseJoint最终看起来正确并且在日志中也发送了正确的值;它还修复了ccTouchMoved和ccTouchEnded方法,它们都已经正确,但由于没有实现touchDispatcher而无法正常工作。
我还将m_fixture的检查设置为等于b2_dynamicBody并且它好多了。
这样:
if (fixture->GetBody()->GetType() == b2_dynamicBody || nil
而不是:
if (fixture->GetBody()->GetType() != b2_staticBody || nil
最后,当我检查我的.mm文件时,我发现我不小心删除了我的更新(Tick())方法,所以即使mouseJoint正在工作,也解释了为什么我还没有看到我的身体由于屏幕的刷新损失而移动...
再次实施之后:
-(void) update: (ccTime) dt
{
int32 velocityIterations = 8;
int32 positionIterations = 1;
world->Step(dt, velocityIterations, positionIterations);
}
一切都开始完美。
再次感谢您的帮助!