I am making a driving game for the iOS, where a car (UIView) is put on top of the google maps ios api. I am having trouble detecting collisions with the car and the grey buildings that appear on the map.
I have been trying to do it by pixel color i.e. checking if the pixel color, just ahead of the car, is the color of a buildings roof (grey). There is no direct access to an iPhones pixel color, so I am using the google maps screenshot method to get an image and get the pixel color from that. The problem is, is that I can only take a screen shot of the screen I just left. I am using
mapImage = [GMSScreenshot screenshotOfMainScreen];. I have also tried getting the window and screen and calling mapImage = [GMSScreenshot screenshotOfScreen:topWindow.screen]; Both have the same effect.
What is a solution to this problem? Can you think of a better way of handling collisions for this situation? Does reverse geocoding have the ability to detect the tops of buildings vs streets?
Thanks for any and all help!
EDIT:
Images:
Interface Builder: Left is the main menu, right is the game. The Ui image view in the upper left corner is set as the current screen shot image for referencing purposes. This how I knew It was off
Game Play, As you can see, it is only presenting the previous menu.
My viewdidLoad function: Not much other than this thats related to getting the image.
- (void)viewDidLoad
{
[super viewDidLoad];
cameraPosition = CLLocationCoordinate2DMake(42.271291, -83.729918);
moveDistance = .00055;
cA = [UIColor colorWithRed:.937255 green:.921569 blue:.886275 alpha:1];
camera = [GMSCameraPosition cameraWithLatitude:cameraPosition.latitude
longitude:cameraPosition.longitude
zoom:19
bearing:0
viewingAngle:0];
mapView_ = [GMSMapView mapWithFrame:CGRectMake(0, 0, 480, 300) camera:camera];
mapView_.myLocationEnabled = NO;
[self.view addSubview:mapView_];
car_ = [[Car alloc] initWithFrame:CGRectMake(240, 150, 13, 29) withImage:[UIImage imageNamed:#"carA-01.png"]];
[self.view addSubview:car_];
[self.view addSubview:controllerView];
updateClock = [NSTimer scheduledTimerWithTimeInterval:(1/20)
target:self
selector:#selector(update)
userInfo:nil
repeats:YES];
crashClock = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(checkCrash)
userInfo:nil
repeats:YES];
UIWindow *topWindow = [[UIApplication sharedApplication].windows objectAtIndex:0];
mapImage = [GMSScreenshot screenshotOfScreen:topWindow.screen];
// mapImage = [GMSScreenshot screenshotOfMainScreen];
}
Are you getting a new screenshot every frame (or on some interval), eg from your update callback?
The GMSMapView doesn't render immediately when you create or make changes to it - it renders later on its next update. Therefore when you take the screenshot in viewDidLoad you're probably getting what was on the screen at the time that the map view was added, ie the initial menu.
Related
Im making a scene for my game. Right now im working for IPhone 5-5s-5c screens. The scene is bigger than the normal IPhone 5-5s-5c`s screen widths so the simulated size is freeform.
Now, your supposed to move this image between obstacles. and the view/ camera is supposed to follow the uiimageview.
Here is some code on how i move the image
-(IBAction)left { goLeft = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(goLeft) userInfo:nil repeats:YES]; if (goLeft == nil) { goLeft = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(goLeft) userInfo:nil repeats:YES]; }
}
-(IBAction)stopLeft { [goLeft invalidate]; goLeft = nil;
}
-(void)goLeft { ball2.center = CGPointMake(ball2.center.x -3.5, ball2.center.y);{
// left is connected to touch down
// stopLeft is connected to Touch up inside
// Thanks for any help :)
#cilus-stian The previous version of your question was tagged as SpriteKit, so I'll suppose you use SpriteKit. If you don't use it, please let me know, and I'll delete my answer which becomes irrelevant.
So what you want is your camera to follow your image (ball2).
You can simply create a SKCameraNode which does exactly what you want (sorry I don't know the Objc syntax) :
// Declare your camera
var camera: SKCameraNode = SKCameraNode()
// Add it to your scene (didMoveToView or init)
self.camera = camera
// In the update() function
self.camera.position = ball2.position
More details about SKCameraNode
Also, not sure how/why you use UIImageView, but maybe you should consider using SKSpriteNode to display your ball
Edit: It has been suggested this post is a duplicate, which is not the case as the black bars are not initially present an an affine transformation does not remedy the problem.
I run this on an iPad Air 2 and target iOS 8.
I have a UIImagePickerController whose showsCameraControls property is set to NO. When starting the app in landscape and then zooming in, this is what happens (all images are non-cropped):
A black bar appears and can be gotten rid of by changing device orientation to portrait (which will also show the black bar) and then changing it back.
After change to portrait:
Back to landscape (+ zooming in):
Strangely, after returning to landscape, the zoom slider is not visible anymore during zooming. When starting from portrait initially, zooming first works until one changes to landscape, where a black bar appears, which stays when going back to portrait.
None of this happens when setting showsCameraControls to YES.
How can I get rid of this issue?
UPDATE: Apple claims to have fixed this in iOS 9.
I have found one way to work around what I for lack of better understanding would label a bug (as it happens with apple-provided samples as well).
The solution for me is to do manual zooming, by adding a UIPinchGestureRecognizer to the overlay view. The Controller must then implement a zooming callback which will get rid of the phenomenon described above.
#implementation CameraViewController
{
CGFloat _lastScale; //< the current zoom scale before update
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.delegate = self;
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePicker.allowsEditing = NO;
self.imagePicker.showsCameraControls = NO;
[[NSBundle mainBundle] loadNibNamed:#"CameraOverlay" owner:self options:nil];
UIPinchGestureRecognizer *pinchRec = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(zoom:)];
[self.overlayView addGestureRecognizer:pinchRec];
self.imagePicker.cameraOverlayView = self.overlayView;
_lastScale = 1.;
}
- (void)zoom:(UIPinchGestureRecognizer *) sender
{
// reset scale when pinch has ended so that future scalings are applied cumulatively and the zoom does not jump back (not sure I understand this)
if([sender state] == UIGestureRecognizerStateEnded)
{
_lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (_lastScale - sender.scale); // sender.scale gives current distance of fingers compared to initial distance. We want a value to scale the current transform with, so diff between previous scale and new scale is what must be used to stretch the current transform
CGAffineTransform currentTransform = self.imagePicker.cameraViewTransform;
CGAffineTransform newTransform = CGAffineTransformScale (currentTransform, scale, scale); // stretch current transform by amount given by sender
newTransform.a = MAX(newTransform.a, 1.); // it should be impossible to make preview smaller than screen (or initial size)
newTransform.d = MAX(newTransform.d, 1.);
self.imagePicker.cameraViewTransform = newTransform;
_lastScale = sender.scale;
}
#end
In my application I am using Google Maps SDK.
I have a full screen map in my application.
The problem is that Google logo is cut off from bottom part of the screen behind navigation tab.
I don't know what to change anymore to resize map to show logo on a screen.
I would attach screenshot of the problem but I don't have enough reputation.
As I am fairly new with Obj-C and programming in Xcode, I may have forgotten to post some part of code essential for maps implementation.
- (void)viewDidLoad
{
[super viewDidLoad];
_firstLocationUpdate = NO;
_errorView.layer.cornerRadius = 5;
_errorView.clipsToBounds = YES;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithTarget:_mapView.myLocation.coordinate zoom:14];
_mapView = [GMSMapView mapWithFrame:self.view.frame camera:camera];
_mapView.delegate = self;
[self.view addSubview:_mapView];
[self.view sendSubviewToBack:_mapView];
}
I managed to force it a little bit up, but this is really ugly way of doing it.
_mapView = [GMSMapView
mapWithFrame: CGRectMake(
0, -50,
self.view.frame.size.width, self.view.frame.size.height)
camera: camera];
[self.view addSubview:_mapView];
[self.view sendSubviewToBack:_mapView];
Another option would be to pad the controls while leaving the view the same size:
// top, left, bottom, right
_mapView.padding = UIEdgeInsetsMake(0.0, 0.0, 50.0, 0.0);
Testing with SDK 1.8, it moves the Google logo and the various controls.
Google SDK documentation for the padding property:
Controls the 'visible' region of the view.
By applying padding an area arround the edge of the view can be created which will contain map data but will not contain UI controls.
If the padding is not balanced, the visual center of the view will move as appropriate. Padding will also affect the projection property so the visible region will not include the padding area. GMSCameraUpdate fitToBounds will ensure that both this padding and any padding requested will be taken into account.
This property may be animated within a UIView-based animation block.
You are pretty close, you just need to set the size of the map frame to not include the space behind the tab view. So something like this:
_mapView = [GMSMapView
mapWithFrame: CGRectMake(
0,
0,
self.view.frame.size.width,
self.view.frame.size.height - {the height of the tab view})
camera: camera];
I use a MKMapView to show my current location , I found that when i am doing nothing ,it will take me about 15+ seconds to see the blue circle and point in the map view ,but if i move the map after the map view is start to locating ,the blue circle and point will show immediately (will dont need 5 seconds now) ,what 's the diffrence between them ? can I short the time to show blue circle in coding ? thanks alot
i create the map
self.runMapView = [[[MKMapView alloc] initWithFrame:self.bounds] autorelease];
self.runMapView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.runMapView.showsUserLocation = YES;
runMapView.delegate = self;
and then :
- (void)mapView:(MKMapView *)mapView_ didUpdateUserLocation:(MKUserLocation *)userLocation
{
if (loc2 == nil)//loc 2 is the ivar i used to track my first location
{
if (CLLocationCoordinate2DIsValid(userLocation.location.coordinate))
{
self.loc2 = userLocation.location;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 2000, 2000);
[runMapView setRegion:region];
}
}
}
and i add some polylineview to the map,and when i add the mapview to the view ctrl 's view at start ,the mapview 's alpha is set to 0(because i have a button to decide show or hide mapview),i dont know if the map update location in back can cause this problem?
Create one variable for location manager,
You need to update location just below the mapview initialize like this:
self.runMapView = [[[MKMapView alloc] initWithFrame:self.bounds] autorelease];
self.runMapView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
self.runMapView.showsUserLocation = YES;
self.runMapView.delegate = self;
[self.locationManager startUpdatingLocation];
I try to rotate and move a UIImage.
Here is my code :
im = [[UIImageView alloc ] initWithFrame:CGRectMake(160, 240, 100, 100)];
im.image = [UIImage imageNamed:#"image.png"];
[view addSubview:im];
NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1.0/30.0 target:self selector:#selector(actionIm) userInfo:nil repeats:YES];
-(void) actionIm
{
[im setFrame:CGRectMake(im.frame.origin.x+1 , im.frame.origin.y+1 ,100, 100)];
im.transform=CGAffineTransformMakeRotation (mRotation);
mRotation+=0.1;
}
The result is a very strange behaviour : If I use only the rotation, it works. If I use only the move, it works. But both uses give a strange result (the IUImage "jump" bizzarly).
I red a lot of things about rotation, frame, bounds, center... but nothing that can solve my problem.
Thank you.
Try moving the center instead of changing the frame. I believe setting the frame when the rotation is not Identity does something different.