Rotate imageView as per touch - ios

I am rotating imageView which is minuit hand of a clock, with
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == _imgViewMinuit)
{
NSLog(#"Touched");
_imgMinuitHand.transform = CGAffineTransformRotate(_imgMinuitHand.transform,DEGREES_RADIANS(6));
}
}
Now i want to rotate it as per my finger, clockwise/anticlockwise, with speed of my touch.
How I can achieve this ?

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;
}

Related

Move CCSprite based on users touch - Cocos2d

I have an object that I wish to move 50 pixels in the direction the the touch event occurs. It is a fixed CCSprite called _eyeObject.
I know I need to use
- (void)touchBegan:(UITouch *)touches withEvent:(UIEvent *)event {
CGPoint touchLocation = [touches locationInNode:self];
//Not sure what to do now
}
How would I calculate the CCSprite to move 50 pixels towards the users touch? Then move back to the original position when the touch ends?
A starting point would be great....I don't need to know how to animate or anything, just the calculation.
Whenever a touch happens you want to move 50 pixels in that direction you can do (based on your desire to do it based on a statically positioned eye object sprite):
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchPos = [touch locationInNode:self];
CGPoint delta = ccpSub(touchPos, self.eyeObject.position);
float moveAmount = 50.0f;
CGPoint moveVec;
if (delta.x > 0.0f)
{
moveVec.x = moveAmount;
}
else
{
moveVec.x = -moveAmount;
}
if (delta.y > 0.0f)
{
moveVec.y = moveAmount;
}
else
{
moveVec.y = -moveAmount;
}
self.spriteStartPosition = self.sprite.position;
self.sprite.position = ccpAdd(self.sprite.position, moveVec);
}
- (void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
self.sprite.position = self.spriteStartPosition;
}
If the object you are moving IS that eyeObject then it would be:
- (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchPos = [touch locationInNode:self];
CGPoint delta = ccpSub(touchPos, self.eyeObject.position);
float moveAmount = 50.0f;
CGPoint moveVec;
if (delta.x > 0.0f)
{
moveVec.x = moveAmount;
}
else
{
moveVec.x = -moveAmount;
}
if (delta.y > 0.0f)
{
moveVec.y = moveAmount;
}
else
{
moveVec.y = -moveAmount;
}
self.eyeObjStartPosition = self.eyeObject.position;
self.eyeObject.position = ccpAdd(self.eyeObject.position, moveVec);
}
- (void)touchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
self.eyeObject.position = self.eyeObjStartPosition;
}
To move in general if the static object was representing a joystick or gamepad (would do the same in touch began so I'd separate this into its own method):
- (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchPos = [touch locationInNode:self];
CGPoint delta = ccpSub(touchPos, self.dPad.position);
float moveAmount = 50.0f;
if (delta.x > 0.0f)
{
self.sprite.position.x += moveAmount;
}
else
{
self.sprite.position.x -= moveAmount;
}
if (delta.y > 0.0f)
{
self.sprite.position.y += moveAmount;
}
else
{
self.sprite.position.y -= moveAmount;
}
}
Here's a simple solution - get the unit vector between the two points, multiply it by 50, and add it to the current position. AKA this:
- (void)touchBegan:(UITouch *)touches withEvent:(UIEvent *)event {
CGPoint touchLocation = [touches locationInNode:self];
//Not sure what to do now
CGPoint destinationVector = ccpSub(touchPos, self.eyeObject.position);
CGPoint movementVector = ccpNormalize(destinationVector);
movementVector = ccpMult(movementVector, 50);
[_eyeObject runAction:[CCActionMoveTo actionWithDuration:1.0 position:ccpAdd(_eyeObject, movementVector)]];
}
If you want to have it move back on touchEnded, just save the position in a variable before you move it the first time, and send it back to that spot on touchEnded.

Drag SKSpriteNode based on touch location

I am trying to drag a sprite in the y axis but make the sprite "stick" to the users finger depending on where the touches began on the node.
The sprite is currently dragging but it seems to be snapping the anchorpoint of the sprite to the touch location within the node.
Im assuming it has something to do with getting the location within the node by doing [touch locationInNode:selectedNode]; but I am unsure where to go from there.
Here is my current code.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
CGPoint newPosition = CGPointMake(node.position.x, location.y);
if ([node.name isEqualToString:self.selectedNode] ) {
if (newPosition.y > 230) {
newPosition.y = 230;
}
node.position = newPosition;
}
}
}
You need to offset the newPosition based on the current touch position on the node.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches)
{
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node.name isEqualToString:self.selectedNode] )
{
CGPoint previousLocation = [touch previousLocationInNode:self];
float diff = location.y - previousLocation.y;
CGPoint newPosition = CGPointMake(node.position.x, node.position.y + diff);
if (newPosition.y > 230) {
newPosition.y = 230;
}
node.position = newPosition;
}
}
}
There are a couple of ways of doing this. The sample code below tracks the user's touch location and moves the sprite towards that position during the update method. You can modify the code to only move on the y axis or x axis.
#implementation MyScene
{
SKSpriteNode *object1;
CGPoint destinationLocation;
}
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
[self createObject];
destinationLocation = CGPointMake(300, 150);
}
return self;
}
-(void)createObject
{
object1 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(50, 50)];
object1.position = CGPointMake(300, 150);
[self addChild:object1];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
destinationLocation = [touch locationInNode:self.scene];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
destinationLocation = [touch locationInNode:self.scene];
}
-(void)update:(CFTimeInterval)currentTime
{
float x = fabs(object1.position.x - destinationLocation.x);
float y = fabs(object1.position.y - destinationLocation.y);
float divider = 0;
if(x > y)
{
divider = x;
} else
{
divider = y;
}
float xMove = (x/divider)*8; // change number to increase or decrease speed
float yMove = (y/divider)*8; // change number to increase or decrease speed
if(object1.position.x > destinationLocation.x)
object1.position = CGPointMake(object1.position.x-xMove, object1.position.y);
if(object1.position.x < destinationLocation.x)
object1.position = CGPointMake(object1.position.x+xMove, object1.position.y);
if(object1.position.y > destinationLocation.y)
object1.position = CGPointMake(object1.position.x, object1.position.y-yMove);
if(object1.position.y < destinationLocation.y)
object1.position = CGPointMake(object1.position.x, object1.position.y+yMove);
}
#end

Having issue with UITextView drag and drop

I am trying to drag a UITextView object with touch ! but I have a problem , I need when user touches the custom view , the touching event begins, but touching methods works only on self.view . here is my code :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touch began ");
UITouch *touch = [touches anyObject];
startingX = [touch locationInView:_captureView].x;
startingY = [touch locationInView:_captureView].y;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint currentPoint = _mText.frame.origin;
float xForView, yForView;
UITouch *touch = [touches anyObject];
float newX = [touch locationInView:_captureView].x;
float deltaX;
if(startingX > newX){
deltaX = startingX - newX;
xForView = currentPoint.x - deltaX;
} else if(newX > startingX){
deltaX = newX - startingX;
xForView = currentPoint.x + deltaX;
} else xForView = currentPoint.x;
float newY = [touch locationInView:_captureView].y;
float deltaY;
if(startingY > newY){
deltaY = startingY - newY;
yForView = currentPoint.y - deltaY;
} else if(newY > startingY){
deltaY = newY - startingY;
yForView = currentPoint.y + deltaY;
} else yForView = currentPoint.y;
CGRect newFrame = CGRectMake(xForView, yForView, _mText.frame.size.width, _mText.frame.size.height);
_mText.frame = newFrame;
startingX = newX;
startingY = newY;
}
my textView is not editable all views are userInteractionEnabled
Write your touches began method and touches moved method inside the your custom text view and try to adjust the frame.

how can I fix this turret so that it moves smoothly

Okay guys I have managed to make a sprite kit game where I have a turret that shoots candies but the problem I have is that the turret doesn't move smoothly as I point a location with my finger. It just jumps to point to the location.
so here is my code below:
- (void) rotateSprite:(SKSpriteNode *)sprite toFace:(CGPoint)velocity rotateRadiansPerSec:(CGFloat)rotateRadiansPerSec {
float targetAngle = CGPointToAngle(velocity);
float shortest = ScalarShortestAngleBetween(sprite.zRotation, targetAngle);
float amtToRotate = rotateRadiansPerSec * _dt;
if (ABS(shortest) < amtToRotate) {
amtToRotate = ABS(shortest);
}
sprite.zRotation += ScalarSign(shortest) * amtToRotate;
}
- (void) movePlayerToward:(CGPoint)location {
_lastTouchLocation = location;
CGPoint offset = CGPointSubtract(location, _Player.position);
CGPoint direction = CGPointNormalize(offset);
_velocity = CGPointMultiplyScalar(direction, PLAYER_MOVE_POINTS_PER_SEC);
}
- (void) update:(NSTimeInterval)currentTime {
if (_lastUpdateTime) {
_dt = currentTime - _lastUpdateTime;
}
else {
_dt = 0;
}
_lastUpdateTime = currentTime;
CGPoint offset = CGPointSubtract(_lastTouchLocation, _Player.position);
float distance = CGPointLength(offset);
if (distance < PLAYER_MOVE_POINTS_PER_SEC * _dt) {
_velocity = CGPointZero;
}
else
{
[self rotateSprite:_Player toFace:_velocity rotateRadiansPerSec:PLAYER_ROTATE_RADIANS_PER_SEC];
}
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self.scene];
[self movePlayerToward:touchLocation];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self.scene];
[self movePlayerToward:touchLocation];
}
I assume you are using the Zombie Conga code which uses static const to set fixed movement and rotation speed values.
In your code you have the line float amtToRotate = rotateRadiansPerSec * _dt;
Make sure you have the rotateRadiansPerSec value set properly as this controls the speed of your rotation.
In the Conga code, the value was:
static const float ZOMBIE_ROTATE_RADIANS_PER_SEC = 4 * M_PI;

UIImage which follow touches

I'm trying to draw a ruller which follow the touches on the screen. On the first touch, I set the first point and on all the other, the ruller follow the finger on ther screen resizing and rotating around the first point depending on where the finger is.
I tried to do this :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self.view];
self.regleFirstPoint = p;
UIImageView* img = [[UIImageView alloc] initWithImage:self.regleImg];
img.frame = CGRectMake(self.regleFirstPoint.x, self.regleFirstPoint.y, 0, self.regleImg.size.height);
[self.view addSubview:img];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self.view];
// Width
float deltaY = p.y - self.regleFirstPoint.y;
float deltaX = p.x - self.regleFirstPoint.x;
float width = sqrt((deltaX * deltaX) + (deltaY * deltaY));
// Angle
float angleInRadians = atanf(deltaY / deltaX);
float angleInDegrees = angleInRadians * 180 / M_PI; // JUST FOR INFO
NSLog(#"angle : %f / %f", angleInRadians, angleInDegrees);
// Resizing image
UIImageView* img = [self.regles lastObject];
img.frame = CGRectMake(self.regleFirstPoint.x, self.regleFirstPoint.y, width, self.regleImg.size.height/2);
img.center = self.regleFirstPoint;
CGAffineTransform transform = CGAffineTransformIdentity;
img.transform = CGAffineTransformRotate(transform, angleInRadians);
}
The ruller doesn't follow the finger correctly, I think I missed something. What's wrong with my code ?
EDIT : I also tried this after some researches :
// Resizing images
img.frame = CGRectMake(self.regleFirstPoint.x, self.regleFirstPoint.y, largeur, self.regleImg.size.height/2);
[img.layer setAnchorPoint:CGPointMake(self.regleFirstPoint.x / img.bounds.size.width, self.regleFirstPoint.y / img.bounds.size.height)];
img.transform = CGAffineTransformRotate(img.transform, angleInRadians);
This is just a question of order:
Set transform of your view to identity
Change the frame of your view
Finally, apply your transform
Here is an updated piece of code, just used an UIView instead of your image:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
// Hold first touch
self.regleFirstPoint = [touch locationInView:self.view];
// Reset view / image
_rulerView.transform = CGAffineTransformIdentity;
_rulerView.frame = CGRectMake(self.regleFirstPoint.x, self.regleFirstPoint.y, 0, CGRectGetHeight(_rulerView.frame));
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self.view];
// Compute width
float deltaX = p.x - self.regleFirstPoint.x;
float deltaY = p.y - self.regleFirstPoint.y;
float width = sqrt((deltaX * deltaX) + (deltaY * deltaY));
// Compute angle
float angleInRadians = atan2(deltaY, deltaX);
NSLog(#"angle (rad) : %f", angleInRadians);
NSLog(#"angle (deg) : %f", angleInRadians * 180 / M_PI);
// First reset the transformation to identity
_rulerView.transform = CGAffineTransformIdentity;
// Set anchor point
_rulerView.layer.anchorPoint = CGPointMake(0.0f, 0.5f);
// Resizing view / image
_rulerView.frame = CGRectMake(self.regleFirstPoint.x, self.regleFirstPoint.y, width, CGRectGetHeight(_rulerView.frame));
// Reset the layer position to the first point
_rulerView.layer.position = self.regleFirstPoint;
// Apply rotation transformation
_rulerView.transform = CGAffineTransformMakeRotation(angleInRadians);
}
Hope that helps.
Cyril

Resources