I am developing a game where i have my game character in a class that implements CCNODE. And i have one CCSPRITE in other class so how can i get collision between these two.
Thanks in advance
One way to do it is to check the bounding boxes for an intersection.
if (CGRectIntersectsRect([yourNode boundingBox], [yourSprite boundingBox])) {
//Handle collision
}
Related
I am trying to detect a touch on a CCSprite using:
#implementation MainScene{
CCPhysicsNode *_levelView;
}
- (void)touchBegan:(CCTouch *)touch withEvent:(CCTouchEvent *)event{
CGPoint location = touch.locationInWorld;
CCSprite *clickedSprite;
for (CCSprite *obj in _levelView.children)
{
if (CGRectContainsPoint(obj.boundingBox, location))
clickedSprite = obj;
}
}
which works perfectly fine.
So I can detect clicked Sprites already.
Since I am using sprites which are transparent at some parts, they are also detected when the transparent part of the sprite is clicked.
But I want to exclude the transparent part from the detection…
For the physics I am using physics shape polygon. Is there a way to use this polygon for something like:
polygonContainsPoint(obj.physicsPolygon, location)
? Or maybe even a way saying all pixels but those with transparency 100? Or an even easier solution?
I use this code to show game over menu after _hero sprite and _enemy sprite collide :
if (CGRectIntersectsRect(_hero.boundingBox,_enemy.boundingBox)) {
CCActionCallFunc *_callShowMenu=[CCActionCallFunc actionWithTarget:self selector:#selector(showMenu)];
[self runAction:_callShowMenu];
// EDIT : I also remove both sprites when collision happens.
[_hero removeFromParent];
[_enemy removeFromParent];
}
In _callShowMenu I just stop all actions and show a sprite with half transparent black background image and buttons.
Sometimes when collision happens, it seems to me, that _callShowMenu is called twice, because
background is completely black, like there is the same image behind. Has anyone had a similar problem? (Mostly background image is half-transparent, as it should be).
EDIT:
-(void)showMenu{
[[CCDirector sharedDirector] pause];
CCSprite *_halfTransparentBackground=[CCSprite spriteWithImageNamed:#"halfTransparentBackground.png"];
_halfTransparentBackground.position=ccp(160, 280);
[self addChild:_blackBack z:5];
}
I found a solution using BOOL. Actually everyone uses BOOL in this case, so I don't need to reinvent the wheel.
BOOL doNotCallMeTwice;
Somewhere in the didLoad method:
doNotCallMeTwice=NO;
In the collision detection method:
if (doNotCallMeTwice==NO) {
[self showMenu];
}
And finally:
-(void)showMenu{
doNotCallMeTwice=YES;
}
Possibly, showMenu was called twice(or much more times),because collision detection is in the update method.
I am new to cocos2d-x and I am implementing my own flappy bird.
Now I am working with the collision detection and I am stuck.
I added the down_pipe sprite and the up_pipe sprite to a parent sprite pipes, and I move the parent shift from right to left.
But when I check the collision by
if (bird->boundingBox().intersectsRect(pipes->boundingBox()))
It doesn't work.
And I try this way:
if (bird->boundingBox().intersectsRect(pipes->getChildByTag(DOWN_PIPE)->boundingBox()) || bird->boundingBox().intersectsRect(pipes->getChildByTag(UP_PIPE)->boundingBox()))
It still doesn't work.
How can I solve the problem? Any advice?
You try this,
CCRect target = CCRectMake(pipes->getPosition().x - (pipes->getContentSize().width/2),pipes->getPosition().y - (pipes->getContentSize().height/2),pipes->getContentSize().width,pipes->getContentSize().height);
if (bird->boundingBox().intersectsRect(target))
I need to create an object that contains several sprites (2 for simplicity: the game object and its' shadow).
I need to compose them into the same class, so having the following questions:
what is the best ancestor class to the described one?
I used CCNode for this purpose. I overridden its draw method in the following way:
- (void)draw {
[super draw];
[_item draw];
[_itemShadow draw];
}
and suddenly found that need to change all other CCNode methods in the same way. For ex. change position, visible, etc. in order to change these properties in both Sprites my custom container aggregates:
#interface NBChecker : CCNode {
CCSprite *_item;
CCSprite *_itemShadow;
}
#end
There is the other way I see - to make both sprites parent property pointing to self. This should synchronise positions, visibility, etc. for these sprites.
Who has better ideas?
Would like to use aggregation and not sure I'm right in my thoughts.
Thanks!
Scrap the draw code. All you need to do is to add the two sprites as children of the CCNode subclass. Write your logic code in the CCNode subclass and have two ivars for each sprite for easier access (like you already have).
You don't need to draw the sprites yourself as long as they are part of the scene graph.
The sprites will move and rotate relative to their parent automatically. Move the node to move the sprites in unison, etc.
Here is the setup. I have a orthogonal tile map made with Tiled. There are 5 layers. The bottom 4 comprise the background, while the top layer is the foreground that I will refer to as the “tree” layer. I have a hero sprite that I have added as a child of the tile map at the same node zorder as the tree layer.
The issue that invariably comes up with this scenario is that I want my hero to be in front of trees that he is “below”, but behind those trees that he is “above”. Below and above are determined by the Y coordinate of the hero versus the Y coordinate of any given tree.
The Cocos2d programming guide contains a section for tile maps, and in that section it specifically discusses how to achieve the affect I have described. This information can be found here.
http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:tiled_maps
The solution is pretty simple. Enable the depth buffer in my code. Add a cc_vertexz property with a value of -1000 to each layer that the hero will be above. Then add a cc_vertexz property to the tree layer with a value of “automatic” as well as a cc_alpha_func property with a value of .5. Then as your hero moves re-adjust its sprite’s vertexz value based on its position within the map.
I did all this and it worked great. However, a problem appeared as soon as I added other “enemy” sprites to this map. As with the hero sprite these sprites were added to the map with the same node zorder as the tree layer, and they too have their vertexz values changed based on their Y coordinate within the map. It should be noted that the hero sprite is added after the enemy sprites. In addition, both the hero and enemy sprites are animated and their textures are not part of the tile map textures. Based on the Cocos2d documentation this should not matter.
The problem is this. If my hero is below an enemy sprite on the map then everything looks and works fine. However, if my hero is above an enemy sprite on the map then as the enemy passes over the hero sprite the background comes through rather than the hero sprite. The best way to describe it is to say that as soon as the enemy sprite begins to pass over the hero sprite, the transparent areas of the enemy sprite begin to fill with the background and the hero sprite is partially obscured until then enemy sprite moves off the hero. It is like the hero sprite is not there.
I know this is related to the order that the sprites are added to the map, because if I change this and have the hero sprite added to the map before the enemy sprites, then the effect reverses in that the background comes through the transparent areas of the hero sprite rather than the enemy sprites. It is almost like the vertexz property is not absolutely determining the order that things are drawn.
Looking into this it appears to be a blending issue and I found what seems to be the solution, which is to subclass the CCSprite class and override the draw method with the following:
-(void) draw {
glEnable(GL_ALPHA_TEST);
glAlphaFunc( GL_GREATER, 0 );
[super draw];
glDisable(GL_ALPHA_TEST);
}
The problem however is that this code is not applicable to the version of Cocos2d that I use, which is Cocos2d 2.1. In addition this appears to be handled by the CCTMXLayer drawing function if automatic vertexz is enabled. As such I do not know if subclassing CCSprite would just be redundant. See below for how CCTMXLayer handles this:
// CCTMXLayer drawing function -(void) draw
{
if( useAutomaticVertexZ_ ) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, alphaFuncValue_);
}
[super draw];
if( useAutomaticVertexZ_ )
glDisable(GL_ALPHA_TEST);
}
I am not new to Cocos2d, but I am very new to anything related to OpenGL. So in short, is the solution just to subclass CCSprite and find the Cocos2d 2.1 equivalent to the above code snippet, or am I simply doing something wrong? I suspect the latter.
Any help would be very much appreciated. Thanks!
This has been resolved. The solution was to use the following on my sprites or sprite sheets as the case may be:
mySprite.shaderProgram = [[CCShaderCache sharedShaderCache]programForKey:kCCShader_PositionTextureColorAlphaTest];
This essentially takes the place of sub-classing CCSprite and overriding the draw method, which is the prescribed method for Cocos2d 1.x, whereas I am using Cocos2d 2.x.