Reputation: 2464
Bird, GameWorld and GameScene are three custom classes in my project.
I've an object of type Bird(as a property) in the class Gameworld. I've objects of type Bird and Gameworld in the class GameScene. Now in Gamescene class, when I do:
_bird = [_gameWorld bird];
an error is alerted:
Implicit conversion of a non-Objective-C pointer type 'int *' to 'Bird *' is disallowed with ARC
Why this is happening?
Edit:
GameScene.h
#import <SpriteKit/SpriteKit.h>
#import "Bird.h"
#import "ScrollHandler.h"
#import "Pipe.h"
#import "GameWorld.h"
@interface GameScene : SKScene <SKPhysicsContactDelegate>{
int _midPointY;
float _gameHeight;
NSString *_gameName;
NSString *_getReady;
Bird *_myBird;
NSTimeInterval _dt;
float bottomScrollerHeight;
GameWorld *_myWorld;
}
@property (nonatomic) SKSpriteNode* backgroundImageNode;
@property (nonatomic) SKSpriteNode* greenBird;
@property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
@end
GameWorld.h
#import <Foundation/Foundation.h>
#import <SpriteKit/SpriteKit.h>
#import "Bird.h"
#import "ScrollHandler.h"
typedef NS_ENUM(NSInteger, GameState){
MENU,
READY,
RUNNING,
GAMEOVER,
HIGHSCORE
};
@interface GameWorld : NSObject <ScrollHandlerDelegate>{
float _runTime;
GameState _currentState;
}
@property (nonatomic, strong) ScrollHandler *scroller;
@property (nonatomic, strong) Bird *bird;
@property (nonatomic, assign) int midPointY;
@property (nonatomic, assign) int score;
@property (nonatomic, strong) SKSpriteNode *bg;
@property (nonatomic, strong) NSArray *birds;
@property (nonatomic, strong) SKSpriteNode *birdNode;
@end
GameScene.m
#import "GameScene.h"
#define UPWARD_PILLER @"Upward_Green_Pipe"
#define Downward_PILLER @"Downward_Green_Pipe"
static const uint32_t pillerCategory = 0x1 << 0;
static const uint32_t birdCategory = 0x1 << 1;
static const uint32_t grassCategory = 0x1 << 2;
static const float BG_VELOCITY = (TIME * 60);
static inline CGPoint CGPointAdd(const CGPoint a, const CGPoint b)
{
return CGPointMake(a.x + b.x, a.y + b.y);
}
static inline CGPoint CGPointMultiplyScalar(const CGPoint a, const CGFloat b)
{
return CGPointMake(a.x * b, a.y * b);
}
@implementation GameScene
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
self.anchorPoint = CGPointMake(0, 1);
self.yScale = -1;
//To detect collision detection
self.physicsWorld.contactDelegate = self;
_myWorld = [[GameWorld alloc] initWithMidPointY:_midPointY];
[self initGameObjects];
[self initAssets];
[self setCoinAnimation];
}
return self;
}
-(void) initGameObjects {
_myBird = [_myWorld bird]; //here is the problem
}
-(void) initAssets {
//initialize other assets
}
-(void) setCoinAnimation {
//initialize other assets
}
@end
Bird.h
#import "GameWorld.h"
@import UIKit;
@interface Bird : NSObject {
CGPoint _position;
CGPoint _velocity;
CGPoint _acceleration;
float _rotation;
float _originalY;
int _width;
int _height;
int _dieCount;
bool _isAlive;
}
@end
Note:I just found out that when I remove the import "Gameworld.h" from "Bird.h", the error disappears and it is working. The import was made there accidentally and it is not needed. But I don't why it caused the error.
Upvotes: 0
Views: 3120
Reputation: 42588
Import statements must be linear, but you had a loop. GameScene.m
-> GameScene.h
-> Bird.h
-> GameWorld.h
-> Bird.h
.
Because of this, when GameWorld.h
had #import "Bird.h"
, the compiler saw that Bird.h
was already imported and didn't import it. The problem was @interface Bird
had not been defined yet, so GameWorld
didn't have the proper interface for Bird
.
Upvotes: 2
Reputation: 5343
Well as you mentioned in the end, thats was the only issue.
So what was happening?
When you imported Gameworld
to your Bird
interface file, in that, your Gameworld
itself had a variable named bird
which was of type Bird
. You then went ahead and defined the Bird
class in the subsequent lines. Before that the compiler din't knew what the Bird
object is and it by default assumes it as int
.
If you any how want to to declare Gameworld
object in your Bird
class, then instead of importing it your interface, you just need to use forward declaration, i.e.
@class Gameworld;
This tells the compiler that a Class do exist with the name Gameworld
.
Upvotes: 1