做这个游戏的时候,我大二,那时还不会用git, 项目代码什么的都给压缩存到了百度云里,现在有了自己的github账号,代码资源什么的就都有啦。需要的可以自己去clone, 地址在这里:大兵小将

一:概述

我们组C++课设游戏:大兵小将,是通过cocos2d-x3.0用C++语言编写的,它是根据一个童年时自己玩的一款游戏改编而来的,即小兵围大炮。打开过渡游戏界面,你会看到可爱的Q版明星,界面上有三个按钮:进入游戏,游戏规则和退出。其中进入游戏和游戏规则这两个按钮居于页面中间,退出游戏的按钮则位于右下角。点击规则按钮,你会进入到相应的页面,这里有专门为初玩者准备的详细游戏规则,通过它,你可以迅速了解掌握这个小游戏的玩法。然后点击游戏规则页面的返回按钮,返回到过渡页面,点击开始游戏按钮,你将进入简洁明了的游戏界面。该界面由一个棋盘和三个按钮,以及一张古香古色的背景图构成。选择角色之后,就可以进入游戏了。

二:游戏介绍

大兵小将这个游戏是属于棋盘类游戏。棋子个数:将共18枚,兵共2枚。游戏规则:玩家先选定兵或将的角色,每局由兵先开始。兵和将每次只能移动一格。当兵和将中间隔一格时,兵可以吃掉将。当兵把将全部吃掉时,兵获胜。当将把全部兵围困住,让兵无法移动时,将获胜。

三:游戏算法代码实现:

3.1主菜单

3.1.1创建主菜单场景:

Scene* HelloWorld::createScene()
{// 'scene' is an autorelease objectauto scene = Scene::create();// 'layer' is an autorelease objectauto layer = HelloWorld::create();// add layer as a child to scenescene->addChild(layer);// return the scenereturn scene;
}

3.1.2.对场景进行初始化,添加按钮

bool HelloWorld::init()
{// 1. super init firstif ( !Layer::init() ){return false;}//获取整个手机可视屏幕尺寸Size visibleSize = Director::getInstance()->getVisibleSize(); //获取手机可视屏原点的坐标 Point origin = Director::getInstance()->getVisibleOrigin();//创建一个带图标的按钮//点击后调用menuCloseCallback方法退出游戏 auto closeItem = MenuItemImage::create("kaishi.png","kaishi1.png",CC_CALLBACK_1(HelloWorld::GameShow, this)); closeItem->setPosition(Point(400, 320));auto closeItem1= MenuItemImage::create("guize.png","guize1.png",CC_CALLBACK_1(HelloWorld::GameRule, this));closeItem1->setPosition(Point(410, 200));//创建一个带图标的按钮//点击后调用menuCloseCallback方法退出游戏 auto closeItem2 = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));//设置按钮的显示位置//显示在可视屏幕的右下角 closeItem2->setPosition(Point(origin.x + visibleSize.width - closeItem2->getContentSize().width / 2,origin.y + closeItem2->getContentSize().height / 2));//创建一个可释放的菜单 auto menu = Menu::create(closeItem, closeItem1, closeItem2, NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);//创建一个显示"Little Big Soldier"文字的Labelauto label = LabelTTF::create("Little Big Soldier", "Arial", 24);//position the label on the center of the screenlabel->setPosition(Point(origin.x + visibleSize.width/2,origin.y + visibleSize.height - label->getContentSize().height));// add the label as a child to this layerthis->addChild(label, 1);auto bg = Sprite::create("_jiemian.png");bg->setPosition(Point(400,261));//bg->setContentSize(Size(11,16));addChild(bg);return true;
}

3.1.3.跳转到游戏界面

void HelloWorld::GameShow(Ref* pSender)
{auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(MyScene::create());//把创建的画面层添加到场景中Director::getInstance()->pushScene(TransitionFlipAngular::create(.5, scene));//运用导演类来进行切换场景
}

3.1.4.跳转到规则界面

void HelloWorld::GameRule(Ref* pSender)
{auto scene1 = Scene::create();//创建一个自释放的场景对象scene1->addChild(MyRule::create());//把创建的画面层添加到场景中Director::getInstance()->pushScene(TransitionFlipAngular::create(.5, scene1));//运用导演类来进行切换场景
}

3.1.5.退出按钮事件

void HelloWorld::menuCloseCallback(Ref* pSender)
{
//当是wp8或者winrt平台的时候
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");return;
#endif
//结束DirectorDirector::getInstance()->end();
//当是ios平台的时候退出
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)exit(0);
#endif
}

3.2游戏规则页面

3.2.1.创建规则页面的场景

Scene* MyRule::createScene()
{auto scene1 = Scene::create();auto layer = MyRule::create();scene1->addChild(layer);return scene1;
}

3.2.2.对规则层进行初始化

 bool MyRule::init()
{if (!Layer::init()){return false;}Sprite *guize = Sprite::create("guize.jpg");//括号里面是图片的路径guize->setPosition(Point(400, 261));addChild(guize);auto closeItem = MenuItemImage::create("back.png","back1.png",CC_CALLBACK_1(MyRule::Back, this));closeItem->setPosition(Point(300,35));auto menu = Menu::create(closeItem,NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);}

3.2.3.在规则层里返回到主界面的回调函数

<pre name="code" class="cpp">void MyRule::Back(Ref* pSender)
{/*auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(HelloWorld::create());//把创建的画面层添加到场景中Director::getInstance()->replaceScene(TransitionFlipAngular::create(.5, scene));//运用导演类来进行切换场景 */Director::getInstance()->popScene();
}

3.3游戏页面

3.3.1.创建游戏主界面的场景

Scene* MyScene::createScene()
{auto scene = Scene::create();auto layer = MyScene::create();scene->addChild(layer);return scene;
}

3.3.2.对棋盘场景进行初始化

/*
我们的棋盘是6*6的。所以呢就用一个二维数组来标记棋盘上的每一个点的状态。每一个点又有两个属性。一个是value标记该点上是否有棋子,如果有的话是兵还是将,另一个是id标记该value下的第几个精灵。
struct node
{int value, id;//value为0,id为1到18是将,value为1,id为0到1,是兵,value为2,id为0是空
};棋子分两种,一种是兵,一种是将。则分别定义两个精灵数组即可。Sprite* pos[18];//将Sprite* bing[2];//兵还有一个精灵不算棋子但是也是棋盘上的一个精灵。就是选择框。一般情况下该精灵隐身,当某个可以被选的棋子被选中时,该选择框就显示在该棋子上。
Sprite* selectSprite;刚开始的时候两个兵位于下方中间,18个将位于前三行。选择框隐身并给棋盘标记赋相应的值。标记该兵走,num_jiang记录将的数量,以便判断输赢。
*/
bool MyScene::init()
{if (!Layer::init()){return false;}//预加载背景音乐SimpleAudioEngine::getInstance()->preloadBackgroundMusic("MyMusic/firework.mp3");Sprite *bj = Sprite::create("bj.png");//括号里面是图片的路径bj->setPosition(Point(400, 261));addChild(bj);Sprite *qipan = Sprite::create("__qipan.png");//括号里面是图片的路径qipan->setPosition(Point(280,261));addChild(qipan);bing[0] = Sprite::create("bing.png");//括号里面是图片的路径bing[0]->setPosition(Point(70 + 2 * 84, 471 - 5 * 84));addChild(bing[0]);bing[1] = Sprite::create("bing.png");//括号里面是图片的路径bing[1]->setPosition(Point(70 + 3 * 84, 471 - 5 * 84));addChild(bing[1]);Sprite *an = Sprite::create("an.png");//括号里面是图片的路径an->setPosition(Point(620, 190));addChild(an);auto closeItem= MenuItemImage::create("xin.png","xin1.png",CC_CALLBACK_1(MyScene::GameAgain, this));closeItem->setPosition(Point(620,410));auto closeItem1 = MenuItemImage::create("fan.png","fan1.png",CC_CALLBACK_1(MyScene::GameBack, this));closeItem1->setPosition(Point(620, 300));auto musicOnMenuItem = MenuItemImage::create("on.png","on.png");auto musicOffMenuItem = MenuItemImage::create("off.png","off.png");auto musicToggleMenuItem = MenuItemToggle::createWithCallback(CC_CALLBACK_1(MyScene::menuMusicToggleCallback, this),musicOffMenuItem,musicOnMenuItem,NULL);musicToggleMenuItem->setPosition(Point(618, 194));auto menu = Menu::create(closeItem, closeItem1, musicToggleMenuItem, NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);for (int i = 1; i <= 6; i++){for (int j = 1; j <= 6; j++){vis[i][j].id = 0;vis[i][j].value = 2;}}for (int i = 0; i < 18; i++)pos[i] = Sprite::create("jiang.png");for (int i = 1,k=0, x = 70; i <= 6; i++, x += 84){for (int j = 1, y = 471; j <= 3; j++, y -= 84){//pos[k] = Sprite::create("jiang.png");pos[k]->setPosition(Point(x, y));addChild(pos[k]);vis[i][7 -j].id = k++;vis[i][7 - j].value = 0;}}num_jiang = 18;//记录将的数量TurnBing = 1;//是否该兵走selected = false;//是否选择了棋子vis[3][1].value = vis[4][1].value = 1;vis[3][1].id = 0, vis[4][1].id = 1;//设置选择框 selectSprite = Sprite::create("selected.png");this->addChild(selectSprite);selectSprite->setVisible(false);selectSprite->setPosition(Point(70,471));
//  selectSprite->setZOrder(1000);// vis[6][1].id = vis[6][3].id = vis[6][2].id = 0;
//  vis[6][1].value = vis[6][2].value = vis[6][3].value = 2;for (int i = 1; i <= 6;i++)for (int j = 1; j <= 6; j++)log("%d %d %d %d", i, j, vis[i][j].value, vis[i][j].id);//注册触摸事件auto listeren = EventListenerTouchOneByOne::create();listeren->onTouchBegan = [=](Touch *touch, Event *even){this->ccTouchesBegan(touch, even);return true;};_eventDispatcher->addEventListenerWithSceneGraphPriority(listeren, this);return true;}

3.3.3.通过触摸点下标,确定是否为选中点

void MyScene::ccTouchesBegan(Touch *touch, Event *event)
{Point p = touch->getLocationInView();int x, y;//触摸点下标(vis)if (!getPos(p,x,y))//如果没点在交点{return ;}log("%d %d %d %d", x, y,vis[x][y].id,vis[x][y].value);if (false == selected){if (vis[x][y].value == TurnBing)select(x, y);return;}else {if (x == selected_x&&y == selected_y){selectSprite->setVisible(false);selected = false;}elsemove(x, y);}return ;
}

3.3.4点击就记录选中点

void MyScene::select(int x1, int y1)//点击并记录
{selected_x = x1;selected_y = y1;this->selected = true;selectSprite->setVisible(true);selectSprite->setPosition(Point(70 + (x1 - 1) * 84, 471 - (6-y1) * 84));
}

3.3.5.确定点击是否有效,设定一定的范围,鼠标点击在此范围内才可以选中交点作为棋子的位置

bool MyScene::getPos(Point p, int &x, int &y)
{for (x = 1; x <= 6; x++){for (y = 1; y <= 6; y++){if (abs(70+(x-1)*84,p.x)<30 &&abs(471-(6-y)*84,533-p.y)<30)return true;}}return false;
}

3.3.6.移动棋子

void MyScene::move(int x, int y)
{MoveTo *mt = MoveTo::create(0.2, Point(70 + (x - 1) * 84, 533-(471 - (y - 1) * 84)));//移动if (vis[selected_x][selected_y].value == vis[x][y].value)//如果点击同种类型的棋子{select(x, y);return;}if (vis[x][y].value == 2 && (((abs(selected_x, x) == 1 && abs(selected_y, y) == 0) || (abs(selected_x, x) == 0 && abs(selected_y, y) == 1))))//可以移动{selected = false;selectSprite->setVisible(false);switch (vis[selected_x][selected_y].value){case 1:bing[vis[selected_x][selected_y].id]->runAction(mt);vis[x][y].value = 1;vis[x][y].id = vis[selected_x][selected_y].id;break;case 0:pos[vis[selected_x][selected_y].id]->runAction(mt);vis[x][y].value = 0;vis[x][y].id = vis[selected_x][selected_y].id;break;}vis[selected_x][selected_y].value = 2;vis[selected_x][selected_y].id = 0;TurnBing = !TurnBing;if (JudgeWin())GameAgain(this);return;}else if(vis[selected_x][selected_y].value == 1 && vis[x][y].value == 0 && JudgeKill(selected_x, selected_y, x, y))//吃子{selected = false;selectSprite->setVisible(false);removeChild(pos[vis[x][y].id]);bing[vis[selected_x][selected_y].id]->runAction(mt);vis[x][y].value = 1;vis[x][y].id = vis[selected_x][selected_y].id;vis[selected_x][selected_y].value = 2;vis[selected_x][selected_y].id = 0;TurnBing = !TurnBing;num_jiang--;if (JudgeWin())GameAgain(this);return;}elsereturn;
}

3.3.7.判断输赢,当兵被将团团围住,兵无法移动,无路可走时,判将赢。当将被兵杀得只剩三个以下的时候,将无法把兵围住,此时即可判兵赢。

bool MyScene::JudgeWin()//判断输赢
{int i, j;if (!num_jiang){MessageBox("Bing is succeessfully", "Alert");return true;}for ( i = 1; i <= 6; i++){for ( j = 1; j <= 6; j++){if (vis[i][j].value == 1 && (vis[i - 1][j].value == 2 || vis[i + 1][j].value == 2 || vis[i][j + 1].value == 2 || vis[i][j - 1].value == 2))break;}if (j <=6)break;}if (i > 6 && j > 6){MessageBox("Jiang is succeessfully", "Alert");return true;}return false;
}

3.3.8.判断指定兵是否能杀指定将

bool MyScene::JudgeKill(int x1, int y1, int x2, int y2)
{if (x1 - x2 == 2 && abs(y1, y2) == 0 && vis[x2 + 1][y1].value == 2)return true;if (x2 - x1 == 2 && abs(y1, y2) == 0 && vis[x1 + 1][y1].value == 2)return true;if (y1 - y2 == 2 && abs(x1, x2) == 0 && vis[x1][y2 + 1].value == 2)return true;if (y2 - y1 == 2 && abs(x1, x2) == 0 && vis[x1][y1 + 1].value == 2)return true;return false;
}

3.3.9.求绝对值函数

int MyScene::abs(int x, int y)
{return x > y ? x - y : y - x;
}

3.3.10.新局回调函数

void MyScene::GameAgain(Ref* pSender)
{auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(MyScene::create());//把创建的画面层添加到场景中Director::getInstance()->replaceScene(TransitionFadeDown::create(.5, scene));//运用导演类来进行切换场景 /*this->removeAllChildren();this->init();*/
}

3.3.11.返回到主菜单界面

void MyScene::GameBack(Ref* pSender)
{auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(HelloWorld::create());//把创建的画面层添加到场景中Director::getInstance()->replaceScene(TransitionFadeDown::create(.5, scene));//运用导演类来进行切换场景 /*Director::getInstance()->popScene();*/
}

3.3.12.控制音乐的开关

void MyScene::menuMusicToggleCallback(Ref* pSender)
{auto musicToggleMenuItem = (MenuItemToggle*)pSender;log("musicToggleMenuItem %d", musicToggleMenuItem->getSelectedIndex());if (musicToggleMenuItem->getSelectedIndex() == 1) {//选中状态Off -> On                 SimpleAudioEngine::getInstance()->playBackgroundMusic("MyMusic/firework.mp3");}else {SimpleAudioEngine::getInstance()->stopBackgroundMusic("MyMusic/firework.mp3");}
}

四,代码汇总

三个界面,一个窗口,共八个文件

4.1AppDelegate.cpp

#include "AppDelegate.h"
#include "HelloWorldScene.h"
#include "pan.h"
#include "guize.h"USING_NS_CC;AppDelegate::AppDelegate() {}AppDelegate::~AppDelegate()
{
}bool AppDelegate::applicationDidFinishLaunching() {// initialize directorauto director = Director::getInstance();auto glview = director->getOpenGLView();if(!glview) {glview = GLView::create("My Game");glview->setFrameSize(800, 533);director->setOpenGLView(glview);}// turn on display FPSdirector->setDisplayStats(false);// set FPS. the default value is 1.0/60 if you don't call thisdirector->setAnimationInterval(1.0 / 60);// create a scene. it's an autorelease objectauto scene =HelloWorld::createScene();// rundirector->runWithScene(scene);// create a scene. it's an autorelease objectauto scene1 = HelloWorld::createScene();// rundirector->runWithScene(scene1);return true;
}// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {Director::getInstance()->stopAnimation();// if you use SimpleAudioEngine, it must be pause// SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {Director::getInstance()->startAnimation();// if you use SimpleAudioEngine, it must resume here// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}

4.2AppDelegate.h

#ifndef  _APP_DELEGATE_H_
#define  _APP_DELEGATE_H_#include "cocos2d.h"/**
@brief    The cocos2d Application.The reason for implement as private inheritance is to hide some interface call by Director.
*/
class  AppDelegate : private cocos2d::Application
{
public:AppDelegate();virtual ~AppDelegate();/**@brief    Implement Director and Scene init code here.@return true    Initialize success, app continue.@return false   Initialize failed, app terminate.*/virtual bool applicationDidFinishLaunching();/**@brief  The function be called when the application enter background@param  the pointer of the application*/virtual void applicationDidEnterBackground();/**@brief  The function be called when the application enter foreground@param  the pointer of the application*/virtual void applicationWillEnterForeground();
};#endif // _APP_DELEGATE_H_

4.3HelloWorldScene.cpp

#include "HelloWorldScene.h"Scene* HelloWorld::createScene()
{// 'scene' is an autorelease objectauto scene = Scene::create();// 'layer' is an autorelease objectauto layer = HelloWorld::create();// add layer as a child to scenescene->addChild(layer);// return the scenereturn scene;
}// on "init" you need to initialize your instance
bool HelloWorld::init()
{// 1. super init firstif ( !Layer::init() ){return false;}//获取整个手机可视屏幕尺寸Size visibleSize = Director::getInstance()->getVisibleSize(); //获取手机可视屏原点的坐标 Point origin = Director::getInstance()->getVisibleOrigin();//创建一个带图标的按钮//点击后调用menuCloseCallback方法退出游戏 auto closeItem = MenuItemImage::create("kaishi.png","kaishi1.png",CC_CALLBACK_1(HelloWorld::GameShow, this)); closeItem->setPosition(Point(400, 320));auto closeItem1= MenuItemImage::create("guize.png","guize1.png",CC_CALLBACK_1(HelloWorld::GameRule, this));closeItem1->setPosition(Point(410, 200));//创建一个带图标的按钮//点击后调用menuCloseCallback方法退出游戏 auto closeItem2 = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));//设置按钮的显示位置//显示在可视屏幕的右下角 closeItem2->setPosition(Point(origin.x + visibleSize.width - closeItem2->getContentSize().width / 2,origin.y + closeItem2->getContentSize().height / 2));//创建一个可释放的菜单 auto menu = Menu::create(closeItem, closeItem1, closeItem2, NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);//创建一个显示"Hello World"文字的Labelauto label = LabelTTF::create("Little Big Soldier", "Arial", 24);//position the label on the center of the screenlabel->setPosition(Point(origin.x + visibleSize.width/2,origin.y + visibleSize.height - label->getContentSize().height));// add the label as a child to this layerthis->addChild(label, 1);auto bg = Sprite::create("_jiemian.png");bg->setPosition(Point(400,261));//bg->setContentSize(Size(11,16));addChild(bg);return true;
}void HelloWorld::GameShow(Ref* pSender)
{auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(MyScene::create());//把创建的画面层添加到场景中Director::getInstance()->pushScene(TransitionFlipAngular::create(.5, scene));//运用导演类来进行切换场景
}void HelloWorld::GameRule(Ref* pSender)
{auto scene1 = Scene::create();//创建一个自释放的场景对象scene1->addChild(MyRule::create());//把创建的画面层添加到场景中Director::getInstance()->pushScene(TransitionFlipAngular::create(.5, scene1));//运用导演类来进行切换场景
}//退出按钮事件
void HelloWorld::menuCloseCallback(Ref* pSender)
{
//当是wp8或者winrt平台的时候
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");return;
#endif
//结束DirectorDirector::getInstance()->end();
//当是ios平台的时候退出
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)exit(0);
#endif
}

4.4HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"
#include "guize.h"
#include "pan.h"
USING_NS_CC;class MyScene;
class HelloWorld : public cocos2d::Layer
{
public:// there's no 'id' in cpp, so we recommend returning the class instance pointerstatic cocos2d::Scene* createScene();// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphonevirtual bool init(); void GameShow(Ref* pSender);void GameRule(Ref *pSender);// a selector callbackvoid menuCloseCallback(cocos2d::Ref* pSender);// implement the "static create()" method manuallyCREATE_FUNC(HelloWorld);
};#endif // __HELLOWORLD_SCENE_H__

4.5guize.cpp

#include "guize.h"
USING_NS_CC;
Scene* MyRule::createScene()
{auto scene1 = Scene::create();auto layer = MyRule::create();scene1->addChild(layer);return scene1;
}
bool MyRule::init()
{if (!Layer::init()){return false;}Sprite *guize = Sprite::create("guize.jpg");//括号里面是图片的路径guize->setPosition(Point(400, 261));addChild(guize);auto closeItem = MenuItemImage::create("back.png","back1.png",CC_CALLBACK_1(MyRule::Back, this));closeItem->setPosition(Point(300,35));auto menu = Menu::create(closeItem,NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);}
void MyRule::Back(Ref* pSender)
{/*auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(HelloWorld::create());//把创建的画面层添加到场景中Director::getInstance()->replaceScene(TransitionFlipAngular::create(.5, scene));//运用导演类来进行切换场景 */Director::getInstance()->popScene();
}

4.6guize.h

#ifndef _MyScene_H_
#define _MyScene_H_#include "cocos2d.h"
#include "HelloWorldScene.h"
#include "guize.h"
#include "pan.h"
USING_NS_CC;class MyRule :public cocos2d::Layer
{
public:static cocos2d::Scene* createScene();virtual bool init();void Back(Ref *pSender);CREATE_FUNC(MyRule);
};#endif

4.7pan.cpp

#include "pan.h"
#include "SimpleAudioEngine.h"
#include "CCMenuItem.h"using namespace CocosDenshion;
USING_NS_CC;
Scene* MyScene::createScene()
{auto scene = Scene::create();auto layer = MyScene::create();scene->addChild(layer);return scene;
}
/*
Scene* MyScene::create()
{MyScene* pRet = new MyScene();if (pRet){if (pRet->init()){pRet->autorelease();}else{pRet->release();return NULL;}}else{return NULL;}return pRet;
}*/
bool MyScene::init()
{if (!Layer::init()){return false;}//预加载背景音乐SimpleAudioEngine::getInstance()->preloadBackgroundMusic("MyMusic/firework.mp3");Sprite *bj = Sprite::create("bj.png");//括号里面是图片的路径bj->setPosition(Point(400, 261));addChild(bj);Sprite *qipan = Sprite::create("__qipan.png");//括号里面是图片的路径qipan->setPosition(Point(280,261));addChild(qipan);bing[0] = Sprite::create("bing.png");//括号里面是图片的路径bing[0]->setPosition(Point(70 + 2 * 84, 471 - 5 * 84));addChild(bing[0]);bing[1] = Sprite::create("bing.png");//括号里面是图片的路径bing[1]->setPosition(Point(70 + 3 * 84, 471 - 5 * 84));addChild(bing[1]);Sprite *an = Sprite::create("an.png");//括号里面是图片的路径an->setPosition(Point(620, 190));addChild(an);auto closeItem= MenuItemImage::create("xin.png","xin1.png",CC_CALLBACK_1(MyScene::GameAgain, this));closeItem->setPosition(Point(620,410));auto closeItem1 = MenuItemImage::create("fan.png","fan1.png",CC_CALLBACK_1(MyScene::GameBack, this));closeItem1->setPosition(Point(620, 300));auto musicOnMenuItem = MenuItemImage::create("on.png","on.png");auto musicOffMenuItem = MenuItemImage::create("off.png","off.png");auto musicToggleMenuItem = MenuItemToggle::createWithCallback(CC_CALLBACK_1(MyScene::menuMusicToggleCallback, this),musicOffMenuItem,musicOnMenuItem,NULL);musicToggleMenuItem->setPosition(Point(618, 194));auto menu = Menu::create(closeItem, closeItem1, musicToggleMenuItem, NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);for (int i = 1; i <= 6; i++){for (int j = 1; j <= 6; j++){vis[i][j].id = 0;vis[i][j].value = 2;}}for (int i = 0; i < 18; i++)pos[i] = Sprite::create("jiang.png");for (int i = 1,k=0, x = 70; i <= 6; i++, x += 84){for (int j = 1, y = 471; j <= 3; j++, y -= 84){//pos[k] = Sprite::create("jiang.png");pos[k]->setPosition(Point(x, y));addChild(pos[k]);vis[i][7 -j].id = k++;vis[i][7 - j].value = 0;}}num_jiang = 18;//记录将的数量TurnBing = 1;//是否该兵走selected = false;//是否选择了棋子vis[3][1].value = vis[4][1].value = 1;vis[3][1].id = 0, vis[4][1].id = 1;//设置选择框 selectSprite = Sprite::create("selected.png");this->addChild(selectSprite);selectSprite->setVisible(false);selectSprite->setPosition(Point(70,471));
//  selectSprite->setZOrder(1000);// vis[6][1].id = vis[6][3].id = vis[6][2].id = 0;
//  vis[6][1].value = vis[6][2].value = vis[6][3].value = 2;for (int i = 1; i <= 6;i++)for (int j = 1; j <= 6; j++)log("%d %d %d %d", i, j, vis[i][j].value, vis[i][j].id);//注册触摸事件auto listeren = EventListenerTouchOneByOne::create();listeren->onTouchBegan = [=](Touch *touch, Event *even){this->ccTouchesBegan(touch, even);return true;};_eventDispatcher->addEventListenerWithSceneGraphPriority(listeren, this);return true;}void MyScene::ccTouchesBegan(Touch *touch, Event *event)
{Point p = touch->getLocationInView();int x, y;//触摸点下标(vis)if (!getPos(p,x,y))//如果没点在交点{return ;}log("%d %d %d %d", x, y,vis[x][y].id,vis[x][y].value);if (false == selected){if (vis[x][y].value == TurnBing)select(x, y);return;}else {if (x == selected_x&&y == selected_y){selectSprite->setVisible(false);selected = false;}elsemove(x, y);}return ;
}void MyScene::select(int x1, int y1)//点击并记录
{selected_x = x1;selected_y = y1;this->selected = true;selectSprite->setVisible(true);selectSprite->setPosition(Point(70 + (x1 - 1) * 84, 471 - (6-y1) * 84));
}bool MyScene::getPos(Point p, int &x, int &y)
{for (x = 1; x <= 6; x++){for (y = 1; y <= 6; y++){if (abs(70+(x-1)*84,p.x)<30 &&abs(471-(6-y)*84,533-p.y)<30)return true;}}return false;
}void MyScene::move(int x, int y)
{MoveTo *mt = MoveTo::create(0.2, Point(70 + (x - 1) * 84, 533-(471 - (y - 1) * 84)));//移动if (vis[selected_x][selected_y].value == vis[x][y].value)//如果点击同种类型的棋子{select(x, y);return;}if (vis[x][y].value == 2 && (((abs(selected_x, x) == 1 && abs(selected_y, y) == 0) || (abs(selected_x, x) == 0 && abs(selected_y, y) == 1))))//可以移动{selected = false;selectSprite->setVisible(false);switch (vis[selected_x][selected_y].value){case 1:bing[vis[selected_x][selected_y].id]->runAction(mt);vis[x][y].value = 1;vis[x][y].id = vis[selected_x][selected_y].id;break;case 0:pos[vis[selected_x][selected_y].id]->runAction(mt);vis[x][y].value = 0;vis[x][y].id = vis[selected_x][selected_y].id;break;}vis[selected_x][selected_y].value = 2;vis[selected_x][selected_y].id = 0;TurnBing = !TurnBing;if (JudgeWin())GameAgain(this);return;}else if(vis[selected_x][selected_y].value == 1 && vis[x][y].value == 0 && JudgeKill(selected_x, selected_y, x, y))//吃子{selected = false;selectSprite->setVisible(false);removeChild(pos[vis[x][y].id]);bing[vis[selected_x][selected_y].id]->runAction(mt);vis[x][y].value = 1;vis[x][y].id = vis[selected_x][selected_y].id;vis[selected_x][selected_y].value = 2;vis[selected_x][selected_y].id = 0;TurnBing = !TurnBing;num_jiang--;if (JudgeWin())GameAgain(this);return;}elsereturn;
}bool MyScene::JudgeWin()//判断输赢
{int i, j;if (!num_jiang){MessageBox("Bing is succeessfully", "Alert");return true;}for ( i = 1; i <= 6; i++){for ( j = 1; j <= 6; j++){if (vis[i][j].value == 1 && (vis[i - 1][j].value == 2 || vis[i + 1][j].value == 2 || vis[i][j + 1].value == 2 || vis[i][j - 1].value == 2))break;}if (j <=6)break;}if (i > 6 && j > 6){MessageBox("Jiang is succeessfully", "Alert");return true;}return false;
}bool MyScene::JudgeKill(int x1, int y1, int x2, int y2)
{if (x1 - x2 == 2 && abs(y1, y2) == 0 && vis[x2 + 1][y1].value == 2)return true;if (x2 - x1 == 2 && abs(y1, y2) == 0 && vis[x1 + 1][y1].value == 2)return true;if (y1 - y2 == 2 && abs(x1, x2) == 0 && vis[x1][y2 + 1].value == 2)return true;if (y2 - y1 == 2 && abs(x1, x2) == 0 && vis[x1][y1 + 1].value == 2)return true;return false;
}int MyScene::abs(int x, int y)
{return x > y ? x - y : y - x;
}void MyScene::GameAgain(Ref* pSender)
{auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(MyScene::create());//把创建的画面层添加到场景中Director::getInstance()->replaceScene(TransitionFadeDown::create(.5, scene));//运用导演类来进行切换场景 /*this->removeAllChildren();this->init();*/
}void MyScene::GameBack(Ref* pSender)
{auto scene = Scene::create();//创建一个自释放的场景对象scene->addChild(HelloWorld::create());//把创建的画面层添加到场景中Director::getInstance()->replaceScene(TransitionFadeDown::create(.5, scene));//运用导演类来进行切换场景 /*Director::getInstance()->popScene();*/
}void MyScene::menuMusicToggleCallback(Ref* pSender)
{auto musicToggleMenuItem = (MenuItemToggle*)pSender;log("musicToggleMenuItem %d", musicToggleMenuItem->getSelectedIndex());if (musicToggleMenuItem->getSelectedIndex() == 1) {//选中状态Off -> On                 SimpleAudioEngine::getInstance()->playBackgroundMusic("MyMusic/firework.mp3");}else {SimpleAudioEngine::getInstance()->stopBackgroundMusic("MyMusic/firework.mp3");}
}

4.8pan.h

#ifndef _MYSCENE_H_
#define _MYSCENE_H_#include "cocos2d.h"
#include "HelloWorldScene.h"
#include "guize.h"USING_NS_CC;
struct node
{int value, id;//value为0,id为1到18是将,value为1,id为0到1,是兵,value为2,id为0是空
};class MyScene :public cocos2d::Layer
{
public:node vis[7][7];int num_jiang;Sprite* pos[18];Sprite* bing[2];Sprite* selectSprite;static cocos2d::Scene* createScene();virtual bool init();int selected_x;int selected_y;bool selected;//标记是否选中棋子int  TurnBing;void select(int x, int y);int abs(int x, int y);bool getPos(Point p,int &x,int &y);//判断该点是否点对位置bool Judge(Point p);//判断bool JudgeWin();bool JudgeKill(int x1, int y1, int x2, int y2);void move(int x, int y);virtual void ccTouchesBegan(Touch *touch, Event *event);//点击判定void GameAgain(Ref *pSender);void GameBack(Ref *pSender);void menuMusicToggleCallback(Ref *pSender);CREATE_FUNC(MyScene);
};#endif

小兵围大炮||大兵小将【C++】相关推荐

  1. C++之《小货兵摆大炮》

    背景 记得小时候经常和爷爷在水泥地上,随手抓来两颗石子,一边口里念叨"小货兵摆大炮",一边在地上划下横竖各6条道,然后在从旁边的土地上捡一些小石子和两个大石块,小石子代表小兵,大石 ...

  2. 项目实例--大炮小兵游戏源码解析

    游戏说明:大炮2个棋子,小兵18个棋子,大炮隔格可以吃掉小兵,小兵只好一步一步围死大炮 package com.wenbo.game.cbp; import android.app.Activity; ...

  3. 记第一款游戏《大炮小兵》发布

    从10月份开始写这款游戏,期间写写停停,不过终于在前天发布了中文版.今天看了下载量,将近4000,虽然不怎么大,但是也对自己近一个月的努力有了回报.在此谢谢大家的支持! 写这款游戏的初衷是想巩固下自己 ...

  4. IOS塔防游戏《坦克对大炮》的开发设计记录

    IOS塔防游戏<坦克对大炮>的开发设计记录 引子 游戏已经在App Store上线几个月了,一直很想写点什么记录一下.真要写的时候,却又发现无从下笔没啥好写的.在2012年进入IOS,对于 ...

  5. 强制建筑+造小兵不花钱+炒兵赚钱.

    [原创]红色警戒多年游戏心得㈠--高手必读 本人鏖战<<红色警戒>>多年,积累了不少失败的经验,现在拿出来和大家分享.希望能给大家的红警之旅带来快乐.   先来说一下作弊的方法 ...

  6. 无穷级数求和7个公式_双色球2019129期渗透围红蓝(6+1实战,附:7个双色球胆码公式)...

    数据近期调整,谨慎参考.玩彩票是胆量和智慧加机遇,我买彩票完全碰运气. 第2019129期双色球红球解析: 第一位:近10期振幅走势7-2-2-2-9-9-9-4-4-1,奇偶比为4:6,目前偶数振幅 ...

  7. 小兵别嚣张,签名算法分析

    点击上方↑↑↑蓝字[协议分析与还原]关注我们 "分析unity3d游戏小兵别嚣张的签名算法." 不久前,写了个unity3d的引子,介绍了使用工具从unity3d游戏中提取出各种资 ...

  8. ACMNO.38 C语言-报数 有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。

    题目描述 有n人围成一圈,顺序排号. 从第1个人开始报数(从1到3报数),凡报到3的人退出圈子.`在这里插入代码片` 问最后留下的是原来的第几号的那位. 输入 初始人数n 输出 最后一人的初始编号 样 ...

  9. BiB:王秀杰/裴小兵合作开发单细胞组学细胞标记基因鉴定算法COSG

    在单细胞测序数据分析中,对细胞进行准确分类是数据分析的重要基础.在利用聚类算法将细胞进行分组后,需要通过鉴定不同细胞群特异表达的标记基因来注释细胞类型.同时,细胞标记基因在所有细胞类群中的表达模式也能 ...

最新文章

  1. 详细!快速入门指南!Docker!
  2. 自学使用sort他命令使用
  3. php in循环与for循环,详谈js中标准for循环与foreach(for in)的区别
  4. 【2021年度训练联盟热身训练赛第五场】Jam-packed
  5. esriFeatureType与esriGeometryType的区别与联系
  6. 美团配送数据治理实践
  7. ppt图表图表类型起始_梅科图表
  8. [游戏开发-学习笔记]菜鸟慢慢飞(14)- ScrollView刷新
  9. json接收与发送(转自csdnblog)
  10. 收获,不止SQL优化——抓住SQL的本质--第八章
  11. zookeeper3.4.6 使用研究
  12. 【Python3】待解决的疑问
  13. [原]gcc 中c实现所定义的特征
  14. 关于php的函数吗,关于PHP的函数运行你了解多少?
  15. Atitit.软件开发提升稳定性总结
  16. 根据给出的关系矩阵,判断该关系所具有的特性
  17. 魔兽对战平台官网地图《小兵合成》 最强攻略+合成表+隐藏合成+隐藏英雄+
  18. 【codevs 4246】奶牛的身高 差分约束
  19. 中央电大 c语言程序设计a 试题,中央电大开放本科计算机科学与技术专业C语言程序设计(A)试题_1007...
  20. 嵌入式linux学习路径--新手入门篇

热门文章

  1. 解决TensorFlow“Your CPU supports instructions TensorFlow binary was not compiled to use : AVX2 FMA”
  2. 上市即亏损?谈谈爱奇艺和拼多多上市后的艰难人生
  3. SEO优化之生成静态网页
  4. 【人脸识别考勤门禁】管理系统功能解析
  5. 科普|未来 3~5 年内,哪个方向的机器学习人才最紧缺?
  6. 渗透测试之破解详细演示
  7. 高考数学试题数列求和|附习题
  8. 汉字数组,配合转换拼音
  9. 光学定位与追踪技术_光学追踪技术
  10. 从0到1 | 转行如何开启机器学习之旅?