衝突検出と、マルチタッチによって回転した別のスプライトからの 1 つのスプライトの物理ベースのバウンスを実装しようとしています。ccTouchesBegan
画像では、2 つの黄色い点が同時タッチ ポイントであることがわかります。メソッドとメソッドで、これらのタッチに基づいて雲の適切な位置と角度を計算しましたccTouchesMoved
。ユーザーが 2 つのタッチを移動および回転すると、それに応じて雲が追従し、回転します。
鳥が雲に衝突したとき、独自の種類の衝突/跳ね返りを数学で使用して転がすときに、雲の角度を別の方法に渡そうとしましたCGRectIntersectsRect
が、これでは望ましい結果が得られなかったため、Box2D に目を向けました。
Ray Wenderlich のチュートリアルを 4 つまたは 5 つ実行した後、マルチタッチ クラウドで作成した動きを、Box2D のボディ、フィクスチャ、マウス ジョイント、およびワールドとメッシュ化するのに問題があります。
私はこれを読みました: Cocos2d - 回転スプライトの衝突検出
...そして、すでにこれを行っています: Ray Wenderlich Collision Detection
私の最新のccTouchesMoved
方法は次のようになります。
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (_mouseJoint != NULL) return;
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
if (_cloudFixture->TestPoint(locationWorld)) {
b2MouseJointDef md;
md.bodyA = _groundBody;
md.bodyB = _cloudBody;
md.target = locationWorld;
md.collideConnected = true;
md.maxForce = 1000.0f * _cloudBody->GetMass();
_mouseJoint = (b2MouseJoint *)_world->CreateJoint(&md);
_cloudBody->SetAwake(true);
}
NSSet *allTouches = [event allTouches];
if([allTouches count] == 2){
UITouch * touch1 = [[allTouches allObjects] objectAtIndex:0];
CGPoint location1 = [touch1 locationInView: [touch1 view]];
location1 = [[CCDirector sharedDirector] convertToGL:location1];
UITouch * touch2 = [[allTouches allObjects] objectAtIndex:1];
CGPoint location2 = [touch2 locationInView: [touch2 view]];
location2 = [[CCDirector sharedDirector] convertToGL:location2];
//EASIER TO WORK WITH INTS
int touch1X = location1.x;
int touch2X = location2.x;
int touch1Y = location1.y;
int touch2Y = location2.y;
//FIND THE LEFT-MOST TOUCH
int minX = (touch1X < touch2X) ? touch1X : touch2X;
int maxX = (minX == touch1X) ? touch2X : touch1X;
//FIND THE BOTTOM-MOST TOUCH
int minY = (touch1Y < touch2Y) ? touch1Y : touch2Y;
int maxY = (minY == touch1Y) ? touch2Y : touch1Y;
int touchXDiff = maxX - minX;
int touchYDiff = maxY - minY;
[_cloud setPosition:ccp(touchXDiff/2 + minX, touchYDiff/2 + minY)];
//ROTATE CLOUD AS IT MOVES
int offDiffX = touch1X - touch2X;
int offDiffY = touch1Y - touch2Y;
float angleRadians = atanf((float)offDiffY / (float)offDiffX);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cloudAngle = -1 * angleDegrees;
//[_cloud setRotation:cloudAngle];
_cloudBody->SetTransform( _cloudBody->GetPosition(), cloudAngle );
}
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (_mouseJoint == NULL) return;
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
NSSet *allTouches = [event allTouches];
if([allTouches count] == 2){
UITouch * touch1 = [[allTouches allObjects] objectAtIndex:0];
CGPoint location1 = [touch1 locationInView: [touch1 view]];
location1 = [[CCDirector sharedDirector] convertToGL:location1];
UITouch * touch2 = [[allTouches allObjects] objectAtIndex:1];
CGPoint location2 = [touch2 locationInView: [touch2 view]];
location2 = [[CCDirector sharedDirector] convertToGL:location2];
//EASIER TO WORK WITH INTS
int touch1X = location1.x;
int touch2X = location2.x;
int touch1Y = location1.y;
int touch2Y = location2.y;
//FIND THE LEFT-MOST TOUCH
int minX = (touch1X < touch2X) ? touch1X : touch2X;
int maxX = (minX == touch1X) ? touch2X : touch1X;
//FIND THE BOTTOM-MOST TOUCH
int minY = (touch1Y < touch2Y) ? touch1Y : touch2Y;
int maxY = (minY == touch1Y) ? touch2Y : touch1Y;
int touchXDiff = maxX - minX;
int touchYDiff = maxY - minY;
//ROTATE CLOUD AS IT MOVES
int offDiffX = touch1X - touch2X;
int offDiffY = touch1Y - touch2Y;
float angleRadians = atanf((float)offDiffY / (float)offDiffX);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cloudAngle = -1 * angleDegrees;
//BEFORE BOX2D
//[_cloud setRotation:cloudAngle];
//[_cloud setPosition:ccp(touchXDiff/2 + minX, touchYDiff/2 + minY)];
//WITH BOX2D
_cloudBody->SetTransform( _cloudBody->GetPosition(), cloudAngle );
b2Vec2 locationWorld = b2Vec2((touchXDiff/2 + minX)/PTM_RATIO, (touchYDiff/2 + minY)/PTM_RATIO);
_mouseJoint->SetTarget(locationWorld);
}
}
編集(わかりやすくするため): 何が起こっているかというと、Box2D コードが実装されている場合、クラウドは最初のタッチにのみ応答し、タッチ間に作成された角度に調整されず、2 つのタッチに追従しません。Box2D でこれを達成するにはどうすればよいですか?
誰か提案はありますか?