I'm relativity new to Xcode and I was making a small just-for-fun kinda game for the iPhone and I'm having some trouble as far as making a certain sprite disappear when it spawns.
Brief:
So basically I have a sprite spawning on screen each time every 0.70 seconds and that sprite is set to a global IBOutlet variable called "Circle". These circles spawn at random locations around the screen of the iPhone at random widths and heights.
Overall
So basically I'm trying to make it so that when you click on the exact circle, it only hides that ball.
Thanks. Also, sorry to the mods for the sloppy formatting.
Here's the code in file that's relevant:
GameController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.gameState = GameStatePaused;
circleVerlocity = CGPointMake(CircleSpeedX, CircleSpeedY);
[NSTimer scheduledTimerWithTimeInterval:SpawnSpeed target:self selector:#selector(addCircle:) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:BallSpeed target:self selector:#selector(gameLoop) userInfo:nil repeats:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)addCircle: (NSTimer *) aTimer {
if(gameState == GameStateRunning)
{
UIImageView *Circle1 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"sprite-small-1.png"]];
self.Circle = Circle1;
CGRect rect = CGRectMake(arc4random() % (274), arc4random() % (532), 50, 50);
[Circle1 setFrame:rect];
[self.view addSubview:Circle1];
}
}
-(void)gameLoop
{
if(gameState == GameStateRunning)
{
Circle.center = CGPointMake(Circle.center.x + circleVerlocity.x, Circle.center.y + circleVerlocity.y);
if(Circle.center.x > self.view.bounds.size.width || Circle.center.x < 0)
{
circleVerlocity.x = -circleVerlocity.x;
}
if(Circle.center.y > self.view.bounds.size.height || Circle.center.y < 0)
{
circleVerlocity.y = -circleVerlocity.y;
}
}else{
if(tapToBegin.hidden)
{
tapToBegin.hidden = NO;
}
}
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if(gameState == GameStatePaused)
{
tapToBegin.hidden = YES;
gameState = GameStateRunning;
}
if([touch view] == Circle)
{
Circle.hidden = YES;
}
}
You could use GestureRecognizer in your circle. with class UITapGestureRecognizer you could add a recognizer to an element,
circle.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideThatBall)];
[circle addGestureRecognizer:tapGesture];
-(void)hideThatBall{
circle.hidden = YES;
}
I would use something like this
Related
I'm making my second game on XCode and there seems to be something wrong with the code. It's a space shooter game where the playership follows your finger and you tap to release the missile. The problem is... when I press 'start game', everything is hidden and will not popup. Here is my viewcontroller.h and viewcontroller.m
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
int score;
int lives;
int enemyAttackOccurence;
int enemyPosition;
int randomSpeed;
float enemySpeed;
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#implementation PlayViewController
-(void)viewDidAppear:(BOOL)animated {
// Images that are to be hidden
playerShip.hidden = YES;
enemyShip.hidden = YES;
missile.hidden = YES;
earth.hidden = YES;
// Hidden Labels
scoreLabel.hidden = YES;
livesLabel.hidden = YES;
// Set score and lives remaining
score = 0;
lives = 0;
// Strings
scoreString = [NSString stringWithFormat:#"Score: 0"];
liveString = [NSString stringWithFormat:#"Lives: 0"];
// Initial Label Text
scoreLabel.text = scoreString;
livesLabel.text = liveString;
// Image starting positions
playerShip.center = CGPointMake(150, 658);
enemyShip.center = CGPointMake(175, 20);
missile.center = CGPointMake(playerShip.center.x, playerShip.center.y);
}
-(IBAction)startGame:(id)sender {
// Hide buttons
startButton.hidden = YES;
exitButton.hidden = YES;
// Images to show
playerShip.hidden = NO;
enemyShip.hidden = NO;
earth.hidden = NO;
// Labels
scoreLabel.hidden = NO;
livesLabel.hidden = NO;
[self positionEnemy];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
playerShip.center = CGPointMake(point.x, playerShip.center.y);
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[missileMovementTimer invalidate];
missile.hidden = NO;
missile.center = CGPointMake(playerShip.center.x, playerShip.center.y);
missileMovementTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(missileMovement) userInfo:nil repeats:YES];
}
-(void)positionEnemy {
// Random enemy position
enemyPosition = arc4random() % 249;
enemyPosition = enemyPosition + 20;
// Enemy Image Location
enemyShip.center = CGPointMake(enemyPosition, -40);
// Set enemy speed
randomSpeed = arc4random() % 3;
switch (randomSpeed) {
case 0:
enemySpeed = 0.03;
break;
case 1:
enemySpeed = 0.02;
break;
case 2:
enemySpeed = 0.01;
default:
break;
}
enemyAttackOccurence = arc4random() % 5;
[self performSelector:#selector(enemyMovementTimerMethod) withObject:nil afterDelay:enemyAttackOccurence];
}
-(void)enemyMovementTimerMethod {
enemyMovementTimer = [NSTimer scheduledTimerWithTimeInterval:enemySpeed target:self selector:#selector(enemyMovement) userInfo:nil repeats:YES];
}
-(void)enemyMovement {
enemyShip.center = CGPointMake(enemyShip.center.x, enemyShip.center.y + 2);
if (CGRectIntersectsRect(enemyShip.frame, earth.frame)) {
lives = lives - 1;
liveString = [NSString stringWithFormat:#"Lives: %i", lives];
livesLabel.text = liveString;
// Stop Enemy Moving
[enemyMovementTimer invalidate];
if (lives > 0) {
[self positionEnemy];
}
if (lives == 0) {
[self gameOver];
}
}
}
-(void)missileMovement {
missile.hidden = NO;
missile.center = CGPointMake(missile.center.x, missile.center.y - 2);
if (CGRectIntersectsRect(missile.frame, enemyShip.frame)) {
score = score + 1;
scoreString = [NSString stringWithFormat:#"Score: %i", score];
scoreLabel.text = scoreString;
// Stop missile
[missileMovementTimer invalidate];
// Position missile to be at the playerShip's center
missile.center = CGPointMake(playerShip.center.x, playerShip.center.y);
missile.hidden = YES;
// Stop enemy movement
[enemyMovementTimer invalidate];
[self positionEnemy];
}
}
-(void)gameOver {
[enemyMovementTimer invalidate];
[missileMovementTimer invalidate];
[self performSelector:#selector(gameReplay) withObject:nil afterDelay:3];
}
-(void) gameReplay {
// Images that are to be hidden
playerShip.hidden = YES;
enemyShip.hidden = YES;
missile.hidden = YES;
earth.hidden = YES;
// Hidden Labels
scoreLabel.hidden = YES;
livesLabel.hidden = YES;
// Set score and lives remaining
score = 0;
lives = 0;
// Strings
scoreString = [NSString stringWithFormat:#"Score: 0"];
liveString = [NSString stringWithFormat:#"Lives: 0"];
// Initial Label Text
scoreLabel.text = scoreString;
livesLabel.text = liveString;
// Image starting positions
playerShip.center = CGPointMake(150, 658);
enemyShip.center = CGPointMake(175, 20);
missile.center = CGPointMake(playerShip.center.x, playerShip.center.y);
}
#end
ViewController.h (Just for backup)
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
IBOutlet UIButton *startGame;
}
#end
#interface PlayViewController : UIViewController {
IBOutlet UIImageView *playerShip;
IBOutlet UIImageView *enemyShip;
IBOutlet UIImageView *missile;
IBOutlet UIImageView *earth;
IBOutlet UILabel *livesLabel;
IBOutlet UILabel *scoreLabel;
IBOutlet UIButton *startButton;
IBOutlet UIButton *exitButton;
UITouch *touch;
NSString *liveString;
NSString *scoreString;
NSTimer *enemyMovementTimer;
NSTimer *missileMovementTimer;
}
-(IBAction)startGame:(id)sender;
#end
I am watching a tutorial for this game, the person who created doesn't reply. Please help -- I cannot be any more specific. It just must be a weird gap in the code. Thanks.
Also, you have an IBOutlet and IBAction set for your StartGame button. The IBOutlet you never seem to use. You could be confusing your compiler by having the same name for the UIButton's IBOutlet and IBAction. Remove the IBOutlet, or change the name properly and see if that changes anything.
I'd recommend messing with your lines of code where you are setting object.hidden = YES and object.hidden = NO and see what happens. Often times tampering and testing your code is a good way to see what is going on. Make sure images are set for your UIImageViews. I'm assuming they are set in your interface builder because i don't see where you set them in your code. If there is no image set for the UIImageViews they will be see-through unless given a specific color. If tampering with the code doesn't work it won't hurt to re-watch the tutorial and make sure you didn't mess anything up. Often times the tutorials we watch are out-dated and we are left to solve a small problem ourselves and this may or may not be one of those instances. Again though, test your code and see if things are actually being set to hidden or not when you press that button.
I am confused with this logic, please help me find a solution.
I am making a uibutton with every touch on UIview and it works in principle. But the button should not overlap with the previous button when touching a second time.
Here is the code for creating a button on a 'touch ended' event.
int const kRadius = 4;
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
loop = [[MagnifierView alloc] init];
loop.viewToMagnify = self;
[loop setNeedsDisplay];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[btnCamera removeFromSuperview];
if(self.activateEditMode){
self.touchTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(addLoop)
userInfo:nil
repeats:NO];
// just create one loop and re-use it.
if(loop == nil){
loop = [[MagnifierView alloc] init];
loop.viewToMagnify = self;
}
UITouch *touch = [touches anyObject];
loop.touchPoint = [touch locationInView:self];
[loop setNeedsDisplay];
}else{
// Message
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self handleAction:touches];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[self.touchTimer invalidate];
self.touchTimer = nil;
if(self.activateEditMode){
[self createCameraBtn];
[loop removeFromSuperview];
[self setBackgroundColor:[UIColor colorWithRed:(102/255) green:(102/255) blue:(102/255) alpha:1]];
}
}
Whenever the user is touching the view I am taking the x,y value of the view and save them into a CGPoint loop.touchPoint
and I also save the x,y values into a database to check before creating the next button against the previous x,y values which I stored in the database.
So far everything is ok.
When I am handling the previous values, I am not doing it correctly in the code.
Handling code and button creation
- (BOOL)handleOverlapping{
for (ImageInfo *img in self.profileInfo.imageInfo)
{
int xr = [img.xcord intValue] + kRadius;
int yr = [img.ycord intValue] + kRadius;
if ((([selectedXCord intValue] - kRadius) <= xr) && (([selectedYCord intValue] - kRadius) <=yr))
{
[CSNotificationView showInViewController:[(SkinViewController *)[self.superview nextResponder] navigationController]
style:CSNotificationViewStyleError message:kOVERLAPING_REDDOT_ERROE];
return false;
}
else if ((([selectedXCord intValue] - kRadius+10) <= xr) && (([selectedYCord intValue] - kRadius+10) <=yr))
{
[CSNotificationView showInViewController:[(SkinViewController *)[self.superview nextResponder] navigationController]
style:CSNotificationViewStyleError message:kOVERLAPING_REDDOT_ERROE];
return false;
}
}
return true;
}
button creation
- (void)createCameraBtn{
//[self colorOfPoint:loop.touchPoint];
selectedXCord = [NSNumber numberWithDouble:loop.touchPoint.x-12];
selectedYCord = [NSNumber numberWithDouble:loop.touchPoint.y-75];
// Check whether user focusing on monitored region.
if(![self handleOverlapping])
return;
// else if (![self red:red green:green blue:blue])
// return;
btnCamera = [UIButton buttonWithType:UIButtonTypeCustom];
btnCamera.frame = CGRectMake(loop.touchPoint.x-12, loop.touchPoint.y-75, 25, 25);
[btnCamera setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btnCamera setImage:[UIImage imageNamed:#"camera.png"] forState:UIControlStateNormal];
[btnCamera addTarget:self action:#selector(captureSkin) forControlEvents:UIControlEventTouchDown];
[self addSubview:btnCamera];
}
I think I am wrongly handling the overlap method.
In this method
1. xr,yr are the x,y values of the previous button,
2. selectedYcord,selectedXcore is the current touch position.
3. every button has width and height of 25
What I want to do here is to make sure that the second button does not overlap with previous one.
example x,top,y,bottom values.
It can create button minus 10 points with respect to the previous button for any side.
Thanks in advance.
Acutally My code is corret,i did mistake in a for loop..its checking every single time because i returned a value so it never check another button.finally i came to solution by changing code like this..
- (BOOL)handleOverlapping{
BOOL firstCondition=false;
BOOL secondCondition=false;
for (ImageInfo *img in self.profileInfo.imageInfo){
int xr = [img.xcord intValue];
int yr = [img.ycord intValue];
if (xr+12<=[selectedXCord intValue]||xr-12>=[selectedXCord intValue]){
firstCondition=true;
}
else if (yr+12<=[selectedYCord intValue]||yr-12>=[selectedYCord intValue]){
secondCondition=true;
}
else
{
[CSNotificationView showInViewController:[(SkinViewController *)[self.superview nextResponder] navigationController]
style:CSNotificationViewStyleError message:kOVERLAPING_REDDOT_ERROE];
return false;
}
}
if (firstCondition || secondCondition){
return true;
}
return true;
}
I want to drag my label in Application. I create new label when starting Application
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 200, 100)];
myLabel.text = #"DRAG ME!!!";
[self.view addSubview:myLabel];
How can I drag this label? I can't find normal tutorial and i new in Xcode...
The following implementation may help you. Change your above label with this one and you can see that now your label is draggable.
#import "DraggableLabel.h"
#interface DraggableLabel()
{
CGPoint _previousLocation;
}
#end
#implementation DraggableLabel
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.userInteractionEnabled = YES;
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(handlePan:)];
self.gestureRecognizers = #[panRecognizer];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.superview bringSubviewToFront:self];
_previousLocation = self.center;
}
- (void)handlePan:(UIPanGestureRecognizer *)panGestureRecognizer
{
CGPoint translation = [panGestureRecognizer translationInView:self.superview];
self.center = CGPointMake(_previousLocation.x + translation.x,
_previousLocation.y + translation.y);
}
#end
This is really basic stuff, but I can't seem to get it right (I'm new to programming). What I'm trying to do is, have my Xcode 5 App detect if an image with a certain name (say for ex. #"go.png" is pressed or touched. How can I do this? There are only two buttons, so I've been doing it with the (touchLocation.y and .x ...) method, but I need to have the Button being pressed method now. I have pasted the code below. I really appreciate your help everyone.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self];
switch (_flyGo) {
case HeadMenu:
if (touchLocation.y < self.size.height * 0.7) {
} else if (touchLocation.x < self.size.width * 0.3) {
[self switchNewFly:FlyTutorial];
} else {
[self giveRatingToApp];
}
break;
case FlyTutorial:
[self switchToFly];
break;
case FlyStatePlay:
[self flyPlayer];
break;
case FlyDisplayFalling:
break;
case FlyDisplayScore:
break;
case FlyDisplayDone:
if (touchLocation.x < self.size.width * 0.6) {
[self switchNewFly:FlyDisplayTutorial];
} else {
[self ShareMyScore];
}
break;
}
//I would like to get an image for ex. "flyer.png" to be detected as a touch instead of using (touchLocation.x or .y < self.size.width * 0.6)
Thanks!!!!
Yes, you can
Add touch recogniser to UIImageView (don't forget to set imgView.userInteractionEnabled = YES;
). Also set tag property for imgView to some value.
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapAll:)];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.numberOfTouchesRequired = 1;
[imgView addGestureRecognizer:tapRecognizer];
Then
- (void)handleTapAll:(UITapGestureRecognizer *)recognizer {
UIImageView *img = (UIImageView *)recognizer.view;
if(img.tag == some_vale) //your code
}
ViewController.h
#interface ViewController : UIViewController<UIGestureRecognizerDelegate>
......
ViewController.m
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image = [UIImage imageNamed:#"yourimage.png"];
imageView.userInteractionEnabled = YES;
imageView.exclusiveTouch = YES;
imageView.multipleTouchEnabled = YES;
// Add tap gesture
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[tap setNumberOfTapsRequired:1];
tap.delegate = self;
[imageView addGestureRecognizer:tap];
[self.view addSubview:imageView];
- (IBAction)handleTap:(UIGestureRecognizer *)recognizer { //Your code here }
I have just started working on a project and I already have a few problems and errors. I was wondering if you guys could help me figure out where the bug is.
Quick overview: I have two files: (ViewController.m and Scroller.m). In the ViewController I have some code under ViewDidLoad (which I'll show in a second), I also have a function (addImagesToView) that does what it says, and some touchesBegan,moved and ended for intractability.
In the Scroller I decided to rewrite some of the "-(void)touches" functions implementations.
The problem I have: is that the buttons (coming from the addImagesToView function) get stuck on highlighted. I performed some tests with an NSLog to see which "touches" working and which don't. "touchesMoved" doesn't work properly. If the user drags downward, the log stops after about 3 or 4 lines of text. I think that it interferes with the scroll somehow.
This is the content of ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"bgPNG.png"]];
imageView.frame = CGRectMake(0, 0, 320, 480);
[self.view addSubview:imageView];
//UIColor *background = [[UIColor alloc]initWithPatternImage:imageView.image];
//self.view.backgroundColor = background;
CGRect fullScreen = [[UIScreen mainScreen] applicationFrame];
scroll = [[Scroller alloc] initWithFrame:fullScreen];
scroll.contentSize = CGSizeMake(320, 2730);
scroll.delaysContentTouches = NO;
//scroll.canCancelContentTouches = NO;
scroll.scrollEnabled = YES;
[self.view addSubview:scroll];
buttons = [[NSMutableArray alloc]init];
[self addImagesToView];
}
-(void) addImagesToView{
CGFloat yCoordinate = 35;
for (int i=1; i<=18; i++) {
UIImageView *image = [[UIImageView alloc]initWithImage:[UIImage imageNamed:[NSString stringWithFormat:#"picture%d.png",i]]highlightedImage:[UIImage imageNamed:[NSString stringWithFormat:#"picture%dHG.png",i]]];
CGRect position = CGRectMake(105, yCoordinate, IMAGE_SIZE, IMAGE_SIZE);
image.frame = position;
[scroll addSubview:image];
image.userInteractionEnabled = YES;
image.tag = i;
[buttons addObject:image];
yCoordinate += 150;
}
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Get any touch
UITouch *t = [touches anyObject];
if ([t.view class] == [UIImageView class])
{
// Get the tappedImageView
UIImageView *tappedImageView = (UIImageView*) t.view;
tappedImageView.highlighted = YES;
}
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
if ([t.view class] == [UIImageView class])
{
// Get the tappedImageView
UIImageView *tappedImageView = (UIImageView*) t.view;
tappedImageView.highlighted = NO;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources th at can be recreated.
}
#end
and this is the Scroller.m
#import "Scroller.h"
#implementation Scroller
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!self.dragging)
[self.nextResponder touchesBegan: touches withEvent:event];
else
[super touchesBegan: touches withEvent: event];
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
if ([t.view class] == [UIImageView class])
{
// Get the tappedImageView
UIImageView *tappedImageView = (UIImageView*) t.view;
tappedImageView.highlighted = NO;
}
}
-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!self.dragging)
[self.nextResponder touchesEnded: touches withEvent:event];
else
[super touchesEnded: touches withEvent: event]; // Get the tappedImageView
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
I have also tried to implement all the touches in the ViewController, but I don't know how to make it read from the scroll (please notice the diff. between SCROLL and SCROLLER).
As you can tell I've tried to order them like this: view -> backGroundImage ->scroller ->addImagesToView(function), so that the images that come out from [I]addImagesToView[/I] are on top of the scroll. That's my desired hierarchy.
Thank you very much.
You don't have to write your own touch handling routines for button presses. Instead of using UIImageViews, just create UIButtons instead and hook into their UIControlEventTouchUpInside event.
I think you'd be better off telling us what you are trying to accomplish as you're probably barking up the wrong tree here. As Jim said, there are better ways to select images, and even if you want to handle touches yourself, UIGestureRecognizers are probably a better option. If you are allowing users to select images, I'd recommend you take a look at iCarousel on github. It's an open source carousel that works great for image selection. Also, if you can target iOS 6 there is a new collection view that could be right up your alley.