Exists two images for example the wall and square. main task is make imposible crossing square via wall during touchesMoving. and we can't know from which direction we moving square.
Code:
if (CGRectIntersectsRect(square.frame, wall.frame) {
{
// what position we need set for stop moving of square??
}
on practice if set coordinates of collision, it works just during conditions of intersection inside the wall frame, when finger over cross wall center , this condition
Code:
if (CGRectIntersectsRect(square.frame, wall.frame)
not working and square moving later cross wall
maybe needs one more conditions, or another restrictions for square position inside collision's condition
It's hard to understand what you're asking, sorry, but I'll try to help.
In general with this kind of collision you need to test if the new position is valid, and if it is not then you do NOT move into the new position. Once you allow the objects to move into a collision you are in trouble.
You want to do something like this:
Code:
//calculate new frame
CGRect newFrame = square.frame;
newFrame.origin = CGPointMake(square.origin.x+xspeed, square.origin.y+yspeed);
//only move if the new frame is OK
if(CGRectIntersectsRect(newFrame, wall.frame)==NO){
square.frame = newFrame;
}
Your second problem is that touchesMoved is not guaranteed to fire every frame or ever few pixels; if the system is very busy then you might get 100 pixels or more between calls to touchesMoved, which would make you jump right through a wall. You probably need touchesMoved to update some "target" position, and then use an update method every frame to move the square toward the target at constant speed and check for collisions.
//old school C way
static BOOL collide(int x1, int y1, int wt1, int ht1, int x2, int y2, int wt2, int ht2)
{
return (!(((x1 > (x2+wt2)) || (x2 > (x1+wt1)) || (y1 > (y2+ht2)) || (y2 > (y1+ht1)))));
}
Smasher, many thanks for your help. I will try to implement your solution.
about:
Quote:
Originally Posted by smasher
Your second problem is that touchesMoved is not guaranteed to fire every frame or ever few pixels; if the system is very busy then you might get 100 pixels or more between calls to touchesMoved, which would make you jump right through a wall. You probably need touchesMoved to update some "target" position, and then use an update method every frame to move the square toward the target at constant speed and check for collisions.
i did understand your logic, but still don't know method to implement it. could you tell advise or example for this realisation. if it's not hard for you.
//calculate new frame
CGRect newFrame = square.frame;
newFrame.origin = CGPointMake(square.origin.x+xspeed, square.origin.y+yspeed);
//only move if the new frame is OK
if(CGRectIntersectsRect(newFrame, wall.frame)==NO){
square.frame = newFrame;
}
What xspeed, yspeed are mean in this code ? is't predefined variables ? may be in case with tochesMoved will be somthing like that
Code:
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.view];
//calculate new frame
CGRect newFrame = square.frame;
newFrame.origin = CGPointMake( touchLocation.x, touchLocation.y);
//only move if the new frame is OK
if(CGRectIntersectsRect(newFrame, wall.frame)==NO){
square.frame = newFrame;
}
i am intresting only in moving during touching , but not with defined speed like during gameloop.
and in this code the same problem as in first post.
as soon as finger crossing wall newFrame not intersect with wall image and as result square move cross wall too
>i am intresting only in moving during touching , but not with defined speed like during gameloop.
Okay... but if someone drags their finger very quickly, or the system is busy, they can drag right through a wall. The defined speed fixes that.
>as soon as finger crossing wall newFrame not intersect with wall image and as result square move cross wall too
I think I understand - if someone drags over the wall, the square stays on the old side of the wall while they drag and then "pops" to the new side.
The problem is that your code says this:
(1) is the new position clear?
(2) if so, pop to the new position.
It does not check the positions in between.
The fix is not to "pop" - do no move directly to the new location. You must check every location in between, either by using a loop or my only moving at a specific speed every frame. I prefer the specific speed, otherwise if you tap on one side of the screen the square will still jump there if all of the spaces in-between are clear.
To move at a specific speed, you'd do something like this:
Code:
//in your .h file, two new instance variables
float speedx;
float speedy;
//your touch code, in touchesmoved:
UITouch *touch = [[event allTouches] anyObject];
CGPoint targetLocation = [touch locationInView:self.view];
float dx = targetLocation.x-square.center.x;
float dy = targetLocation.y-square.center.y;
float distanceToTarget = sqrt (dx*dx +dy*dy);
float squareSpeed = 10 ; //10 pixels per frame; it'd be nicer to have this in tiles per second.
float steps = distanceToTarget / squareSpeed;
speedx = dx /steps;
speedy = dy / steps;
//trigger this method with an NStimer 10 or 20 times a second
-(void)update{
//calculate new frame
CGRect newFrame = square.frame;
newFrame.origin = CGPointMake( square.origin.x+speedx, square.origin.y+speedy);
//only move if the new frame is OK
BOOL isClear = CGRectIntersectsRect(newFrame, wall.frame)==NO;
if(isClear){
square.frame = newFrame;
}
}