前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cocos2dx 象棋

cocos2dx 象棋

作者头像
_gongluck
发布2018-03-08 14:44:03
1.9K0
发布2018-03-08 14:44:03
举报
代码语言:javascript
复制
/*******************************************************************
*  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);
}
代码语言:javascript
复制
/*******************************************************************
*  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);
	}
		
}
代码语言:javascript
复制
/*******************************************************************
*  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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年07月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档