レイキャストの設定方法についてインターネットから収集したいくつかの異なる方法を試しましたが、何をしても、どのような種類の接続も登録できません。何が起きてる?世界は正しく設定されています (物事が現れて衝突するなど)。完全を期すために、テストケースと関連するクラスを含めます (Ray Wenderlich のセットアップに気付く人もいるでしょう)。
ccLayer ヘッダー
//B2dtest.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Box2D.h"
#import "GLES-Render.h"
#import "MyContactListener.h"
#define PTM_RATIO 16
@interface B2dTest : CCLayer {
b2World* world; // strong ref
GLESDebugDraw *m_debugDraw;
MyContactListener *_contactListener;
b2Body* groundBody;
b2Body* wallBody;
DataModel *m;
float rayAngle;
b2Vec2 p1;
b2Vec2 p2;
b2Vec2 intersectionPoint;
}
+(CCScene *) scene;
-(void)initPhysics;
@end
ccLayer クラス (問題のあるコードは更新中の可能性が最も高い)
//B2dtest.mm
#import "B2dTest.h"
#import "RaysCastCallback.h"
#import "OtherCast.h"
enum {kTagParentNode = 1,};
@implementation B2dTest
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
B2dTest *layer = [B2dTest node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if( (self=[super init])) {
[self initPhysics];
[self addBarrier];
[self scheduleUpdate];
}
return self;
}
-(void) initPhysics
{
CGSize s = [[CCDirector sharedDirector] winSize];
b2Vec2 gravity;
gravity.Set(0.0f, -21.0f); //was ten
world = new b2World(gravity);
_contactListener = new MyContactListener();
world->SetContactListener(_contactListener);
world->SetAllowSleeping(true);
world->SetContinuousPhysics(true);
m_debugDraw = new GLESDebugDraw( PTM_RATIO );
world->SetDebugDraw(m_debugDraw);
uint32 flags = 0;
flags += b2Draw::e_shapeBit;
m_debugDraw->SetFlags(flags);
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0, 0); // bottom-left corner
groundBody = world->CreateBody(&groundBodyDef);
b2EdgeShape groundBox;
groundBox.Set(b2Vec2(0,s.height/PTM_RATIO/3), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO/3));
b2FixtureDef fixtureDef;
fixtureDef.filter.categoryBits = 0x0004;
fixtureDef.filter.maskBits = 0x0002;
fixtureDef.shape = &groundBox;
fixtureDef.density = 0;
fixtureDef.restitution = 0.0f;
groundBody->CreateFixture(&fixtureDef);
}
-(void)addBarrier{
b2BodyDef bodyDef;
bodyDef.type = b2_staticBody;
wallBody = world->CreateBody(&bodyDef);
for (int i = 0; i < 2;i++){
b2PolygonShape platform;
platform.SetAsBox(2, .25, b2Vec2(12+ (i * 5), 9 + i),0);
b2FixtureDef fixtureDef;
fixtureDef.shape = &platform;
wallBody->CreateFixture(&fixtureDef);
}
}
-(void) draw{
ccDrawLine(ccp(p1.x,p1.y),
ccp(p2.x,p2.y));
[super draw];
ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
kmGLPushMatrix();
world->DrawDebugData();
kmGLPopMatrix();
}
-(void) update: (ccTime) dt{
int32 velocityIterations = 4;
int32 positionIterations = 1;
world->Step(dt, velocityIterations, positionIterations);
rayAngle = rayAngle + (2 * (M_PI / 180));
float rayLength = 200;
p1 = b2Vec2( 240, 240 ); //center of scene
p2 = p1 + rayLength * b2Vec2( sinf(rayAngle), cosf(rayAngle) );
RaysCastCallback callback; //FIRST RAYCAST METHOD
world->RayCast(&callback, p1, p2);
if (callback.m_fixture){
CCLOG(@"OH YESAAH!");
p2 = b2Vec2(callback.m_point.x * PTM_RATIO, callback.m_point.y * PTM_RATIO);
}
OtherCast allback; //SECONDRAYCASTMETHOD
world->RayCast(&allback, p1, p2);
if (allback.m_hit){
CCLOG(@"OH YESAAH! AD");
// p2 = b2Vec2(callback.m_point.x * PTM_RATIO, callback.m_point.y * PTM_RATIO);
}
b2RayCastInput input; //THIRDRAYCASTMETHOD
input.p1 = p1;
input.p2 = p2;
input.maxFraction = 1;
float closestFraction = 1;
b2Vec2 intersectionNormal(0,0);
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) {
for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext()) {
b2RayCastOutput output;
if ( ! f->RayCast( &output, input, 0 ) )
continue;
if ( output.fraction < closestFraction ) {
CCLOG(@"woo");
closestFraction = output.fraction;
intersectionNormal = output.normal;
}
}
}
}
@end
RaysCastCallback.h
#ifndef Shoot_N_Run_RaysCastCallback_h
#define Shoot_N_Run_RaysCastCallback_h
#endif
#import "Box2D.h"
class RaysCastCallback : public b2RayCastCallback{
public:
RaysCastCallback() : m_fixture(NULL) {
}
float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction) {
m_fixture = fixture;
m_point = point;
m_normal = normal;
m_fraction = fraction;
return fraction;
}
b2Fixture* m_fixture;
b2Vec2 m_point;
b2Vec2 m_normal;
float32 m_fraction;
};
OtherCast.h
#import "Box2D.h"
class OtherCast : public b2RayCastCallback{
public:
OtherCast()
{
m_hit = false;
}
float32 ReportFixture( b2Fixture* fixture, const b2Vec2& point,
const b2Vec2& normal, float32 fraction)
{
b2Body* body = fixture->GetBody();
void* userData = body->GetUserData();
if (userData)
{
int32 index = *(int32*)userData;
if (index == 0)
{
// filter
return -1.0f;
}
}
m_hit = true;
m_point = point;
m_normal = normal;
return fraction;
}
bool m_hit;
b2Vec2 m_point;
b2Vec2 m_normal;
};