Sprite Kit Detecting Collisions - objective-c

sorry for re-opening this title but none of the titles about this question helped me that much. In my game you are a space ship and you trying to escape from the incoming asteroids. When your ship touches an asteroid, you explode.
My codes are like these;
static const uint32_t asteroidCategory = 1;
static const uint32_t playerCategory = 2;
static const uint32_t laserCategory = 3;
player.physicsBody.categoryBitMask = playerCategory;
player.physicsBody.contactTestBitMask = asteroidCategory;
player.physicsBody.collisionBitMask = 0;
asteroid.physicsBody.categoryBitMask=asteroidCategory;
asteroid.physicsBody.contactTestBitMask=playerCategory;
asteroid.physicsBody.collisionBitMask=0;
But I don't know what should I do at 'didBeginContact' method.
please help me, thank you...

Try starting with
-(void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ((firstBody.categoryBitMask & playerCategory) != 0 &&
(secondBody.categoryBitMask & astroidCategory) != 0)
{
[self player:(SKSpriteNode *) firstBody.node didCollideWithAstroid:(SKSpriteNode *) secondBody.node];
}
You also need to make a method for 'didCollideWithAstroid'

Related

iOS 13 get application statusBar crash

only crash on beta2 and beta 3 when call code like this,:
[application valueForKeyPath:#"statusBar"]
some can help me? i call this method to get phone's network status.
the whole code like this:
if (![self isIPhoneX]) {
if ([[application valueForKeyPath:#"_statusBar"] isKindOfClass:NSClassFromString(#"UIStatusBar_Modern")]) {
children = [[[[application valueForKeyPath:#"_statusBar"] valueForKeyPath:#"_statusBar"] valueForKeyPath:#"foregroundView"] subviews];
} else {
children = [[[application valueForKeyPath:#"_statusBar"] valueForKeyPath:#"foregroundView"] subviews];
}
Class expectClass = NSClassFromString(#"UIStatusBarDataNetworkItemView");
for (id child in children) {
if ([child isKindOfClass:expectClass]) {
int netType = [[child valueForKeyPath:#"dataNetworkType"] intValue];
switch (netType) {
case 0: state = #"";break;
case 1: state = #"2g";break;
case 2: state = #"3g";break;
case 3: state = #"4g";break;
case 5: state = #"wifi";break;
default: state = #"";break;
} /* switch */
}
}
} else {
id statusBar = [application valueForKeyPath:#"statusBar"];
id statusBarView = [statusBar valueForKeyPath:#"statusBar"];
UIView *foregroundView = [statusBarView valueForKeyPath:#"foregroundView"];
children = [[foregroundView subviews][2] subviews];
for (id child in children) {
if ([child isKindOfClass:NSClassFromString(#"_UIStatusBarWifiSignalView")]) {
state = #"wifi";
}else if ([child isKindOfClass:NSClassFromString(#"_UIStatusBarStringView")]) {
NSString *str = [child valueForKeyPath:#"_originalText"];
if ([str isEqualToString:#"4G"]) {
state = #"4g";
}else if([str isEqualToString:#"3G"]){
state = #"3g";
} else{
state = #"2g";
}
}
}
}
I install iOS 13 open beta version and every thing runs good except some label showing ...,but i receive crash when online beta2 and beta3 version.
+ (NSString *)deviceNetworkingType
{
NSString *strNetworkInfo = #"No Network";
struct sockaddr_storage zeroAddress;
bzero(&zeroAddress,sizeof(zeroAddress)); zeroAddress.ss_len = sizeof(zeroAddress);
zeroAddress.ss_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL,(struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability,&flags);
CFRelease(defaultRouteReachability);
if(!didRetrieveFlags){ return strNetworkInfo;}
BOOL isReachable = ((flags & kSCNetworkFlagsReachable)!=0);
BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired)!=0);
if(!isReachable || needsConnection) {return strNetworkInfo;}
if((flags & kSCNetworkReachabilityFlagsConnectionRequired)== 0){
strNetworkInfo = #"WIFI";
}
if(((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0) {
if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0){
strNetworkInfo = #"WIFI";
}
}
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) ==kSCNetworkReachabilityFlagsIsWWAN) {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CTTelephonyNetworkInfo * info = [[CTTelephonyNetworkInfo alloc] init];
NSString *currentRadioAccessTechnology = info.currentRadioAccessTechnology;
if (currentRadioAccessTechnology) {
if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
strNetworkInfo =#"4G";
} else if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge] || [currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
strNetworkInfo =#"2G";
} else {
strNetworkInfo =#"3G";
}
}
} else {
if((flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable) {
if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) {
if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) {
strNetworkInfo =#"2G";
} else {
strNetworkInfo =#"3G";
}
}
}
}
}
return strNetworkInfo;
}

FFmpeg jump to most recent frame

I am looking for some help with dropping/skipping FFmpeg frames. The project I am working on streams live video which when the app goes into the background, upon returning to an active state the video stream spends a long time catching up by fast forwarding itself to the current frame. This isn't ideal and what I am aiming to achieve is have the app immediately jump to the most recent frame.
What I need to do is drop the amount of frames that are being fast-forwarded in order to catch up to the most recent frame. Is this possible? Here is my current code which decodes the frames:
- (NSArray *) decodeFrames: (CGFloat) minDuration
{
NSMutableArray *result = [NSMutableArray array];
#synchronized (lock) {
if([_reading integerValue] != 1){
_reading = [NSNumber numberWithInt:1];
#synchronized (_seekPosition) {
if([_seekPosition integerValue] != -1 && _seekPosition){
[self seekDecoder:[_seekPosition longLongValue]];
_seekPosition = [NSNumber numberWithInt:-1];
}
}
if (_videoStream == -1 &&
_audioStream == -1)
return nil;
AVPacket packet;
CGFloat decodedDuration = 0;
CGFloat totalDuration = [TimeHelper calculateTimeDifference];
do {
BOOL finished = NO;
int count = 0;
while (!finished) {
if (av_read_frame(_formatCtx, &packet) < 0) {
_isEOF = YES;
[self endOfFileReached];
break;
}
[self frameRead];
if (packet.stream_index ==_videoStream) {
int pktSize = packet.size;
while (pktSize > 0) {
int gotframe = 0;
int len = avcodec_decode_video2(_videoCodecCtx,
_videoFrame,
&gotframe,
&packet);
if (len < 0) {
LoggerVideo(0, #"decode video error, skip packet");
break;
}
if (gotframe) {
if (!_disableDeinterlacing &&
_videoFrame->interlaced_frame) {
avpicture_deinterlace((AVPicture*)_videoFrame,
(AVPicture*)_videoFrame,
_videoCodecCtx->pix_fmt,
_videoCodecCtx->width,
_videoCodecCtx->height);
}
KxVideoFrame *frame = [self handleVideoFrame];
if (frame) {
[result addObject:frame];
_position = frame.position;
decodedDuration += frame.duration;
if (decodedDuration > minDuration)
finished = YES;
}
} else {
count++;
}
if (0 == len)
break;
pktSize -= len;
}
}
av_free_packet(&packet);
}
} while (totalDuration > 0);
_reading = [NSNumber numberWithInt:0];
return result;
}
}
return result;

How to play pcm audio buffer from a socket server using audio unit circular buffer

I hope someone can help me. I am new to Objective-c and OSX and I am trying to play audio data I am receiving via socket into my audio queue. I found out this link https://stackoverflow.com/a/30318859/4274654 which in away address my issue with circular buffer.
However when I try to run my project it returns
It returns an error (OSStatus) -10865. That is why the code logs " Error enabling AudioUnit output bus".
status = AudioUnitSetProperty(_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &one, sizeof(one));
Here is my code:
Test.h
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
#import "TPCircularBuffer.h"
#interface Test : Communicator
#property (nonatomic) AudioComponentInstance audioUnit;
#property (nonatomic) TPCircularBuffer circularBuffer;
-(TPCircularBuffer *) outputShouldUseCircularBuffer;
-(void) start;
#end
Test.m
#import "Test.h"
#define kOutputBus 0
#define kInputBus 1
#implementation Test{
BOOL stopped;
}
static OSStatus OutputRenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData){
Test *output = (__bridge Test*)inRefCon;
TPCircularBuffer *circularBuffer = [output outputShouldUseCircularBuffer];
if( !circularBuffer ){
SInt32 *left = (SInt32*)ioData->mBuffers[0].mData;
for(int i = 0; i < inNumberFrames; i++ ){
left[ i ] = 0.0f;
}
return noErr;
};
int32_t bytesToCopy = ioData->mBuffers[0].mDataByteSize;
SInt16* outputBuffer = ioData->mBuffers[0].mData;
uint32_t availableBytes;
SInt16 *sourceBuffer = TPCircularBufferTail(circularBuffer, &availableBytes);
int32_t amount = MIN(bytesToCopy,availableBytes);
memcpy(outputBuffer, sourceBuffer, amount);
TPCircularBufferConsume(circularBuffer,amount);
return noErr;
}
-(void) start
{
[self circularBuffer:&_circularBuffer withSize:24576*5];
stopped = NO;
[self setupAudioUnit];
// [super setup:#"http://localhost" port:5321];
}
-(void) setupAudioUnit
{
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
OSStatus status;
status = AudioComponentInstanceNew(comp, &_audioUnit);
if(status != noErr)
{
NSLog(#"Error creating AudioUnit instance");
}
// Enable input and output on AURemoteIO
// Input is enabled on the input scope of the input element
// Output is enabled on the output scope of the output element
UInt32 one = 1;
status = AudioUnitSetProperty(_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &one, sizeof(one));
if(status != noErr)
{
NSLog(#"Error enableling AudioUnit output bus");
}
// Explicitly set the input and output client formats
// sample rate = 44100, num channels = 1, format = 16 bit int point
AudioStreamBasicDescription audioFormat = [self getAudioDescription];
status = AudioUnitSetProperty(_audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, sizeof(audioFormat));
if(status != noErr)
{
NSLog(#"Error setting audio format");
}
AURenderCallbackStruct renderCallback;
renderCallback.inputProc = OutputRenderCallback;
renderCallback.inputProcRefCon = (__bridge void *)(self);
status = AudioUnitSetProperty(_audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &renderCallback, sizeof(renderCallback));
if(status != noErr)
{
NSLog(#"Error setting rendering callback");
}
// Initialize the AURemoteIO instance
status = AudioUnitInitialize(_audioUnit);
if(status != noErr)
{
NSLog(#"Error initializing audio unit");
}
}
- (AudioStreamBasicDescription)getAudioDescription {
AudioStreamBasicDescription audioDescription = {0};
audioDescription.mFormatID = kAudioFormatLinearPCM;
audioDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian;
audioDescription.mChannelsPerFrame = 1;
audioDescription.mBytesPerPacket = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
audioDescription.mFramesPerPacket = 1;
audioDescription.mBytesPerFrame = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
audioDescription.mBitsPerChannel = 8 * sizeof(SInt16);
audioDescription.mSampleRate = 44100.0;
return audioDescription;
}
-(void)circularBuffer:(TPCircularBuffer *)circularBuffer withSize:(int)size {
TPCircularBufferInit(circularBuffer,size);
}
-(void)appendDataToCircularBuffer:(TPCircularBuffer*)circularBuffer
fromAudioBufferList:(AudioBufferList*)audioBufferList {
TPCircularBufferProduceBytes(circularBuffer,
audioBufferList->mBuffers[0].mData,
audioBufferList->mBuffers[0].mDataByteSize);
}
-(void)freeCircularBuffer:(TPCircularBuffer *)circularBuffer {
TPCircularBufferClear(circularBuffer);
TPCircularBufferCleanup(circularBuffer);
}
-(TPCircularBuffer *) outputShouldUseCircularBuffer
{
return &_circularBuffer;
}
-(void) stop
{
OSStatus status = AudioOutputUnitStop(_audioUnit);
if(status != noErr)
{
NSLog(#"Error stopping audio unit");
}
TPCircularBufferClear(&_circularBuffer);
_audioUnit = nil;
stopped = YES;
}
-(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)event{
switch (event) {
case NSStreamEventOpenCompleted:
NSLog(#"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
if (stream == [super inputStream]) {
NSLog(#"NSStreamEventHasBytesAvailable");
uint8_t buffer[1024];
NSUInteger len;
while ([[super inputStream] hasBytesAvailable]) {
len = [[super inputStream] read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
//converting buffer to byte data
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if (nil != output) {
//NSLog(#"server overideddddd said: %#", output);
}
NSData *data0 = [[NSData alloc] initWithBytes:buffer length:len];
if (nil != data0) {
SInt16* byteData = (SInt16*)malloc(len);
memcpy(byteData, [data0 bytes], len);
double sum = 0.0;
for(int i = 0; i < len/2; i++) {
sum += byteData[i] * byteData[i];
}
Byte* soundData = (Byte*)malloc(len);
memcpy(soundData, [data0 bytes], len);
if(soundData)
{
AudioBufferList *theDataBuffer = (AudioBufferList*) malloc(sizeof(AudioBufferList) *1);
theDataBuffer->mNumberBuffers = 1;
theDataBuffer->mBuffers[0].mDataByteSize = (UInt32)len;
theDataBuffer->mBuffers[0].mNumberChannels = 1;
theDataBuffer->mBuffers[0].mData = (SInt16*)soundData;
NSLog(#"soundData here");
[self appendDataToCircularBuffer:&_circularBuffer fromAudioBufferList:theDataBuffer];
}
}
}
}
}
break;
case NSStreamEventErrorOccurred:
NSLog(#"Can't connect to server");
break;
case NSStreamEventEndEncountered:
[stream close];
[stream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
break;
default:
NSLog(#"Unknown event");
}
[super stream:stream handleEvent:event];
}
#end
I would highly appreciate if there is any one with an example of playing buffers returned from a socket server into audio queue so that I can be able to listen to sound as it comes from the socket server.
Thanks
Your code seems to be asking for a kAudioUnitSubType_VoiceProcessingIO audio unit. But kAudioUnitSubType_RemoteIO would be a more suitable iOS audio unit for just playing buffers of audio samples.
Also, your code does not seem to first select an appropriate audio session category and activate it before playing audio. See Apple's documentation for doing this: https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Introduction/Introduction.html

Sprite Collision With Three Different Sprites?

I've created three sprites that works as walls in my scene. Then I have a sprite and a score. I want the sprite to set the score to 0 only when it touches the floor(one of the three sprites). So that's what I have for the contact.
- (void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ((firstBody.categoryBitMask & shipCategory) != 0 &&
(secondBody.categoryBitMask & obstacleCategory) != 0)
{
score = 0;
myLabel.text = [NSString stringWithFormat:#"%i", score];
}
}
Here are the categoryBitMask
static const uint32_t shipCategory = 0x1 << 1;
static const uint32_t obstacleCategory = 0x1 << 1;
static const uint32_t wallCategory = 0x1 << 1;
Theese are the codes for the sprite, the floor and the walls
-(SKSpriteNode *)floorNode
{
floorNode = [SKSpriteNode spriteNodeWithImageNamed:#"rectangle.png"];
floorNode.position = CGPointMake(160,100);
floorNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:floorNode.size];
floorNode.physicsBody.categoryBitMask = obstacleCategory;
floorNode.physicsBody.contactTestBitMask = shipCategory;
fireNode.physicsBody.usesPreciseCollisionDetection = YES;
fireNode.physicsBody.collisionBitMask = 2;
floorNode.physicsBody.dynamic = NO;
floorNode.zPosition = 1.0;
return floorNode;
}
-(SKSpriteNode *)walldxNode
{
walldxNode = [SKSpriteNode spriteNodeWithImageNamed:#"wall.png"];
walldxNode.position = CGPointMake(30, 568);
walldxNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:walldxNode.size];
walldxNode.physicsBody.categoryBitMask = wallCategory;
walldxNode.physicsBody.dynamic = NO;
return walldxNode;
}
-(SKSpriteNode *)wallsxNode
{
wallsxNode = [SKSpriteNode spriteNodeWithImageNamed:#"wall.png"];
wallsxNode.position = CGPointMake(290, 568);
wallsxNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:wallsxNode.size];
wallsxNode.physicsBody.categoryBitMask = wallCategory;
wallsxNode.physicsBody.dynamic = NO;
return wallsxNode;
}
-(SKSpriteNode *)fireButtonNode
{
fireNode = [SKSpriteNode spriteNodeWithImageNamed:#"Spaceship.png"];
fireNode.position = CGPointMake(160,450);
fireNode.xScale = 0.32;
fireNode.yScale = 0.32;
fireNode.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius: fireNode.size.height/2];
fireNode.physicsBody.categoryBitMask = shipCategory;
fireNode.physicsBody.dynamic = YES;
fireNode.physicsBody.contactTestBitMask = obstacleCategory;
fireNode.physicsBody.collisionBitMask = 2;
fireNode.physicsBody.usesPreciseCollisionDetection = YES;
fireNode.name = #"fireButtonNode";//how the node is identified later
fireNode.zPosition = 2.0;
return fireNode;
}
The problem is that the sprite sets the score to 0 also when collides with the others two walls, which have differents categoryBitMask. I don't know what to do.
Your category bitmasks all have the same values. Make them differ like this:
static const uint32_t shipCategory = 0x1 << 1; // this equals 2
static const uint32_t obstacleCategory = 0x1 << 2; // this equals 4
static const uint32_t wallCategory = 0x1 << 3; // this equals 8
Batalia is correct, but these days you should probably use an enum rather than some crusty old static const. I did it in some code like this and then filed a bug against the sample code for not using Apple's own current best practices:
// These constans are used to define the physics interactions between physics bodies in the scene.
typedef NS_OPTIONS(NSUInteger, RockBusterCollionsMask) {
RBCmissileCategory = 1 << 0,
RBCasteroidCategory = 1 << 1,
RBCshipCategory = 1 << 2
};

Cocos2D - Detecting collision

I am a beginner in cocos2d and im facing a problem with detecting collision for my coins.
Sometimes it works sometimes it doesn't.
So basically, im creating a game which the user (ship) have to avoid the obstacles and collect coins on the way. The collision of the obstacle works well but not for the coins.
I was thinking maybe the loops for creating many coins is the problem but im not sure.
Can anyone help?
My codes:
- (void)update:(ccTime)dt{
double curTime = CACurrentMediaTime();
if (curTime > _nextBridgeSpawn) {
float randSecs = [self randomValueBetween:3.0 andValue:5.0];
_nextBridgeSpawn = randSecs + curTime;
float randX = [self randomValueBetween:50 andValue:500];
float randDuration = [self randomValueBetween:8.0 andValue:10.0];
CCSprite *bridge = [_bridge objectAtIndex:_nextBridge];
_nextBridge++;
if (_nextBridge >= _bridge.count) _nextBridge = 0;
[bridge stopAllActions];
bridge.position = ccp(winSize.width/2, winSize.height);
bridge.visible = YES;
[bridge runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:randDuration position:ccp(0, -winSize.height)],
[CCCallFuncN actionWithTarget:self selector:#selector(setInvisible:)],
nil]];
this is where i declare my coins (continued from the update method)
int randCoin = [self randomValueBetween:0 andValue:5];
_coin = [[CCArray alloc] initWithCapacity:randCoin];
for(int i = 0; i < randCoin; ++i) {
coin = [CCSprite spriteWithFile:#"coin.png"];
coin.visible = NO;
[self addChild:coin];
[_coin addObject:coin];
}
float randCoinX = [self randomValueBetween:winSize.width/5 andValue:winSize.width - (border.contentSize.width *2)];
float randCoinY = [self randomValueBetween:100 andValue:700];
float randCoinPlace = [self randomValueBetween:30 andValue:60];
for (int i = 0; i < _coin.count; ++i) {
CCSprite *coin2 = [_coin objectAtIndex:i];
coin2.position = ccp(randCoinX, (bridge.position.y + randCoinY) + (randCoinPlace *i));
coin2.visible = YES;
[coin2 runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:randDuration position:ccp(0, -winSize.height-2000)],
[CCCallFuncN actionWithTarget:self selector:#selector(setInvisible:)],
nil]];
}
}
this is to check for collision (also in the update method)
for (CCSprite *bridge in _bridge) {
if (!bridge.visible) continue;
if (CGRectIntersectsRect(ship.boundingBox, bridge.boundingBox)){
bridge.visible = NO;
[ship runAction:[CCBlink actionWithDuration:1.0 blinks:5]];
}
}
}
//this is the collision for coins which only work at times
for (CCSprite *coin2 in _coin) {
if (!coin2.visible) continue;
if (CGRectIntersectsRect(ship.boundingBox, coin2.boundingBox)) {
NSLog(#"Coin collected");
coin2.visible = NO;
}
}
}
Thank you.
Why you just don't check distances?
float dist = ccpDistance(ship.position, coin2.position);
float allowedDist = ship.contentSize.width*0.5 + coin2.contentSize.width*0.5;
if (dist<allowedDist){
NSLog(#"Collision detected");
}
If your sprites are not on the same layer, these layers should have at least same positions.
what is phone in the last piece of code? you check there if it's boundingBox intersects coins one, but I cannot see it anywhere else. Another one, boundingBox will work only if your objects have the same parent, because it returns "local" rect, relatieve to it's parent
another one point is that in case of too fast movement speed of your objects it is possible, that they will pass throw each other during tick time. I mean, that one update will be called before collision, so it will not detect it and the next one will be called after collision was finished, so it will not detect it either.
I've solved my problem by creating a timer in init and call it every 10 secs to create my coins.
My codes:
-(void) createCoins:(ccTime)delta{
CGSize winSize = [CCDirector sharedDirector].winSize;
int randCoin = [self randomValueBetween:0 andValue:10];
_coin = [[CCArray alloc] initWithCapacity:randCoin];
for(int i = 0; i < randCoin; i++) {
coin = [CCSprite spriteWithFile:#"coin30p.png"];
coin.visible = NO;
[self addChild:coin];
[_coin addObject:coin];
}
float randCoinX = [self randomValueBetween:winSize.width/5 andValue:winSize.width - (border.contentSize.width *2)];
float randCoinY = [self randomValueBetween:100 andValue:700];
float randCoinPlace = [self randomValueBetween:30 andValue:60];
for (int i = 0; i < _coin.count; i++) {
CCSprite *coin2 = [_coin objectAtIndex:i];
coin2.position = ccp(randCoinX, (winSize.height + randCoinY) + (randCoinPlace *i));
coin2.visible = YES;
[coin2 runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:8 position:ccp(0, -winSize.height-2000)],
[CCCallFuncN actionWithTarget:self selector:#selector(setInvisible:)],
nil]];
}
}
in the update method:
for (CCSprite *coins in _coin){
if (!coins.visible) continue;
if (CGRectIntersectsRect(phone.boundingBox, coins.boundingBox)) {
NSLog(#"Coin collected");
coins.visible = NO;
}
}
Thank you everyone for the help(: