Been programming an iOS/objective-c/cocos2d app. Things have been going fine up until this snag... I should note that it's Objective-C++, ie. .mm files, compiling for the iOS 5.0 simulator.
Basically, I'm only trying to subclass an interface. The error is produced on the #interface line: "Cannot find interface declaration for GameObject"
#import <Foundation/Foundation.h>
#import "CCSprite.h"
#import "cocos2d.h"
#import "Box2D.h"
#import "GameObject.h"
#interface AvalancheBlock : GameObject
{
}
#end
Here's the code for GameObject.h:
#import <UIKit/UIKit.h>
#import "cocos2d.h"
#import "Box2D.h"
#import "b2Body.h"
#import "OhSnowGame.h"
#interface GameObject : CCNode {
#public
b2Body *body;
b2BodyDef *bodyDef;
b2FixtureDef *fixtureDef;
b2PolygonShape *polygonShape;
b2CircleShape *circleShape;
CCSprite *sprite;
int typeTag;
bool markedForDestruction;
}
#property (readwrite, assign) b2Body *body;
#property (nonatomic, assign) b2BodyDef *bodyDef;
#property (nonatomic, assign) b2FixtureDef *fixtureDef;
#property (nonatomic, assign) b2PolygonShape *polygonShape;
#property (nonatomic, assign) b2CircleShape *circleShape;
#property (nonatomic, retain) CCSprite *sprite;
#property (readwrite, assign) int typeTag;
#property (readwrite, assign) bool markedForDestruction;
#property (readonly) int type;
-(id) init;
-(void) initBox2D;
-(int) type;
#end
And GameObject.mm:
#import "GameObject.h"
#implementation GameObject
#synthesize body, bodyDef, fixtureDef, polygonShape, circleShape, sprite, type, typeTag, markedForDestruction;
-(id) init {
if( (self=[super init]) ) {
[self initBox2D];
markedForDestruction = NO;
}
return self;
}
-(void) initBox2D {
bodyDef = new b2BodyDef();
fixtureDef = new b2FixtureDef();
//Initial fixture settings
fixtureDef->density = 1.0f;
fixtureDef->friction = 0.5f;
fixtureDef->restitution = 0.3f;
bodyDef->userData = self;
}
-(int) type {
return 0;
}
#end
If the correct file is being included... then why the error?
Thanks!
SOLVED:
Figured it out... there WAS a circular reference, but I still needed the reference. The solution was to remove the #import "OhSnowGame.h" from GameObject.h, and instead add the directive:
#class OhSnowGame
Learn something new every day.
SECOND UPDATE:
New issue, but very much related.
I have OhSnowGame.mm which includes a "AvalancheGrid.h".
AvalancheGrid.h includes AvalancheParams.h.
In OhSnowGame, I'm referencing both AvalancheGrid and AvalancheParams.
The compiler is throwing a linker error:
"Duplicate symbol AvalancheParams in OhSnowGame.o and AvalancheGrid.o"
But really it doesn't seem like there's any circular reference to me.
If I replace the #import "AvalancheGrid.h" in OhSnowGame.mm with just
#class AvalancheGrid; (and also #class AvalancheParams.h;)
then it doesn't let me reference the properties of those objects like I need to, ie:
avParams.severity = 3; //nope
avParams->severity = 3; //nope
[avParams setSeverity:3]; //nope (with #property severity exposed and synthesized)
I don't understand. How can I avoid the linker error and still access those properties?
Related
I have read question after question about people getting the same error as me, but I simply do not understand them, so before you go searching for duplicate questions, maybe someone can explain to me what I am doing wrong with this subclassing deal.
I have a subclass of UIImageView called swapView that I want to subclass to override the method -(void)count for special cases. I went to subclass this as I have any pre-existing UIKit class, but when I tried to build and run the project, I get this error:
Attempting to use the forward class 'swapView' as superclass of 'coinView'
I have tried putting both the #import statement of swapView and #class swapView in coinView.h and I've tried putting the import statement in coinView.m, but it refuses to build because of this continued error. If I move the import statement into the .m file, all references to the superclass's methods and properties, such as #property (nonatomic) int max; cause errors as well.
What am I doing wrong?
swapView.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#class ViewController;
#interface swapView : UIImageView
{
NSTimer* tmr;
}
#property (nonatomic) int current;
#property (nonatomic) int max;
#property (nonatomic, retain) UIImage* firstImage;
#property (nonatomic, retain) UIImage* secondImage;
#property (nonatomic) BOOL smallMax;
#property (nonatomic, retain) ViewController* pvc;
- (BOOL)testCollision:(CGPoint)point;
- (float)randomFloatBetween:(float)smallNumber bigNumber:(float)bigNumber;
#end
coinView.h
#import "swapView.h"
#class swapView;
#interface coinView : swapView
- (void)count;
- (void)move;
#end
For inheritance, the superclass MUST be inherited.
coinView.h
#import "swapView.h"
#interface coinView : swapView
- (void)count;
- (void)move;
#end
You're both forward declaring and importing ViewController.h in your swapView, which may cause compiler to complain.
swapView.h
#import <UIKit/UIKit.h>
#class ViewController
#interface swapView : UIImageView
.
.
.
#end
My GameScene.m file :
#import "GameScene.h"
// Needed to obtain the Navigation Controller
#import "AppDelegate.h"
#pragma mark - GameScene
// GameScene implementation
#implementation GameScene
// on "init" you need to initialize your instance
-(id) init
{
self = [super init];
if (self != nil)
{
[self addChild:[GameLayer node]];
}
return self;
}
- (void) dealloc
{
[super dealloc];
}
#end
#implementation GameLayer
#synthesize hero;
-(id) init
{
if( (self=[super init] ))
{
hero = [[Hero alloc] initWithGame:self];
}
return self;
}
-(void) dealloc
{
[super dealloc];
}
#end
My GameScene.h file :
#import <GameKit/GameKit.h>
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
// GameScene
#interface GameScene : CCScene
{
}
#end
#class Hero;
#interface GameLayer : CCLayer
{
Hero * _hero;
NSMutableArray * _bullets;
bool _playerFiring;
NSMutableArray * _enemies;
float _lastTimeEnemyLaunched;
float _enemyInterval;
int _score;
int _lives;
int _bombs;
int _level;
}
#property (nonatomic,retain) Hero * hero;
#property (nonatomic,readwrite) bool playerFiring;
#property (nonatomic,readwrite) float lastTimeEnemyLaunched;
#property (nonatomic,readwrite) float enemyInterval;
#property (nonatomic,retain) NSMutableArray * enemies;
#property (nonatomic,retain) NSMutableArray * bullets;
#property (assign,readwrite) int score;
#property (assign,readwrite) int lives;
#property (assign,readwrite) int bombs;
#property (assign,readwrite) int level;
#end
My Hero.h file :
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "GameScene.h"
#class GameLayer;
#interface Hero : CCNode
{
CCSprite * mySprite;
GameLayer * theGame;
float _lastTimeFired;
float _fireInterval;
float _firingSpeed;
float _movementSpeed;
}
#property (nonatomic,retain) CCSprite * mySprite;
#property (nonatomic,retain) GameLayer * theGame;
#property (nonatomic,readwrite) float lastTimeFired;
#property (nonatomic,readwrite) float fireInterval;
#property (nonatomic,readwrite) float firingSpeed;
#property (nonatomic,readwrite) float movementSpeed;
#end
And my Hero.m file :
#import "Hero.h"
#implementation Hero
#synthesize theGame,mySprite;
-(id) initWithGame:(GameLayer *)game
{
self = [super init];
if(self != nil)
{
// ask director for the window size
CGSize size = [[CCDirector sharedDirector] winSize];
self.theGame = game;
mySprite = [CCSprite spriteWithFile:#"hero.png"];
[theGame addChild:mySprite z:2];
[mySprite setPosition:ccp(size.width/2,50)];
self.lastTimeFired = 0;
self.fireInterval = 3;
self.firingSpeed = 10;
self.movementSpeed = 5;
}
return self;
}
-(void) dealloc
{
[super dealloc];
}
#end
And here's my problem : I get two warnings - 1. "instance method -initWithGame not found (return type default to 'id')" and 2. "Receiver 'Hero' is a forward class and corresponding #interface may not exist"
I tried to add "-(id) initWithGame:(GameLayer *)game" line to Hero.h interface, but it won't work. I tried to add that line but with + instead of -, but nothing.
I end up without my Hero displayed on a screen. Does anyone knows how to solve this problem (I use newest version of Xcode)?
In GameScene.m, you should
#import "Hero.h"
This explains why you get the "forward class" warning: since you did not import the header, the only thing known to the compiler in the GameScene compilation unit is the forward declaration.
Once you do that, if you also declare initWithGame in Hero.h, then you won't get any warning.
I have made a very simple NSObject:
GameSetUpData.h
#interface GameSetUpData : NSObject
#property (readwrite, nonatomic) NSUInteger numberOfPlayers;
#property (strong, nonatomic) NSMutableArray *playerNames;
#property (strong, nonatomic) NSString *gameType;
#property (readwrite, nonatomic) NSUInteger numberOfMinutes;
#property (readwrite, nonatomic) NSUInteger numberOfTurns;
#property (readwrite, nonatomic) CGSize boardSize;
#end
GameSetUpData.m
#import "GameSetUpData.h"
#implementation GameSetUpData
#synthesize numberOfPlayers = _numberOfPlayers;
#synthesize playerNames = _playerNames;
#synthesize gameType = _gameType;
#synthesize numberOfMinutes = _numberOfMinutes;
#synthesize numberOfTurns = _numberOfTurns;
#synthesize boardSize = _boardSize;
#end
This class basically just holds data. I then try to use this object in my viewcontroller:
MainMenu.h
#import <UIKit/UIKit.h>
#class GameSetUpData;
#interface MainMenu : UIViewController
#property (strong, nonatomic) GameSetUpData *gameSetUp;
-(IBAction)tappedNewGame:(id)sender;
-(IBAction)tappedTwoPlayers:(id)sender;
...
MainMenu.m
#import "MainMenu.h"
#import "MJViewController.h"
#import "GameSetUpData.h"
#implementation MainMenu
#synthesize gameSetUp = _gameSetUp;
...
-(IBAction)tappedTwoPlayers:(id)sender {
_gameSetUp.numberOfPlayers = 2;
NSLog(#"number of Players: %d", _gameSetUp.numberOfPlayers);
}
Unfortunately, my NSLog says that numberOfPlayers is equal to 0. What is wrong with my GameSetUpData? I was told that in iOS5 we do not need to call alloc/init or make a dealloc method. Do I still need a -(void)init method in GameSetUpData. Thank you all for your time!
Edit: Please alloc/init your objects -- ARC ONLY deals with release/retain/autorelease. You still need to make an instance of an Object! I apologize for the mis-information. I will make sure to RTFM next time...
Of course you have to alloc/init your object. How should the compiler know when to do that? With ARC you just don't need to retain or release.
Add _gameSetUp = [[GameSetUpData alloc] init]; somewhere.
Hi guys please can anyone help out this error: "Accessing unknown' lives' getter method" I am getting on the 2nd line(CCSprite line) of the code below.
GamePlayLayer.h is:
#import "cocos2d.h"
#import "Box2D.h"
#import "GLES-Render.h"
#import <Foundation/Foundation.h>
#class UILayer;
#class Insect;
#interface GamePlayLayer : CCLayer {
b2World * world;
GLESDebugDraw * debugDraw;
CCSpriteBatchNode * sceneSpriteBatchNode;
Insect * insect;
b2Body *body;
SceneUILayer * uiLayer;
double startTime;
bool gameOver;
bool gameWon;
NSMutableArray *lives;
}
- (id)initWithUILayer:(UILayer *)sceneUILayer;
#end
GamePlayLayer.m
UILayer * sr = (UILayer *)[self.parent getChildByTag:10];
CCSprite * live = [sr.lives objectAtIndex:self.lives];
[live setVisible:NO];
Allright I have to add the following information:
The UILayer.h (The UILayer is the HUD layer)file is :
#interface UILayer : CCLayer {
NSMutableArray *lives;
}
#property (nonatomic,retain) NSMutableArray *lives;
The UILayer.m is:
#import "UILayer.h"
#import "GameManager.h"
#implementation UILayer
#synthesize lives;
- (id)init {
if ((self = [super init])) {
lives = [[NSMutableArray arrayWithCapacity:3]retain];
for(int i=0;i<3;i++)
{
CCSprite * life = [CCSprite spriteWithFile:#"life_Label.png"];
[life setPosition:ccp(winSize.width/18+ 32*i,290)];
[self addChild:life];
[lives addObject:life];
}
}
The way that the compiler sees your method -setVisible is a setter method for a property visible. I'm guessing that isn't what you intended. Try renaming your method to something like [live visible:NO]; or anything other than -set.
are you defining a property for lives?
e.g. in your .h:
#interface blah
// ...
#property (assign) NSInteger lives;
#end
then in your .m:
#implementation blah
#synthesize lives = _lives;
//your code
#end
You could:
have no #property int lives; in header file
have no #synthesize lives; in implementation file.
have lives as something else than int (or convertible to int).
But it's just a poor guessing with the snippet you have provided.
I wonder what is wrong with this?
.h file:
typedef enum {
N4LoupeTypeRound,
N4LoupeTypeRectangle,
} N4LoupeType;
#interface N4LoupeLayer : CALayer {
N4LoupeType _type;
UIView *_originalView;
CALayer *_mask;
CALayer *_overlay;
}
#property (nonatomic) N4LoupeType type;
#property (nonatomic, assign) UIView *originalView;
#end
.m file:
#import "N4LoupeLayer.h"
#interface N4LoupeLayer (Privates)
#property (nonatomic, retain) CALayer *mask;
#property (nonatomic, retain) CALayer *overlay;
#end
#implementation N4LoupeLayer
#synthesize type = _type;
#synthesize originalView = _originalView;
#synthesize mask = _mask;
#synthesize overlay = _overlay; // ******I GET THE ERROR HERE*********
#end
No declaration of property 'overlay' found in the interface in N4LoupeLayer.m
You defined the properties for the Privatescategory, but you are trying to synthesize them in N4LoupeLayer.