teach_0402

前言

會寫這篇文章主要是看到網路上有人詢問控制CCSprite的問題,想寫個類似Candy Crash置換圖片的控制。提到是否有效能比較好的作法!我個人是覺得不要一個一個pixel去拜訪效能就不會太差。這次寫一個簡易版的,測試結果還蠻順的啊,提供給大家參考參考。

 

執行結果

點選一個Candy,再拉到另一個Cindy,放手之後就會移動嚕。

teach_0401
初始畫面

teach_0402
點選(1,0)與(1,1)的方塊

teach_0403
置換後

 

開發環境

作業系統:Win7

開發工具:VC Express 2010

Cocos2dx版本:2.1.beta3

 

出發~HelloCpp,環境的設定

這次一樣拿HelloCpp專案修改,先設定一些環境,開啟HelloWorldScene.h,新增一下下面的設定,後面的程式寫起來才比較乾淨。

#ifndef __HELLOWORLD3_SCENE_H__
#define __HELLOWORLD3_SCENE_H__

#include "cocos2d.h"
using namespace cocos2d;

 

新增一下 using namespace cocos2d; 這樣後續宣告變數時,有關于cocos2d的型別就不用前面再加 cocos2d:: ,程式碼看起來就會比較舒服。

 

再來,定義一下我們要放置旗盤的大小,這次設定成5x5的盤。設定成有5種類型的candy。

#ifndef __HELLOWORLD3_SCENE_H__
#define __HELLOWORLD3_SCENE_H__

#include "cocos2d.h"
using namespace cocos2d;
#define MAX_ROW 5
#define MAX_COL    5
#define NUM_OF_CANDY MAX_ROW*MAX_COL
#define MAX_TYPE 5 //紅黃綠藍澄

MAX_ROW 表示有5列,MAX_COL表示有5行,所以總共可以放25個Candy(NUM_OF_CANDY),MAX_TYOE是假設Candy分別為紅黃綠藍澄這五種。

 

 

宣告,一堆Candy的變數

在HelloWorld類別中,新增放至Candy圖片的變數,大小就是總Candy數大小。

CCSprite*    m_apImgBlock[NUM_OF_CANDY];

 

 

定義Candy位置

這次先把各位置Candy作標訂好,在Create時就可以方便取用。開啟HelloWorldScene.cpp,在檔案上頭我們定義位置如下

#include "HelloWorldScene3.h"
#include "AppMacros.h"
#include "base64.h"
USING_NS_CC;

float g_afPosX[MAX_COL]={
    145, 199, 253, 308, 361
};

float g_afPosY[MAX_ROW]={
    244, 190, 137,  84,  31
};

 

 

Create Candy
開啟HelloWorldScene.cpp,編輯init(),新增create sprite的內容

// on "init" you need to initialize your instance
bool HelloWorld3::init()
{
    //以上省略

    //--------------------
    // Blocks create
    for(int c=0;c<MAX_COL;c++)
    {
        for(int r=0;r<MAX_ROW;r++)
        {
            int iSeed = rand()%MAX_TYPE;
            char acName[20];
            memset(acName,0,sizeof(acName));
            sprintf(acName,"BLOCK%02d.jpg",iSeed+1);
            m_apImgBlock[(r*MAX_COL)+c] = CCSprite::create(acName);
            m_apImgBlock[(r*MAX_COL)+c]->setAnchorPoint(ccp(0,0));
            m_apImgBlock[(r*MAX_COL)+c]->setPosition(ccp(g_afPosX[c],g_afPosY[r]));
            this->addChild(m_apImgBlock[(r*MAX_COL)+c]);
        }
    }
 
    return true;
}

 說明一下,我們隨機rand出25個candy,五個Candy圖檔分別為"BLOCK01.jpg"~"BLOCK05.jpg"。在設定setPosition時,我們將剛剛定義的位置放進去。

 

 

第一次的執行結果

寫好之後Run一下,可以得到結果如下。

teach_0401  

 

 

觸碰環境設置

回到HelloWorldScene.h,要宣告一些觸碰處理的虛擬函數讓我們overwrite它們。

    // 觸碰處理
    void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
    void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
    void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);

 

這時候我們還需要兩個變數,一個記錄點到candy的索引,另一個記錄目標轉換的candy的索引。分別為m_iStIdx與m_iEdIdx。

    // 觸碰處理
    void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
    void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
    void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);

    int            m_iStIdx;
    int            m_iEdIdx;
    CCSprite*    m_apImgBlock[NUM_OF_CANDY];

 

實作控制

至HelloWorldScene.h,立即實作virtual function。

void HelloWorld3::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( pTouches->anyObject() );
    CCPoint location = touch->locationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    //--------------------
    // Blocks process
    for(int i=0;i<NUM_OF_CANDY;i++)
    {
        if(m_apImgBlock[i]->numberOfRunningActions()>0) return;
    }

    m_iStIdx=-1;
    m_iEdIdx=-1;
    for(int c=0;c<MAX_COL;c++)
    {
        for(int r=0;r<MAX_ROW;r++)
        {
            CCRect rect = m_apImgBlock[(r*MAX_COL)+c]->boundingBox();
            if(rect.containsPoint(location))
            {
                CCLog("click block begin %d",(r*MAX_COL)+c);
                m_iStIdx=(r*MAX_COL)+c;
                break;
            }
        }
    }
}

..

void HelloWorld3::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( pTouches->anyObject() );
    CCPoint location = touch->locationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    //--------------------
    // Blocks process
    if((m_iStIdx<0)||(m_iEdIdx>=0)) return;
    CCRect rectSrc = m_apImgBlock[m_iStIdx]->boundingBox();
    if(!rectSrc.containsPoint(location)){
        for(int c=0;c<MAX_COL;c++){
            for(int r=0;r<MAX_ROW;r++){
                CCRect rect = m_apImgBlock[(r*MAX_COL)+c]->boundingBox();
                if(rect.containsPoint(location)){
                    CCLog("click block end %d",(r*MAX_COL)+c);
                    m_iEdIdx=(r*MAX_COL)+c;
                    break;
                }
            }
        }
    }
}

..

void HelloWorld3::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
    CCTouch* touch = (CCTouch*)( pTouches->anyObject() );
    CCPoint location = touch->locationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    //--------------
    // change position
    if((m_iStIdx>=0)&&(m_iEdIdx>=0))
    {
        CCPoint p1 = m_apImgBlock[m_iStIdx]->getPosition();
        CCPoint p2 = m_apImgBlock[m_iEdIdx]->getPosition();

        m_apImgBlock[m_iStIdx]->runAction(CCMoveTo::create(0.5f,p2));
        m_apImgBlock[m_iEdIdx]->runAction(CCMoveTo::create(0.5f,p1));
    }

    m_iStIdx=-1;
    m_iEdIdx=-1;
}

 

 

最後Run一下,點選一個Candy,再拉到另一個Cindy,放手之後就會移動嚕。時間問題來不及寫清楚最後一段的說明,之後會補上更新。

 

 

 

 

 

 

全站熱搜

巴比特 發表在 痞客邦 留言(0) 人氣()