cocos2dx 象棋
时间:2022-05-03
本文章向大家介绍cocos2dx 象棋,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
/*******************************************************************
* Copyright(c) 2017
* All rights reserved.
*
* 文件名称: Chess.cpp
* 简要描述: Chess
*
* 创建日期: 2017-07-21
* 作者: gongluck
* 说明:
*
* 修改日期: 2017-07-24
* 作者: gongluck
* 说明:
******************************************************************/
#include "Define.h"
#include "Chess.h"
USING_NS_CC;
bool Chess::init()
{
if (!Sprite::init())
return false;
return true;
}
Chess* Chess::createChess(TAG tag, TYPE type, cocos2d::Vec2 pos)
{
auto chess = new Chess();
if (chess && chess->init())
{
chess->autorelease();
chess->initChess(tag, type, pos);
}
else
{
delete chess;
chess = NULL;
}
return chess;
}
void Chess::initChess(TAG tag, TYPE type, cocos2d::Vec2 pos)
{
std::string picName;
if (tag == TAG::RED)
{
picName += "r";
}
else if (tag == TAG::BLACK)
{
picName += "b";
}
else
{
CCLOG("initChess error : tag = %d", tag);
return;
}
this->tag = tag;
if (type < TYPE::JIANG || type > TYPE::BING)
{
CCLOG("initChess error : type = %d", type);
return;
}
else
{
picName += TypeStr[type];
picName += ".png";
}
this->type = type;
this->setDisplayFrame(SpriteFrame::create(picName,Rect(0,0,56,56)));
this->setPosition(pos);
this->setScale(0.75);
}
void Chess::InitPos()
{
this->runAction(MoveTo::create(1.5,Vec2(35+initPos.x*36,20+initPos.y*36)));
this->currentPos = initPos;
this->setVisible(true);
}
/*******************************************************************
* Copyright(c) 2017
* All rights reserved.
*
* 文件名称: GameStart.cpp
* 简要描述: GameStart
*
* 创建日期: 2017-07-21
* 作者: gongluck
* 说明:
*
* 修改日期:
* 作者:
* 说明:
******************************************************************/
#include "Define.h"
#include "GameStart.h"
#include "GameScene.h"
USING_NS_CC;
bool GameStart::init()
{
if (!Layer::init())
return false;
auto size = Director::getInstance()->getVisibleSize();
auto red = Sprite::create("chessRed.png");
red->setPosition(size.width/2-100,size.height/2);
addChild(red, 0, TAG::RED);
auto black = Sprite::create("chessBlack.png");
black->setPosition(size.width / 2 + 100, size.height / 2);
addChild(black, 0, TAG::BLACK);
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(GameStart::touchBegan, this);
listener->onTouchEnded = CC_CALLBACK_2(GameStart::touchEnded, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
return true;
}
Scene* GameStart::createScene()
{
auto scene = Scene::create();
auto layer = GameStart::create();
scene->addChild(layer);
return scene;
}
bool GameStart::touchBegan(Touch*, Event*)
{
return true;//touchEnded
}
void GameStart::touchEnded(Touch* touch, Event* event)
{
//getLocation返回的是OpenGL的坐标系,getBoundingBox返回的是父节点坐标系
auto pos = touch->getLocation();//OpenGL
auto red = static_cast<Sprite*>(getChildByTag(TAG::RED));
auto black = static_cast<Sprite*>(getChildByTag(TAG::BLACK));
auto size = Director::getInstance()->getVisibleSize();
auto select = TAG::NONE;
if (red->getBoundingBox().containsPoint(this->convertToNodeSpace(pos)))
{
select = TAG::RED;
red->setZOrder(red->getZOrder()+1);
}
else if (black->getBoundingBox().containsPoint(this->convertToNodeSpace(pos)))
{
select = TAG::BLACK;
black->setZOrder(black->getZOrder()+1);
}
if (select != TAG::NONE)
{
auto moveto1 = MoveTo::create(1, size / 2);
auto rotate1 = RotateBy::create(1, 360);
auto spawn1 = Spawn::create(moveto1, rotate1, NULL);
auto moveto2 = moveto1->clone();
auto rotate2 = rotate1->reverse();
auto spawn2 = Spawn::create(moveto2, rotate2, NULL);
auto action1 = TargetedAction::create(red, spawn1);
auto action2 = TargetedAction::create(black, spawn2);
auto spawn = Spawn::create(action1, action2, NULL);
auto sequence = Sequence::create(spawn,
CallFunc::create([=](){
Director::getInstance()->replaceScene(TransitionJumpZoom::create(2, GameScene::createScene(select)));
}),
NULL);
runAction(sequence);
}
}
/*******************************************************************
* Copyright(c) 2017
* All rights reserved.
*
* 文件名称: GameScene.cpp
* 简要描述: GameScene
*
* 创建日期: 2017-07-21
* 作者: gongluck
* 说明:
*
* 修改日期: 2017-07-24
* 作者: gongluck
* 说明:
******************************************************************/
#include "Define.h"
#include "Chess.h"
#include "GameScene.h"
USING_NS_CC;
bool GameScene::init()
{
if (!Layer::init())
return false;
return true;
}
Scene* GameScene::createScene(TAG tag)
{
auto scene = Scene::create();
auto layer = GameScene::createGame(tag);
scene->addChild(layer);
return scene;
}
GameScene* GameScene::createGame(TAG tag)
{
auto layer = new GameScene();
if (layer && layer->init())
{
layer->autorelease();
layer->initGame(tag);
}
else
{
delete layer;
layer = NULL;
}
return layer;
}
void GameScene::initGame(TAG Tag)
{
this->tag = Tag;
auto size = Director::getInstance()->getVisibleSize();
auto background = Sprite::create("background.png");
background->setScale(size.height / background->getContentSize().height);
background->setPosition(background->getBoundingBox().size.width/2,size.height /2);
addChild(background);
auto floor = Sprite::create("floor.jpg");
floor->setScaleX((size.width - background->getBoundingBox().size.width) / floor->getContentSize().width);
floor->setScaleY(size.height / floor->getContentSize().height);
floor->setPosition(size.width - floor->getBoundingBox().size.width / 2, size.height / 2);
addChild(floor);
auto mNew = MenuItemImage::create("new.jpg", "new.jpg",CC_CALLBACK_1(GameScene::menuNew,this));
auto mReg = MenuItemImage::create("regret.jpg", "regret.jpg", CC_CALLBACK_1(GameScene::menuRegret, this));
auto menu = Menu::create(mNew, mReg, NULL);
menu->alignItemsVertically();
menu->setPosition(floor->getPosition());
addChild(menu);
srand(time(NULL));
int i = 0;
for (int tag = TAG::RED; tag <= TAG::BLACK; ++tag)//先创建红色棋子
{
chesses[i] = Chess::createChess((TAG)tag, TYPE::JIANG, Vec2(rand() % HEIGHT, rand() % HEIGHT));
chesses[i]->setInitPos(Point(4, tag == Tag ? 0:9));
addChild(chesses[i]);
++i;
int flag = 0;
for (int times = 0; times < 2; ++times,++flag)
{
chesses[i] = Chess::createChess((TAG)tag, TYPE::SHI, Vec2(rand() % HEIGHT, rand() % HEIGHT));
chesses[i]->setInitPos(Point(3+flag*2,tag==Tag?0:9));
addChild(chesses[i]);
++i;
chesses[i] = Chess::createChess((TAG)tag, TYPE::XIANG, Vec2(rand() % HEIGHT, rand() % HEIGHT));
chesses[i]->setInitPos(Point(2 + flag * 4, tag == Tag ? 0 : 9));
addChild(chesses[i]);
++i;
chesses[i] = Chess::createChess((TAG)tag, TYPE::MA, Vec2(rand() % HEIGHT, rand() % HEIGHT));
chesses[i]->setInitPos(Point(1 + flag * 6, tag == Tag ? 0 : 9));
addChild(chesses[i]);
++i;
chesses[i] = Chess::createChess((TAG)tag, TYPE::CHE, Vec2(rand() % HEIGHT, rand() % HEIGHT));
chesses[i]->setInitPos(Point(0 + flag * 8, tag == Tag ? 0 : 9));
addChild(chesses[i]);
++i;
chesses[i] = Chess::createChess((TAG)tag, TYPE::PAO, Vec2(rand() % HEIGHT, rand() % HEIGHT));
chesses[i]->setInitPos(Point(1+flag*6,tag==Tag?2:7));
addChild(chesses[i]);
++i;
}
flag = 0;
for (int times = 0; times < 5; ++times,++flag)
{
chesses[i] = Chess::createChess((TAG)tag, TYPE::BING, Vec2(rand() % HEIGHT, rand() % HEIGHT));
chesses[i]->setInitPos(Point(0+flag*2,tag==Tag?3:6));
addChild(chesses[i]);
++i;
}
}
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(GameScene::touchBegan, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
selected = Sprite::create("selected.png");
selected->setScale(0.75);
selected->setVisible(false);
addChild(selected);
selectIndex = -1;
for (auto& i : pane)
{
for (auto &j : i)
{
j = -1;
}
}
win = Sprite::create("yingjiemian.png");
win->setPosition(size / 2);
addChild(win);
win->setVisible(false);
}
void GameScene::menuNew(cocos2d::Ref*)
{
Point pos;
int index = 0;
for (auto i : chesses)
{
i->InitPos();
pos = i->getInitPos();
pane[(int)pos.x][(int)pos.y] = index;
++index;
}
selected->setVisible(false);
selectIndex = -1;
turn = tag;
steps.clear();
}
void GameScene::menuRegret(cocos2d::Ref*)
{
if (steps.size() > 0)
{
Step step = steps.back();
Point from = step.from;
Point to = step.to;
chesses[pane[(int)to.x][(int)to.y]]->runAction(MoveTo::create(0.1, Vec2(35 + from.x * 36, 20 + from.y * 36)));
chesses[pane[(int)to.x][(int)to.y]]->setPos(from);
pane[(int)from.x][(int)from.y] = pane[(int)to.x][(int)to.y];
pane[(int)to.x][(int)to.y] = step.killnum;
if (step.killnum != -1)
chesses[step.killnum]->setVisible(true);
steps.pop_back();
selected->setVisible(false);
selectIndex = -1;
turn = turn == TAG::RED ? TAG::BLACK : TAG::RED;
}
}
bool GameScene::touchBegan(cocos2d::Touch* touch, cocos2d::Event*)
{
auto touchPos = touch->getLocation();//OpenGL
int x = (touchPos.x - 35 + 18) / 36;
int y = (touchPos.y - 20 + 18) / 36;
CCLOG("x=%d,y=%d", x, y);
if (x<0 || x>9 || y<0 || y>10)
return false;
moveChess(selectIndex, Point(x, y));
return false;
}
bool GameScene::moveChess(int index, Point pos)
{
if (pane[(int)pos.x][(int)pos.y] != -1 && chesses[pane[(int)pos.x][(int)pos.y]]->getTag() == turn)//点中棋子是我方
{
selected->setVisible(true);
selected->setPosition(35 + 36 * pos.x, 20 + 36 * pos.y);
selectIndex = pane[(int)pos.x][(int)pos.y];
return false;//没有移动
}
else
{
if (index == -1)
return false;
if (moveChessFromTo(chesses[index]->getType(), chesses[index]->getPos(), pos))
{
selected->setVisible(false);
selectIndex = -1;
turn = turn == TAG::RED ? TAG::BLACK : TAG::RED;
}
}
}
bool GameScene::moveChessFromTo(TYPE type, cocos2d::Point from, cocos2d::Point to)
{
int x1 = from.x;
int x2 = to.x;
int y1 = from.y;
int y2 = to.y;
int d_x = abs(x1 - x2);
int d_y = abs(y1 - y2);
bool res = false;
int num = 0;
Step step;
switch (type)
{
case TYPE::JIANG:
if (x2 < 3 || x2 >5 || (y2 > 2 && y2 <7) || d_x>1 || d_y > 1 || (x1 != x2 && y1 != y2))
res = false;
else
res = true;
break;
case TYPE::SHI:
if (d_x != 1 || d_y != 1 || x2 < 3 || x2 >5 || (y2 > 2 && y2 <7))
res = false;
else
res = true;
break;
case TYPE::XIANG:
if (d_x != 2 || d_y != 2 || (y1 <= 4 && y2>4) || (y1 > 4 && y2 <= 4) || pane[(x1 + x2) / 2][(y1 + y2) / 2] != -1)
res = false;
else
res = true;
break;
case TYPE::MA:
if (d_x == 2 && d_y == 1)
{
if (pane[(x1 + x2) / 2][y1] != -1)
res = false;
else
res = true;
}
else if (d_y == 2 && d_x == 1)
{
if (pane[x1][(y1 + y2) / 2] != -1)
res = false;
else
res = true;
}
else
res = false;
break;
case TYPE::CHE:
if (d_x > 0 && d_y > 0)
res = false;
res = true;
if (d_x == 0)
{
auto min = y1 < y2 ? y1 : y2;
auto max = y1 > y2 ? y1 : y2;
for (int temp = min+1; temp < max; ++temp)
{
if (pane[x1][temp] != -1)
res = false;
}
}
else if (d_y == 0)
{
auto min = x1 < x2 ? x1 : x2;
auto max = x1 > x2 ? x1 : x2;
for (int temp = min+1; temp < max; ++temp)
{
if (pane[temp][y1] != -1)
res = false;
}
}
break;
case TYPE::PAO:
num = 0;
if (d_x == 0)
{
auto min = y1 < y2 ? y1 : y2;
auto max = y1 > y2 ? y1 : y2;
for (int temp = min + 1; temp < max; ++temp)
{
if (pane[x1][temp] != -1)
++num;
}
if ((num == 0 && pane[x2][y2] == -1) || (num == 1 && pane[x2][y2] != -1 && chesses[pane[x2][y2]]->getTag() != turn))
res = true;
}
else if (d_y == 0)
{
auto min = x1 < x2 ? x1 : x2;
auto max = x1 > x2 ? x1 : x2;
for (int temp = min + 1; temp < max; ++temp)
{
if (pane[temp][y1] != -1)
++num;
}
if ((num == 0 && pane[x2][y2] == -1) || (num == 1 && pane[x2][y2] != -1 && chesses[pane[x2][y2]]->getTag() != turn))
res = true;
}
else
res = false;
break;
case TYPE::BING:
if (d_y == 0 && d_x == 1 && ((chesses[pane[x1][y1]]->getTag() == tag && y1>4) || (chesses[pane[x1][y1]]->getTag() != tag && y1<5)))
res = true;
else if (d_x == 0 && d_y == 1)
{
if ((chesses[pane[x1][y1]]->getTag() == tag && y2 > y1) || (chesses[pane[x1][y1]]->getTag() != tag && y2 < y1))
res = true;
else res = false;
}
else
res = false;
break;
default:
res = false;
break;
}
if (res)
{
step.from = from;
step.to = to;
step.killnum = -1;
chesses[pane[(int)from.x][(int)from.y]]->runAction(MoveTo::create(0.5, Vec2(35 + x2 * 36, 20 + y2 * 36)));
chesses[pane[(int)from.x][(int)from.y]]->setPos(to);
if (pane[(int)to.x][(int)to.y] != -1)
{
step.killnum = pane[(int)to.x][(int)to.y];
chesses[pane[(int)to.x][(int)to.y]]->setVisible(false);
if (chesses[pane[(int)to.x][(int)to.y]]->getType() == TYPE::JIANG)
{
win->setVisible(true);
scheduleOnce(schedule_selector(GameScene::winCall), 2.0f);
}
}
steps.push_back(step);
pane[(int)to.x][(int)to.y] = pane[(int)from.x][(int)from.y];
pane[(int)from.x][(int)from.y] = -1;
}
return res;
}
void GameScene::winCall(float dt)
{
win->setVisible(false);
}
https://github.com/gongluck93/GameChineseChess.git
- Extjs4.2 rest 与webapi数据交互----顺便请教了程序员的路该怎么走
- 这或许是对小白最友好的python入门了吧——7,组织列表
- 这或许是对小白最友好的python入门了吧——6,删除列表元素
- 集群开源软件赏:JGroups
- 看到他我一下子就悟了---委托
- 这或许是对小白最友好的python入门了吧——5,修改和添加列表元素
- 这或许是对小白最友好的python入门了吧——4,列表
- 【深度学习】自动驾驶:使用深度学习预测汽车的转向角度
- 这或许是对小白最友好的python入门了吧——3,数字处理
- 数据库恢复方案
- 这或许是对小白最友好的python入门了吧——2,变量和字符串
- Extjs4.2+webAPI+EF实现分页以及webapi的数据传值(续)
- Linux 系统安全与优化配置
- Extjs 项目中常用的小技巧,也许你用得着(2)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP ABAP字符和字符串变量隐式转换的一些规则
- MySQL information_schema详解 COLLATION_CHARACTER_SET_APPLICABILITY
- 如何处理Angular项目在Visual Studio Code打开报关于@Decorators的警告信息
- QT 中普通数值与字符串之间的转换
- C# 时间与时间戳互转 13位
- 在C#中ref和out具体怎么使用?在什么情况下使用?
- Vs code 创建vue模版
- [892]python中re.split()方法
- MacOS抓包工具Charles
- PYTHON替代MATLAB在线性代数学习中的应用(使用Python辅助MIT 18.06 Linear Algebra学习)
- C# TCP/IP 文件(图片、视频等)收发系统
- 反制面试官 | 14张原理图 | 再也不怕被问 volatile!
- Javascript之其实我觉得原型链没有难的那么夸张!
- 归纳一下:C#线程同步的几种方法
- C# 主界面的扁平化