I am developing 'Paper Toss' for iphone using cocos2d & I would like to know that how to implement 3D perspective view into this,because while we are throwing the paper ball to the bin,we have to get the 3D feel.I'am attaching the code which i have done,using this i have got a straight line motion.Please help me..
*- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
// Set up initial location of projectile
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *projectile = [CCSprite spriteWithFile:#"ball.png"
rect:CGRectMake(0, 0, 40, 40)];
projectile.position = ccp(winSize.width/2,20);
// Determine offset of location to projectile
int offX = location.x - projectile.position.x;
int offY = location.y - projectile.position.y;
// Bail out if we are shooting down or backwards
if (offY <= 0) return;
// Ok to add now - we've double checked position
[self addChild:projectile];
// Determine where we wish to shoot the projectile to
int realY = winSize.height + (projectile.contentSize.width/2);
float ratio = (float) offX / (float) offY;
int realX = (realY * ratio) + projectile.position.x;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far we're shooting
int offRealX = realX + projectile.position.x;
int offRealY = realY + projectile.position.y;
float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));
float velocity = 480/1; // 480pixels/1sec
float realMoveDuration = length/velocity;
// Move projectile to actual endpoint
[projectile runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallFuncN actionWithTarget:self selector:#selector(spriteMoveFinished:)],
nil]];
//add to the projectiles array
projectile.tag = 2;
[_projectiles addObject:projectile];
}*
Finally I have completed paper toss using cocos2d.I implemented bezier curve and here it is,
// Bezier curve control points
bezier.controlPoint_1 = ccp(location.x-CONTROL_POINT1_X, CONTROL_POINT1_Y);
bezier.controlPoint_2 = ccp(location.x-CONTROL_POINT2_X, CONTROL_POINT2_Y);
bezier.endPosition = ccp(location.x-CONTROL_POINT1_X,distance);
// Motion along bezier curve and finally call a function
[projectile runAction:[CCSequence actions:
[CCAutoBezier actionWithDuration:DEFAULT_ACTION_DURATION bezier:bezier],
[CCCallFuncN actionWithTarget:self selector:#selector(collisionCheck:)], nil]];
Just scale your sprite image so it gets smaller the "further away" it is.
Hey you can use bezier curve for 3d perspective view in cocos2d.
bezier.controlPoint_1 = ccp(location.x-CONTROL_POINT1_X, CONTROL_POINT1_Y);
bezier.controlPoint_2 = ccp(location.x-CONTROL_POINT2_X, CONTROL_POINT2_Y);
Related
i want to select my targets using touches rect
am creating my unselected dots by coding like these:-
targets1 = [[NSMutableArray alloc] init];
for(int i=0;i<3;i++)
{
for (int y=0; y<3; y++) {
CCTexture2D *texture =
[[CCTextureCache sharedTextureCache] addImage:#"UnselectedDot.png"];
block = [CCSprite spriteWithTexture:texture rect:CGRectMake(0,0,82,82)];
CGFloat xoffset = ((block.contentSize.width)*10) + (((block.contentSize.height)-175)*y);
block.position = ccp( (i*82)+80,xoffset);
[bg1 addChild:block];
[targets1 addObject:block];
}
}
below is my sample output .
now i need to select all the dots by touches method. i written coding like these:-
- (void)update:(ccTime)dt {
// NSLog(#"%#",targets1);
for (CCSprite *sprite in targets1) {
CGRect dotrect = CGRectMake(sprite.position.x,
sprite.position.y-95,
sprite.contentSize.width,
sprite.contentSize.height);
CGFloat x = location.x;
CGFloat y = location.y;
CGFloat width = (location1.x - location.x);
CGFloat height = -(location1.y - location.y);
CGRect touchrect = CGRectMake (x, y, width,height);
NSLog(#"dotrect = %f,%f,%f,%f",dotrect.origin.x,dotrect.origin.y,dotrect.size.width,dotrect.size.height );
NSLog(#"touch rect = %f,%f,%f,%f,%f,%f",touchrect.origin.x,touchrect.origin.y,touchrect.size.width,touchrect.size.height,location1.x,location1.y);
if( CGRectContainsRect(dotrect, touchrect))
{ //collision detection
NSLog(#"am touched dot ");
}
}
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
NSLog(#"am touched began");
return YES;
}
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
location1 = [touch locationInView:[touch view]];
location1 = [[CCDirector sharedDirector] convertToGL:location1];
location1 = [self convertToNodeSpace:location1];
}
as per above coding my concept is :- using touches began and touches ended am making rectangle here.. inside these touchrect my unselected dot rect came means collsison detected.. then i can do my stuffs there. but its not colliding all.
am not getting were am making mistake.
Edit :1
now i got why coillision not working... actually insidemy touches rect having multiple rect.. so only ... here, am using rectcontainsrect.. tahts the problem.. any other method to rect having several rect for colllsion detection..
Try using:
CGPoint location=[touch locationInView:[touch view]];
location = [self convertTouchToNodeSpace:touch];
CGRectContainsPoint([dot boundingBox], location);
inside the CCTouch.. methods (as you wish depending on what you want to do).
I have to develop curved line in cocos2d.Curved is similler to finger rotaion that is some of top spirits curved as per touch location.
i have an array of 50 spirit point array.if we move first spirit (in code BG_Sprite3) , want to set 1st,2nd,3rd,....50th spirit position (in code BG_Sprite2)and rotation as per touchlocation .if we move more deep(IF Y IS LESS )then rotation and position of BG_Sprite2 is also change.just like a Finger bend and Finger rotation.
This is my code ..haft of code working.but not getting curved rotation of BG_Sprite2.
-(id) init
{
if( (self=[super init]))
{
aPoints = [[NSMutableArray alloc]init];
[self removeChild:BG_Sprite2 cleanup:YES];
int m=100,n=80;
for(int i=0;i<25;i++)
{
BG_Sprite2 = [CCSprite spriteWithFile:#"nodeConnectorWhite.png"];
BG_Sprite2.position = ccp(m,n);
m=m+5;
n=n+5;
BG_Sprite2.rotation=135;
[self addChild:BG_Sprite2];
[aPoints addObject:[NSValue valueWithCGPoint:ccp(m,n)]];
}
[self removeChild:BG_Sprite3 cleanup:YES];
BG_Sprite3 = [CCSprite spriteWithFile: #"connection_green.png"];//This is first spirit
BG_Sprite3.position=ccp(235, 215);
[BG_Sprite3 setRotation:135];
[self addChild:BG_Sprite3];
}
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch * touch = [touches anyObject];
NSMutableArray *apointsarray = [[NSMutableArray alloc]init];
CGPoint movedtouchLocation = [touch locationInView: [touch view]];
movedtouchLocation = [[CCDirector sharedDirector] convertToGL: movedtouchLocation];
int xDiff= movedtouchLocation.x-225;//angle between first spirit and touch location
int yDiff= movedtouchLocation.y-205;
for(int i=0;i<[aPoints count];i++)
{
float angle2 = atan2f(xDiff, yDiff);
angle2 = CC_RADIANS_TO_DEGREES(angle2); // convert to degrees
angle2 -= 90; // rotate
angle2 *= -1; // clockwise
BG_Sprite2 = [CCSprite spriteWithFile:#"nodeConnectorWhite.png"];
BG_Sprite2.position =movedtouchLocation;
[BG_Sprite2 setRotation:angle2];
[self addChild:BG_Sprite2];
}
}
I know this question has been asked several times, trust me I have searched. I have found one answer to rotating a sprite with touch, but there has to be a simpler way.
All I need is for my sprite to rotate with my touch. Max rotation 0 Minimum rotation 0.
I know that I'll need a few checks.
int maxRot = 0;
int minRot = 0;
if (arrowRotation > maxRot)
{
//do or don't do something
} else if (arrowRotation < minRot)
{
//do or don't do something
}
Can someone lead me in the right direction to rotating a sprite with touch, with a minimun and maximum rotation?
Here is the code that I think is to complicated or can be accomplished in a simpler way.
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//acquire the previous touch location
CGPoint firstLocation = [touch previousLocationInView:[touch view]];
CGPoint location = [touch locationInView:[touch view]];
//preform all the same basic rig on both the current touch and previous touch
CGPoint touchingPoint = [[CCDirector sharedDirector] convertToGL:location];
CGPoint firstTouchingPoint = [[CCDirector sharedDirector] convertToGL:firstLocation];
CGPoint firstVector = ccpSub(firstTouchingPoint, _arrow.position);
CGFloat firstRotateAngle = -ccpToAngle(firstVector);
CGFloat previousTouch = CC_RADIANS_TO_DEGREES(firstRotateAngle);
CGPoint vector = ccpSub(touchingPoint, _arrow.position);
CGFloat rotateAngle = -ccpToAngle(vector);
CGFloat currentTouch = CC_RADIANS_TO_DEGREES(rotateAngle);
//keep adding the difference of the two angles to the dial rotation
arrowRotation += currentTouch - previousTouch;
}
Thanks in advance!
I dont think you can simplify the rotation into anything simpler. I honestly didnt get how you want to both the minimum and the maximum rotations to be zero. They cant be same value. If you want to limit the rotation to a maximum and minimum add the following to the end of your ccTouchesMoved: method:
if (arrowRotation >= maxRot) {
arrowRotation = maxRot;
}
else if (arrowRotation <= minRot) {
arrowRotation = minRot;
}
use KTOneFingerRotationGestureRecognizer...
KTOneFingerRotationGestureRecognizer *rotation;
rotation = [[KTOneFingerRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotating:)];
[[self Wheel] addGestureRecognizer:rotation];
[rotation release];
Method
- (void)rotating:(KTOneFingerRotationGestureRecognizer *)recognizer {
view = [recognizer view];
if(isRotating == FALSE) {
[view setTransform:CGAffineTransformRotate([view transform], [recognizer rotation])];
}
}
In my game I'm using Box2D to apply linear impulse to a circle object. When the impulse is applied to the object, it starts spinning clockwise but I can't get it to stop spinning.
Here is the code:
-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
CGPoint vector = ccpSub(ccp(touchLocation.x,touchLocation.y), _ball.position);
b2Vec2 forceVector(vector.x / 5, vector.y / 5);
if ((vector.x <= 100) && (vector.y <= 100))
_ballBody->ApplyLinearImpulse(forceVector, _ballBody->GetLocalCenter());
}
Hope someone could clarify the situation.
UPD:
// Create ball body and shape
b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(100/PTM_RATIO, 100/PTM_RATIO);
ballBodyDef.userData = _ball;
_ballBody = _world->CreateBody(&ballBodyDef);
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 0.3f;
ballShapeDef.friction = 0.2f;
ballShapeDef.restitution = 0.4f;
_ballBody->CreateFixture(&ballShapeDef);
use body->applyLinearImpulse(impulse, body->GetPosition())
transform a square image or round image is easy to do...
But what if a rectangle image ???
This is the image I want to transform with touch event .
The circle center is (30 , 236) , if I touch any place on the screen
Imageview will transform the arrow to my touch point.
But the circle center still the same place .
I try to transform the image use a test angle
It will become like this ...
How to adjust the image ?
Also the code is here
- (void)viewDidLoad {
CGRect arrowImageRect = CGRectMake(20.0f, 20.0f, 15.0f, 220.0f);
arrow = [[UIImageView alloc] initWithFrame:arrowImageRect];
[arrow setImage:[UIImage imageNamed:#"arrow.png"]];
arrow.opaque = YES;
[self.view addSubview:arrow];
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
NSLog(#"Position X: %f \n, Y: %f",touchPoint.x,touchPoint.y);
CGAffineTransform transform = CGAffineTransformIdentity;
arrow.transform = CGAffineTransformRotate(transform, ?????? );
}
The ?????? part should be the last solution ...
Or Maybe I need to resize the imageview ???
Thanks for any reply or answer :-)
Webber
Here is the final solution I figure this problem
check this code
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch=[[event allTouches]anyObject];
[self transformSpinnerwithTouches:touch];
}
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation
{
CGPoint touchLocationpoint = [touchLocation locationInView:self.view];
CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:self.view];
//origin is the respective piont from that i gonna measure the angle of the current position with respective to previous position ....
CGPoint origin;
origin.x = arrow.center.x;
origin.y = arrow.center.y;
CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint];
CGAffineTransform newTransform = CGAffineTransformScale(arrow.transform, 1, 1);
CGFloat previousRotation = atan2(previousDifference.y, previousDifference.x);
CGPoint currentDifference = [self vectorFromPoint:origin toPoint:touchLocationpoint];
CGFloat currentRotation = atan2(currentDifference.y, currentDifference.x);
CGFloat newAngle = currentRotation- previousRotation;
temp1 = temp1 + newAngle;
//NSLog(#"temp1 is %f",temp1);
//NSLog(#"Angle:%F\n",(temp1*180)/M_PI);
newTransform = CGAffineTransformRotate(newTransform, newAngle);
[self animateView:arrow toPosition:newTransform];
}
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform
{
arrow.transform = newTransform;
}
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint
{
CGFloat x = secondPoint.x - firstPoint.x;
CGFloat y = secondPoint.y - firstPoint.y;
CGPoint result = CGPointMake(x, y);
//NSLog(#"%f %f",x,y);
return result;
}
From the documentation about transform method:
The origin of the transform is the value of the center property, or the layer’s anchorPoint property if it was changed. (Use the layer property to get the underlying Core Animation layer object.) The default value is CGAffineTransformIdentity.
So you should be able to set the center of your rotation this way!
And for determining the rotation angle, use the atan2 or atan2f function:
float angleInRadians = atan2f(touchPoint.y-circleCenter.y , touchPoint.x-circleCenter.x);
You can re set the center after transform.
CGPoint centerBeforeTransform = view.center;
//your transform code
view.center = centerBeforeTransform;