I want to make sure that the motion moved with the button held down picture (as in some trategiyah). But the image shake when I move it. Here's the code:
// PROPERTY
#property (nonatomic, retain) UIView *gameView;
#property GameState gameState; // for current state == Game
#property CGPoint touchPoint;
#property CGPoint screenOffset;
// INICIALIZE
_gameView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIGraphicsBeginImageContext(_gameView.frame.size);
[[UIImage imageNamed:iname] drawInRect:_gameView.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_gameView.backgroundColor = [UIColor colorWithPatternImage:image];
_gameView.userInteractionEnabled = YES;
[self.view addSubview:_gameView];
// METHODS
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
switch (_gameState) {
case Start:
break;
case Game:
if ([touch view] == _gameView) {
_touchPoint = [touch locationInView:touch.view];
NSLog(#"startTouch");
}
break;
default:
break;
}
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint currentTouchPoint = [touch locationInView:touch.view];
switch (_gameState) {
case Start:
break;
case Game:
if ([touch view] == _gameView) {
NSLog(#"%f%f", [touch locationInView:touch.view].x, [touch locationInView:touch.view].y);
currentTouchPoint.x += _screenOffset.x - _touchPoint.x;
currentTouchPoint.y += _screenOffset.y - _touchPoint.y;
_gameView.center = currentTouchPoint;
}
break;
default:
break;
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint endedTouchPoint = [touch locationInView:touch.view];
switch (_gameState) {
case Start:
break;
case Game:
if ([touch view] == _gameView) {
_screenOffset.x += endedTouchPoint.x - _touchPoint.x;
_screenOffset.y += endedTouchPoint.y - _touchPoint.y;
_gameView.center = _screenOffset;
NSLog(#"endTouch");
}
break;
default:
break;
}
}
Even if slightly moving the mouse - the image jumps. Here is what appears in the log:
startTouch
206.000000 319.000000
206.000000 338.000000
209.000000 342.000000
211.000000 367.000000
217.000000 393.000000
228.000000 435.000000
291.000000 580.000000
244.000000 470.000000
316.000000 620.000000
250.000000 470.000000
330.000000 620.000000
263.000000 468.000000
...
endTouch
At the same time I moved the pointer one direction. Where mistake?
I not want to move all objects.
I find reason. If write:
_gameView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"field1.png"]];
_gameView.frame = [[UIScreen mainScreen] bounds];
//_gameView.userInteractionEnabled = YES;
that's work, but if uncomment last string problem return. But it needs for my program =(
You can make sure the location of the touch is given in coordinates of AddView's parent view with the line:
CGPoint location = [touch locationInView:AddView.superview];
Related
The game I'm trying to make is simple enough. A UIImageView fireball falls from the top of the screen, and the touch screen is used to move the other UIImageView Dustin to avoid it.
Once the fireball reaches the bottom of the screen, it resets back to the top, and the user's score increases by 1. The problem is that after I added the scoring functions, the Dustin UIImage resets to its original position after the fireball reaches the bottom. Without the scoring method, Dustin's image doesn't reset. How does the scoring cause my imageview's position to reset? Most of my code from the ViewController is below.
int theScore;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initializeTimer];
}
- (void)updateScore {
theScore = theScore + 1;
_score.text = [[NSString alloc] initWithFormat:#"%d",theScore];
}
- (void) initializeTimer {
if(theTimer == nil)
{
theTimer = [CADisplayLink displayLinkWithTarget:self selector:#selector(gameLogic:)];
}
theTimer.frameInterval = 1;
[theTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void) gameLogic:(CADisplayLink *) theTimer {
if(!CGRectIntersectsRect(_fireball.frame, _Dustin.frame)){
if(_fireball.center.y >600){
_fireball.center = CGPointMake(0, 0);
[self updateScore];
}
_fireball.center = CGPointMake(_fireball.center.x, _fireball.center.y+4);
}
else{
}
}
- (void) touchesBegan:(NSSet *) touches withEvent:(UIEvent *) event {
UITouch *touch = [touches anyObject];
_firstTouch = [touch locationInView:self.view];
_lastTouch = [touch locationInView:self.view];
_Dustin.center = CGPointMake(_firstTouch.x, _Dustin.center.y);
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
_firstTouch = [touch locationInView:self.view];
_lastTouch = [touch locationInView:self.view];
_Dustin.center = CGPointMake(_firstTouch.x, _Dustin.center.y);
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
_firstTouch = [touch locationInView:self.view];
_lastTouch = [touch locationInView:self.view];
_Dustin.center = CGPointMake(_firstTouch.x, _Dustin.center.y);
}
I have some object on my screen view which moves by touch, but the problem is if I click somewhere else on my screen which has no object on, the last moved object skipped to that clicked position, anyone who know how I can be able to stop that? PostView contains code about my objects
in .h file
#property (weak, nonatomic) IBOutlet PostView *pv;
and .m file
- (void)viewDidLoad
{
[super viewDidLoad];
viewArray = [NSMutableArray arrayWithObjects: nil];
pv.frame = CGRectMake(10, 10, 100, 100);
pv.backgroundColor = [UIColor blackColor];
[viewArray insertObject:pv atIndex:0];
[self.view addSubview:pv];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint firstTouch = [touch locationInView:self.view];
for (PostView *view in viewArray) {
if (CGRectContainsPoint(view.frame, firstTouch)) {
toMove = view;
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:self.view];
toMove.center = location;
// [_delegate dragViewDidMove:self];
// toMove.center = currentTouch;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
currentTouch = [touch locationInView:self.view];
toMove.center = currentTouch;
}
Set toView to null at the start of touchesBegan:. This ensures that if the user makes a touch that touches nothing (and so toView doesn't get set to anything deliberately), nothing will happen when the touch moves (the setCenter: message will be sent to null which will return null and have no side effects.)
I subclass a sprite called newSprite.h / newSprite.m, and I add a sprite in it
CCSprite *nsprite = [CCSprite spriteWithFile:#"mouse.png"];
[self addChild: nsprite];
and in gamelayer.m, I add the following code
newSprite *newp = [newSprite node];
newp.position = ccp(actualX, actualY);
[self addChild:newp];
[_NSMutableArrayName addObject:newp];
when I use following code to detect which sprite i touched
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace: touch];
for (CCSprite *target in _NSMutableArrayName) {
if (CGRectContainsPoint(target.boundingBox, location)) {
CCLOG(#"yes i am touched");
}
}
}
but it doesn't work, the sprite can not be detected, so where is the wrong? please help me, thanks
Try using this:
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace:touch];
for (CCSprite *target in _NSMutableArrayName) {
CGSize size = node.contentSize;
CGRect r = CGRectMake(0.f, 0.f,
size.width, size.height);
if (CGRectContainsPoint(r, local)) {
CCLOG(#"yes i am touched");
}
}
}
You are trying to detect touches on sub sprite and giving the bounds of parent sprite.
First, take nsprite as class variable in NewSprite to keep its reference when you call it from GameLayer. Then try changing this method like:
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [self convertTouchToNodeSpace: touch];
for (CCSprite *target in _NSMutableArrayName) {
CCSize size = target.nSprite.contentSize;
CCRect rect = CCRectMake(target.position.x - size.width/2, target.position.y - size.height/2, width, height);
if (CGRectContainsPoint(rect, location)) {
CCLOG(#"yes i am touched");
}
}
}
I have a UIView on where i add balls with a ID. When i touch the ball with the ID 1 i draw a dashed line follows my finger.
The problem if when i move the finger to the other balls, i don't know how to detect these balls and check the ID they have. The what i need to happen is when i touch the next ball with the ID 2, the line finish draw and stay from ball 1 to ball 2, and create new one from 2 to finger, next.. 3 etc...
The code:
#import "DrawView.h"
#implementation DrawView
- (id)init
{
self = [super initWithFrame:CGRectMake(0, 0, 1024, 768)];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.opaque = YES;
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:315 posY:138 andNumber:1];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:706 posY:138 andNumber:2];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:315 posY:526 andNumber:3];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
checkPointCircle = [[CheckPointCircle alloc] initWithPosX:706 posY:526 andNumber:4];
checkPointCircle.userInteractionEnabled = YES;
[self addSubview:checkPointCircle];
}
return self;
}
- (Line *)drawLine {
return drawLine;
}
- (void)setDrawLine:(Line *)line
{
drawLine = line;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if (touch.view.class == checkPointCircle.class) {
if ([checkTouch getObjectID] == 1) {
startTouchPoint = CGPointMake([checkTouch center].x, [checkTouch center].y);
endTouchPoint = [touch locationInView:self];
}
}
self.drawLine = [[Line alloc] initWithPoint:[touch locationInView:self]];
[self setNeedsDisplay];
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"Cancelado");
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
UITouch *secondaryTouch = (UITouch *)[[[event touchesForView:checkPointCircle] allObjects] objectAtIndex: 0];
NSLog(#"Que toco: %# ", secondaryTouch.view);
if (touch.view.class == checkPointCircle.class) {
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if ([checkTouch getObjectID] == 1) {
endTouchPoint = [touch locationInView:self];
}
}
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CheckPointCircle * checkTouch = (CheckPointCircle *)touch.view;
if (touch.view.class == checkPointCircle.class) {
if ([checkTouch getObjectID] == 1) {
endTouchPoint = [touch locationInView:self];
}
}
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
[drawLine drawLineFrom:startTouchPoint to:endTouchPoint];
}
#end
How to detect the other balls to get the ID.
Can anybody help me?
Thanks!
The Apple documentation of class UIView (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/hitTest:withEvent:) lists two methods which will determine which view contains a hit/point:
– hitTest:withEvent:
– pointInside:withEvent:
Probably hitTest will help most: Its description reads "Returns the farthest descendant of the receiver in the view hierarchy (including itself) that contains a specified point.", so it even converts coordinates as needed.
If you check [self hitTest: [touch.locationInView self] withEvent: event] (or similar, no code completion here ;-)= in your touchesMoved: method, you should be able to detect when the finger is over any of the other circles.
Hope this helps, nobi
I am trying to create four touchable and movable labels on a UIView.
When I touch a ifAnimaPart01 somehow they are all gathered in one location and I can not touch or move the other labels.
Does anyone know why my four labels are acting this way?
I added another 4 labels to display the x and y coordinates for debugging.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
if ([touch view] == ifAnimPart01){
ifAnimPart01.center = location;
}
else if ([touch view] == ifAnimPart02){
ifAnimPart02.center= location;
}
else if ([touch view] == ifAnimPart03){
ifAnimPart03.center= location;
}
else if ([touch view] == ifAnimPart04){
ifAnimPart04.center= location;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[self touchesBegan:touches withEvent:event];
UITouch *myTouch = [touches anyObject];
startPoint1 = [myTouch locationInView:self.view];
xCoordLabel1.text = [NSString stringWithFormat:#"Line OneX = %f", startPoint1.x];
yCoordLabel1.text = [NSString stringWithFormat:#"Line OneY = %f", startPoint1.y];
ifAnimPart01.center = CGPointMake(startPoint1.x, startPoint1.y);
startPoint2 = [myTouch locationInView:self.view];
xCoordLabel2.text = [NSString stringWithFormat:#"Line TwoX = %f", startPoint2.x];
yCoordLabel2.text = [NSString stringWithFormat:#"Line TwoY = %f", startPoint2.y];
ifAnimPart02.center = CGPointMake(startPoint2.x, startPoint2.y);
startPoint3 = [myTouch locationInView:self.view];
xCoordLabel3.text = [NSString stringWithFormat:#"Line ThreeX = %f", startPoint3.x];
yCoordLabel3.text = [NSString stringWithFormat:#"Line ThreeY = %f", startPoint3.y];
ifAnimPart03.center = CGPointMake(startPoint3.x, startPoint3.y);
startPoint4 = [myTouch locationInView:self.view];
xCoordLabel4.text = [NSString stringWithFormat:#"Line FourX = %f", startPoint4.x];
yCoordLabel4.text = [NSString stringWithFormat:#"Line FourY = %f", startPoint4.y];
ifAnimPart04.center = CGPointMake(startPoint4.x, startPoint4.y);
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
}