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
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.
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
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];
}
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;
}
}
}
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.