Trong cocos2d, bạn có thể dễ dàng trong CCSprites và di chuyển chúng xung quanh bằng mọi cách. Quan trọng nhất - họ có thể giảm bớt trong/ngoài. Đối với hầu hết các trò chơi, điều này là mong muốn cho chuyển động trơn tru, v.v.Di chuyển các đối tượng Box2d Giống như các đối tượng CCSprite
id action = [CCMoveTo actionWithDuration:dur position:pos];
move = [CCEaseInOut actionWithAction:action rate:2];
[self runAction: move];
Khi di chuyển hộp2, phần tử gắn liền với nó được cập nhật sau bước box2d(). Di chuyển các sprite và sau đó cập nhật cơ thể không phải là một lựa chọn ở đây, vì nó hoàn toàn đánh bại mục đích của khung vật lý. Vì vậy, các tùy chọn khác, mà tôi đã thực hiện thành công, là để tính toán chuyển, vận tốc và gia tốc của một sprite bằng cách xử lý nó như là một thực thể cơ học theo đúng nghĩa của nó. Mỗi lần tôi gọi cập nhật của tôi() trên sprite để nhân vật có thể quyết định nơi để di chuyển vv, siêu lớp của tôi cũng lưu trữ vị trí và vận tốc trước đó. Chúng được lưu trữ dưới dạng giá trị tuân thủ box2d bằng cách chia cho PTM_RATIO.
Trong lớp con của CCSprite, gọi FMSprite:
-(CGPoint) displacement {
return ccpSub(self.position, lastPos);
}
-(b2Vec2) getSpriteVelocity:(ccTime)dt {
return b2Vec2(self.displacement.x/dt/PTM_RATIO,
self.displacement.y/dt/PTM_RATIO);
}
-(b2Vec2) getSpriteAccel:(ccTime)dt {
b2Vec2 currVel = [self getSpriteVelocity:dt];
if (dt == 0) {
return b2Vec2(0,0);
} else {
float accelX = (currVel.x - lastVel.x)/dt;
float accelY = (currVel.y - lastVel.y)/dt;
return b2Vec2(accelX, accelY);
}
}
// This is called each update()
-(void) updateLast:(ccTime)dt {
// MUST store lastVel before lastPos is updated since it uses displacement
lastVel = [self getSpriteVelocity:dt];
lastPos = ccp(self.X, self.Y);
}
// Leave this method untouched in subclasses
-(void) update:(ccTime)dt {
[self updateObject:dt];
// Store previous update values
[self updateLast:dt];
}
// Override this method in subclasses for custom functionality
-(void) updateObject:(ccTime)dt {
}
Tôi đã sau đó subclassed "FMSprite" vào "FMObject", mà các cửa hàng một b2Body, vv
Để di chuyển cơ thể , Trước tiên tôi phải di chuyển một sprite và theo dõi gia tốc của nó, thông qua đó tôi có thể tìm thấy lực lượng cần thiết (sử dụng khối lượng) cần thiết để theo dõi chuyển động của sprite. Vì tôi không thể di chuyển sprite của đối tượng (được đồng bộ với cơ thể), tôi tạo một sprite khác được gọi là "beacon", thêm nó như một đứa trẻ vào đối tượng và di chuyển nó xung quanh. Tất cả những gì chúng ta cần làm là có chức năng đồng bộ hóa vị trí của thân box2d với ngọn hải đăng này bằng cách sử dụng các lực tôi đã đề cập trước đây.
-(void) followBeaconWithDelta:(ccTime)dt {
float forceX = [beacon getSpriteAccel:dt].x * self.mass;
float forceY = [beacon getSpriteAccel:dt].y * self.mass;
[self addForce:b2Vec2(forceX, forceY)];
}
Kết quả là rực rỡ, một chuyển động nới lỏng mịn của b2body di chuyển nơi nào bạn muốn nó, mà không chơi đùa với bất kỳ lực lượng của riêng mình, mà đúng hơn là sao chép của một CCSprite và tái tạo chuyển động của nó. Vì nó là tất cả các lực, nó sẽ không gây ra sự rung và méo mó khi va chạm với các đối tượng b2Body khác. Nếu bất cứ ai có bất kỳ phương pháp khác để làm điều này, xin vui lòng gửi một câu trả lời. Cảm ơn!
Xin chào, Cảm ơn bài đăng này. Tôi chưa hiểu một điều. Tại sao bạn cần một ngọn hải đăng sprite? nếu một đối tượng kiểu FMObject (là một CCSprite) đang được di chuyển bằng cách sử dụng một số hành động tùy chỉnh, tại sao không làm cho b2Body trong FMObject theo sau sprite cha. Tôi không chắc những gì 'đồng bộ hóa với cơ thể' có nghĩa là gì. Tại sao bạn lại cần một ngọn hải đăng và di chuyển nó xung quanh? – Aks
Đã gần 3 năm kể từ khi tôi đăng bài này, nhưng tôi nghĩ bạn có thể đúng. Tôi không thể thấy lý do để có một ngọn hải đăng. Tôi nghĩ đó chỉ là một chi tiết thực hiện. Bạn sẽ có thể thay thế chính 'FMObject'. –