No member named 'frame' in struct CGRect - frame

I get the error "No member named 'frame' in struct CGRect".
UITouch *touch = [[event2 allTouches] anyObject];
CGPoint touchlocation = [touch locationInView:self.view];
if ( CGRectContainsPoint( enemy.frame, touchlocation ) ) {
MedalGo = 0;
// inside imgView
} else {
// outside imgView Now we will found out is it within proximityImgViewRect
CGRect proximityImgViewRect = CGRectMake( enemy.frame.origin.x-25,enemy.frame.origin.y - 25, enemy.frame.size.width+50,enemy.frame.size.height+50);
if ( CGRectContainsPoint( proximityImgViewRect.frame, touchlocation ) ) {
// inside proximityImgViewRect
MedalGo = 1;
} else {
//outside proximityImgViewRect
MedalGo = 0;
}
}
Any help would be appreciated. Thank you.

A CGRect is the frame.
if ( CGRectContainsPoint( proximityImgViewRect.frame, touchlocation ) )
no
if ( CGRectContainsPoint( proximityImgViewRect, touchlocation ) )
yes

Related

SKSpriteNode Targeting

So RIGHT NOW my code presents 7 playing cards. If the playing card is pressed it moves removes the card from the playerCard array and adds it to the playedCards array. The problem is, is move the card I target it with a SKNode in the touchesBegan method;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node isKindOfClass:[CardSpriteNode class]]) {
Okay, no problem, the card moves up. The problem is, All the other cards left in the playerCards now need to move i.e ( tighten up ) as they were originally. Here's my formula for distances between them;
int cardsLaid = i * (cardDisplay.size.width / 3);
So I can now get the cards that are originally displayed and the ones that are touched, to form a nice gap between them.
What I need to do is to move the cards back to a nice gap, after one of the cards between them has been moved
for (int i = 0; i < [playerCards count]; i++) {
int cardsLaid = i * (cardDisplay.size.width / 3);
CGPoint forPoint = CGPointMake((0.5 - (self.frame.size.width / 4)) + cardsLaid, 0.0);
playerCards[i] //Here I need to target each skspritenode.name for each playerCards
[??? runAction:[SKAction moveTo:forPoint duration:0.6]];
}
So I need to target each SKSpritenode.name by the names saved in the playerCards MutableArray. Then once I've targetted a spritenode I need to move it where the ??? is.
Here's my entire touchesBegan method if it helps.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node isKindOfClass:[CardSpriteNode class]]) {
int add = (int)[playerCards count] * (cardDisplay.size.width / 3);
CGPoint origPos = CGPointMake(-self.frame.size.width/2.8 + add, -218);
if ([cardsPlayed containsObject:node.name]) {
//Card is already played, return to original position and remove from array.
CGPoint point = origPos;
[node runAction:[SKAction moveTo:point duration:0.6]];
node.zPosition = zPosCount;
zPosCount += 1;
[cardsPlayed removeObject:node.name];
[playerCards addObject:node.name];
NSLog(#"this ran");
} else {
//Card is not already played, position to add card and add to array.
amountOfCardsLaid = (int)[cardsPlayed count] * (cardDisplay.size.width / 3);
CGPoint point = CGPointMake((0.5 - (self.frame.size.width / 4
)) + amountOfCardsLaid, 0.0);
[node runAction:[SKAction moveTo:point duration:0.6]];
node.zPosition = zPosCount;
zPosCount += 1;
[playerCards removeObject:node.name];
[cardsPlayed addObject:node.name];
for (int i = 0; i < [playerCards count]; i++) {
int cardsLaid = i * (cardDisplay.size.width / 3);
CGPoint forPoint = CGPointMake((0.5 - (self.frame.size.width / 4)) + cardsLaid, 0.0);
playerCards[i]
[??? runAction:[SKAction moveTo:forPoint duration:0.6]];
}
}
//Hide.Unhide buttons
if ([cardsPlayed count] == 0) {
if (addButton.hidden == FALSE) addButton.hidden = true;
if (cancelButton.hidden == FALSE) cancelButton.hidden = true;
} else {
if (addButton.hidden == TRUE) addButton.hidden = false;
if (cancelButton.hidden == TRUE) cancelButton.hidden = false;
}
}
}
The gap I need to close is on the bottom playerCards
SKNode *tempNode = [self childNodeWithName:playerCards[i]];
After a few days. fml

Getting location of sprite within array cocos2d`

I need to be able to touch a specific moving sprite in my array and perform an action on it. However when I perform my MoveTo action, the sprite location doesn't update. Help!
Array:
int numbreds = 7;
redBirds = [[CCArray alloc] initWithCapacity: numbreds];
for( int i = 1; i<=numbreds; i++){
int xvalue = ((-50*i) + 320);
int yvalue= 160;
if (i==4)
{
CCSprite *parrot = [CCSprite spriteWithFile:#"taco.png"];
[birdLayer addChild:parrot];
[self movement]; //the action that moves the array horizontally
parrot.position = ccp(xvalue,yvalue);
parrot.tag=100;
Touch
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CCSprite *mark = (CCSprite *)[birdLayer getChildByTag:100];
if (CGRectContainsPoint([mark boundingBox], location))
{
CCLOG(#"YAY!");
}
THe problem is that the location of the CCSprite doesn't actually update or move. YAY! only is generated at the origin location of the sprite.
Try this:
CCSprite *temp = [CCSprite spriteWithFile:#"taco.png"];
temp = [birdLayer getChildByTag:100];
if (temp.position.x == location.x) {
// do stuff...
}

cocso2d pinch-zoom like Fieldrunners

I've been trying to set up the parallax node correctly but need some help with this.
This http://goo.gl/Piqy5 would be the frame of the game and for the parallax node area I have 3 layers:
background layer (zoomable but not scrollable, z order -1)
layer 1 (z order 1)
layer 2 (z order 2)
//Adding the layers to the parallax node
CGPoint offsetLayer = ccp(0,0);
//background layer
[parallaxNode addChild:backgroundLayer z:-1 parallaxRatio: ccp(0,0) positionOffset: offsetLayer];
//layer 1
[parallaxNode addChild:secondParallaxLayer z:1 parallaxRatio: ccp(0.5,0) positionOffset: offsetLayer];
//layer 2
[parallaxNode addChild:firstParallaxLayer z:2 parallaxRatio: ccp(1.1,0) positionOffset: offsetLayer];
//the pan/zoom & scroll controller
_controller = [[CCPanZoomController controllerWithNode:baseLayer] retain];
_controller.boundingRect = boundingRect;
_controller.zoomOutLimit = _controller.optimalZoomOutLimit;
_controller.zoomInLimit = 2.0f;
[_controller centerOnPoint:CGPointMake(screenSize.width/2.0, screenSize.height/2.0)];
[_controller enableWithTouchPriority:-2 swallowsTouches:YES];
I think I should fix using:
//Setting the touch delegate to my CCScene
#interface GameScene : CCScene <CCStandardTouchDelegate>
//and add register to touch delegate
[[CCTouchDispatcher sharedDispatcher] addStandardDelegate:self priority:2];
- (CGPoint)convertPoint:(CGPoint)point fromNode:(CCNode *)node {
return [self convertToNodeSpace:[node convertToWorldSpace:point]];
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
#define CLAMP(x,y,z) MIN(MAX(x,y),z)
if ([[[event allTouches] allObjects] count] == 2) {
UITouch* touch1 = [[[event allTouches] allObjects] objectAtIndex:0];
UITouch* touch2 = [[[event allTouches] allObjects] objectAtIndex:1];
// calculate scale value
double prevDistance = ccpDistance([touch1 previousLocationInView:[touch1 view]], [touch2 previousLocationInView:[touch2 view]]);
double newDistance = ccpDistance([touch1 locationInView:[touch1 view]], [touch2 locationInView:[touch2 view]]);
CGFloat relation = newDistance / prevDistance;
CGFloat newScale = self.scale * relation;
if ((newScale >= MIN_SCALE) && (newScale <= MAX_SCALE)) {
CGPoint touch1Location = [baseLayer convertTouchToNodeSpace:touch1];
CGPoint touch2Location = [baseLayer convertTouchToNodeSpace:touch2];
// calculate center point between two touches
CGPoint centerPoint = ccpMidpoint(touch1Location, touch2Location);
// store center point location (ScrollableView space)
CGPoint centerPointInParentNodeSpace = [self convertPoint:centerPoint fromNode:baseLayer];
CGPoint oldPoint = ccp(centerPointInParentNodeSpace.x * (self.scale), centerPointInParentNodeSpace.y * (self.scale));
self.scale = newScale;
CGPoint newPoint = ccp(centerPointInParentNodeSpace.x * (self.scale), centerPointInParentNodeSpace.y * (self.scale));
CGPoint diff = ccp(oldPoint.x - newPoint.x , oldPoint.y - newPoint.y);
[baseLayer setPosition:ccp(baseLayer.position.x + (diff.x*(1/self.scale)), baseLayer.position.y + (diff.y*(1/self.scale)))];
}
} else if ([[[event allTouches] allObjects] count] == 1) {
// get touch locations
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPosition = [[CCDirector sharedDirector] convertToGL:[touch locationInView:[touch view]]];
CGPoint oldPosition = [[CCDirector sharedDirector] convertToGL:[touch previousLocationInView:[touch view]]];
// calculate difference in position
CGPoint diff = ccpSub(touchPosition, oldPosition);
self.position = ccpAdd(self.position, diff);
}
#undef CLAMP
}
Any remarks or help would be great! :)
Check out CCLayerPanZoom in the Cocos2d Extensions on Github. I have used this class to enable pinch zoom and pan in my game

Differentiate between two ImageViews

I have two imageViews imageView1 and imageView2. I have given gestureRecognizer to move these both images. Now the problem is when i move first imageView near second imageView only second image view is displayed. But when i put first imageView on another image the first imageView should be displayed on the second imageView which is not happening.Can any body please tell me how can the first imageView gets view on the top of another imageView.
You can use the UIView method bringSubviewToFront:, and pass in the UIImageView that you want displayed on top.
Why dont you use something similar like this to drag your UIImageViews?
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor yellowColor];
test1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
test1.backgroundColor = [UIColor whiteColor];
test1.userInteractionEnabled = YES;
test1.clipToBounds = YES;
[self.view addSubview:test1];
test2 = [[UIImageView alloc] initWithFrame:CGRectMake(400, 400, 100, 100)];
test2.backgroundColor = [UIColor whiteColor];
test2.userInteractionEnabled = YES;
test2.clipToBounds = YES;
[self.view addSubview:test2];
}
CGPoint startLocation;
float diffX;
float diffY;
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == test1)
{
startLocation = [touch locationInView:self.view];
[self.view bringSubviewToFront:test1];
}
if( [touch view] == test2)
{
startLocation = [touch locationInView:self.view];
[self.view bringSubviewToFront:test2];
}
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
if( [touch view] == test1)
{
CGPoint location = [touch locationInView:self.view];
diffX = location.x - startLocation.x;
diffY = location.y - startLocation.y;
test1.frame = CGRectMake(test1.frame.origin.x + diffX, test1.frame.origin.y + diffY, test1.frame.size.width, test1.frame.size.height);
startLocation = test1.frame.origin;
}
if( [touch view] == test2)
{
CGPoint location = [touch locationInView:self.view];
diffX = location.x - startLocation.x;
diffY = location.y - startLocation.y;
test2.frame = CGRectMake(test2.frame.origin.x + diffX, test2.frame.origin.y + diffY, test2.frame.size.width, test2.frame.size.height);
startLocation = test2.frame.origin;
}
}
//---EDIT---//
Added: cliptobounds in viewdidload

Cocos2d rotation on touches moved problem

I have a spear like sprite. It rotation is decided by touchesMoved method. whenever the user slides his finger it points towards that touch. This is my method:
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: [touch view]];
float angleRadians = atanf((float)location.y / (float)location.x);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
spear.rotation = -1 * angleDegrees;
}
This kinda works, but only from 0 to 45 degrees. and it goes opposite. So as I am moving from finger for bottom to top, it rotates clockwise (it should follow direction of fnger and rotate counter clockwise). From 45 to 90, it works fine (moves counter clickwise) but only if i start the touch in upper diagonal of the screen.
What am i doing wrong?
Thanks
#define PTM_RATIO 32
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
for( UITouch *touch in touches ) {
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
spriteBody->SetTransform(locationWorld,spriteBody->GetAngle());
}
}
-(void) tick: (ccTime) dt
{
//It is recommended that a fixed time step is used with Box2D for stability
//of the simulation, however, we are using a variable time step here.
//You need to make an informed choice, the following URL is useful
//http://gafferongames.com/game-physics/fix-your-timestep/
int32 velocityIterations = 8;
int32 positionIterations = 1;
// Instruct the world to perform a single step of simulation. It is
// generally best to keep the time step and iterations fixed.
m_world->Step(dt, velocityIterations, positionIterations);
// for (int i = 0; i < (int)birds.size(); i++)
// birds[i]->render();
//Iterate over the bodies in the physics world
for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != NULL) {
//Synchronize the AtlasSprites position and rotation with the corresponding body
CCSprite *myActor = (CCSprite*)b->GetUserData();
myActor.position = CGPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
myActor.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
Figured out what was wrong. I needed to change the CGPoint I got from the touches into GL point like this:
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];
Silly me. Should have thought about this before.
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];
GPoint diff = ccpSub(touchLocation, _player.position);
//rotate to face the touch
CGPoint diff = ccpSub(_player.position, touchLocation);
float angleRadians = atanf((float)diff.y / (float)diff.x);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cocosAngle = -1 * angleDegrees;
if(diff.x < 0)
{
cocosAngle += 180;
}
id actionRotateTo = [CCRotateTo actionWithDuration:0.1 angle:cocosAngle];
[_player runAction:actionRotateTo];