Increasing ball (object) speed - ios

I have create simple game. How can I increase the speed of ball. Please help!
-(void)BallMovement{
[self ComputerMovement];
[self Collision];
football.center = CGPointMake(football.center.x + X, football.center.y + Y);
if (football.center.x < 15) {
X = 0 - X;
}
if (football.center.x > 305) {
X = 0 - X;
}
if (football.center.y < 0) {
PlayerScoreNumber = PlayerScoreNumber + 1;
PlayerScore.text = [NSString stringWithFormat:#"%i", PlayerScoreNumber];
[timer invalidate];
StartButton.hidden = NO;
button.hidden = NO;
football.center = CGPointMake(147, 250);

clearly based on your code variable X is your velocity.
so just increase it. (example X +=0.1) based on some condition.

-(void)BallMovement{
X=X+1
[self ComputerMovement];
[self Collision];
football.center = CGPointMake(football.center.x + X, football.center.y + Y);
if (football.center.x < 15) {
X = 0 - X;
}
if (football.center.x > 305) {
X = 0 - X;
}
if (football.center.y < 0) {

Related

Need help in changing the counter for player and computer in my pong game from a team selection page

I have a pong game with computer and player working well was looking if anyone could help in making a team selection view controller so players can choose their side. Also looking to control the ball speed from a settings controller. If any one could help would be awesome thank you.
My code I'm using is :
#implementation Game
-(void)Collision{
if (CGRectIntersectsRect(Ball.frame, Player.frame)) {
Y = arc4random() %5;
Y = 0-Y;
}
if (CGRectIntersectsRect(Ball.frame, Computer.frame)) {
Y = arc4random() %5;
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *Drag = [[event allTouches] anyObject];
Player.center = [Drag locationInView:self.view];
if (Player.center.y > 620) {
Player.center = CGPointMake(Player.center.x, 620);
}
if (Player.center.y < 620) {
Player.center = CGPointMake(Player.center.x, 620);
}
if (Player.center.x < 25) {
Player.center = CGPointMake(25, Player.center.y);
}
if (Player.center.x > 340) {
Player.center = CGPointMake(340, Player.center.y);
}
}
-(void)ComputerMovement{
if (Computer.center.x > Ball.center.x) {
Computer.center = CGPointMake(Computer.center.x - 2, Computer.center.y);
}
if (Computer.center.x < Ball.center.x) {
Computer.center = CGPointMake(Computer.center.x + 2, Computer.center.y);
}
if (Computer.center.x < 25) {
Computer.center = CGPointMake(25, Computer.center.y);
}
if (Computer.center.x > 340) {
Computer.center = CGPointMake(340, Computer.center.y);
}
}
-(IBAction)StartButton:(id)sender{
StartButton.hidden = YES;
Exit.hidden = YES;
WinOrLose.hidden = YES;
Y = arc4random() %11;
Y = Y- 5;
X = arc4random() %11;
X = X - 5;
if (Y == 0){
Y =1;
}
if (X==0){
X = 1;
}
{
timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(BallMovement) userInfo:nil repeats:YES];
}
}
-(void)BallMovement{
[self ComputerMovement];
[self Collision];
Ball.center= CGPointMake(Ball.center.x + X, Ball.center.y + Y);
if (Ball.center.x <5) {
X = 0 - X;
}
if (Ball.center.x >340) {
X = 0 - X;
}
if (Ball.center.y < 0) {
PlayerScoreNumber = PlayerScoreNumber + 1;
PlayerScore.text = [ NSString stringWithFormat:#"%i", PlayerScoreNumber];
[timer invalidate];
StartButton.hidden = NO;
WinOrLose.hidden = YES;
Ball.center = CGPointMake(147, 326);
Computer.center = CGPointMake(134, 28);
if (PlayerScoreNumber == 10) {
StartButton.hidden = YES;
Exit.hidden = NO;
WinOrLose. Hidden = NO;
WinOrLose.text = [NSString stringWithFormat:#"You Win!"];
}
}
if (Ball.center.y > 640) {
ComputerScoreNumber = ComputerScoreNumber + 1;
ComputerScore.text = [NSString stringWithFormat:#"%i", ComputerScoreNumber];
[timer invalidate];
StartButton.hidden = NO;
Ball.center = CGPointMake(147, 3269);
Computer.center = CGPointMake(134, 28);
if (ComputerScoreNumber == 10) {
StartButton.hidden =YES;
Exit.hidden = NO;
WinOrLose. Hidden = NO;
WinOrLose.text = [NSString stringWithFormat:#"You Lose!"];
}
}
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
I would start with a Storyboard to create the needed ViewControllers. After that you can connect them with segues and model the transition triggers.
I've written a small tutorial about this some time ago. Maybe this helps:
HowTo: Add View Controllers to the game storyboard and use segues to navigate between them

Get all X,Y coordinates between two points in objective C

How to get all X,Y coordinates between two points.
I want to move a UIButton in a diagonal pattern in objective C.
Example. To move UIButton from position 'Point A' towards position 'Point B'.
.Point B
. Point A
Thanks in advance.
you can use Bresenham's line algorithm
Here is a slightly simplified version, I have used a bunch of times
+(NSArray*)getAllPointsFromPoint:(CGPoint)fPoint toPoint:(CGPoint)tPoint
{
/*Simplified implementation of Bresenham's line algoritme */
NSMutableArray *ret = [NSMutableArray array];
float deltaX = fabsf(tPoint.x - fPoint.x);
float deltaY = fabsf(tPoint.y - fPoint.y);
float x = fPoint.x;
float y = fPoint.y;
float err = deltaX-deltaY;
float sx = -0.5;
float sy = -0.5;
if(fPoint.x<tPoint.x)
sx = 0.5;
if(fPoint.y<tPoint.y)
sy = 0.5;
do {
[ret addObject:[NSValue valueWithCGPoint:CGPointMake(x, y)]];
float e = 2*err;
if(e > -deltaY)
{
err -=deltaY;
x +=sx;
}
if(e < deltaX)
{
err +=deltaX;
y+=sy;
}
} while (round(x) != round(tPoint.x) && round(y) != round(tPoint.y));
[ret addObject:[NSValue valueWithCGPoint:tPoint]];//add final point
return ret;
}
If you simply want to animate a UIControl from one location to another, you might want to use UIAnimation:
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveLinear animations:^{
btn.center = CGPointMake(<NEW_X>, <NEW_Y>)
} completion:^(BOOL finished) {
}];
You should really use Core Animation for this. You just need to specify the new origin for your UIButton and Core Animation does the rest:
[UIView animateWithDuration:0.3 animations:^{
CGRect frame = myButton.frame;
frame.origin = CGPointMake(..new X.., ..new Y..);
myButton.frame = frame;
}];
For Swift 3.0,
func findAllPointsBetweenTwoPoints(startPoint : CGPoint, endPoint : CGPoint) {
var allPoints :[CGPoint] = [CGPoint]()
let deltaX = fabs(endPoint.x - startPoint.x)
let deltaY = fabs(endPoint.y - startPoint.y)
var x = startPoint.x
var y = startPoint.y
var err = deltaX-deltaY
var sx = -0.5
var sy = -0.5
if(startPoint.x<endPoint.x){
sx = 0.5
}
if(startPoint.y<endPoint.y){
sy = 0.5;
}
repeat {
let pointObj = CGPoint(x: x, y: y)
allPoints.append(pointObj)
let e = 2*err
if(e > -deltaY)
{
err -= deltaY
x += CGFloat(sx)
}
if(e < deltaX)
{
err += deltaX
y += CGFloat(sy)
}
} while (round(x) != round(endPoint.x) && round(y) != round(endPoint.y));
allPoints.append(endPoint)
}
This version of Bresenham's line algorithm works well with horizontal line:
+ (NSArray*)getAllPointsFromPoint:(CGPoint)fPoint toPoint:(CGPoint)tPoint {
/* Bresenham's line algorithm */
NSMutableArray *ret = [NSMutableArray array];
int x1 = fPoint.x;
int y1 = fPoint.y;
int x2 = tPoint.x;
int y2 = tPoint.y;
int dy = y2 - y1;
int dx = x2 - x1;
int stepx, stepy;
if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
dy <<= 1; // dy is now 2*dy
dx <<= 1; // dx is now 2*dx
[ret addObject:[NSValue valueWithCGPoint:CGPointMake(x1, y1)]];
if (dx > dy)
{
int fraction = dy - (dx >> 1); // same as 2*dy - dx
while (x1 != x2)
{
if (fraction >= 0)
{
y1 += stepy;
fraction -= dx; // same as fraction -= 2*dx
}
x1 += stepx;
fraction += dy; // same as fraction -= 2*dy
[ret addObject:[NSValue valueWithCGPoint:CGPointMake(x1, y1)]];
}
} else {
int fraction = dx - (dy >> 1);
while (y1 != y2) {
if (fraction >= 0) {
x1 += stepx;
fraction -= dy;
}
y1 += stepy;
fraction += dx;
[ret addObject:[NSValue valueWithCGPoint:CGPointMake(x1, y1)]];
}
}
return ret;
}
UPDATE: this is actually simple math find the point on the line made out of two points, here is my algo:
+ (NSArray*)getNumberOfPoints:(int)num fromPoint:(CGPoint)p toPoint:(CGPoint)q {
NSMutableArray *ret = [NSMutableArray arrayWithCapacity:num];
float epsilon = 1.0f / (float)num;
int count = 1;
for (float t=0; t < 1+epsilon && count <= num ; t += epsilon) {
float x = (1-t)*p.x + t*q.x;
float y = (1-t)*p.y + t*q.y;
[ret addObject:[NSValue valueWithCGPoint:CGPointMake(x, y)]];
count++;
}
// DDLogInfo(#"Vector: points made: %d",(int)[ret count]);
// DDLogInfo(#"Vector: epsilon: %f",epsilon);
// DDLogInfo(#"Vector: points: %#",ret);
return [ret copy];
}

CMMotionManager Reference Frame

I'm developing an app that when a user opens there will be an image, controlled by CMMotionManager, which moves according to the direction the user tilts the device.
....
This is my code to start the device motion.
motionManager = [[CMMotionManager alloc] init];
motionManager.showsDeviceMovementDisplay = YES;
motionManager.deviceMotionUpdateInterval = 1.0 / 60.0;
[motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryCorrectedZVertical];
The is the code I use to control my image in reference to the motion of the device.
- (void)drawRect:(CGRect)rect
{
if (placesOfInterestCoordinates == nil) {
return;
}
mat4f_t projectionCameraTransform;
multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);
int i = 0;
for (MovingImage *poi in [placesOfInterest objectEnumerator]) {
vec4f_t v;
multiplyMatrixAndVector(v, projectionCameraTransform, placesOfInterestCoordinates[i]);
float x = (v[0] / v[3] + 1.0f) * 0.5f;
float y = (v[1] / v[3] + 1.0f) * 0.5f;
if (v[2] < 0.0f) {
CGPoint movingTo = CGPointMake(x*self.bounds.size.width, self.bounds.size.height-y*self.bounds.size.height);
if (movingTo.x < -118) {
movingTo.x = -118;
}
if (movingTo.x > 542) {
movingTo.x = 542;
}
if (movingTo.y < 215) {
movingTo.y = 215;
}
if (movingTo.y > 390) {
movingTo.y = 390;
}
poi.view.center = movingTo;
poi.view.hidden = NO;
} else {
poi.view.hidden = YES;
}
i++;
}
}
The image is in the middle of the screen rarely when the user opens the app, the image is usually to the right or left 90 degrees of the starting position, or exactly in the middle consistently.
I assume that CMAttitudeReferenceFrameXArbitraryCorrectedZVertical is the issue, but I have also tried CMAttitudeReferenceFrameXArbitraryZVertical which doesn't work either.
If useful, my project is here, for anyone interested. I used Apple pARk sample code as well.
- (void)drawRect:(CGRect)rect
{
if (placesOfInterestCoordinates == nil) {
return;
}
mat4f_t projectionCameraTransform;
multiplyMatrixAndMatrix(projectionCameraTransform, projectionTransform, cameraTransform);
int i = 0;
for (MovingImage *poi in [placesOfInterest objectEnumerator]) {
vec4f_t v;
multiplyMatrixAndVector(v, projectionCameraTransform, placesOfInterestCoordinates[i]);
float x = (v[0] / v[3] + 1.0f) * 0.5f;
float y = (v[1] / v[3] + 1.0f) * 0.5f;
if (v[2] < 1.0f) { // change here
CGPoint movingTo = CGPointMake(x*self.bounds.size.width, self.bounds.size.height-y*self.bounds.size.height);
if (movingTo.x < -118) {
movingTo.x = -118;
}
if (movingTo.x > 542) {
movingTo.x = 542;
}
if (movingTo.y < 215) {
movingTo.y = 215;
}
if (movingTo.y > 390) {
movingTo.y = 390;
}
poi.view.center = movingTo;
poi.view.hidden = NO;
} else {
poi.view.hidden = YES;
}
i++;
}
}
try changing (v[2] < 0.0f) to (v[2] < 1.0f)
The viewing angle is different because it is looking for when the image comes into view, other than your device's perspective angle.

Add enemy on stage within a limit

I am making an application just for testing some codes. There is a ship that is shooting enemies. These enemies comes down from the top of the screen and they are added with this code (The reason why its 4 different enemies is that they all have different behaviors)
-(void) addEnemy {
int randomX = arc4random() % screenWidth;
Enemy* anEnemy;
int diceRoll = arc4random() % 4;
if (diceRoll == 0) {
anEnemy = [Enemy createEnemy:#"enemy1" framesToAnimate:24];
} else if (diceRoll == 1) {
anEnemy = [Enemy createEnemy:#"enemy2" framesToAnimate:17];
} else if (diceRoll == 2) {
anEnemy = [Enemy createEnemy:#"enemy3" framesToAnimate:14];
} else if (diceRoll == 3) {
anEnemy = [Enemy createEnemy:#"enemy4" framesToAnimate:24];
}
[self addChild:anEnemy z:depthLevelBelowBullet];
anEnemy.position = ccp ( randomX , screenHeight + 200);
numberOfEnemiesOnstage ++;
}
The enemies are being added with a random x-value which means enemies sometimes is half outside the screen. Like this:
How do limit the x-value from both sides of the screen so this won't happen?
You're not considering the image width when you're calculating the random x position. You have to move the randomX declaration and initialization after you've created the enemy objects so the textureRect property will be properly set.
int offset = (int)[Enemy textureRect].size.width / 2;
int randomX = (arc4random() % (screenWidth - (2 * offset))) + offset;
The above answer is correct but if you are using CCSprite it will be a little different. Try the following code:
-(void) addEnemy {
int randomX = arc4random() % screenWidth;
Enemy* anEnemy;
int diceRoll = arc4random() % 4;
int halfWidth;
if (diceRoll == 0) {
anEnemy = [Enemy createEnemy:#"enemy1" framesToAnimate:24];
halfWidth = anEnemy.contentSize.width/2;
} else if (diceRoll == 1) {
anEnemy = [Enemy createEnemy:#"enemy2" framesToAnimate:17];
halfWidth = anEnemy.contentSize.width/2;
} else if (diceRoll == 2) {
anEnemy = [Enemy createEnemy:#"enemy3" framesToAnimate:14];
halfWidth = anEnemy.contentSize.width/2;
} else if (diceRoll == 3) {
anEnemy = [Enemy createEnemy:#"enemy4" framesToAnimate:24];
halfWidth = anEnemy.contentSize.width/2;
}
if(randomX < halfWidth) {
randomX = halfWidth;
} else {
randomX = randomX-halfWidth;
}
[self addChild:anEnemy z:depthLevelBelowBullet];
anEnemy.position = ccp ( randomX , screenHeight + 200);
numberOfEnemiesOnstage ++;
}

Crop UIImage to alpha

I have a rather large, almost full screen image that I'm going to be displaying on an iPad. The image is about 80% transparent. I need to, on the client, determine the bounding box of the opaque pixels, and then crop to that bounding box.
Scanning other questions here on StackOverflow and reading some of the CoreGraphics docs, I think I could accomplish this by:
CGBitmapContextCreate(...) // Use this to render the image to a byte array
..
- iterate through this byte array to find the bounding box
..
CGImageCreateWithImageInRect(image, boundingRect);
That just seems very inefficient and clunky. Is there something clever I can do with CGImage masks or something which makes use of the device's graphics acceleration to do this?
Thanks to user404709 for making all the hard work.
Below code also handles retina images and frees the CFDataRef.
- (UIImage *)trimmedImage {
CGImageRef inImage = self.CGImage;
CFDataRef m_DataRef;
m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef);
size_t width = CGImageGetWidth(inImage);
size_t height = CGImageGetHeight(inImage);
CGPoint top,left,right,bottom;
BOOL breakOut = NO;
for (int x = 0;breakOut==NO && x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
left = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
breakOut = NO;
for (int y = 0;breakOut==NO && y < height; y++) {
for (int x = 0; x < width; x++) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
top = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
breakOut = NO;
for (int y = height-1;breakOut==NO && y >= 0; y--) {
for (int x = width-1; x >= 0; x--) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
bottom = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
breakOut = NO;
for (int x = width-1;breakOut==NO && x >= 0; x--) {
for (int y = height-1; y >= 0; y--) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
right = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
CGFloat scale = self.scale;
CGRect cropRect = CGRectMake(left.x / scale, top.y/scale, (right.x - left.x)/scale, (bottom.y - top.y) / scale);
UIGraphicsBeginImageContextWithOptions( cropRect.size,
NO,
scale);
[self drawAtPoint:CGPointMake(-cropRect.origin.x, -cropRect.origin.y)
blendMode:kCGBlendModeCopy
alpha:1.];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CFRelease(m_DataRef);
return croppedImage;
}
I created a category on UImage which does this if any one needs it...
+ (UIImage *)cropTransparencyFromImage:(UIImage *)img {
CGImageRef inImage = img.CGImage;
CFDataRef m_DataRef;
m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
UInt8 * m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef);
int width = img.size.width;
int height = img.size.height;
CGPoint top,left,right,bottom;
BOOL breakOut = NO;
for (int x = 0;breakOut==NO && x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
left = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
breakOut = NO;
for (int y = 0;breakOut==NO && y < height; y++) {
for (int x = 0; x < width; x++) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
top = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
breakOut = NO;
for (int y = height-1;breakOut==NO && y >= 0; y--) {
for (int x = width-1; x >= 0; x--) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
bottom = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
breakOut = NO;
for (int x = width-1;breakOut==NO && x >= 0; x--) {
for (int y = height-1; y >= 0; y--) {
int loc = x + (y * width);
loc *= 4;
if (m_PixelBuf[loc + 3] != 0) {
right = CGPointMake(x, y);
breakOut = YES;
break;
}
}
}
CGRect cropRect = CGRectMake(left.x, top.y, right.x - left.x, bottom.y - top.y);
UIGraphicsBeginImageContextWithOptions( cropRect.size,
NO,
0.);
[img drawAtPoint:CGPointMake(-cropRect.origin.x, -cropRect.origin.y)
blendMode:kCGBlendModeCopy
alpha:1.];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return croppedImage;
}
There is no clever cheat to get around having the device do the work, but there are some ways to accelerate the task, or minimize the impact on the user interface.
First, consider the need to accelerate this task. A simple iteration through this byte array may go fast enough. There may be no need to invest in optimizing this task if the app is just calculating this once per run or in reaction to a user's choice that takes at least a few seconds between choices.
If the bounding box is not needed for some time after the image becomes available, this iteration may be launched in a separate thread. That way the calculation doesn't block the main interface thread. Grand Central Dispatch may make using a separate thread for this task easier.
If the task must be accelerated, maybe this is real time processing of video images, then parallel processing of the data may help. The Accelerate framework may help in setting up SIMD calculations on the data. Or, to really get performance with this iteration, ARM assembly language code using the NEON SIMD operations could get great results with significant development effort.
The last choice is to investigate a better algorithm. There's a huge body of work on detecting features in images. An edge detection algorithm may be faster than a simple iteration through the byte array. Maybe Apple will add edge detection capabilities to Core Graphics in the future which can be applied to this case. An Apple implemented image processing capability may not be an exact match for this case, but Apple's implementation should be optimized to use the SIMD or GPU capabilities of the iPad, resulting in better overall performance.

Resources