Why is my grid not drawing? - iphone

I'm trying to setup a grid for path finding in a box2d environment. Is it my drawing method which is why none of the nodes and links between them are being drawn? here is my main class for drawing the world:
#interface HelloWorldLayer()
#end
#implementation HelloWorldLayer
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(id) init
{
if( (self=[super init]))
{
[self createGrid];
[self drawGrid];
}
return self;
}
-(void) dealloc
{
[super dealloc];
}
-(void) createGrid
{
//Create 2D array (grid)
nodeSpace = 50.0f;
gridSizeX = 500;
gridSizeY = 500;
grid = [[NSMutableArray alloc] initWithCapacity:(gridSizeX)];
for(int x=0; x<gridSizeX; x++){
[grid addObject:[[NSMutableArray alloc] initWithCapacity:(gridSizeY)]];
}
//Create AStar nodes
for(int x=0; x<gridSizeX; x++){
for(int y=0; y<gridSizeY; y++){
//Add a node
AStarNode *node = [[AStarNode alloc] init];
node.position = ccp(x*nodeSpace + nodeSpace/2, y*nodeSpace + nodeSpace/2);
[[grid objectAtIndex:x] addObject:node];
}
}
//Add neighbors
for(int x=0; x<gridSizeX; x++){
for(int y=0; y<gridSizeY; y++){
//Add a node
AStarNode *node = [[grid objectAtIndex:x] objectAtIndex:y];
//Add self as neighbor to neighboring nodes
[self addNeighbor:node toGridNodeX:x-1 Y:y-1]; //Top-Left
[self addNeighbor:node toGridNodeX:x-1 Y:y]; //Left
[self addNeighbor:node toGridNodeX:x-1 Y:y+1]; //Bottom-Left
[self addNeighbor:node toGridNodeX:x Y:y-1]; //Top
[self addNeighbor:node toGridNodeX:x Y:y+1]; //Bottom
[self addNeighbor:node toGridNodeX:x+1 Y:y-1]; //Top-Right
[self addNeighbor:node toGridNodeX:x+1 Y:y]; //Right
[self addNeighbor:node toGridNodeX:x+1 Y:y+1]; //Bottom-Right
}
}
}
/* Add neighbor helper method */
-(void) addNeighbor:(AStarNode*)node toGridNodeX:(int)x Y:(int)y {
if(x >= 0 && y >= 0 && x < gridSizeX && y < gridSizeY){
AStarNode *neighbor = [[grid objectAtIndex:x] objectAtIndex:y];
if(![AStarNode isNode:neighbor inList:node.neighbors]){
[node.neighbors addObject:neighbor];
}
}
}
-(void) drawGrid
{
for(int x=0; x<gridSizeX; x++){
for(int y=0; y<gridSizeY; y++){
//Draw node
AStarNode *node = [[grid objectAtIndex:x] objectAtIndex:y];
ccDrawColor4F(16, 16, 16, 8);
ccDrawPoint(node.position);
//Draw neighbor lines (there is going to be a lot of them)
for(int i=0; i<node.neighbors.count; i++){
AStarNode *neighbor = [node.neighbors objectAtIndex:i];
ccDrawColor4F(16, 16, 16, 8);
ccDrawLine(node.position, neighbor.position);
}
}
}
}
#end

You can only draw with OpenGL in draw or visit methods.

I did not think that drawing would work in init. Try to put that in an onEnter
-(void) onEnter {
// at this point, the node has been added, is running
// and will be visited as appropriate (i think)
[super onEnter]; // dont forget to super any 'onMethod' override of cocos2d
[self drawGrid];
}

Related

Assertion failure Error when trying to stop sprite action in cocos2d iphone

I am having problem in stoping action. i have 2 sprite animation 1 is ant and second is grasshopper. WHen i am just calling ants animation it works fine but when i try to run both ant and grasshopper animation it gives me error.
* Assertion failure in -[CCSpriteBatchNode addChild:z:tag:], /Users/zohaib/Downloads/zohaibgame/zohaibgame/libs/cocos2d/CCSpriteBatchNode.m:183
it gives error when antMoveEnded is called.
ants animation code
-(void) walk_Ants
{
// 1) Cache the sprite frames and texture
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
#"ant-animation.plist"];
/// 2) Create a sprite batch node
CCSpriteBatchNode *spriteSheet_ant = [CCSpriteBatchNode
batchNodeWithFile:#"ant-animation.png"];
[self addChild:spriteSheet_ant];
// 3rd Step
// 3) Gather the list of frames
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 24; ++i) {
[walkAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"%d.png", i]]];
}
// 4th Step
// 4) Create the animation object
CCAnimation *walkAnim = [CCAnimation
animationWithSpriteFrames:walkAnimFrames delay:0.05f];
// 5th Step
// 5) Create the sprite and run the animation action
self.ants = [CCSprite spriteWithSpriteFrameName:#"1.png"];
_ants.position = ccp(winSize.width, winSize.height/6);
//_ants.position = ccp(459, 16);
self.walkActionAnt = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim]];
[_ants runAction:_walkActionAnt];
[spriteSheet_ant addChild:_ants];
CCLOG(#"Position %#",NSStringFromCGPoint(_ants.position));
[self walkingAnts];
}
-(void) walkingAnts
{
// 2) Set the desired velocity
float antVelocity = 480.0/10.0;
// 3) Figure out the amount moved in X and Y
CGPoint waking_Path = CGPointMake(X_AXIS_ENDINGPATH, _ants.position.y);
CGPoint moveDifference = ccpSub(waking_Path, _ants.position);
// 4) Figure out the actual length moved
float distanceToMove = ccpLength(moveDifference);
// 5) Figure out how long it will take to move
float moveDuration = distanceToMove / antVelocity;
// 7) Run the appropriate actions
//[_ants stopAction:_moveAction];
id restartAntWalk = [CCCallFuncN actionWithTarget:self selector:#selector(antMoveEnded:)];
self.moveActionAnt = [CCSequence actions:
[CCMoveTo actionWithDuration:moveDuration position:waking_Path],
restartAntWalk,
nil];
//self.moveActionAnt.tag = 121;
[_ants runAction:_moveActionAnt];
_movingAnt = TRUE;
}
- (void) antMoveEnded: (ccTime) dt
{
if(_ants.position.x == -50)
{
[_ants stopAction:_moveActionAnt];
//[self stopActionByTag:121];
_movingAnt = FALSE;
[self walk_Ants];
}
}
GrassHopper code ( mantis )
-(void) mantisCome
{
float w_index = arc4random() % 480;
//float h_index = arc4random() % 320;
self.moveActionMantis = [CCSequence actions:
[CCMoveTo actionWithDuration:2 position:ccp(w_index, 63)],
nil];
[_mantis runAction:_moveActionMantis];
[self schedule:#selector(timer:) interval:5];
}
-(void) mantisGo
{
self.moveActionMantis = [CCSequence actions:
[CCMoveTo actionWithDuration:2 position:ccp(-50, 280)],
nil];
[_mantis runAction:_moveActionMantis];
[self unschedule:#selector(timer:)];
[self mantisAnimation];
}
#pragma -mark Mantis Animation
-(void) mantisAnimation
{
// 1) Cache the sprite frames and texture
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
#"mantis-animation.plist"];
/// 2) Create a sprite batch node
CCSpriteBatchNode *spriteSheet_mantis = [CCSpriteBatchNode
batchNodeWithFile:#"mantis-animation.png"];
[self addChild:spriteSheet_mantis];
// 3rd Step
// 3) Gather the list of frames
NSMutableArray *walkAnimFrames_mantis = [NSMutableArray array];
for(int i = 1; i <= 14; ++i) {
[walkAnimFrames_mantis addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"%d.png", i]]];
}
// 4th Step
// 4) Create the animation object
CCAnimation *walkAnim_mantis = [CCAnimation
animationWithSpriteFrames:walkAnimFrames_mantis delay:0.05f];
// 5th Step
// 5) Create the sprite and run the animation action
self.mantis = [CCSprite spriteWithSpriteFrameName:#"1.png"];
_mantis.position = ccp(winSize.width+100, winSize.height+100);
_mantis.flipX=YES;
//_mantis.position = ccp(459, 16);
self.walkActionMantis = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim_mantis]];
walkAnim_mantis.restoreOriginalFrame = NO;
[_mantis runAction:_walkActionMantis];
[spriteSheet_mantis addChild:_mantis];
//CCLOG(#"Position %#",NSStringFromCGPoint(_mantis.position));
[self mantisCome];
}
I figured out what was the problem.
when i was creating animation for ant i was using this code
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 24; ++i) {
[walkAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"%d.png", i]]];
}
self.ants = [CCSprite spriteWithSpriteFrameName:#"1.png"];
and when creating animaiton for mantis
NSMutableArray *walkAnimFrames_mantis = [NSMutableArray array];
for(int i = 1; i <= 14; ++i) {
[walkAnimFrames_mantis addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"%d.png", i]]];
}
self.mantis = [CCSprite spriteWithSpriteFrameName:#"1.png"];
i was using 1.png for both. self.ant and self.mantis. i created a new plist file and changed png name from 1.png to ant1.png . It works now.

array removeObjectsAtIndexes:

I have a problem, with deleting items from an array..
first:
i have a variable of type int, called zan. in my HelloWordScene.h
int zan;
NSMutableArray * targets;
NSMutableArray *projectiles;
in my HelloWordScene.m. i have an object, animated:
-(id) init {
if((self = [super init])) {
[self schedule:#selector(update:)];
_targets = [[NSMutableArray alloc] init];
_projectiles = [[NSMutableArray alloc] init];
}
[self schedule:#selector(gameLogic:) interval:3];
return self;
}
in my selector I increment the var:
-(void)gameLogic:(ccTime)dt {
[self addTarget];
zan ++;
}
Later I have an animation and I have a addTarget:
// This loads an image of the same name (but ending in png), and goes through the
// plist to add definitions of each frame to the cache.
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"zancudo.plist"];
// Create a sprite sheet with the images
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"zancudo.png"];
[self addChild:spriteSheet];
// Load up the frames of our animation
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 0; i <= 4; ++i) {
[walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"zancu000%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
// Create a sprite for our bear
CGSize winSize = [CCDirector sharedDirector].winSize;
self.bear = [CCSprite spriteWithSpriteFrameName:#"zancu0001.png"];
//random position
int minY = _bear.contentSize.width/2;
int maxY = winSize.width - _bear.contentSize.width/2;
int rangeY = maxY - minY;
int actualX = (arc4random() % rangeY) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
_bear.position = ccp(actualX,winSize.height + (_bear.contentSize.height/2));
self.walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
//animation
[spriteSheet addChild:_bear];
//∫aqui pasar un for para poder saber que position es
CCLOG(#"cantidad de zancudos%d",zan);
[_targets insertObject:_bear atIndex:zan];
i have deleted a mutable _target for index- i have a selector update. try delete a mutablearray this.
for (CCSprite *target in targetsToDelete) {
if (_targets.count!=0) {
for (int j=1; j==_targets.count; j++) {
[_targets removeObjectAtIndex:j];
}
}
I need help
use syntax like this for crash free delete;
NSArray *array = [NSArray arrayWithArray: _targets];
for(CCSprite *sprite in array)
{
if(sprite.tag == kToDelete) //mark somewhere in game :or use ur logic here
{
[_targets removeObject: sprite];
[sprite stopAllActions];
[sprite removeFromParentAndCleanup:YES];
}
}
Your loop will try and access an index out of the array's bounds...try this
for (int j = 0; j == _targets.count - 1; j++)
{
[_targets removeObjectAtIndex:j];
}
However, since it appears you are only removing the last element of the array with this code, you could skip the for loop and use:
[_targets removeLastObject];
The moment you remove an object from _targets, the effective count actually changes. So if you start the loop with a count of 10, and eventually the value of j will be out of bounds. I dont follow quite well the logic of your if ( the == ), but if you are trying to remove all objects, instead of the loop :
[_targets removeAllObjects];

Adding a game over scene

I want to add this game over scene to this game that I am trying to do for my homework, and I seem to not have it where if you kill the target the game over scene will pop up. I tried putting my code in every line and see if it will finally work but no it didn't. So now I have to ask for some help.
. m file
- (void)addTarget10 {
Boss *target10 = nil;
if ((arc4random() % 2) == 0) {{
target10 = [WeakAndFastBoss9 boss9];
}} else {
target10 = [WeakAndFastBoss9 boss9];
}
[[SimpleAudioEngine sharedEngine] playEffect:#"lastboss.mp3"];
// Determine where to spawn the target along the Y axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minY = target10.contentSize.height/2;
int maxY = winSize.height - target10.contentSize.height/2;
int rangeY = maxY - minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
target10.position = ccp(winSize.width + (target10.contentSize.width/2), actualY);
[self addChild:target10 ];
// Determine speed of the target
int minDuration = target10.minMoveDuration;
int maxDuration = target10.maxMoveDuration;
int rangeDuration = maxDuration - minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(- target10.contentSize.width/2, actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(spriteMoveFinished9:)];
[target10 runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
target10.tag = 1;
[_targets addObject:target10];
}
-(void)gameLogicboss9:(ccTime)dt {
[self unschedule:_cmd];
[self addTarget10];
}
- (void)updateboss9:(ccTime)dt {
CGRect projectileRect = CGRectMake(projectile.position.x - (projectile.contentSize.width/2),
projectile.position.y - (projectile.contentSize.height/2),
projectile.contentSize.width,
projectile.contentSize.height);
BOOL bossHit = FALSE;
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];
for (CCSprite *target1 in _targets) {
CGRect target1Rect = CGRectMake(target1.position.x - (target1.contentSize.width/2),
target1.position.y - (target1.contentSize.height/2),
target1.contentSize.width,
target1.contentSize.height);
if (CGRectIntersectsRect(projectileRect, target1Rect)) {
[targetsToDelete addObject:target1];
bossHit = TRUE;
Boss *boss = (Boss *)target1;
boss.hp--;
if (boss.hp <= 0 ) {
[targetsToDelete addObject:target1];
}
break;
}
}
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
[self removeChild:target cleanup:YES];
_projectilesDestroyed++;
if (_projectilesDestroyed > 2) {
}
}
if (bossHit) {
//[projectilesToDelete addObject:projectile];
}
[targetsToDelete release];
}
-(void)spriteMoveFinishedboss9:(id)sender {
CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];
if (sprite.tag == 1) { // target
[_targets removeObject:sprite];
} else if (sprite.tag == 2) { // projectile
[_projectiles removeObject:sprite];
} }
This the game over scene I want to add when target 10/ boss 9 is killed
GameOverScene *gameOverScene = [GameOverScene node];
[gameOverScene.layer.label setString:#"You Lose"];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
Right now my other game over scene is when the sprite is moved passed screen.If you need me to answer any questions feel free to ask.
For scene replace you try this for your game code..
First Add this code to your GameOverScene class
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
GameOverScene *layer = [GameOverScene node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
Make your GameOverClass is subclass of CCLayer,
Than when You want to change scene do this
[[CCDirector sharedDirector] replaceScene:[GameOverScene scene]];
Ok, so you have to create a new scene. This can simple be done using File->New File and make it a subclass of NSObject. You then change the subclass to an CCLayer. As a test, you can just copy your code from the hello world layer. Next, just import the new class in your helloworld layer class and create a instance of it. Then in a method use [[CCDirector sharedDirector] replaceScene:sceneName];
You can use this site for more info, its very helpful, just read through it and you will find your answer:http://www.raywenderlich.com/352/how-to-make-a-simple-iphone-game-with-cocos2d-tutorial

Change Sprite with Buttons - Cocos2d

I have 2 buttons (left and right) and a sprite sheet that contains all 55 images. I was wondering, what is the best way to go through each sprite using the buttons?
E.G.
Press the left button and the first sprite is added. Press the right button, the first sprite is removed and the second sprite to added. So on and so forth until it reaches the last image.
This is the Sprite Sheet
#import "cocos2d.h"
#interface GameScene : CCLayer {
CCSpriteBatchNode *pspriteSheet
}
+(CCScene *) scene;
#property (nonatomic, retain) CCSprite *p;
#end
----------------------------------------------------
#import "GameScene.h"
#implementation GameScene
#synthesize p = _p;
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
GameScene *layer = [GameScene node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if ((self = [super init]))
{
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
#"PAnim.plist"];
pspriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"PAnim.pvr.ccz"];
[self addChild:pspriteSheet z:0];
}
return self;
}
- (void) dealloc
{
CCLOG(#"%#: %#", NSStringFromSelector(_cmd), self);
_p = nil;
[CCSpriteFrameCache purgeSharedSpriteFrameCache];
[CCTextureCache purgeSharedTextureCache];
[super dealloc];
}
Should I just keep adding them and removing them?
E.G.
-(void)buttons:(CGPoint)touchLocation
{
if (CGRectContainsPoint(leftB.boundingBox, touchLocation) && tapP == YES && paused == NO) {
if (count == 1)
{
_p = [CCSprite spriteWithSpriteFrameName:#"p1.png"];
[pspriteSheet addChild:_p];
count = 2;
_p.position = ccp(240, 215);
}
if (CGRectContainsPoint(rightB.boundingBox, touchLocation) && tapP == YES && paused == NO) {
if (count == 2)
{
[pspriteSheet removeChild:_p cleanup:YES];
_p = [CCSprite spriteWithSpriteFrameName:#"p2.png"];
_p.position = ccp(240, 215);
[pspriteSheet addChild:_p];
count = 3;
}
}
Here is where the "buttons" method is called
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
[self buttons:touchLocation];
return TRUE;
}
Since it is using spriteframe, you can use setDisplay frame:
CCSpriteFrame* frame = [[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:#"spr1.png"];
[mySprite setDisplayFrame:frame];
This would save up memory instead of always adding and removing..

Countdown timer in cocos2d?

I'm trying to create a countdown timer in cocos2d, but I can not help and would like to resolve this problem, my code is below this, perhaps the logic is wrong but I can not fix.
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {
CCSprite *background = [CCSprite spriteWithFile:#"backgame.png"];
CGSize size = [[CCDirector sharedDirector] winSize];
[background setPosition:ccp(size.width/2, size.height/2)];
[self addChild: background];
[self schedule:#selector(countDown:)];
}
return self;
}
-(void)countDown:(ccTime)delta
{
CCLabel *text = [CCLabel labelWithString:#" "
fontName:#"BallsoOnTheRampage" fontSize:46];
text.position = ccp(160,455);
text.color = ccYELLOW;
[self addChild:text];
int countTime = 20;
while (countTime != 0) {
countTime -= 1;
[text setString:[NSString stringWithFormat:#"%i", countTime]];
}
}
Your int countTime = 20; is declaring itself every time to be 20. Also, your while loop will decrement the countTimer as fast as the system can update the CCLabel. If you're trying to do a real timer, you want it to decrement ONLY when countDown: is called. Not during a while-loop.
Try this:
#interface MyScene : CCLayer
{
CCLabel *_text;
}
#property (nonatomic, retain) int countTime;
#end
#implementation MyScene
#synthesize countTime = _countTime;
-(id) init {
if( (self=[super init] )) {
CCSprite *background = [CCSprite spriteWithFile:#"backgame.png"];
CGSize size = [[CCDirector sharedDirector] winSize];
[background setPosition:ccp(size.width/2, size.height/2)];
[self addChild: background];
_countTime = 20;
_text = [CCLabel labelWithString:[NSString stringWithFormat:#"%i", self.countTime]
fontName:#"BallsoOnTheRampage" fontSize:46];
text.position = ccp(160,455);
text.color = ccYELLOW;
[self addChild:_text];
[self schedule:#selector(countDown:) interval:0.5f];// 0.5second intervals
}
return self;
}
-(void)countDown:(ccTime)delta {
self.countTime--;
[_text setString:[NSString stringWithFormat:#"%i", self.countTime]];
if (self.countTime <= 0) {
[self unschedule:#selector(countDown:)];
}
}
#end
Your count allways becomes 20 in your countDown.
You should also move this to your init:
CCLabel *text = [CCLabel labelWithString:#" "
fontName:#"BallsoOnTheRampage" fontSize:46];
text.position = ccp(160,455);
text.color = ccYELLOW;
[self addChild:text];
Then you should use:
[self schedule:#selector(countDown:) interval:1.0f];
Then instead of using CCLabel you should use CCLabelBMFont. It's much faster :)