"Ghost rectangle" affecting program? - iphone

Yesterday there was a rectangle stuck in the top corner of my program, and for some reason no matter what I did I could not get it out of there. Today I re-ran the program, and it disappeared, but I believe it's memory is still stuck because it's affecting my code.
I'm trying to detect when rectangle A (motioned by accelerometer) contacts rectangle B (randomly placed; motionless). Nothing happens when A contacts B, however when I move A into the top corner where the ghost rectangle was all of yesterday it runs my if statement continuously until I move it away.
Here is the code just incase it's needed
#synthesize Button;
#synthesize Rand;
//Awaking the accelerometer
-(void) awakeaccelerometer
{
[[UIAccelerometer sharedAccelerometer]setUpdateInterval:1.0/50.0];//<---Sensitivity
[[UIAccelerometer sharedAccelerometer]setDelegate:self];
NSLog(#"Accelerometer is awake");
float randX = arc4random() % 320;
float randY = arc4random() % 548;
CGPoint randNewPlace = CGPointMake(randX, randY);
Rand.center = randNewPlace;
}
//Controlling the accelerometer
-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
#define MovingObjectRadius 4
//Acceleration for player
valueX = acceleration.x * 10; //speeds
valueY = acceleration.y * -10; //speeds
//Create new integers
int newX = (int)(Button.center.x + valueX);
int newY = (int)(Button.center.y + valueY);
//Position Validate...This stops the movements from going past the screen; 320 pixels
//For X
if (newX > (320 - MovingObjectRadius))
{
newX = (320 - MovingObjectRadius);
}
if (newX < (0 + MovingObjectRadius))
{
newX = (0 + MovingObjectRadius);
}
//For Y
if (newY > (548 - MovingObjectRadius))
{
newY = (548 - MovingObjectRadius);
}
if (newY < (0 + MovingObjectRadius))
{
newY = (0 + MovingObjectRadius);
}
//Make the new point
CGPoint buttonNewCenter = CGPointMake(newX,newY);
Button.center = buttonNewCenter;
CGRect blockRect = CGRectMake(newX, newY, 20, 20);
CGRect targetRect = CGRectMake(randX, randY, 20, 20);
if (CGRectIntersectsRect(blockRect, targetRect))
{
float tnewX = arc4random() % 320;
float tnewY = arc4random() % 548;
CGPoint randNewPl = CGPointMake(tnewX, tnewY);
Rand.center = randNewPl;
}
}

Related

how to shift the slider image knot outside

i have difficulties understanding the math behind on how to calculate the circumference of the knots to the center of the circle. i hope you guys can give me some pointer.
the current calculation set the knot img in the middle of pie, will like to shift it nearer to the outer circle like in img 2
thank you for viewing and commenting, any comments are appreciated.
how i wan to it to be.
/** Draw a white knob over the circle **/
-(void) drawTheHandle:(CGContextRef)ctx{
CGContextSaveGState(ctx);
NSLog(#"handleCenterA.x %f",handleCenterA.x);
NSLog(#" handleCenterA.y %f", handleCenterA.y);
[[UIColor colorWithWhite:1.0 alpha:1.0]set];
UIImage *myImage = [UIImage imageNamed:#"clock-marker.png"];
//this will give me the result of image 1
[myImage drawInRect:CGRectMake(handleCenterA.x-35, handleCenterA.y-40, TB_BUTTON_WIDTH, TB_BUTTON_WIDTH)];
//this will give me the result of image 2
[myImage drawInRect:CGRectMake(handleCenterA.x-35, handleCenterA.y-40, TB_BUTTON_WIDTH, TB_BUTTON_WIDTH)];
CGContextRestoreGState(ctx);
}
#pragma mark - Math -
/** Move the Handle **/
-(void)movehandle:(CGPoint)lastPoint{
//Get the center
CGPoint centerPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2);
//Calculate the direction from a center point and a arbitrary position.
//float currentAngle = AngleFromNorth(centerPoint, lastPoint, NO);
//int angleInt = floor(currentAngle);
//Calculate the direction from the center point to an arbitrary position.
float currentAngle = AngleFromNorth(centerPoint, lastPoint, NO);
int angleInt = 360 - floor(currentAngle);
if (sliderLock == SliderLockedStart) {
self.startAngle = angleInt;
}
//Redraw
[self setNeedsDisplay];
}
- (CGPoint)centerPointFromAngel:(int)angleInt {
CGPoint point = [self pointFromAngle:angleInt];
point.x += TB_BUTTON_WIDTH/2;
point.y += TB_BUTTON_WIDTH/2;
return point;
}
- (CGFloat)distanceBetween:(CGPoint)p1 and:(CGPoint)p2 {
CGFloat xDist = (p2.x - p1.x);
CGFloat yDist = (p2.y - p1.y);
return sqrt((xDist * xDist) + (yDist * yDist));
}
/** Given the angle, get the point position on circumference **/
-(CGPoint)pointFromAngle:(int)angleInt{
//Circle center
CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - (TB_BUTTON_WIDTH/2), self.frame.size.height/2 - (TB_BUTTON_WIDTH/2));
//The point position on the circumference
CGPoint result;
result.y = round(centerPoint.y + radius * sin(ToRad(-angleInt))) ;
result.x = round(centerPoint.x + radius * cos(ToRad(-angleInt)));
return result;
}
//Sourcecode from Apple example clockControl
//Calculate the direction in degrees from a center point to an arbitrary position.
static inline float AngleFromNorth(CGPoint p1, CGPoint p2, BOOL flipped) {
CGPoint v = CGPointMake(p2.x-p1.x,p2.y-p1.y);
float vmag = sqrt(SQR(v.x) + SQR(v.y)), result = 0;
v.x /= vmag;
v.y /= vmag;
double radians = atan2(v.y,v.x);
result = ToDeg(radians);
return (result >=0 ? result : result + 360.0);
}
finally solved it.
/** Given the angle, get the point position on circumference **/
-(CGPoint)pointFromAngle:(int)angleInt{
//Circle center//TB_BUTTON_WIDTH
CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - (TB_BUTTON_WIDTH/2), self.frame.size.height/2 - (TB_BUTTON_WIDTH/2));
//The point position on the circumference radius
CGPoint result;
result.y = round(centerPoint.y + 120 * sin(ToRad(-angleInt))) ;
result.x = round(centerPoint.x + 120 * cos(ToRad(-angleInt)));
NSLog(#"centerPoint %#",NSStringFromCGPoint(centerPoint));
NSLog(#"result %#",NSStringFromCGPoint(result));
return result;
}

Accelerometer based movement

Now woking on game that uses accelerometer to move player sprite left and right.
I used this tutorial: COCOS2D_ACCELEROMETER_MOVEMENT
This works only sometime….some time not move..How can I resolve this problem?
Here is my sample: See this Sample
Thanks for reading this…what's wrong with my code ? Is there any other way?
Here is my code:
#define kHeroMovementAction 1
#define kPlayerSpeed 500
- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
// use the running scene to grab the appropriate game layer by it's tag
// grab the player sprite from that layer using it's tag
CCSprite *playerSprite = mPlayer;
float destX, destY;
BOOL shouldMove = NO;
float currentX = playerSprite.position.x;
float currentY = playerSprite.position.y;
if(acceleration.x > 0.25) { // tilting the device upwards
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else if (acceleration.x < -0.25) { // tilting the device downwards
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else
if(acceleration.y < -0.25) { // tilting the device to the right
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else if (acceleration.y > 0.25) { // tilting the device to the left
destX = currentX - (acceleration.y * kPlayerSpeed);
destY = currentY + (acceleration.x * kPlayerSpeed);
shouldMove = YES;
} else {
destX = currentX;
destY = currentY;
}
if(shouldMove)
{
CGSize wins = [[CCDirector sharedDirector] winSize];
// ensure we aren't moving out of bounds
if(destX < 30 || destX > wins.width - 30 || destY < 30 || destY > wins.height - 100) {
// do nothing
} else {
CCAction *action = [CCMoveTo actionWithDuration:0.5f position: CGPointMake(destX, playerSprite.position.y)];
[playerSprite stopActionByTag:kHeroMovementAction];
[action setTag:kHeroMovementAction];
[playerSprite runAction:action];
}
} else {
// should stop
[playerSprite stopActionByTag:kHeroMovementAction];
}
}
Updates: Here is best way to do this.
You should look at Ray Wenderlich's scrolling tutorial here
His accelerometer part is near the bottom of the page.

Cocos2D and iPhone's accelerometer

good afternoon!
Today I've started to develop a game and I got a trouble. So, first at all I would like to say that I have no experience developing games...
So, I've a CCSprite in the layer and I want to move this between the scene with a margin (top, bottom, left and right).
The minimum X should be -0.8 (in X-axis using the accelerometer) and the maximum 8. The minimun Y should be -1 (in Y-axis) or 0 in Z-axis and the maximum 0 (in Y-axis) or -1 (in Z-axis).
Ok, knowing this, I've tried to do this using the range between minimum and maximum space and accelerometer value but I haven't getting this working vertically (Y-axis on the iPhone). Then I got a done code in the web but this don't works when I want to move the object to back (the object only goes).
Did someone know how to fix this?
My actual code:
- (void)updatePosition:(ccTime)dt {
CGSize winSize = [[CCDirector sharedDirector] winSize];
float maxY = winSize.height - car.contentSize.height/2 - 20;
float minY = car.contentSize.height/2 + 20;
float newY = car.position.y + (carPointsPerSecY * dt);
newY = MIN(MAX(newY, minY), maxY);
float maxX = winSize.width - car.contentSize.width/2 - 40;
float minX = car.contentSize.width/2 + 40;
float newX = car.position.x + (carPointsPerSecX * dt);
newX = MIN(MAX(newX, minX), maxX);
car.position = ccp(newX, newY);
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
float speedY = acceleration.y * 500;
if(carPointsPerSecY < speedY) {
carPointsPerSecY = MIN(carPointsPerSecY + 10, speedY);
} else {
carPointsPerSecY = MAX(carPointsPerSecY - 2, speedY);
}
float speedX = acceleration.x * 200;
if(carPointsPerSecX < speedX) {
carPointsPerSecX = MIN(carPointsPerSecX + 10, speedX);
} else {
carPointsPerSecX = MAX(carPointsPerSecX - 10, speedX);
}
NSLog(#"Acceleration: X (%f) - Y (%f) - Z (%f)", acceleration.x, acceleration.y, acceleration.z);
}
I'm not sure I completely understand what you want but I hope this helps you with your end goal:
-(void)updatePosition:(ccTime)dt {
CGSize size = [[CCDirector sharedDirector] winSize];
int margin = 20;
float speed = 15;
float maxX = size.width - car.contentSize.width / 2 - margin;
float minX = car.contentSize.width / 2 + margin;
float maxY = size.height - car.contentSize.height / 2 - margin;
float minY = car.contentSize.height / 2 + margin;
float newX = MIN(MAX(car.position.x + xAccel * speed, minX), maxX);
float newY = MIN(MAX(car.position.y + yAccel * speed, minY), maxY);
car.position = ccp(newX, newY);
}
//define in header: float xAccel, yAccel;
- (void)accelerometer: (UIAccelerometer *)accelerometer didAccelerate: (UIAcceleration *)acceleration {
yAccel = acceleration.x;
xAccel = -acceleration.y;
}

Draw Brush Is Not Completly Drawing When Moving Diagonally?

When drawing from currentPoint.x and currentPoint.y to lastPoint.x and lastPoint.y
in diagonally right upside or right downwards it's giving me gaps (spaces) in the drawn line as shown in below image.
-(void)brushType{
UIGraphicsBeginImageContext(drawImage.frame.size);
CGContextRef Mycontext = UIGraphicsGetCurrentContext();
int x, cx, deltax, xstep,y, cy, deltay, ystep,error, st, dupe;
int x0, y0, x1, y1;
x0 = currentPoint.x;
y0 = currentPoint.y;
x1 = lastPoint.x;
y1 = lastPoint.y;
// find largest delta for pixel steps
st =(abs(y1 - y0) > abs(x1 - x0));
// if deltay > deltax then swap x,y
if (st) {
(x0 ^= y0);
(y0 ^= x0);
(x0 ^= y0); //swap(x0, y0);
(x1 ^= y1);
(y1 ^= x1);
(x1 ^= y1); // swap(x1, y1);
}
deltax = abs(x1 - x0);
deltay = abs(y1 - y0);
error = (deltax / 4);
y = y0;
if (x0 > x1) {
xstep = -1;
}
else {
xstep = 1;
}
if (y0 > y1) {
ystep = -1;
}
else {
ystep = 1;
}
for ((x = x0); (x != (x1 + xstep)); (x += xstep))
{
(cx = x);
(cy = y); // copy of x, copy of y
// if x,y swapped above, swap them back now
if (st) {
(cx ^= cy);
(cy ^= cx);
(cx ^= cy);
}
(dupe = 0); // initialize no dupe
if(!dupe) {
CGContextSetRGBStrokeColor(Mycontext, 0.0, 0.0, 0.0, 1.00f);
CGContextMoveToPoint(Mycontext, cx+brushSize*4,cy-brushSize/2);
CGContextAddLineToPoint(Mycontext, cx-brushSize/2, cy+brushSize*4);
}
(error -= deltay); // converge toward end of line
if (error < 0) { // not done yet
(y += ystep);
(error += deltax);}
}
CGContextStrokePath(Mycontext);
[drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)];
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
brushSize = 4;
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
currentPoint = [touch locationInView:drawImage];
currentPoint.y -= 20;
[self brushType];
}
If anyone has an idea please helpe me to fix this issue!
I see a bunch of problems with your function, most of which are poor style. You are using XOR-swap, which makes the code hard to read. You declare all of your variables at the top of the method, making it harder to understand the lifetime of each variable. You put unnecessary parentheses all over the place, making the code harder to read. You call CGContextSetRGBStrokeColor repeatedly in your loop, but you only need to set the stroke color once. So first let's rewrite your method to fix those problems:
static inline void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
-(void)brushType {
int x0 = currentPoint.x;
int y0 = currentPoint.y;
int x1 = lastPoint.x;
int y1 = lastPoint.y;
int deltax = abs(x1 - x0);
int deltay = abs(y1 - y0);
int needSwap = deltay > deltax;
if (needSwap) {
swap(&x0, &y0);
swap(&x1, &y1);
swap(&deltax, &deltay);
}
int error = deltax / 4;
int y = y0;
int xstep = x0 > x1 ? -1 : 1;
int ystep = y0 > y1 ? -1 : 1;
CGSize size = self.drawImage.bounds.size;
UIGraphicsBeginImageContext(size); {
CGContextRef gc = UIGraphicsGetCurrentContext();
for (int x = x0; x != x1 + xstep; x += xstep)
{
int cx = x;
int cy = y;
if (needSwap)
swap(&cx, &cy);
CGContextMoveToPoint(gc, cx + brushSize*4, cy - brushSize/2);
CGContextAddLineToPoint(gc, cx - brushSize/2, cy + brushSize*4);
error -= deltay; // converge toward end of line
if (error < 0) { // not done yet
y += ystep;
error += deltax;
}
}
[UIColor.blackColor setStroke];
CGContextStrokePath(gc);
[self.drawImage.image drawInRect:CGRectMake(0, 0, size.width, size.height)];
self.drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
} UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
So now it's easier to understand that you're stepping along the straight line from lastPoint to currentPoint. If that line is primarily horizontal, you increment x by 1 (or -1) at each step, and increment y as necessary to stay close to the true straight line. If the line is primarily vertical, you swap x and y.
Here's the problem. Suppose the straight line is at a 45 degree angle. You're going to increment x by 1 and y by 1 at every step. Pythagoras tells us that you're moving a distance of sqrt(2) ≈ 1.4142 points per step. Since your “brush” is stroked with the default stroke width of 1 point, there's a gap between adjacent stamps of the brush.
The correct way to fix this is to stop using ints and error correction terms to compute the points along the line. Core Graphics and UIKit use CGFloats anyway, so by using ints you're not only getting less accurate results, you're triggering extra conversions from CGFloat to int and back.
What you need to do is store x and y as CGFloat, and increment them both at each step so that the distance between brush stamps is 1.
-(void)brushType {
CGFloat dx = currentPoint.x - lastPoint.x;
CGFloat dy = currentPoint.y - lastPoint.y;
CGFloat length = hypotf(dx, dy);
dx /= length;
dy /= length;
CGSize size = self.drawImage.bounds.size;
// Bonus! This works correctly on Retina devices!
UIGraphicsBeginImageContextWithOptions(size, NO, self.drawImage.window.screen.scale); {
CGContextRef gc = UIGraphicsGetCurrentContext();
for (CGFloat i = 0; i < length; ++i) {
CGFloat x = lastPoint.x + i * dx;
CGFloat y = lastPoint.y + i * dy;
CGContextMoveToPoint(gc, x + brushSize * 4, y - brushSize / 2);
CGContextAddLineToPoint(gc, x - brushSize / 2, y + brushSize * 4);
}
[UIColor.blackColor setStroke];
CGContextSetLineWidth(gc, 1.01);
CGContextStrokePath(gc);
[self.drawImage.image drawAtPoint:CGPointZero];
self.drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
} UIGraphicsEndImageContext();
lastPoint = currentPoint;
}
If you use this version of the method, you'll find that it looks much better, but still not quite perfect:
The problem, I believe, is that diagonal strokes are drawn using anti-aliasing, and anti-aliasing is an approximation. If you drawn two width-1 lines 1 point apart, the partial colorings that each line contributes to the common pixels don't add up perfectly.
An easy, cheesy way to fix it is to make your stroke width a little wider. Just add this before CGContextStrokePath:
CGContextSetLineWidth(gc, 1.1);
Result:

iPhone, cocos2d and accelerometer

I'm reading 'Learn iPhone and iPad Cocos2D Game Development' and in chapter 4, there's a simple sample using accelerometer. It works well if I use x-axis only as the book but with y-axis, sprite's movement is not smooth if it on the edge of the screen.
+ (id)scene
{
CCScene* scene = [CCScene node];
CCLayer* layer = [GameScene node];
[scene addChild:layer];
return scene;
}
- (id)init
{
if ((self = [super init]))
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
self.isAccelerometerEnabled = YES;
player = [CCSprite spriteWithFile:#"alien.png"];
[self addChild:player z:0 tag:1];
CGSize screenSize = [[CCDirector sharedDirector] winSize];
float imageHeight = [player texture].contentSize.height;
player.position = CGPointMake(screenSize.width / 2, imageHeight / 2);
[self scheduleUpdate];
}
return self;
}
- (void)dealloc
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
[super dealloc];
}
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
float deceleration = 0.4f;
float sensitivity = 6.0f;
float maxVelocity = 100;
playerVelocity.x = playerVelocity.x * deceleration + acceleration.x * sensitivity;
playerVelocity.y = playerVelocity.y * deceleration + acceleration.y * sensitivity;
if (playerVelocity.x > maxVelocity)
{
playerVelocity.x = maxVelocity;
}
else if (playerVelocity.x < -maxVelocity)
{
playerVelocity.x = -maxVelocity;
}
if (playerVelocity.y > maxVelocity)
{
playerVelocity.y = maxVelocity;
}
else if (playerVelocity.y < -maxVelocity)
{
playerVelocity.y = -maxVelocity;
}
}
- (void)update:(ccTime)delta
{
CGPoint pos = player.position;
pos.x += playerVelocity.x;
pos.y += playerVelocity.y;
CGSize screenSize = [[CCDirector sharedDirector] winSize];
float imageWidthHalved = [player texture].contentSize.width * 0.5f;
float leftBorderLimit = imageWidthHalved;
float rightBorderLimit = screenSize.width - imageWidthHalved;
if (pos.x < leftBorderLimit)
{
pos.x = leftBorderLimit;
playerVelocity = CGPointZero;
}
else if (pos.x > rightBorderLimit)
{
pos.x = rightBorderLimit;
playerVelocity = CGPointZero;
}
float imageHeightHalved = [player texture].contentSize.height * 0.5f;
float topBorderLimit = screenSize.height - imageHeightHalved;
float bottomBorderLimit = imageHeightHalved;
if (pos.y < bottomBorderLimit)
{
pos.y = bottomBorderLimit;
playerVelocity = CGPointZero;
}
else if (pos.y > topBorderLimit)
{
pos.y = topBorderLimit;
playerVelocity = CGPointZero;
}
player.position = pos;
}
What's the problem?
If you want you can try what I did in my game:
#define SIGN(x) ((x < 0.0f) ? -1.0f : 1.0f)
- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration {
float kFilteringFactor = 0.01;
accels[0] = acceleration.x * kFilteringFactor + accels[0] * (1.0f - kFilteringFactor);
accels[1] = acceleration.y * kFilteringFactor + accels[1] * (1.0f - kFilteringFactor);
accels[2] = acceleration.z * kFilteringFactor + accels[2] * (1.0f - kFilteringFactor);
float xx;
float yy;
// extract the acceleration components
xx = -[acceleration x];
yy = [acceleration y];
// Has the direction changed?
float accelDirX = SIGN(xvelocity) * -1.0f;
float newDirX = SIGN(xx);
float accelDirY = SIGN(yvelocity) * -1.0f;
float newDirY = SIGN(yy);
// Accelerate. To increase viscosity, lower the values below 1.0f
if (accelDirX == newDirX)
xaccel = (abs(xaccel) + 0.99f) * SIGN(xaccel);
if (accelDirY == newDirY)
yaccel = (abs(yaccel) + 0.99f) * SIGN(yaccel);
// Apply acceleration changes to the current velocity
xvelocity = -xaccel * xx;
yvelocity = -yaccel * yy;
[sprite moveByAccelerometerX:yvelocity Y:xvelocity];
}
First of all, thanks for reading my book! :)
You can find an improved filtering method (ease exponential) that I'm using in this article, it also contains basic info on how the accelerometer works.
You can learn more about accelerometer input from the Tilt to Live developers and their approach, comes with a sample project.
I have bought the book and I found that the edge of screen collision detection doesn't work properly unless you have the same size sprite as in the example. Either make your sprite the same size or make the sprite wrap around the screen instead of stopping, which is what I did.