Has anyone had the need to move a sprite in a circle? Seems like a common action, but I don't see support for it in Cocos. Has anyone implemented this or is this feature slated for inclusion in Cocos2d (sometime soon)?
MoveInCircle action?
(14 posts) (7 voices)-
Posted 2 years ago #
-
I move a sprite in a circle in SPIRUS. I just use the standard SIN/COS functions to derive a point along a circle.
Posted 2 years ago # -
I haven't tried it, but the guys at Mobile Bros did a "RotateAround" action that may be what you're looking for:
http://www.mobile-bros.com/?p=244
Hope it helps!
Posted 2 years ago # -
The mobile-bros code is exactly what I was looking for. Thanks Brad!
Posted 2 years ago # -
Does anybody has the RotateAround.zip from mobile-bros?
I want to try the RoteAround action they did (http://www.mobile-bros.com-RotateAround), but the zip file with the source code is missing.Thanks
Posted 3 months ago # -
*bump*
I'd be interested as well. Scott
Posted 3 months ago # -
I think same thing can be achieved with CCJump action.. but for you people here is CCRotateAround action..
Just modified code from mobile-bros.com...@interface CCRotateAround : CCActionInterval<NSCopying> { CGPoint _centerPt; float _startAngle; float _radius; float _spanAngle; } +(id) actionWithDuration:(ccTime)duration centerPoint:(CGPoint)cpt spanAngle:(float)spanAngle; -(id) initWithDuration:(ccTime)duration centerPoint:(CGPoint)cpt spanAngle:(float)spanAngle; @end@implementation CCRotateAround +(id) actionWithDuration:(ccTime)t centerPoint:(CGPoint)cpt spanAngle:(float)span { return [[[self alloc] initWithDuration:t centerPoint:cpt spanAngle:span] autorelease]; } -(id) initWithDuration:(ccTime)t centerPoint:(CGPoint)cpt spanAngle:(float)span { if( !(self=[super initWithDuration: t]) ) return nil; _spanAngle = -CC_DEGREES_TO_RADIANS(span); _centerPt = cpt; return self; } -(id) copyWithZone: (NSZone*) zone { CCAction *copy = [[[self class] allocWithZone: zone] initWithDuration: [self duration] centerPoint:_centerPt spanAngle:_spanAngle]; return copy; } -(void) startWithTarget:(CCNode *)aTarget { [super startWithTarget:aTarget]; CGPoint sub = ccpSub([aTarget position], _centerPt); _startAngle = ccpToAngle(sub); _radius = ccpLength(sub); } -(void) update: (ccTime) t { CGPoint sub = ccpForAngle(_startAngle + _spanAngle * t); [target_ setPosition: ccpAdd(_centerPt, ccpMult(sub, _radius))]; } -(CCActionInterval*) reverse { return [[self class] actionWithDuration:[self duration] centerPoint:_centerPt spanAngle:CC_RADIANS_TO_DEGREES(_spanAngle)]; } @endHope this helps...
Thanks,
KnightkrowsPosted 3 months ago # -
@knightkrows Thanks for the code.
I actually found the zip file from mobile-bross.
Here it is:
http://www.mobile-bros.com/wp-content/uploads/2009/08/RotateAround.zipThe code in the zip file is outdated, but I did pretty much what you just posted to make it compatible with the new Cocos2d code.
Thanks
Posted 3 months ago # -
I am having a hell of a time trying to get a circular orbiting motion that also keeps the object facing the center point of rotation as it orbits. Imagine an arrow ( ===> ) that as it orbits around a fixed point, it continually points towards the center point of orbit rotation.
I cannot use the above CCRotateAround action because the object I need to orbit is not a CCSprite and does not use a Cocos2D transform method.
I have coded my own custom transform method, for transforming vector primitive objects. Thus far, I can get my vector object to orbit around a fixed point, but I cannot figure out how to get the object to rotate properly in sync with the orbit so that it constantly faces the center point of rotation. I have examined the CCRotateAround code and I'm trying to write my own version of it to work for my purposes.
I'm having trouble figuring out what to do with the startingAngle and spanAngle, in regards to the object rotation.
Does anyone see what I am doing wrong?This is my update code:
-(void) updateMove:(ccTime)delta { float spanAngle = 360; float startingAngle = 0; float orbitDistanceFromCenterPoint = 93; if (orbitRate < degreesToRadians(spanAngle)) { orbitRate = orbitRate + degreesToRadians(1); } //rotationMovementRate must be set to the correct value so that the object's transform matrix method //(called at bottom of this method) will receive the correct value to constantly point towards the center //of orbit, the code directly below does NOT work properly, object does NOT point at center during orbit //rate of rotation is also much too slow rotationMovementRate = -degreesToRadians(startingAngle)+degreesToRadians(spanAngle*delta); // this code updates the vector object x & y positions to orbit around a center point // this orbit code below works CORRECTLY, object just does NOT properly face center while orbiting xCurrentPosition = xOrbitCenterPoint - (sin(orbitRate)*orbitDistanceFromCenterPoint); yCurrentPosition = yOrbitCenterPoint - (cos(orbitRate)*orbitDistanceFromCenterPoint); //xScale, yScale, xTranslate, and yTranslate values are defined by another method and are //all set to 0.0 for this particular orbit update method, only rotationMovementRate is being updated //,in the transformVectorObject matrix transform method [self transformVectorObject:rotationMovementRate :xScaleRate :yScaleRate :xTransRate :yTransRate]; }Again, the proper value for the rotationMovementRate variable is what I need to solve the problem.
For this example:
Starting point of object is at 6 O'Clock position, 93 units from orbit center point
Object starting rotation is 0.0 (no rotation)
Orbit rate is degreesToRadians(1)
Object makes one full degreesToRadians(360) rotationVia trial and error, to get the Object to constantly face the orbit center, I have manually set (hard-coded) rotationMovementRate = degreesToRadians(57.3). When using 57.3 it works. I don't understand why that value works or how to dynamically come up with that value.
Posted 2 months ago # -
LOL unbelievable! Like an idiot, I had completely forgotten that I coded my matrix transform method to accept DEGREES as the rotation argument, the method then converts the degrees to radians so it does not need to be done beforehand..
Once I set the rotationMovementRate = -1, instead of degreesToRadians(57.3), it works perfectly. The Mobile Brothers thing was more complex and not needed for my purposes. All that time spent on stupid shit again..
Now I think I will take a break with a nice game of Pokemon Attack!
Posted 2 months ago # -
I thought my problem was resolved last night, but I still have one remaining issue..
After the object has been orbiting around the orbit center point for about 5 minutes, then the object rotation (around the object's own center point) begins to get out of synchronization with the orbit rotation rate. It then is no longer properly facing the orbit center point.
I see the Mobile Brothers method uses "delta time" or "t" to keep synchronization. I am unsure how to implement the delta time in my particular method.. I am wanting to create an infinite orbit of my object, so that its orbit movement continues infinitely, for the entire duration of the game. I need the object orbit and object rotation rates to stay in synch with each other even if the game is left running for an hour.
Could anyone offer some advice?
New code below for infinite orbit movement and rotation of object:
-(void) updateMove:(ccTime)delta { orbitRate = orbitRate + degreesToRadians(1); // orbit is 1 degree per update cycle // this code below works but object rotation to face center goes out of sync after 5 minutes // the rotation rate starts to lag behind the orbit movement and object starts to face away // from orbit center rotationMovementRate = -1; // object rotation around its own center is 1 degree per update cycle // this code updates the vector object x & y positions to orbit around a center point xCurrentPosition = xOrbitCenterPoint - (sin(orbitRate)*orbitDistanceFromCenterPoint); yCurrentPosition = yOrbitCenterPoint - (cos(orbitRate)*orbitDistanceFromCenterPoint); // xScale, yScale, xTranslate, and yTranslate values are defined by another method and are // all set to 0.0 for this particular orbit update method, only rotationMovementRate is being updated // in the transformVectorObject matrix transform method [self transformVectorObject:rotationMovementRate :xScaleRate :yScaleRate :xTransRate :yTransRate]; }Posted 2 months ago # -
I don't know if anyone cares, but I was going about this whole orbit thing the wrong way. I spent all day researching how to rotate around an arbitrary point using a transform matrix.
My custom transform matrix method was coded to rotate around the object's center only. I modified it, which wasn't easy to figure out how to do, so that I can optionally rotate around an arbitrary point (apparently the "proper terminology"). After doing this, now there in no issue with synchro problems like I had before, even if left rotating for hours on end.
Now I need to figure out how to alter the transform method further, so I can scale around an arbitrary point in addition to rotating around it..
Posted 2 months ago # -
If your wanting to rotate and scale around an arbitrary point, make sure you rotate FIRST, and then scale last. If you scale first then rotate, it does not work correctly, but it does create a bizarre effect.. After this weekend's ordeal, I am all Matrix Transformed out. I think I'm through with this thread.
Posted 2 months ago #
Reply
You must log in to post.