:891: 本人从Android出入cocos2dx大门。。。途中是各种坎坷。。
按照http://www.cocoachina.com/bbs/read.php?tid=197370&page=1 该章节的内容copy 一下,小写了个贪吃蛇。大概算是一只脚踏入了大家庭的门。本来想把游戏界面的画面改得更美观些。无奈学习的东西还不够多。draw这方面的东西实在欠缺。忘大家见谅,下面开始介绍:
一:使用环境:win8.1+vs2013+cocos2dx3.0rc2;
二:环境搭建步骤:
准备事项:需要下载以下几个东西:
1:微软VS2012以上版本。下载地址:
VS2012:http://www.microsoft.com/zh-cn/download/details.aspx?id=30678http://www.microsoft.com/zh-cn/download/details.aspx?id=30678
VS2013:http://www.microsoft.com/zh-cn/download/details.aspx?id=42307http://www.microsoft.com/zh-cn/download/details.aspx?id=42307
WP8.0SDK:http://www.microsoft.com/zh-cn/download/details.aspx?id=35471http://www.microsoft.com/zh-cn/download/details.aspx?id=35471
2:python:我们使用2.7版本。3.0版本在使用时会有问题,因此建议使用2.7.如果用3.0有解决方法的也可以回帖告知下;
下载地址:https://www.python.org/downloads/https://www.python.org/downloads/
3:cocos2d-x-3.0rc2:
下载地址:http://www.cocos2d-x.org/downloadhttp://www.cocos2d-x.org/download
弄wp8环境可谓是九九八十一难啊。。。。各种纠结的问题。注意事项,记得各位基友看看自己的电脑必须是win8 pro以上系统,配置的话需要cpu支持硬件虚拟化才能运行虚拟机啊亲。微软这是要被大家扔砖的节奏啊。
(1)我们需要在win8或者win8.1上安装vs2013,如果已经安装了2012可以选择增加一个wp8.0sdk。。。不大。“也就”1G多。。。准备好腾出C盘宝贵的空间,让你们的仓老湿,波老湿们先挪个作品到垃圾箱去吧。微软的产品安装步骤基本就是下一步下一步。如果是vs2013记得勾选wp环境选项
(2)安装完VS,安装python,也是各种下一步。完毕之后,在系统环境中配置添加安装路径。
(3)下载cocos2d-x-3.0rc2.解压。打开命令行,把setup.py拉进去。因为本身有Android环境,就把提示的sdk,ndk,ant路径都配置了。系统环境自动生成了一些cocos的变量。
三:创建项目
打开命令行,输入创建命令:cocos new mygame -l cpp-d E:\cocos\mygame
注意:这里设置的路径是cocos安装路径底下再建一个文件。可能是rc2对wp8的支持还不是很完善,如果建在其他目录就很容易出现引用项目无法找到的蛋碎情形,因此我都建在了cocos安装目录底下再加一层目录。这样基本上项目就不会再出错;
1:了解项目结构:
WP8的这个C#项目直接无视,貌似如果要修改启动名称跟图标要从这里改,cocos是夸平台,直接修改引用的C++代码就OK真心给力。因此我们只需要修改HelloCppComponent中Classes文件夹下的C++代码;
Classes下代码有四个:
AppDelegate.cpp
AppDelegate.h
HelloWorldScene.cpp
HelloWorldScene.h
AppDelegate的两个文件应该是入口文件。就不做任何修改。
HelloWorldScene的就是默认页的相关代码了。
我的理解就是.h文件声明类以及相关接口,.cpp实现具体功能。只是个人观点。不会C++请谅解;
恶补了一下,cocos的导演,场景等等基础知识后,了解了HelloWorld所做的一些事情.具体都在代码中注释鸟。不一一解释。
2:流程
主菜单->帮助页->游戏页面。
3:开始开发:
首先,我们设计一个主菜单:含几个菜单选项:开始游戏,游戏帮助,退出游戏
.h文件中代码
//游戏主菜单画面
class HelloWorld : public cocos2d::Layer
{
public:
static cocos2d::Scene* createScene();//创建主菜单画面的场景
virtual bool init(); //初始化操作
//菜单项点击事件
void menuCloseCallback(Ref* pSender);
void menuStartCallback(Ref* pSender);
void menuHelpCallback(Ref* pSender);
CREATE_FUNC(HelloWorld);
};
```
.cpp代码:
Scene* HelloWorld::createScene()
{
auto scene = Scene::create();
auto layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
bool HelloWorld::init()
{
if (!Layer::init())
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
//在界面上添加菜单内容
//添加关闭程序按钮
auto closeItem = MenuItemImage::create(
"CloseNormal.png",//默认显示图片
"CloseSelected.png",//点击按下显示图片
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));//绑定点击事件
closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width / 2,
origin.y + closeItem->getContentSize().height / 2));//设定显示位置为屏幕宽度-控件自身宽高一半。也就是显示在右下角
//添加开始按钮
auto startMenu = MenuItemImage::create(
"btn_start.png",
"btn_start.png",
CC_CALLBACK_1(HelloWorld::menuStartCallback, this));
startMenu->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y + 50));
//添加帮助按钮
auto helpMenu = MenuItemImage::create(
"btn_help.png",
"btn_help.png",
CC_CALLBACK_1(HelloWorld::menuHelpCallback, this));
helpMenu->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
//添加退出按钮
auto exitMenu = MenuItemImage::create(
"btn_exit.png",
"btn_exit.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
exitMenu->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y - 50));
//创建菜单载体,将上面的菜单内容都添加到载体中
auto pMenu = Menu::create(startMenu, helpMenu, exitMenu, closeItem, NULL);//添加制定的菜单项
pMenu->setPosition(Point::ZERO);//设置显示位置
this->addChild(pMenu, 1);//添加到场景中
//制定游戏背景
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
this->addChild(sprite, 0);
//------------------------
return true;
}
//退出按钮事件
void HelloWorld::menuCloseCallback(Ref* pSender)
{
//Director::getInstance()->replaceScene(GameHelp::createScene());
Director::getInstance()->end();
}
//开始游戏按钮事件
void HelloWorld::menuStartCallback(Ref* pSender)
{
Director::getInstance()->replaceScene(GameLayer::createScene());
//Director::getInstance()->end();
}
//帮助按钮事件
void HelloWorld::menuHelpCallback(Ref* pSender)
{
Director::getInstance()->replaceScene(GameHelp::createScene());
//Director::getInstance()->end();
}
```
再菜单中监听相关按钮实现场景切换。
接下来,设计一个帮助页,事件关系只写了菜单及调整:
.h代码:
//游戏帮助画面
class GameHelp :public cocos2d::Layer
{
public :
virtual bool init();//初始化
//按钮事件监听
void menuGoGameCallback(Ref* pSender);
void menuGoMainCallback(Ref* pSender);
static cocos2d::Scene * createScene();//创建帮助画面
CREATE_FUNC(GameHelp);
};
```
bool GameHelp::init()
{
if (!Layer::init())
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
//添加退出按钮
auto gotogameMenu = MenuItemImage::create(
"btn_gotogame.png",
"btn_gotogame.png",
CC_CALLBACK_1(GameHelp::menuGoGameCallback, this));
gotogameMenu->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
auto goMainMenu = MenuItemImage::create(
"btn_gomain.png",
"btn_gomain.png",
CC_CALLBACK_1(GameHelp::menuGoMainCallback, this));
goMainMenu->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y - 50));
auto pMenu = Menu::create(gotogameMenu, goMainMenu, NULL);
pMenu->setPosition(Point::ZERO);
this->addChild(pMenu, 1);
auto sprite = Sprite::create("HelloWorld.png");
sprite->setPosition(Point(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
this->addChild(sprite, 0);
return true;
}
//帮助按钮事件
void GameHelp::menuGoGameCallback(Ref* pSender)
{
Director::getInstance()->replaceScene(GameLayer::createScene());
}
//帮助按钮事件
void GameHelp::menuGoMainCallback(Ref* pSender)
{
Director::getInstance()->replaceScene(HelloWorld::createScene());
}
//获取帮助画面
Scene * GameHelp::createScene()
{
auto scene = Scene::create();
auto hl = GameHelp::create();
scene->addChild(hl);
return scene;
}
```
帮助画面仅提供跳转。
接下来,设计游戏界面,由于对draw不熟悉,基本都是copy案例中的代码。
.h代码:
//标识贪食蛇的移动方向
typedef enum {
UP=1,
DOWN,
LEFT,
RIGHT
}DIR_DEF;
//定义每一节蛇元素的属性,包含了所在行,列,移动方向
class SnakeNode :public cocos2d::Ref{
public:
int row;//行
int col;//列
int dir;//方向
};
//游戏画面
class GameLayer :public cocos2d::Layer
{
protected:
SnakeNode *sHead; //创建蛇对象
SnakeNode *sFood; //食物对象
cocos2d::Vector allBody;//蛇的身体
cocos2d::Texture2D * chead;
public :
virtual bool init();//初始化
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
//监听触摸事件
bool onTouchBegan(cocos2d::Touch* touch, Event *event);
void timesthing(float t);//定时事件
static cocos2d::Scene * createScene();//创建游戏画面
CREATE_FUNC(GameLayer);
};
```
.cpp代码
//初始化游戏层
bool GameLayer::init()
{
if (!Layer::init())
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
auto goMainMenu = MenuItemImage::create(
"btn_gomain.png",
"btn_gomain.png",
](Ref* sender){
Director::getInstance()->replaceScene(HelloWorld::createScene());
});
goMainMenu->setPosition(Point(origin.x + visibleSize.width - goMainMenu->getContentSize().width / 2,
origin.y +visibleSize.height + goMainMenu->getContentSize().height / 2));
auto pMenu = Menu::create(goMainMenu, NULL);
pMenu->setPosition(Point::ZERO);
this->addChild(pMenu, 1);
auto labhelp = LabelTTF::create("this is game", "Arial", 15);
labhelp->setPosition(Point(visibleSize.width + origin.x, visibleSize.height + origin.y));
this->addChild(labhelp);
auto labback = LabelTTF::create("MainMenu", "Arial", 15);
auto miback = MenuItemLabel::create(labback, ](Ref* sender)
{
Director::getInstance()->replaceScene(HelloWorld::createScene());
});
miback->setPosition(Point(visibleSize.width + origin.x - miback->getContentSize().width / 2, visibleSize.height + origin.y - miback->getContentSize().height / 2));
this->addChild(miback);
chead = ::CCTextureCache::sharedTextureCache()->addImage("head.png");
//监听触摸事件
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);//指定触摸的回调函数
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);//将listener放入事件委托中
//初始化蛇头坐标和食物的坐标
sHead = new SnakeNode();
sHead->row = rand() % 10;
sHead->col = rand() % 10;
//初始化食物的坐标
sFood = new SnakeNode();
sFood->row = rand() % 10;
sFood->col = rand() % 10;
//执行定时事件
this->schedule(schedule_selector(GameLayer::timesthing), 0.5);
return true;
}
//创建游戏场景
Scene * GameLayer::createScene()
{
auto scene = Scene::create();
auto hl = GameLayer::create();
scene->addChild(hl);
return scene;
}
void GameLayer::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
///绘制形状
::glLineWidth(2);//设定画线的宽度
for (int i = 0; i < 11; i++)
{
DrawPrimitives::drawLine(Point(0, i * 32), Point(320, i * 32));//绘制条横线
DrawPrimitives::drawLine(Point(i * 32, 0), Point(i * 32, 320));//绘制条竖线
}
//绘制蛇头
DrawPrimitives::drawSolidRect(Point(sHead->col * 32 + 2, sHead->row * 32 + 2),
Point(sHead->col * 32 + 32, sHead->row * 32 + 32),
Color4F(Color3B(255, 0, 0)));
//绘制食物
DrawPrimitives::drawSolidRect(Point(sFood->col * 32 + 2, sFood->row * 32 + 2),
Point(sFood->col * 32 + 32, sFood->row * 32 + 32),
Color4F(Color3B(0, 0, 255)));
//绘制身体
for (int i = 0; i < allBody.size(); i++)
{
SnakeNode * node = (SnakeNode *)allBody.at(i);
DrawPrimitives::drawSolidRect(Point(node->col * 32 + 2, node->row * 32 + 2),
Point(node->col * 32 + 32, node->row * 32 + 32),
Color4F(Color3B(0, 0, 255)));
}
}
bool GameLayer::onTouchBegan(Touch* touch, Event *event)
{
auto p = touch->getLocation();
int nowrow; //当前用户触摸的行
nowrow = ((int)p.y) / 32;
int nowcol; //当前用户触摸的列
nowcol = ((int)p.x) / 32;
if (abs(nowrow - sHead->row) > abs(nowcol - sHead->col)) //上下移动
{
if (nowrow > sHead->row)
{
sHead->dir = DIR_DEF::UP;
}
else
{
sHead->dir = DIR_DEF::DOWN;
}
}
else //左右移动
{
if (nowcol > sHead->col)
{
sHead->dir = DIR_DEF::RIGHT;
}
else
{
sHead->dir = DIR_DEF::LEFT;
}
}
CCLOG("rand %d", rand());
CCLOG("you touchbegan%f,%f", p.x, p.y);
return true;
}
//定时器回调
void GameLayer::timesthing(float t)
{
//移动蛇的身体
for (int i = allBody.size() - 1; i >= 0; i--)
{
SnakeNode * sn = (SnakeNode *)allBody.at(i);
if (i > 0)
{
SnakeNode * snpre = (SnakeNode *)allBody.at(i - 1);
sn->dir = snpre->dir;
sn->row = snpre->row;
sn->col = snpre->col;
}
else if (i == 0)
{
//移动第一个节点
sn->dir = sHead->dir;
sn->row = sHead->row;
sn->col = sHead->col;
}
}
//移动蛇头
switch (sHead->dir)
{
case DIR_DEF::UP:
sHead->row++;
if (sHead->row >= 10)
{
sHead->row = 0;
}
break;
case DIR_DEF::DOWN:
sHead->row--;
if (sHead->row < 0)
{
sHead->row = 9;
}
break;
case DIR_DEF::LEFT:
sHead->col--;
if (sHead->col < 0)
{
sHead->col = 9;
}
break;
case DIR_DEF::RIGHT:
sHead->col++;
if (sHead->col >= 10)
{
sHead->col = 0;
}
break;
};
//碰撞检测
if (sHead->row == sFood->row && sHead->col == sFood->col)
{
//食物消失
sFood->row = rand() % 10;
sFood->col = rand() % 10;
//添加身体到集合
SnakeNode * sn = new SnakeNode();
SnakeNode * lastNode = NULL;
if (allBody.size() > 0)
lastNode = (SnakeNode *)allBody.back();
else
lastNode = sHead;
switch (lastNode->dir)
{
case DIR_DEF::UP:
sn->row = lastNode->row - 1;
sn->col = lastNode->col;
break;
case DIR_DEF::DOWN:
sn->row = lastNode->row + 1;
sn->col = lastNode->col;
break;
case DIR_DEF::LEFT:
sn->row = lastNode->row;
sn->col = lastNode->col + 1;
break;
case DIR_DEF::RIGHT:
sn->row = lastNode->row;
sn->col = lastNode->col - 1;
break;
}
this->allBody.pushBack(sn);
}
```
OK,设计完毕。编译一下骚等片刻,编译完成后,就可以运行查看效果了。如果cpu不支持硬件虚拟化无法创建虚拟机只能链接真机调试。我得电脑支持,因此直接运行,开启虚拟机查看效果:
主菜单:
帮助页:
游戏页:
贪吃蛇_WP8版.rar (2652 KB)

