I have a game and I want that every time an image(image1) touchs another image(image2) a counter count one, if it touches a second time it becomes two. So it's something that counts. How can I do this?
Is this a collision detection? This link may help... collision detection
So you may have to write a collision detection method. Then each time it collide, you increment the count.
- (BOOL)collisionCheck:(UIImage *)image1 withImage:(UIImage *)image2 {
return CGRectIntersectsRect(image1.frame, image2.frame);
}
// then in game loop
// code that move the image here
if ([self collisionCheck:image1 withImage:image2] == YES) {
// code that bounce the image here
count++;
}
Related
Im making a brick breaker type game and need to know if all the bricks have been broken in order to transition to the win screen.
The way I've been thinking of solving this is to create a BOOL method that is ran each time a brick is removed to calculate how many bricks are left. If there are no bricks left... move to the win scene.
Im struggling with the logic on how to do this.
So far I have:
-(BOOL)isGameWon{
for (SKNode* node in self.children){
if ([node.name isEqual:brickCategoryName]){
//some logic
}
}
return YES;
}
didBeginContactMethod:
if (notTheBall.categoryBitMask == brickCategory) {
[self runAction:_smashSound];
[notTheBall.node removeFromParent];
if ([self isGameWon]) {
NSLog(#"YOU WIN!");
}
}
Using the method below, how can one refer to specific sprites when checking to see if they intersect?
- (void)update:(ccTime)dt {
for (CCSprite *sprite in movableSprites) {
if (CGRectIntersectsRect(sprite.boundingBox, sprite.boundingBox)) {
break;
}
}
}
It appears that all sprites are available in the moveableSprites object, but I don't know how to check if specific sprites are colliding... I don't know how to refer to them. If there is an easier way to perform collision detection I'm interested.
It appears your code above will always return TRUE because you are checking if the boundingbox of sprite collides with sprite, and since they are the same it always will.
if (CGRectIntersectsRect(sprite.boundingBox, sprite.boundingBox)) {//
break;
}
Should be comparing to a different sprite not the same sprite.
if (CGRectIntersectsRect(sprite.boundingBox, otherSprite.boundingBox)) {//
break;
}
If that does not answer your question maybe you are looking to avoid enumerating through the array? If that is the case try using tags. Someting like below.
CCSprite *aSprite = [CCSprite spriteWithFile:#"hurdle1.png"];
[self addChild:aSprite tag:2];
Now [self getChildByTag:2] can take the place of sprite
and you can just add boundingBox to check collisions, as below.
if (CGRectIntersectsRect([self getChildByTag:2].boundingBox, checkSprite.boundingBox)) {//
break;
}
I have an Array of CCSprites that being displayed all at once.
Every sprite has a movement path, a movement path is a random point on screen.
All the sprites are moving all at once to random points on screen.
What I want to do is to detect collision between the sprites and then change their movement path.
Is it possible?
Iterate through every CCSprite in your array (call it A), and for every iteration iterate again through every CCSprite in the array (excluding A itself of course) (call this one B). Now, use CGRectIntersectsRect along with boundingBox to find a collision between them. It goes something like this:
for (CCSprite *first in mySprites) {
for (CCSprite *second in mySprites) {
if (first != second) {
if (CGRectIntersectsRect([first boundingBox], [second boundingBox])) {
// COLLISION! Do something here.
}
}
}
}
Edit: But of course, it is possible that if two sprites collide, the "collision event" will occur twice (first from the point of view of sprite A, and then from the point of view of sprite B).
If you only want the collision event to trigger once every check, you will need to memorize the pairs so that you can ignore collisions that already did happen on that check.
There are countless ways you could check for that, but here's an example (updated code):
Edited again:
NSMutableArray *pairs = [[NSMutableArray alloc]init];
bool collision;
for (CCSprite *first in mySprites) {
for (CCSprite *second in mySprites) {
if (first != second) {
if (CGRectIntersectsRect([first boundingBox], [second boundingBox])) {
collision = NO;
// A collision has been found.
if ([pairs count] == 0) {
collision = YES;
}else{
for (NSArray *pair in pairs) {
if ([pair containsObject:first] && [pair containsObject:second]) {
// There is already a pair with those two objects! Ignore collision...
}else{
// There are no pairs with those two objects! Add to pairs...
[pairs addObject:[NSArray arrayWithObjects:first,second,nil]];
collision = YES;
}
}
}
if (collision) {
// PUT HERE YOUR COLLISION CODE.
}
}
}
}
}
[pairs release];
Have a look at this S.O. answers.
You can do simple collision detection using CGRectIntersectsRect and the node boundingBox. If you need more advanced features, have a look at a physics engine like chipmunk or Box2D.
Ray Wenderlich has written a good tutorial about using Box2D just for collision detection, if you're interested in going that way. http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone
Check first that your sprites can be approximated by rectangles. If so then #Omega's answer was great. If they can't be, perhaps because they contain a lot of transparency or for some other reason, you might need to approximate your sprites with polys and work with those.
I am developing a game on Iphone using cocos2d. I have a CClayer containing 20 CCSprite. I am playing a sound and I would like to disable the touch events on all the CCSprite or on the entire layer while the sound is playing. I looked at the property of CCLayer called isTouchEnabled but the behavior doesn't propagate to the children (all the CCSprite). Unless it is not documented, there seems to be no equivalent property for CCsprite. Does anybody know an easy way to this?
Thanks
I ma using below method to disable touch on CCMenu items on a layer below on a view may be help you out.
Call the below method and disable all sub Menu or subNode.
[self MenuStatus:NO Node:self]; // to disable
method is:
-(void)MenuStatus:(BOOL)_enable Node:(id)_node
{
for (id result in ((CCNode *)_node).children)
{
if ([result isKindOfClass:[CCMenu class]])
{
for (id result1 in ((CCMenu *)result).children)
{
if ([result1 isKindOfClass:[CCMenuItem class]])
{
((CCMenuItem *)result1).isEnabled = _enable;
}
}
}
else
[self MenuStatus:_enable Node:result];
}
}
[self MenuStatus:YES Node:self]; // to enable**
A member of another forum posted this solution
So all your sprites normally receive touch events? If you know when the sound is playing, you just could have them check that and ignore the touch if the sound is playing. For example, if your sprites implement the CCTargetedTouchDelegate protocol, you could do something like:
- (BOOL)ccTouchBegan:(UITouch*)touch withEvent:(UIEvent*)event {
if (soundIsPlaying) {
return NO; // i.e., the sprite is currently uninterested in the touch
}
// Other checks and behaviour here.
return YES;
}
I'm making a particle system for my game, which basically is smoke coming out from rockets in my game. All particles are in a ccArray called smoke.
ccArray *smoke = ccArrayNew(0);
I have a class called Smoke, which is a subclass of CCSprite, with the addition of an ivar called __opacity.
When I add a new smoke to the ccArray I do like this:
ccArrayAppendObject(smoke, [Smoke spriteWithFile: #"smoke.png"]);
[smoke->arr[smoke->num - 1] setupWithTouch: touch andOpacity: 255.0f];
[self addChild: smoke->arr[smoke->num - 1]];
Which doesn't lag at all, and is fast,
And this is how I handle the smoke every frame:
if(smoke->num > 0)
{
for(NSUInteger i = 0; i < smoke->num; i++)
{
Smoke *s = smoke->arr[i];
s.__opacity = s.__opacity - 255.0f * delta;
[s setOpacity: s.__opacity];
if(s.__opacity <= 0.0f)
{
[self removeChild: s cleanup: YES];
ccArrayFastRemoveObjectAtIndex(smoke, i);
}
}
}
When opacity is less than 0, we remove the smoke from the scene, and then
remove it from the array -- which is the part that slows the game down, removing it from the Array. It goes from 60 FPS to like 15-20 FPS, when there's like, 60 smoke particles on the scene.
Any ideas how I can speed this up?
Also, reason I'm using ccArray instead of NSMutableArray is because I read ccArray is faster.
removing object from the middle or the beginning of an array (any array) will recreate the array, and the operation is very slow (alloc+copy of members), if you have datastruct with many removes that not at the end you probably should use a linked-list
here some implementation i found in the internet (haven't tested it but it looks decent)
http://www.cocoadev.com/index.pl?DoublyLinkedList