CCSprite Follow User Touch - iphone

So far, I have made my CCSprite move to the location of the user's touch on the screen using CCActionMoveTo, however I have only got it to work when the user simply taps.
I would like the CCSprite to move when the user drags their finger, instead of just tapping and moving along with the ability to change direction as the user drags changes direction - I am fairly new to cocos2d and have search for similar questions but have been unable to find any. I have posted my code below:
- (id)init
{
self = [super init];
if (!self) return(nil);
self.userInteractionEnabled = YES;
// Player sprite
_playerSprite = [CCSprite spriteWithImageNamed:#"PlayerSprite.png"];
_playerSprite.scale = 0.5;
_playerSprite.position = ccp(self.contentSize.width/2, 150);
[self addChild:_playerSprite];
return self;
}
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLoc = [touch locationInNode:self];
CCActionMoveTo *actionMove = [CCActionMoveTo actionWithDuration:0.2f position:ccp(touchLoc.x, 150)];
[_playerSprite runAction:actionMove];
}

You will need to implement the touchMoved method and set your sprite position in there. Something like this:
- (void)touchMoved:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLocation = [touch locationInNode:self];
_playerSprite.position = touchLocation;
}

Try this (add a CGPoint property called previousTouchPos):
-(void) touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLoc = [touch locationInNode:self];
self.previousTouchPos = touchLoc;
CCActionMoveTo *actionMove = [CCActionMoveTo actionWithDuration:1.0f position:touchLoc];
[_playerSprite runAction:actionMove];
}
-(void) touchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLoc = [touch locationInNode:self];
CGPoint delta = ccpSub(touchLoc, self.previousTouchPos);
_playerSprite.position = ccpAdd(_playerSprite.position, delta);
self.previousTouchPos = touchLoc;
}

This sounds like an ideal use case for CCActionFollow:
https://www.makegameswith.us/gamernews/365/make-two-nodes-follow-each-other-in-cocos2d-30
If you use the variation where you provide the target position through a block you can use the latest touch position as target position.

Related

Manually passing touches Began to a newly created instance

I want an object to be created when I touch an UIView. But I want the new object to be able to moved without the finger having to be raised. I tried passing the touched event to the new object but it doesn't work.
Is there any way to do it?
You'll have to derive a subclass of the UIView, which will serve as a HolderView for all newly generated views. Also, once a new view is generated, the new view will move along with the finger even if its not raised.
Following code will do it, tweak it later as per your needs:
#interface HolderView : UIView
#property(nonatomic,retain)UIView *newView;
#end
#implementation HolderView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
if (CGRectContainsPoint(self.bounds, touchPoint)) {
CGRect r = CGRectMake(touchPoint.x-50, touchPoint.y-50, 100, 100);
self.newView = [[[UIView alloc] initWithFrame:r]autorelease];
self.newView.backgroundColor= [UIColor cyanColor];
[self addSubview:self.newView];
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (self.newView!=nil) {
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
self.newView.center = touchPoint;
}
}
#end
i think the touch is creating a problem at your end while you touch at some other object the view is also present so touch can not identified on your movable object for that you need to use one UIImageview over your UIView and then detect the touch and then you'll be able to achieve your desired output
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint imgPop = [touch locationInView:imgPopup];
if ([imgPopup pointInside:imgPop withEvent:event])
{
CGPoint imgReply = [touch locationInView:viewComment];
if ([viewComment pointInside:imgReply withEvent:event])
{
} else {
viewPopup.hidden = TRUE;
}
}
}
this is how i manage this code is for dismissing the view on touch but you can modify and use for your purpose.

Determine iPhone Screen Tapped is in region or not?

I want to determine whether the tapped location is in region or not. I have 4 CGPoints and I know this can be done by using UITouch. Also, I have screen tapped location by using the function
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [[touches allObjects] objectAtIndex: 0];
CGPoint currentPos = [myTouch locationInView:self.view];
}
And for example my 4 CGPoints are
self.firstPoint = CGPointMake(50.0f, 50.0f);
self.secondPoint = CGPointMake(200.0, 50.0);
self.thirdPoint = CGPointMake(200.0, 200.0);
self.fourthPoint = CGPointMake(50.0, 120.0);
Thanks in advance
You should use a CGRect to represent the rect instead of four CGPoints and then use CGRectContainsPoint() to check if the rect contains the point.
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
image=[UIImage imageNamed:#"anyImage.gif"];
newView = [[UIImageView alloc]initWithImage:image];
if (location.y<480|| location.y>50)
{
//write your code
}
}

touchesMoved reaching out of my view bounds

I have subclassed UIView and there initially my view will be in a default color and i need to fill some different color on touch (from x axis = 0 to user touched point),here the problem is touchesMoved even if i drag out of my self view bounds it is getting those points,how to restrict it to only for my self view bounds.
I googled & tried below snippets but of no luck
if([self pointInside:point withEvent:nil]){
[self fillColor];
}
My touchesMoved method is as below,
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
endPoint = point;
NSLog(#"moved x: %f,y: %f",point.x,point.y);
if(CGRectContainsPoint([self frame], endPoint)){ // this also not working
[self fillColor];
}
}
Any help is appreciated in advance.
just set tag in viewDidLoad: method and use bellow logic..
fillColorView.tag = 111;
and use bellow logic in touchesMoved: method like bellow..
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *tap = [touches anyObject];
CGPoint pointToMove = [tap locationInView:fillColorView];
if([tap.view isKindOfClass:[UIView class]])
{
UIView *tempView=(UIView *) tap.view;
if (tempView.tag == 111){
[self fillColor];
}
}
}
hope this help you...
In your touchesMoved method, CGPoint point = [touch locationInView:self]; replcae self by the view in which you wants the touch to be worked.
self will get the complete view, you should pass your drawingView at there, so that it will detetc touch only on that view.

Particle engine problem

i am implementing particle engine and here is my code:
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] ))
{
self.isTouchEnabled = YES;
emitter = [[CCParticleMeteor alloc] init];
emitter.texture = [[CCTextureCache sharedTextureCache] addImage:#"stars.png"];
emitter.position = ccp( 240, 160 );
[self addChild:emitter];
}
return self;
}
-(BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self ccTouchesMoved:touches withEvent:event];
return YES;
}
-(BOOL) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
CGPoint point = [[CCDirector sharedDirector] convertToGL:location];
emitter.position = ccp(point.x , point.y);
return YES;
}
And Here is the Screen shot:
Here is i want to need:
1-I want to change the direction of effect( Means flame move upward but i want downward).
2-I want to change the color of flame.
Please help if you can.....
1) A quick look at the particle system documentation gives you either angle or gravity to play with - try setting these to different values i.e.
emitter.angle = <the angle you want>
2) Edit stars.png to be the colour you want?

UIView drag (image and text)

Is it possible to drag UIView around the iOS screen while it has both image and text? e.g. small cards. Could you point me to the similar (solved) topic? I haven't found any.
This is what a neat solution, based on pepouze's answer, would look like (tested, it works!)
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
CGPoint location = [aTouch locationInView:self];
CGPoint previousLocation = [aTouch previousLocationInView:self];
self.frame = CGRectOffset(self.frame, (location.x - previousLocation.x), (location.y - previousLocation.y));
}
While UIView does not have a built-in support for moving itself along the user dragging, it should be not so difficult to implement it. It is even easier when you are only dealing with dragging on the view, and not other actions such as tapping, double tapping, multi-touches etc.
First thing to do is to make a custom view, say DraggableView, by subclassing UIView. Then override UIView's touchesMoved:withEvent: method, and you can get a current dragging location there, and move the DraggableView. Look at the following example.
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *aTouch = [touches anyObject];
CGPoint location = [aTouch locationInView:self.superview];
[UIView beginAnimations:#"Dragging A DraggableView" context:nil];
self.frame = CGRectMake(location.x, location.y,
self.frame.size.width, self.frame.size.height);
[UIView commitAnimations];
}
And because all subviews of the DraggableView object will be moved, too. So put all your images and texts as subviews of the DraggableView object.
What I implemented here is very simple. However, if you want more complex behaviors for the dragging, (for example, the user have to tap on the view for a few seconds to move the view), then you will have to override other event handling methods (touchesBegan:withEvent: and touchesEnd:withEvent) as well.
An addition to MHC's answer.
If you don't want the upper left corner of the view
to jump under your finger, you can also override touchesBegan
like this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
offset = [aTouch locationInView: self];
}
and change MHC's touchesMoved to:
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *aTouch = [touches anyObject];
CGPoint location = [aTouch locationInView:self.superview];
[UIView beginAnimations:#"Dragging A DraggableView" context:nil];
self.frame = CGRectMake(location.x-offset.x, location.y-offset.y,
self.frame.size.width, self.frame.size.height);
[UIView commitAnimations];
}
you should also define CGPoint offset in the interface:
#interface DraggableView : UIView
{
CGPoint offset;
}
EDIT:
Arie Litovsky provides more elegant solution that allows you to ditch the ivar: https://stackoverflow.com/a/10378382/653513
Even though rokjarc solution works, using
CGPoint previousLocation = [aTouch previousLocationInView:self.superview];
avoids the CGPoint offset creation and the call to touchesBegan:withEvent:
Here is a solution to drag a custom UIView (it can be scaled or rotated through its transform), which can hold images and/or text (just edit the Tile.xib as required):
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
CGPoint previous = [touch previousLocationInView:self];
if (!CGAffineTransformIsIdentity(self.transform)) {
location = CGPointApplyAffineTransform(location, self.transform);
previous = CGPointApplyAffineTransform(previous, self.transform);
}
self.frame = CGRectOffset(self.frame,
(location.x - previous.x),
(location.y - previous.y));
}
This work for me. My UIView rotated and scaled
- (void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self];
CGPoint previous = [touch previousLocationInView:self];
if (!CGAffineTransformIsIdentity(self.transform)) {
location = CGPointApplyAffineTransform(location, self.transform);
previous = CGPointApplyAffineTransform(previous, self.transform);
}
CGRect newFrame = CGRectOffset(self.frame,
(location.x - previous.x),
(location.y - previous.y));
float x = CGRectGetMidX(newFrame);
float y = CGRectGetMidY(newFrame);
self.center = CGPointMake(x, y);
}