Get Position of gesture Cocos2d - cocos2d-iphone

Right now I have two gestures, double tap and a single tap. The selector is:
-(void)handleTap:(UITapGestureRecognizer *)tapRecognizer {
CCLOG(#"Tap!");
}
I was wondering how to get the position of the tap.

You can use the recognizer's locationInView: method:
-(void)handleTap:(UITapGestureRecognizer *)tapRecognizer {
CCLOG(#"Tap!");
CGPoint loc = [tapRecognizer locationInView:tapRecognizer.view];
}

Related

Fixed sprite on the tile map cocos2d?

I can't figure out how to handle with tile map layer and other node. I want to make another one layer(CCNode) for such things as menu button, score, joystick that must always stay fixed(not scrolled), when the whole map is scrolled.
self.theMap=[CCTiledMap tiledMapWithFile:#"map.tmx"];
self.bgLayer=[theMap layerNamed:#"bg"];
[self addChild:theMap z:-1];
CCNode *joystickNode;
joystickNode=[CCNode node];
[bgLayer.parent addChild:joystickNode z:2];
upArrowFrame=[CCSpriteFrame frameWithImageNamed:#"uparrow.png"];
upArrow=[CCButton buttonWithTitle:#"" spriteFrame:upArrowFrame];
[upArrow setTarget:self selector:#selector(upArrowPressed)];
upArrow.position= ccp(190,190);
[joystickNode addChild:upArrow z:2];
Now upArrow is not visible on the screen at all. If I add to self instead of joystickNode, it will appear.
I can't even understand, what parent should new CCNode have. Can anyone explain it to me? I also tried to add new CCNode as a child of self and theMap.
EDIT: Oops, it's actually moving the camera. How to implement it in this case?
-(void)setCenterOfScreen :(CGPoint) position {
CGSize screenSize=[[CCDirector sharedDirector]viewSize];
int x=MAX(position.x, screenSize.width/2);
int y=MAX(position.y, screenSize.height/2);
x= MIN(x, theMap.mapSize.width * theMap.tileSize.width - screenSize.width/2);
y= MIN(y, theMap.mapSize.height * theMap.tileSize.height - screenSize.height/2);
CGPoint goodPoint =ccp(x,y);
CGPoint centerOfScreen = ccp(screenSize.width/2, screenSize.height/2);
CGPoint difference = ccpSub(centerOfScreen, goodPoint);
self.position=difference;
}
- (void)update:(CCTime)dt{
[self setCenterOfScreen:hero.position];
}

Cocos2d 3.0 Chipmunk with gravity: sprite position doesn't change

Porting my game from Cocos2d v2 to v3 I don't know when the sprites go out of screen.
In v2 my solution was:
-(void) update:(ccTime) delta
{
// Should use a fixed size step based on the animation interval.
int steps = 2;
CGFloat dt = [[CCDirector sharedDirector] animationInterval]/(CGFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceStep(space_, dt);
}
if (mySprite.getPhysicsBody->p.y > 500)
[mySprite resetPosition];
}
now with Cocos2d v3 mySprite.physicsNode.position doesn't change through the time.
Any idea or link with some example?
Thanks.
physicsNode.position doesn't change with time because it uses its parent sprite coordinate space, not the global coordinate space.
You can get the global position of any node, considering the Anchor Point, using this:
CGPoint worldPos = [node convertToWorldSpaceAR:CGPointZero];
After that you can easily convert it to any other node space if necessary (like your level, maybe) using:
CGPoint position = [_levelNode convertToNodeSpaceAR:worldPos];
But beware that you shouldn't hardcode the screen size on your code, as it varies for each device. You can use instead:
CGSize viewSize = [[CCDirector sharedDirector] viewSize];

Collision with sprite having another sprite as parent

Seems impossible but there has to be a solution.
I have the following classes:
#interface EnemiesEntities : CCSprite {
bool isFunctional;
CCSprite * laserBeam; // <----------- !!!!! That's where I want to check the collision.
CCSprite * leftRingEffect;
CCSprite * rightRingEffect;
}
#interface ShipEntity : CCSprite
{}
And I simply want to verify the collision between the ShipEntity and the laserBeam sprite (laserBeam is a member variable and child of EnemiesEntities class).
The method [laserBeam boundingBox] doesn't work as the boundingBox converts the coordinates relative to the parent node.
I tried thend adding to CCNode a method computing the boundingBox relative to the world but also this one did not work:
- (CGRect) worldBoundingBox
{
CGRect rect = CGRectMake(0, 0, contentSize_.width, contentSize_.height);
return CGRectApplyAffineTransform(rect, [self nodeToWorldTransform]);
}
I checked online and found only unuseful (to me) answers to the same question.
I then tried a different approach and tried to start from the boudningBox and change the position of the rectangle so obtained in respect to the parent position as following:
-(BOOL) collidesWithLaser:(CCSprite*)laserBeam
{
CGPoint newPosition = [laserBeam convertToWorldSpace:laserBeam.position];
[laserBeam worldBoundingBox];
CGRect laserBoundingBox = [laserBeam boundingBox];
CGRect laserBox = CGRectMake(laserBeam.parent.position.x, laserBeam.parent.position.y, laserBoundingBox.size.width, laserBoundingBox.size.height);
CGRect hitBox = [self hitBox];
if(CGRectIntersectsRect([self boundingBox], laserBox))
{
laserBeam.showCollisionBox=TRUE;
return TRUE;
}
else {
return FALSE;
}
}
Unfortunately this does work only when the rotation of the parent sprite is set to 0.0 but when it actually changes then it doesn't work (is probably because the boundingBox is relative to the parent node and not world).
I am a bit lost and was wondering if any of you had better luck in solving this problem and which solution (code snippets please :)) you used.
EDIT in Response to #LearnCocos2D answer:
I followed the suggestion and added the following code which doesn't work properly (e.g. try with an EnemiesEntities object is rotated to -130.0f).
-(BOOL) collidesWithLaser:(CCSprite*)laserBeam
{
CCLOG(#"rotation %f", laserBeam.rotation);
CGRect laserBoundingBox = [laserBeam boundingBox];
laserBoundingBox.origin = [self convertToWorldSpace:laserBeam.position];
CGRect shipBoundingBox = [self boundingBox]; //As we are in ShipEntity class
shipBoundingBox.origin = [self convertToWorldSpace:shipBoundingBox.origin];
//As this method is in the ShipEntity class there is no need to convert the origin to the world space. I added a breakpoint here and doing in this way the CGRect of both ShipEntity and gets misplaced.
if(CGRectIntersectsRect(shipBoundingBox, laserBoundingBox))
{
return TRUE;
}
else {
return FALSE;
}
}
The problem is in this line I think:
CGPoint newPosition = [laserBeam convertToWorldSpace:laserBeam.position];
laserBeam isn't in laserBeam's space but laserBeams parent space. So the correct is:
CGPoint newPosition = [[laserBeam parent] convertToWorldSpace:laserBeam.position];
The whole code
-(BOOL) collidesWithLaser:(CCSprite*)laserBeam
{
CGPoint newPosition = [laserBeam convertToWorldSpace:laserBeam.position];
CGRect laserBoundingBox = [laserBeam boundingBox];
laserBoundingBox.origin = newPosition;
CGRect hitBox = [self boundingBox];
hitbox.origin = [[self parent] convertToWorldSpace:hitbox.origin];
if(CGRectIntersectsRect(hitbox, laserBoundingBox))
{
laserBeam.showCollisionBox=TRUE;
return TRUE;
}
else {
return FALSE;
}
}
for both boundingboxes do:
bbox.origin = [self convertToWorldSpace:bbox.origin];
now you can compare the rects...
Update to update:
The boundingBox is an axis-aligned bounding box.
If the entity is rotated, the bounding box size increases to encompass all of the sprite's corners. Therefore collision (intersection) may be detected even relatively far away from the node when testing axis-aligned bounding boxes.
In ccConfig.h there's an option you can turn on to draw sprite bounding boxes, you should set this to 1 to see the bounding boxes: #define CC_SPRITE_DEBUG_DRAW 1
For oriented rectangles you need a different data structure and different intersection test, see for example this tutorial.

QML: how to get a direction of Mouse movement on top of MouseAeria without actually moving any visiable component?

I wonder if there is a way to send to some function like utilety.move some variables like (newX, newY) that would represent where to the mouse have moved alike something like such pseudocode
each time event calls function
var coord = - initioal mouse coords + current mouse coords
utilety.move(coord )
initioal mouse coords = current mouse coords
So to controll movment of QML element not using Drag target but own method (probable C++ one)
I don't understand your question clearly, but looks like you want to have mouse cordinate in QML.
if that is case then, you can use MouseArea element, it has mouseX and mouseY property which you can use to locate mouse cursor.
and onPositionChanged handler is called when mouse position is changed.
MouseArea {
anchors.fill: parent
onPositionChanged: {
//var curMouseX = mouseX
//var curMouseY = mouseY
}
}
If you developing for mobile platform you may consider for Qt Quick Gestures plugin:
import Qt.labs.gestures 2.0
GestureArea {
Tap: {
when: gesture.hotspot.x > gesture.hotspot.y
onStarted: console.log("tap in upper right started")
onFinished: console.log("tap in upper right completed")
}
}
Look here for more info: http://labs.qt.nokia.com/2010/10/05/getting-in-touch-with-qt-quick-gestures-and-qml/

dragging sprite

I have a problem dragging a sprite i've got the sprite moving left and right while keeping the y position the same, but i can't get the sprite to move up or down when the x position stays the same.
Also in the cctouchended the sprite moves so that it is in a fixed position, when all touches have ended
I am trying to make a game like slidieo/skozzle. Could do with some help
c1 is the column that is being moved, r1 is the row that is being moved,
[pos objectAtIndex:0] is the sprite's:red1 position and checks if the sprite is in c1 as every time you go into the game the sprite has a new random position and t1 is the cgrect of the sprite so that you must be clicking on the spirte because if you don't when you click above the sprite and try moving the sprite jumps to the touchlocation.
here is my code:
CGPoint touchLocation = [touch locationInView:[touch view]];
CGPoint prevLocation = [touch previousLocationInView:[touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
prevLocation = [[CCDirector sharedDirector] convertToGL:prevLocation];
if (CGRectContainsPoint(c1,touchLocation)) {
if (CGRectContainsPoint(c1,[[pos objectAtIndex:0]CGPointValue])) {
if (CGRectContainsPoint(t1,touchLocation)) {
if (touchLocation.y>0||touchLocation.y<0) {
touchLocation.x = red1.position.x;
[red1 setPosition:ccp(touchLocation.x,touchLocation.y)];
}
}
}
}
if (touchLocation.x>0||touchLocation.x<0) {
touchLocation.y=red1.position.y;
[red1 setPosition:ccp(touchLocation.x,touchLocation.y)];
}
}
thanks
i've solved the problem :) just had to remove a few if statements and edit a few, now i've got it moving up and down and when the sprite stops it can move left and right