0

I have used the tutorial from Here

and successfully made a similar puzzle game (with custom layout and imaged tiles)

My problem now is to recognize when the user finishes the puzzle..

I am and android developer, but this cocos2d is very new to me.

I have downloaded the source code to check what the writer of the tutorial have done to find when the user has finished the puzzle, but his code for this part is not working, and I need to find a way to check after every move if the user has finished or not.. if it were android I would not have any problem with it..

here is the relevant code:

public void generateTiles(){

    //We create a Node element to hold all our tiles
    CCNode tilesNode = CCNode.node();
    tilesNode.setTag(TILE_NODE_TAG);
    addChild(tilesNode);        
    float scalefactor ;   // a value we compute to help scale our tiles
    int useableheight  ;    
    int tileIndex = 0 ;

    //We attempt to calculate the right size for the tiles given the screen size and 
    //space left after adding the status label at the top
    int nextval ;

    int[] tileNumbers = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//{12,1,10,2,7,11,4,14,5,0,9,15,8,13,6,3};  //random but solvable sequence of numbers

    //TILE_SQUARE_SIZE = (int) ((screenSize.height  *generalscalefactor)/NUM_ROWS) ;
    int useablewidth = (int) (screenSize.width - statusLabel.getContentSize().width*generalscalefactor ) ;
    useableheight =  (int) (screenSize.height  - 40*generalscalefactor - statusLabel.getContentSize().height * 1.3f*generalscalefactor) ;

    TILE_SQUARE_SIZE = (int) Math.min((useableheight/NUM_ROWS) , (useablewidth/NUM_COLUMNS)) ;

    toppoint = (int) (useableheight  - (TILE_SQUARE_SIZE / 2) + 30*generalscalefactor)   ;
    scalefactor = TILE_SQUARE_SIZE / 125.0f ;

    topleft = (int) ((TILE_SQUARE_SIZE / 2) + 15*generalscalefactor) ;

    for (int j = toppoint ; j > toppoint - (TILE_SQUARE_SIZE * NUM_ROWS); j-= TILE_SQUARE_SIZE){
        for (int i = topleft ; i < (topleft - 5*generalscalefactor) + (TILE_SQUARE_SIZE * NUM_COLUMNS); i+= TILE_SQUARE_SIZE){

            if (tileIndex >= (NUM_ROWS * NUM_COLUMNS)) {
                break ;
            }
            nextval = tileNumbers[tileIndex ];

            //Generate tile by it's number and it's subfolder
            Tile tile = new Tile();
            tile.setIndex(nextval);
            tile.setSprite(CCSprite.sprite(subFolder+"/"+subFolder+"_tile_"+String.valueOf(nextval+1)+".jpg"));
            tiles.add(tile);
            //CCSprite tile = CCSprite.sprite(subFolder+"/"+subFolder+"_tile_"+String.valueOf(nextval+1)+".jpg");

            CCNodeExt eachNode =  new  CCNodeExt(); 
            eachNode.setContentSize(tile.getSprite().getContentSize());
            //
            //Layout Node based on calculated postion
            eachNode.setPosition(i, j);
            eachNode.setNodeText(nextval + "");

            //Add Tile number
            if(showNumbers == true)
            {
                CCBitmapFontAtlas tileNumber = CCBitmapFontAtlas.bitmapFontAtlas ("00", "bionic.fnt");
                tileNumber.setScale(1.4f);               
                eachNode.setScale(scalefactor);
                eachNode.addChild(tile.getSprite(),1,1);
                tileNumber.setString(nextval + ""); 
                eachNode.addChild(tileNumber,2 );
            }
            else
            {
                eachNode.setScale(scalefactor);
                eachNode.addChild(tile.getSprite(),1,1);
            }


            if( nextval != 0){
                tilesNode.addChild(eachNode,1,nextval);
            }else {
                emptyPosition = CGPoint.ccp(i, j);
            }

            //Add each Node to a HashMap to note its location
            tileIndex++;
        }
    } 

}


 @Override
public boolean ccTouchesBegan(MotionEvent event)
{
    //Get touch location cordinates
    CGPoint location = CCDirector.sharedDirector().convertToGL(CGPoint.ccp(event.getX(), event.getY()));
    CGRect spritePos ;

    CCNode tilesNode = (CCNode) getChildByTag(TILE_NODE_TAG) ;
    //ccMacros.CCLOG("Began", "Began : " + location.x + " :  "  );

    //We loop through each of the tiles and get its cordinates
    for (int i = 1 ; i < (NUM_ROWS * NUM_COLUMNS); i++){
        CCNodeExt eachNode = (CCNodeExt) tilesNode.getChildByTag(i) ;
        //Log.d(String.valueOf(eachNode), String.valueOf(tiles.get(i).getIndex()));

        //we construct a rectangle covering the current tiles cordinates
        spritePos = CGRect.make(
                eachNode.getPosition().x - (eachNode.getContentSize().width*generalscalefactor/2.0f),
                eachNode.getPosition().y - (eachNode.getContentSize().height*generalscalefactor/2.0f),
                eachNode.getContentSize().width*generalscalefactor   ,
                eachNode.getContentSize().height*generalscalefactor   );
        //Check if the user's touch falls inside the current tiles cordinates
        if(spritePos.contains(location.x, location.y)){
            //ccMacros.CCLOG("Began Touched Node", "Began touched : " + eachNode.getNodeText());
            slideCallback(eachNode); // if yes, we pass the tile for sliding.

        }
    }

    return true ;
}

 public void slideCallback(CCNodeExt thenode) {

    CGPoint nodePosition = thenode.getPosition();

    //Determine the position to slide the tile to .. ofcourse only if theres an empty space beside it

    if((nodePosition.x - TILE_SQUARE_SIZE)== emptyPosition.x && nodePosition.y == emptyPosition.y){
        slideTile("Left", thenode,true);
    }else if((nodePosition.x + TILE_SQUARE_SIZE) == emptyPosition.x && nodePosition.y == emptyPosition.y){
        slideTile("Right", thenode,true);
    }else if((nodePosition.x)== emptyPosition.x && nodePosition.y == (emptyPosition.y  + TILE_SQUARE_SIZE )){
        slideTile("Down", thenode,true);
    }else if((nodePosition.x )== emptyPosition.x && nodePosition.y == (emptyPosition.y  - TILE_SQUARE_SIZE)){ 
        slideTile("Up", thenode,true);
    }else{
        slideTile("Unmovable", thenode,false);
    }

}

public void slideTile(String direction, CCNodeExt thenode, boolean move){ 
    CCBitmapFontAtlas moveslabel = (CCBitmapFontAtlas) getChildByTag(MOVES_LABEL_TAG);

    if(move && !gameover){ 
        //  Increment the moves label and animate the tile
        moves ++ ;
        moveslabel.setString("Moves : " + CCFormatter.format("%03d", moves ));

        //Update statuslabel
        statusLabel.setString("Tile : " + thenode.getNodeText() + " -> " + direction);

        //Animate the tile to slide it
        CGPoint nodePosition = thenode.getPosition();
        //Log.d("current pos",String.valueOf(nodePosition));
        CGPoint tempPosition = emptyPosition ;
        //Log.d("go to pos",String.valueOf(tempPosition));
        CCMoveTo movetile = CCMoveTo.action(0.4f, tempPosition); 
        CCSequence movetileSeq = CCSequence.actions(movetile, CCCallFuncN.action(this, "handleWin"));
        thenode.runAction(movetileSeq);
        emptyPosition = nodePosition ;

        //Play a sound 
        appcontext = CCDirector.sharedDirector().getActivity();
        SoundEngine.sharedEngine().playEffect(appcontext, R.raw.tileclick);
        thenode.runAction(movetileSeq); 
    }else{ 
    }

}


public void handleWin(Object sender){
    if(checkCorrect()){
        gameover = true ;
        Log.d("Game "+String.valueOf(gameover), "VICTORY!");
        SoundEngine.sharedEngine().playEffect(appcontext, R.raw.tileclick);

        //WinCallback(sender);
    }
}

//This method checks if the puzzle has been correctly solved.
public boolean checkCorrect(){
    CCNode tileNode = (CCNode) getChildByTag(TILE_NODE_TAG);
    int nodeindex = 1 ;
    boolean result = false;

    int rowindex = 0 ;
    for (int j = toppoint ; j > toppoint - (TILE_SQUARE_SIZE * NUM_ROWS); j-= TILE_SQUARE_SIZE){
        for (int i = topleft ; i < (topleft - 5*generalscalefactor) + (TILE_SQUARE_SIZE * NUM_COLUMNS); i+= TILE_SQUARE_SIZE){
            Log.d(String.valueOf(tileNode.getChildByTag(nodeindex).getPosition().x), String.valueOf(tileNode.getChildByTag(nodeindex).getPosition().y));
            Log.d(String.valueOf(i), String.valueOf(j));

            if(tileNode.getChildByTag(nodeindex).getPosition().x == i && tileNode.getChildByTag(nodeindex).getPosition().y == j ){
                //Log.d(String.valueOf(tileNode.getChildByTag(nodeindex).getPosition().x), String.valueOf(tileNode.getChildByTag(nodeindex).getPosition().y));
                //Log.d(String.valueOf(i), String.valueOf(j));
                result = true ; 
                Log.d("Game "+String.valueOf(result), "result");

            }else{ 
                //Log.d("Game "+String.valueOf(false), "result");
                return false ;
            }
            nodeindex++ ;
            //Log.d("nodeindex "+String.valueOf(nodeindex), "index total");
            if(nodeindex == (NUM_ROWS * NUM_COLUMNS)){
                Log.d("Game "+String.valueOf(result), "result");
                return result ;
            }
        }


    }
    rowindex = 0 ;
    Log.d("Game "+String.valueOf(result), "result");
    return result ;
}

}

basically I just need the last method to be fixed for me, all of the other code is just for reference and understanding of the last needed part..

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
Matan Dahan
  • 390
  • 5
  • 10

1 Answers1

0

OK, since I have solved it, and I know it is kind of hard to get good examples and answers on this subject, I will share the solution here:

Add this line as global declaration:

//Array to hold the correct order of tiles so we can compare..
private ArrayList<Tile> tilesCompleted = new ArrayList<Tile>();

and change this method:

public void generateTiles(){

    //We create a Node element to hold all our tiles
    tilesNode.setTag(TILE_NODE_TAG);
    addChild(tilesNode);        
    float scalefactor ;   // a value we compute to help scale our tiles
    int useableheight  ;    
    int tileIndex = 0 ;

    //We attempt to calculate the right size for the tiles given the screen size and 
    //space left after adding the status label at the top
    int nextval ;

    //{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};//
    int[] tileNumbers = {12,1,10,2,7,11,4,14,5,0,9,15,8,13,6,3};  //random but solvable sequence of numbers

    //TILE_SQUARE_SIZE = (int) ((screenSize.height  *generalscalefactor)/NUM_ROWS) ;
    int useablewidth = (int) (screenSize.width - statusLabel.getContentSize().width*generalscalefactor ) ;
    useableheight =  (int) (screenSize.height  - 40*generalscalefactor - statusLabel.getContentSize().height * 1.3f*generalscalefactor) ;

    TILE_SQUARE_SIZE = (int) Math.min((useableheight/NUM_ROWS) , (useablewidth/NUM_COLUMNS)) ;

    toppoint = (int) (useableheight  - (TILE_SQUARE_SIZE / 2) + 30*generalscalefactor)   ;
    scalefactor = TILE_SQUARE_SIZE / 125.0f ;

    topleft = (int) ((TILE_SQUARE_SIZE / 2) + 15*generalscalefactor) ;

    for (int j = toppoint ; j > toppoint - (TILE_SQUARE_SIZE * NUM_ROWS); j-= TILE_SQUARE_SIZE){
        for (int i = topleft ; i < (topleft - 5*generalscalefactor) + (TILE_SQUARE_SIZE * NUM_COLUMNS); i+= TILE_SQUARE_SIZE){

            if (tileIndex >= (NUM_ROWS * NUM_COLUMNS)) {
                break ;
            }
            nextval = tileNumbers[tileIndex ];

            //Generate tile by it's number and it's subfolder
            Tile tile = new Tile();
            tile.setIndex(nextval);
            tile.setSprite(CCSprite.sprite(subFolder+"/"+subFolder+"_tile_"+String.valueOf(nextval+1)+".jpg"));
            tiles.add(tile);

                           //This is the solution
            if(tileIndex > 0)
            {
                tile.setPositionX(i);
                tile.setPositionY(j);
                tile.setIndex(tileIndex);
                tilesCompleted.add(tile);
            }
            else
                tilesCompleted.add(tile);
            //CCSprite tile = CCSprite.sprite(subFolder+"/"+subFolder+"_tile_"+String.valueOf(nextval+1)+".jpg");

            CCNodeExt eachNode =  new  CCNodeExt(); 
            eachNode.setContentSize(tile.getSprite().getContentSize());
            //
            //Layout Node based on calculated postion
            eachNode.setPosition(i, j);
            eachNode.setNodeText(nextval + "");

            //Add Tile number
            if(showNumbers == true)
            {
                CCBitmapFontAtlas tileNumber = CCBitmapFontAtlas.bitmapFontAtlas ("00", "bionic.fnt");
                tileNumber.setScale(1.4f);               
                eachNode.setScale(scalefactor);
                eachNode.addChild(tile.getSprite(),1,1);
                tileNumber.setString(nextval + ""); 
                eachNode.addChild(tileNumber,2 );
            }
            else
            {
                eachNode.setScale(scalefactor);
                eachNode.addChild(tile.getSprite(),1,1);
            }


            if( nextval != 0){
                tilesNode.addChild(eachNode,1,nextval);
            }else {
                emptyPosition = CGPoint.ccp(i, j);
            }

            //Add each Node to a HashMap to note its location
            tileIndex++;
        }
    } 

}

And now change this:

//This method checks if the puzzle has been correctly solved.
public boolean checkCorrect(){
    //CCNode tileNodes = (CCNode) getChildByTag(TILE_NODE_TAG);
    int nodeindex = 0 ;
    boolean result = false;

    int rowindex = 0 ;
    for (int j = toppoint ; j > toppoint - (TILE_SQUARE_SIZE * NUM_ROWS); j-= TILE_SQUARE_SIZE){

        if(nodeindex > 0)
        {
            //Log.d("y", String.valueOf(tilesNode.getChildByTag(nodeindex).getPosition().y));
            //Log.d("J", String.valueOf(tilesCompleted.get(nodeindex).getPositionY()));
        }
        for (int i = topleft ; i < (topleft - 5*generalscalefactor) + (TILE_SQUARE_SIZE * NUM_COLUMNS); i+= TILE_SQUARE_SIZE){
            if(nodeindex > 0)
            {
                //Log.d("x", String.valueOf(tilesNode.getChildByTag(nodeindex).getPosition().x));
                //Log.d("i", String.valueOf(tilesCompleted.get(nodeindex).getPositionX()));
            }
            if(nodeindex>0)
            {
            if(tilesNode.getChildByTag(nodeindex).getPosition().x == tilesCompleted.get(nodeindex).getPositionX()
                    && tilesNode.getChildByTag(nodeindex).getPosition().y == tilesCompleted.get(nodeindex).getPositionY()){
                //Log.d(String.valueOf(tileNode.getChildByTag(nodeindex).getPosition().x), String.valueOf(tileNode.getChildByTag(nodeindex).getPosition().y));
                //Log.d(String.valueOf(i), String.valueOf(j));
                result = true ; 
                Log.d("Game "+String.valueOf(result), "result");

            }else{ 
                //Log.d("Game "+String.valueOf(false), "result");
                return false ;
            }
            }
            nodeindex++ ;
            //Log.d("nodeindex "+String.valueOf(nodeindex), "index total");
            if(nodeindex == (NUM_ROWS * NUM_COLUMNS)){
                Log.d("Game "+String.valueOf(result), "result");
                return result ;
            }
        }


    }
    rowindex = 0 ;
    Log.d("Game "+String.valueOf(result), "result");
    return result ;
}

}

GOOD LUCK :)

Matan Dahan
  • 390
  • 5
  • 10