Testing Rectagles Intersection on CGRect's - cocos2d-iphone

I am trying to detect collision between sprites from the same NSMutableArray. I am running a loop to compare one sprite with all of them, inclusing itself.
The thing is that the "CGRectEqualToRect" method is returning me a TRUE boolean, even though it is not!
- (BOOL)detectCollision: (CCSprite*)sprite{
BOOL result = FALSE;
CCSprite *toCollide;
CGRect rect1 = [GameScene positionRect:sprite];
for (int i = 0; i < [movableSprites count]; i++){
toCollide = [movableSprites objectAtIndex:i];
CGRect rect2 = [GameScene positionRect:toCollide];
if (!CGRectIsNull(CGRectIntersection(rect1, rect2))) {
if(!CGRectEqualToRect(rect1, rect2)){
//handle collision
NSLog(#"Collides");
result = TRUE;
}
}
}
return result;
}
For instance, when debugging, rect1 is returning the same sizes as rect2, but its x and y are completely different.
Any ideas on this one?
Thanks!

Try this..
- (BOOL)detectCollision: (CCSprite*)sprite
{
BOOL result = FALSE;
for (int i = 0; i < [movableSprites count]; i++)
{
CCSprite *toCollide; = [movableSprites objectAtIndex:i];
if(sprite==toCollide){
continue;
}
if (CGRectIntersectsRect(sprite.boundingBox, toCollide.boundingBox)) {
//handle collision
NSLog(#"Collides");
result = TRUE;
return result;
}
}
return result;
}
Make sure that all sprites are added to same object(Parent),otherwise you same to do some changes..

Related

Outline of pixels after detecting object (without convex hull)

The idea is to use grabcut (OpenCV) to detect the image inside a rectangle and create a geometry with Direct2D.
My test image is this:
After performing the grab cut, resulting in this image:
the idea is to outline it. I can use an opacity brush to exclude it from the background but I want to use a geometric brush in order to be able to append/widen/combine geometries on it like all other selections in my editor (polygon, lasso, rectangle, etc).
If I apply the convex hull algorithm to the points, I get this:
Which of course is not desired for my case. How do I outline the image?
After getting the image from the grabcut, I keep the points based on luminance:
DWORD* pixels = ...
for (UINT y = 0; y < he; y++)
{
for (UINT x = 0; x < wi; x++)
{
DWORD& col = pixels[y * wi + x];
auto lumthis = lum(col);
if (lumthis > Lum_Threshold)
{
points.push_back({x,y});
}
}
}
Then I sort the points on Y and X:
std::sort(points.begin(), points.end(), [](D2D1_POINT_2F p1, D2D1_POINT_2F p2) -> bool
{
if (p1.y < p2.y)
return true;
if ((int)p1.y == (int)p2.y && p1.x < p2.x)
return true;
return false;
});
Then, for each line (traversing the above point array from top Y to bototm Y) I create "groups" for each line:
struct SECTION
{
float left = 0, right = 0;
};
auto findgaps = [](D2D1_POINT_2F* p,size_t n) -> std::vector<SECTION>
{
std::vector<SECTION> j;
SECTION* jj = 0;
for (size_t i = 0; i < n; i++)
{
if (i == 0)
{
SECTION jp;
jp.left = p[i].x;
jp.right = p[i].x;
j.push_back(jp);
jj = &j[j.size() - 1];
continue;
}
if ((p[i].x - jj->right) < 1.5f)
{
jj->right = p[i].x;
}
else
{
SECTION jp;
jp.left = p[i].x;
jp.right = p[i].x;
j.push_back(jp);
jj = &j[j.size() - 1];
}
}
return j;
};
I'm stuck at this point. I know that from an arbitrary set of points many polygons are possible, but in my case the points have defined what's "left" and what's "right". How would I proceed from here?
For anyone interested, the solution is OpenCV contours. Working example here.

how to I change CCArray type to SpriteFrame?

The error lies in
CCAnimation *_runAnim = CCAnimation::createWithSpriteFrames(zoewalkingFrames, 0.1);
this line, when I'm trying to pass CCArray zoewalkingFrames to CCAnimation _runAnim, the log says "Reference to type 'const Vector could not bind to an lvalue of type 'CCArray' aka '"here, so what should I do so I can pass the CCArray var to SpriteFrame? Thanks
#include "ZoeAnime.h"
using namespace cocos2d;
bool ZoeAnime::init()
{
if ( !Node::init() )
{
return false;
}
auto spritecache = SpriteFrameCache::getInstance();
spritecache->addSpriteFramesWithFile("zoeanime.plist");
CCSpriteBatchNode *_spritesheet = CCSpriteBatchNode::create("zoeanime.png");
this->addChild(_spritesheet);
CCArray* zoewalkingFrames = CCArray::create();
for(int i = 1; i <= 3; i++) {
CCString* filename = CCString::createWithFormat("zoewalking%0d.png", i);
CCSpriteFrame* frame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(filename->getCString());
zoewalkingFrames->addObject(frame);
}
CCAnimation *_runAnim = CCAnimation::createWithSpriteFrames(zoewalkingFrames, 0.1);
CCSprite* zoe = CCSprite::createWithSpriteFrameName("zoewalking01.png");
CCSize winsize = CCDirector::sharedDirector()->getWinSize();
zoe->setPosition(ccp(winsize.width*0.5, winsize.height*0.5));
CCAction* action = CCRepeatForever::create(CCAnimate::create(_runAnim));
zoe->runAction(action);
_spritesheet->addChild(zoe);
return true;
}
This is a good one for reference, just replace CCArray with Vector data type.
http://discuss.cocos2d-x.org/t/erro-sprite-createwithspriteframes/16887

spritekit nodeAtPoint intersection

I am trying to detect the coordinates where two sprites (shipLaser and baddie) intersect and then make a new sprite (speedPowerUp) in that position. Below is what I have attempted to do with nodeAtPoint but it is just running and then crashing when the two sprites intersect.
for (SKSpriteNode *baddie in _baddies)
{
baddie.name = #"baddie1";
if (baddie.hidden) {
continue;
}
for (SKSpriteNode *shipLaser in _shipLasers){
if (shipLaser.hidden) {
continue;
}
if ([shipLaser intersectsNode:baddie]) {
shipLaser.hidden = YES;
baddie.hidden = YES;
[shipLaser nodeAtPoint:*(_itemDrop)];
NSLog(#"You just destroyed a baddie");
_score = _score + 10;
_scoreLabel.text = [NSString stringWithFormat:#"%i", _score];
if (_score == 10)
{
_speedPowerUp.hidden = NO;
_speedPowerUp.position = *(_itemDrop);
[self addChild:_speedPowerUp];
}

Xcode Collision Detection Error Cocos2D Assertion Error

I am making a ball game in cocos2D, where you can slide the ball in a direction, and it will travel until it collides with a wall. My collision detection is giving me an "assertion error" when I swipe the ball in a direction.
I am using tiledmap to make the levels.
The way I've coded it is that I find the tilesize that my ball is in, then, in a for loop, I check if there are any wall sprites around the ball.
Any ideas where its going wrong?
-(void)callEveryFrame:(ccTime)dt{
//Error Here vvv (Assertion Failure in -[CCTMXLayer tileAt:])
NSLog(#"First Touch x: /%f Last Touch x: /%f First Touch y: /%f Last Touch y: /%f", firstTouch.x, lastTouch.x, firstTouch.y, lastTouch.y);
if(swipeLeft || swipeRight || swipeDown || swipeUp)
{
bool collision = false;
int ballTileX = (player.position.x / level1.tileSize.width);
int ballTileY = (player.position.y / level1.tileSize.width);
int collisionAreaX = ballTileX-1;
int collisionAreaY = ballTileY-1;
for(int i = 0; i < 9; i++)
{
bool tilePresent = [background tileAt:CGPointMake(collisionAreaX, collisionAreaY)] != NULL;
if(tilePresent && CGRectIntersectsRect(CGRectMake(collisionAreaX*level1.tileSize.width, collisionAreaY*level1.tileSize.height, level1.tileSize.width, level1.tileSize.height), CGRectMake(ballTileX*level1.tileSize.width, ballTileY*level1.tileSize.height, level1.tileSize.width, level1.tileSize.height)))
{
collision = true;
break;
}
if(i % 3 == 0)
{
collisionAreaX -= 2;
collisionAreaY++;
}
else
{
collisionAreaX++;
}
}
if(collision) {
swipeLeft = false;
swipeRight = false;
swipeDown = false;
swipeUp = false;
}
}
}

How make a Rect for tiles from a Tiled Map

For my collision detection I need to check of the ball rect intersects any of the wall rects. Right now I have it working but its checking to see if the ball's position is at one of the tile's GID, using this.
-(void) checkHits:(CGPoint)position {
CGPoint tileCoord = [self tileCoordForPosition:position];
int tileGid = [levelLayer tileGIDAt:tileCoord];
//NSLog(#"%g",tileRect.origin);
if (tileGid) {
NSDictionary *properties = [level propertiesForGID:tileGid];
if (properties) {
NSString *collision = [properties valueForKey:#"break"];
if (collision && [collision compare:#"True"] == NSOrderedSame) {
//for blocks
//[[SimpleAudioEngine sharedEngine] playEffect:#"hit.caf"];
[levelLayer removeTileAt:tileCoord];
velocity.y *= -1;
}
if (collision && [collision compare:#"False"] == NSOrderedSame) {
//for edges
//[[SimpleAudioEngine sharedEngine] playEffect:#"hit.caf"];
velocity.y *= -1;
}
}
}
}
I need to know how to change this to checking to see if the balls rect/boundingbox intersects with any of the tiles rects/boundingboxex(and how to get the tiles rect/boundingbox in the first place) that have the property break.
P.S. I'm using the Tiled map editor.
Figured this out a little while ago:
CCSprite *tile;
for (int i = 0; i < level.contentSize.width/level.tileSize.width; i ++)
for (int j = 0; j < level.contentSize.height/level.tileSize.height; j ++){
tile = [levelLayer tileAt:ccp(i,j)];
if (CGRectIntersectsRect(ball.boundingBox, tile.boundingBox)) {
//Do whatever...
}
}
}
I recommend having a collide layer to make map making easier.