How can I convert a value to a CGPoint? - iphone

I´ve got a problem with my Xcode-Project and hope you can help me!
I just began coding, so my problem should be very easy to solve.
I wanna make a Pong Game with two paddles and a ball. I have got a value, which is between 0 and 1. If the value is high the paddle should also go up. The paddle position can be changed with "CGPoint", but how can I convert my value to a point?
Please help me.
Thanks and greets from Germany :)

CGPoint is a 2-dimensional point.
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
You can create a CGPoint with CGPointMake(x,y).
When your value is between 0 and 1 you may want to scale either x or y by multiplying with a constant factor.

I have a better idea for the paddle controll:
You can use the users touch imput to controll the paddle:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint pointToMove = [touch locationInView:self.view];
yourImage.center = CGPointMake(yourImage.center.x, pointToMove.y);
}
When the user touches the screen, the paddle moves to the .y position of the touch but stays on its defaulf x cordinates!
That way, the controlls would be more fluid. Just try it out!
Viel Spass beim programmieren :D

This is exact code from my app to do this job
for (id obj in points) {
[self moveToPoint:[((NSValue*) obj) CGPointValue]];

Related

applyImpulse towards CGPoint SpriteKit

I'm kind of a newb in SpriteKit, game dev, as a matter of fact I'm just learning. So I got to a point where I what to move a bunch of nodes towards a users tap location. So far I fought that I might calculate a virtual right triangle and get sin and cos of angles based on the sides. Unfortunately that left me with a very strong impulse that doesn't really consider the user tap location.
Any ideas?
Thanks in advance.
Look up the shooting projectiles section in the tutorial by Ray Wenderlich here:
http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners
Change the code from the tutorial as follows:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// 1 - Choose one of the touches to work with
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
// 2 - Set up initial location of projectile
SKSpriteNode * projectile = [self childNodeWithName:#"desirednode"];
//make projectile point to your desired node.
// 3- Determine offset of location to projectile
CGPoint offset = rwSub(location, projectile.position);
// 4 - Bail out if you are shooting down or backwards. You can ignore this if required.
if (offset.x <= 0) return;
// 5 - OK to add now - we've double checked position
[self addChild:projectile];
// 6 - Get the direction of where to shoot
CGPoint direction = rwNormalize(offset);
// 7 - Make it shoot far enough to be guaranteed off screen
float forceValue = 200; //Edit this value to get the desired force.
CGPoint shootAmount = rwMult(direction, forceValue);
//8 - Convert the point to a vector
CGVector impulseVector = CGVectorMake(shootAmount.x, shootAmount.y);
//This vector is the impulse you are looking for.
//9 - Apply impulse to node.
[projectile.physicsBody applyImpulse:impulseVector];
}
The projectile object in the code represents your node. Also, you will need to edit the forceValue to get the desired impulse.

UIImageView how to track clockwise or counterclockwise user motion

I have successfully implemented rotating a uiimageview using this code from this post
iPhone - Wheel tracking finger jumps to same starting position?
My question to fellow developers is that the user on touch can rotate the image both clockwise and counterclockwise. Is there a way I can detect in which direction is the user moving the view?
Its important to me because I am making a clock app. I let users move the min hand form 0 min all the way to 60 min. When it reaches there I move the hour hand one up. But the user can spin the min hand counter clockwise in which case I need to move the hour hand one down. Any ideas?
you can set a member variable named "lastPoint" to record the point last time you moved
the you can calc the direction next time
CGPoint lastPoint;
- (void) touchedBegin:(NSSet *)touches withEvent:(UIEvent *)event {
lastPoint = [touch locationInView:self.view];
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *allTouches = [event allTouches];
//you can save the point , then used in next time you want
int tInput = [allTouches count]-1;
UITouch *touch =[[allTouches allObjects] objectAtIndex:tInput];
CGPoint location = [touch locationInView:self.view];
float theAngle = atan2( location.y-imageX.center.y, location.x-imageX.center.x );
float theLastAngle = atan2( lastPoint.y-imageX.center.y, lastPoint.x-imageX.center.x );
lastPoint = location;
// compare theAngle & theLastAngle , so you can know it is clockwise or counterclockwise.
}

iPhone hitTest broken after rotation

I have a UIView that contains a number of CALayer subclasses. I am using the following code to detect which layer a touch event corresponds to:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
NSLog(#"%#,%#",NSStringFromCGPoint(point),[self.layer hitTest:point].name);
}
This works fine until the device is rotated. When the device is rotated all current layers are removed from the superlayer, and new CALayers are created to fit the new orientation. The new layers are correctly inserted and viewable in the correct orientation.
After the rotation the hitTest method consistently returns null for the layer. I have noticed that when rotated 180 degrees, the returned layer is what was in that location before the rotation, i.e. touching the top left layer gives the layer in the bottom right when rotated 180 degrees. The coordinates of the hit test are printed as expected with (0,0) being in the top left. I redraw the layers with every rotation, but for some reason they seem to be mapped to being the "correct" way up, with the home button at the bottom. Am I missing a function call or something after handling the rotation?
Cheers,
Adam
Okay, I've found that the following code works in all orientations without any issues (In my case there are no overlapping views so this is appropriate for me):
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
CGPoint point = [t locationInView:self];
for(CALayer *layer in self.layer.sublayers) {
CGPoint convertedPoint = [self.layer convertPoint:point
toLayer:layer];
if([layer containsPoint:convertedPointPoint]) {
NSLog(#"%#",layer.name);
}
}
}
While this manual point conversion works correctly, the question still remains as to why the original method call did not. Can anybody enlighten me?
Adam

Smoothly drag a Sprite in cocos2d - iPhone

I have implemented a drag on a sprite object as follows..
-(BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
CGPoint location = [[Director sharedDirector] convertCoordinate: [touch locationInView:touch.view]];
[diskSprite setPosition:ccp(location.x , location.y )];
return kEventHandled;
}
but this dragging is not smooth.....
when i drag fast with my thumb the object left from the path.
Thanks
Probably a little bit late but I was searching for a similar thing.
I found this great Tutorial which explained everything:
http://www.raywenderlich.com/2343/how-to-drag-and-drop-sprites-with-cocos2d
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
CGPoint oldTouchLocation = [touch previousLocationInView:touch.view];
oldTouchLocation = [[CCDirector sharedDirector] convertToGL:oldTouchLocation];
oldTouchLocation = [self convertToNodeSpace:oldTouchLocation];
CGPoint translation = ccpSub(touchLocation, oldTouchLocation);
CGPoint newPos = ccpAdd(mySpriteToMove.position, translation);
mySpriteToMove.position = newPos;
}
I had this same issue with my game. Dragging operations appeared jerky. I believe the reason is that touch events aren't generated fast enough to give a smooth appearance.
To solve the problem I smoothed the motion out by running an action on the sprite toward the desired location, instead of setting the position immediately.
I'm not exactly sure what you mean by "the object left from the path". I suppose what you mean is that if you drag your finger over the screen in an arc or circle, that the sprite will "jump" from point to point, instead of follow your finger precisely. Is this correct?
If you want your sprite to follow an exact path, you will have to create a path and then set the sprite to follow it. What you do now is simply set the sprite's position to the touch position, but a "dragged" touch will not create an event for every pixel it touches.
It is fairly easy to create a path for touches received, and code samples can be found here and there. However, if the sprite's speed (in pixels per frame) is too high, you will always see it "jump", even if you use a smooth path.
Example:
You can animate a sprite over a circular path. If you animate this to complete the path in 1 second, you will likely see smooth animation. But if it runs at a high speed, like a full circle in 4 frames, you will just see your sprite at 4 places, not in a smooth circle.
If you wish to 'correct' that, you will need to look into blending, or determine what the maximum speed is for acceptable motion, and slow your sprite down when it's too fast.
I hope that answers your question. If it's not clear, feel free to edit your question, or add a comment to my answer.
look here, what I suggest you to try in such case:
-(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
if (_binCaptured) {
CGPoint location = [self convertTouchToNodeSpace:touch];
[_sprite stopAllActions];
id move = [CCEaseIn actionWithAction:[CCMoveTo actionWithDuration:0.1 position:ccp(location.x, _sprite.position.y)]];
[_sprite runAction:move];
}
}
And it really work smoothly.
I enjoyed this easy way.

Problem with touch in cocos2D

Hey guys, i ready many many questions about that point, but i really didn't get the right one yet.
So.. this is the problem..
This is my first project with cocos2d, so sorry for that.
I have one scene called Gameplay inside that i have one Layer with the name Grid and inside of this grid, have many many Block (Layer too).
I need check when you touch one Block, i do this before with Interface Builder, so when i call touchesBegin i have the exact touch in one view. But in cocos2D, i understand you have to check the position of the objects, and not hit test then right?!
So my touchesBegin is like this:
- (void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
//location = [[Director sharedDirector] convertCoordinate: location];
for(int i = 0; i < [arrAllBlocks count]; i++)
{
for (int j = 0; j < [[arrAllBlocks objectAtIndex:i] count]; j++)
{
Block *tempBlock = [[arrAllBlocks objectAtIndex:i] objectAtIndex:j];
CGRect mySurface = (CGRectMake(tempBlock.position.x, tempBlock.position.y, tempBlock.contentSize.width,tempBlock.contentSize.height));
if(CGRectContainsPoint(mySurface, location))
{
NSLog(#"Hit Positions %fl:%fl",location.x,location.y);
NSLog(#"Object Positions %fl:%fl",tempBlock.position.x,tempBlock.position.y);
NSLog(#"Object Color:%# hited", tempBlock.strName);
}
}
}
}
The first Problem is: This looks upsidedown! When i click in one of this blocks at the first line! I get the block at last line!! I Really dont get that! And the hit not seens perfect to me! And when i convertCoordinate this going even worst!
Someone can help me?! And sorry for bad english =/
There are two things to remember...
Cocos2D coordinate system's origin is bottom left corner.
By default, the anchor points of display elements are their centers.
So this is how I solved this problem:
Set the anchor points of the elements to be bottom left as well.
[block setAnchorPoint:ccp(0, 0)];
Use convertCoordinate in ccTouchesBegan.
-(BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint pt = [touch locationInView:[touch view]];
CGPoint ptConv = [[Director sharedDirector] convertCoordinate:pt];
}
Calculate the rectangle of the element and compare...
CGSize size = [block contentSize];
CGPoint point = [block position];
rect = CGRectMake(point.x, point.y, size.width, size.height);
if (CGRectContainsPoint(rect, ptConv))
{
// touched
}
It looks like the only step you are missing is to change the anchor point.
If you prefer not to change the anchor point, you need to change the way rectangle is calculated; adding and subtracting the half of width and height.
Hope it helps.
Remember that the coordinate system in Cocos2D is upside down from that of Cocoa. (Really, Cocoa is upside down to me, but it's just a convention).
I forget this all the time myself!