diff --git a/GameLayer.cpp b/GameLayer.cpp new file mode 100644 index 0000000..6758698 --- /dev/null +++ b/GameLayer.cpp @@ -0,0 +1,263 @@ +#include "GameLayer.h" + +#define MATRIX_WIDTH (9) +#define MATRIX_HEIGHT (9) + +#define SPIRTE_GAP (1) + +#define userDefault UserDefault::getInstance() + +int choices[2][6][2] = { + { + {1,-1},{1,0},{0,1},{-1,0},{-1,-1},{0,-1} + }, + { + {1,0},{1,1},{0,1},{-1,1},{-1,0},{0,-1} + } +}; + +GameLayer::GameLayer() + :m_exit(NULL), + m_matrix(NULL), + m_mark(NULL), + //spriteSheet(NULL), + m_width(0), + m_height(0), + m_isTouchEnable(true), + m_raindrop(NULL), + m_markSize(0) +{ + +} + +GameLayer::~GameLayer() +{ + if(m_matrix){ + free(m_matrix); + } + if(m_mark){ + free(m_mark); + } +} + +Scene *GameLayer::createScene() +{ + auto scene = Scene::create(); + auto layer = GameLayer::create(); + scene->addChild(layer); + return scene; +} +bool GameLayer::init() +{ + if (!Layer::init()) { + return false; + } + + // background + Size winSize = Director::getInstance()->getWinSize(); + auto background = Sprite::create("main_game/lawn.png"); + background->setAnchorPoint(Point(0, 1)); + background->setPosition(Point(0, winSize.height)); + this->addChild(background); + + m_height = MATRIX_HEIGHT; + m_width = MATRIX_WIDTH; + //初始化地图矩阵 + int arraySize = sizeof(SquareSprite *) * m_width * m_height; + m_matrix = (SquareSprite **)malloc(arraySize); + memset((void*)m_matrix, 0, arraySize); + //初始化标记数组 + m_markSize = sizeof(bool) * m_width * m_height; + m_mark = (bool*)malloc(m_markSize); + memset((void*)m_mark,false,m_markSize); + //初始化所有地图精灵 + for(int row = 0;rowsetPosition(position); + addChild(sprite,1); + m_matrix[row * m_width + col] = sprite; + } + } + //随机初始化云彩 + initCloud(); + //初始化小雨滴 + m_raindrop = Raindrop::create(4,4); + Point position = positionOfItem(4, 4); + m_raindrop->setPosition(position); + addChild(m_raindrop,2); + // bind touch event实现触摸效果 + auto touchListener = EventListenerTouchOneByOne::create(); + touchListener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); + + //响应键盘消息 + auto keyListener = EventListenerKeyboard::create(); + keyListener->onKeyReleased = CC_CALLBACK_2(GameLayer::onKeyReleased, this); + _eventDispatcher->addEventListenerWithSceneGraphPriority(keyListener, this); + + return true; +} +//得到坐标 +Point GameLayer::positionOfItem(int row, int col) +{ + float x = (SquareSprite::getContentWidth() + SPIRTE_GAP) * col + SquareSprite::getContentWidth() / 2; + float y = (SquareSprite::getContentWidth() + SPIRTE_GAP) * row + SquareSprite::getContentWidth() / 2 + 45; + if(row%2)//形成偏移的效果 + { + x = x+SquareSprite::getContentWidth() / 2; + } + return Point(x, y); +} +//响应安卓返回键 +void GameLayer::onKeyReleased(EventKeyboard::KeyCode keycode,Event* event) +{ + if(keycode == EventKeyboard::KeyCode::KEY_BACKSPACE) + { + /*Scene* newScene = Pause::createScene(); + Pause* layer = Pause::create(); + layer->scene_num = 1; + newScene->addChild(layer); + Director::sharedDirector()->pushScene(newScene);*/ + } +} +//获取点击事件 +bool GameLayer::onTouchBegan(Touch *touch, Event *unused) +{ + /* + if(exit) + { + exit->removeFromParentAndCleanup(true); + exit = NULL; + }*/ + //m_srcSushi = NULL; + if (m_isTouchEnable ) + { + //点击出现云彩 + auto location = touch->getLocation(); + SquareSprite* srcSprite = spriteOfPoint(&location); + if(srcSprite) + { + if(!srcSprite->getSelected())//未被选择过 + { + srcSprite->setSelected(true); + CCTexture2D * texture = CCTextureCache::sharedTextureCache()->addImage("block2.png"); + srcSprite->setTexture(texture); + moveRaindrop(); + } + } + } + return m_isTouchEnable; +} +//得到点击了哪个格子 +SquareSprite *GameLayer::spriteOfPoint(Point *point) +{ + SquareSprite *sprite = NULL; + Rect rect = Rect(0, 0, 0, 0); + + for (int i = 0; i < m_height * m_width; i++) { + sprite = m_matrix[i]; + if (sprite) { + rect.origin.x = sprite->getPositionX() - (sprite->getContentSize().width / 2); + rect.origin.y = sprite->getPositionY() - (sprite->getContentSize().height / 2); + rect.size = sprite->getContentSize(); + //修改,空隙也属于精灵的一部分 + rect.size.height += SPIRTE_GAP; + rect.size.width += SPIRTE_GAP; + if (rect.containsPoint(*point)) { + return sprite; + } + } + } + return NULL; +} +//随机初始化云彩 +void GameLayer::initCloud() +{ + srand(time(NULL)); + //初始化云彩的数量 + int num = rand()%14 + 7; + //初始化云彩的位置 + while(num--) + { + int col = rand()%9; + int row = rand()%9; + if(col != 4 && row != 4) + { + SquareSprite* srcSprite = m_matrix[row*MATRIX_WIDTH + col]; + srcSprite->setSelected(true); + CCTexture2D * texture = CCTextureCache::sharedTextureCache()->addImage("block2.png"); + srcSprite->setTexture(texture); + } + } +} +//移动雨滴 +void GameLayer::moveRaindrop() +{ + SquareSprite* next; + int row = m_raindrop->getRow(); + int col = m_raindrop->getCol(); + int bestWay = 81; + int odd = row%2; + for(int i = 0;i<6;++i) + { + memset((void*)m_mark,false,m_markSize); + int next_row = row + choices[odd][i][0]; + int next_col = col + choices[odd][i][1]; + SquareSprite* next_sprite = m_matrix[next_row*MATRIX_WIDTH + next_col]; + if(next_sprite->getSelected())//已经变成云了 + { + continue; + } + else + { + int result = findWay(next_row,next_col,1); + if(result != -1) + { + if(result < bestWay) + { + bestWay = result; + next = next_sprite; + } + } + } + } + m_raindrop->runAction(MoveTo::create(0.3, next->getPosition())); + m_raindrop->setCol(next->getCol()); + m_raindrop->setRow(next->getRow()); +} +//雨滴的逃生路线 +int GameLayer::findWay(int row,int col,int result) +{ + m_mark[row*m_width+col] = true; + int odd = row%2; + int best_way = 81; + if(col <= 0 || col >= 8 || row <= 0 || row >= 8){ //走到终点 + return result; + } + for(int i = 0;i<6;++i) + { + int next_row = row + choices[odd][i][0]; + int next_col = col + choices[odd][i][1]; + SquareSprite* next_sprite = m_matrix[next_row*MATRIX_WIDTH + next_col]; + if(next_sprite->getSelected() || m_mark[next_row*m_width+next_col])//已经变成云了 + { + continue; + } + else + { + int res = findWay(next_row,next_col,result+1); + if(res != -1) + { + if(res < best_way) + { + best_way = res; + } + } + } + } + return best_way; +} \ No newline at end of file diff --git a/GameLayer.h b/GameLayer.h new file mode 100644 index 0000000..03a15c0 --- /dev/null +++ b/GameLayer.h @@ -0,0 +1,43 @@ +#ifndef __GAMELAYER_H__ +#define __GAMELAYER_H__ + +#include "cocos2d.h" +#include "SquareSprite.h" +#include "Raindrop.h" + +USING_NS_CC; + +class GameLayer : public Layer +{ +public: + GameLayer(); + ~GameLayer(); + static Scene* createScene(); + CREATE_FUNC(GameLayer); + + virtual bool init() override; + virtual bool onTouchBegan(Touch *touch, Event *unused) override; + virtual void onKeyReleased(EventKeyboard::KeyCode keycode,Event* event)override; + + void ReturnToMainFunc(cocos2d::Ref* pSender); +private: + //返回键弹窗 + LabelTTF * m_exit; + //保存指向所有方格精灵的指针 + SquareSprite ** m_matrix; + //标记,一次选路过程中是否找过该精灵 + bool * m_mark; + //SpriteBatchNode *spriteSheet; + int m_width; + int m_height; + bool m_isTouchEnable; + Raindrop* m_raindrop; + int m_markSize; + + Point positionOfItem(int row, int col); + int findWay(int row,int col,int result); + SquareSprite *GameLayer::spriteOfPoint(Point *point); + void initCloud(); + void moveRaindrop(); +}; +#endif /* defined(__GAMELAYER_H__) */ \ No newline at end of file diff --git a/HelloWorldScene.cpp b/HelloWorldScene.cpp index 911f4bc..4f0e3d3 100644 --- a/HelloWorldScene.cpp +++ b/HelloWorldScene.cpp @@ -31,6 +31,19 @@ bool HelloWorld::init() this->addChild(Background); //触摸效果开启 this->setTouchEnabled(true); + + //冒险模式 + auto item_Adventure = MenuItemImage::create( + "menu/play1.png", + "menu/play2.png", + CC_CALLBACK_1(HelloWorld::startGame, this)); + item_Adventure->setPosition(ccp(0,50)); + //关于界面 + auto item_About= MenuItemImage::create( + "menu/about1.png", + "menu/about2.png", + CC_CALLBACK_1(HelloWorld::startGame, this)); + item_About->setPosition(ccp(120,-200)); //播放背景音乐 if(!userDefault->getBoolForKey("Music")){ userDefault->getBoolForKey("Music",true); @@ -46,8 +59,8 @@ bool HelloWorld::init() //声音开关 //打开关闭两个状态 - auto on = MenuItemImage::create("menu/voice1.png","menu/voice1.png",NULL,NULL); - auto off = MenuItemImage::create("menu/voice3.png","menu/voice3.png",NULL,NULL); + auto on = MenuItemImage::create("menu/voice1.png","menu/voice2.png",NULL,NULL); + auto off = MenuItemImage::create("menu/voice3.png","menu/voice4.png",NULL,NULL); //初始化状态为1 MenuItemToggle *item_Voice; int selectId; @@ -67,7 +80,7 @@ bool HelloWorld::init() item_Voice->setSelectedIndex(selectId); item_Voice->setPosition(ccp(-120,-200)); - CCMenu* menu = CCMenu::create(item_Voice,NULL); + CCMenu* menu = CCMenu::create(item_Adventure,item_Voice,item_About,NULL); this->addChild(menu); //响应键盘消息 @@ -82,7 +95,13 @@ bool HelloWorld::init() return true; } -//声音选项,把用户的选择存储在后台 +//开始游戏按键的回调函数 +void HelloWorld::startGame(cocos2d::Ref* pSender) +{ + CCLOG("dventure_Menu item clicked"); + CCDirector::sharedDirector()->replaceScene(GameLayer::createScene()); +} +//声音按键的回调函数,把用户的选择存储在后台 void HelloWorld::setOptions(cocos2d::Ref* pSender) { bool temp = userDefault->getBoolForKey("Music"); diff --git a/HelloWorldScene.h b/HelloWorldScene.h index 5420793..45989a5 100644 --- a/HelloWorldScene.h +++ b/HelloWorldScene.h @@ -3,6 +3,7 @@ #include "cocos2d.h" #include "SimpleAudioEngine.h" +#include "GameLayer.h" USING_NS_CC; @@ -14,6 +15,9 @@ class HelloWorld : public cocos2d::Layer void menuCloseCallback(cocos2d::Ref* pSender); CREATE_FUNC(HelloWorld); + //开始按键的回调函数 + void startGame(cocos2d::Ref* pSender); + //声音按键的回调函数 void setOptions(cocos2d::Ref* pSender); //响应安卓返回键 virtual void onKeyReleased(EventKeyboard::KeyCode keycode,Event* event)override; diff --git a/Raindrop.cpp b/Raindrop.cpp new file mode 100644 index 0000000..553e922 --- /dev/null +++ b/Raindrop.cpp @@ -0,0 +1,13 @@ +#include "Raindrop.h" + +USING_NS_CC; + +Raindrop *Raindrop::create(int row, int col) +{ + Raindrop *square = new Raindrop(); + square->m_row = row; + square->m_col = col; + square->initWithFile("block3.png"); + square->autorelease(); + return square; +} \ No newline at end of file diff --git a/Raindrop.h b/Raindrop.h new file mode 100644 index 0000000..99e3f7c --- /dev/null +++ b/Raindrop.h @@ -0,0 +1,18 @@ +#ifndef __Raindrop_H__ +#define __Raindrop_H__ + +#include "cocos2d.h" + +USING_NS_CC; + +class Raindrop : public Sprite +{ +public: + static Raindrop *create(int row, int col); + + //雨滴所在的行列数 + CC_SYNTHESIZE(int, m_row, Row); + CC_SYNTHESIZE(int, m_col, Col); +}; + +#endif /* defined(__Raindrop_H__) */ diff --git a/SquareSprite.cpp b/SquareSprite.cpp new file mode 100644 index 0000000..b39e734 --- /dev/null +++ b/SquareSprite.cpp @@ -0,0 +1,29 @@ +#include "SquareSprite.h" +#include + +USING_NS_CC; + + +float SquareSprite::getContentWidth() +{ + static float itemWidth = 0; + if (0 == itemWidth) { + CCTexture2D * texture = CCTextureCache::sharedTextureCache()->addImage("block1.png"); + Sprite *sprite = CCSprite::createWithTexture(texture); + itemWidth = sprite->getContentSize().width; + } + return itemWidth; +} + +SquareSprite *SquareSprite::create(int row, int col) +{ + SquareSprite *square = new SquareSprite(); + square->m_row = row; + square->m_col = col; + square->m_selected = false; + //sushi->m_imgIndex = rand() % TOTAL_SUSHI; + //square->initWithSpriteFrameName("block1.png"); + square->initWithFile("block1.png"); + square->autorelease(); + return square; +} \ No newline at end of file diff --git a/SquareSprite.h b/SquareSprite.h new file mode 100644 index 0000000..01f2060 --- /dev/null +++ b/SquareSprite.h @@ -0,0 +1,30 @@ +#ifndef __SquareSprite_H__ +#define __SquareSprite_H__ + +#include "cocos2d.h" + +USING_NS_CC; + +typedef enum { + DISPLAY_MODE_NORMAL = 0, + DISPLAY_MODE_HORIZONTAL, + DISPLAY_MODE_VERTICAL, +} DisplayMode; + + +class SquareSprite : public Sprite +{ +public: + static SquareSprite *create(int row, int col); + static float getContentWidth(); + + //精灵所在的行列数 + CC_SYNTHESIZE(int, m_row, Row); + CC_SYNTHESIZE(int, m_col, Col); + //是否被选中 + CC_SYNTHESIZE(bool,m_selected,Selected); + //CC_SYNTHESIZE_READONLY(DisplayMode, m_displayMode, DisplayMode); + //void setDisplayMode(DisplayMode mode); +}; + +#endif /* defined(__SquareSprite_H__) */