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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏DannyHoo的专栏

iOS开发中创建一个纵向滑动控件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

631
来自专栏图形学与OpenGL

9.3.3编程实例-图形拾取

int select_point = 0; //1 是第一个点,2是第二个,以此类推

984
来自专栏向治洪

android画图之贝塞尔曲线讲解

首先对于《赛贝尔曲线》不是很了解的童鞋,请自觉白度百科、google等等... 为了方便偷懒的童鞋,这里给个《贝赛尔曲线》百科地址,以及一段话简述《贝赛尔曲线...

2037
来自专栏逍遥剑客的游戏开发

Untiy Native Render Plugin在VR中的绘制

1866
来自专栏吴小龙同學

Android调用系统相机和相册-填坑篇

之前分享了Android调用系统相机和相册,但是由于国内Android机型繁多,各家都自己的rom,调用系统的还是会出现不少问题: 拍照后照片被旋转 这种...

2726
来自专栏jianhuicode

关于贝塞尔曲线的故事

概述 在开始本故事的之前,先来介绍下故事的背景。话说几百年前,从天而降一座神山,远远看去像一天光滑的丝带,它的名字叫做:“贝塞尔曲线"。有大法师预言登上这座神山...

1928
来自专栏非著名程序员

十分钟搞定酷炫动画,Android自定义 View 入门

前几天 Ui 突然给我一个 gif 图说要把这个做成启动动画,看到效果图的我表示一脸懵逼。 ? 好吧,懵逼归懵逼,效果还是要做出来,作为一只没怎么写过动效的猿...

2258
来自专栏向治洪

android放大镜效果实现

概述 我相信很多用过英语应用的同学都看多一个放大镜的效果,就是选中一段文字后,会有一个放大镜,这个究竟怎么实现的呢,我们今天来分析分析。 ? 源码分析 publ...

2498
来自专栏封碎

Android的3D旋转 博客分类: Android AndroidUPBlog

       见过没有用opengl的3D动画,看了一下,是用的Camera实现的,内部机制实际上还是opengl,不过大大简化了使用。        C...

571
来自专栏SAP最佳业务实践

SAP S/4 HANA新变化-CO物料帐(for Ver.1610)

Material Ledger Actual Costing has been activated already in the system before t...

4195

扫码关注云+社区