#include "GameScene.h"
#include "StartScene.h"
Scene * GameScene::createScene() {
auto scene = Scene::create();
auto layer = GameScene::create();
scene->addChild(layer);
return scene;
}
bool GameScene::init() {
if (!Layer::init()) {
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
timeval tv;
gettimeofday(&tv, NULL);
unsigned long int seed = tv.tv_sec * 1000 + tv.tv_usec / 100;
srand(seed);
auto backLabel = Label::createWithTTF("Main Menu", "fonts/Marker Felt.ttf", 24);
auto backItem = MenuItemLabel::create(backLabel, CC_CALLBACK_1(GameScene::menuCallBack, this));
backItem->setAnchorPoint(Point::ANCHOR_BOTTOM_RIGHT);
backItem->setPosition(Vec2(visibleSize.width, 0));
auto menu = Menu::create(backItem, NULL);
menu->setPosition(Vec2::ZERO);
addChild(menu);
_sHead = new SnakeNode();
_sHead->row = rand() % 10;
_sHead->col = rand() % 15;
_sHead->preNode = NULL;
_sFood = new SnakeNode();
_sFood->row = rand() % 10;
_sFood->col = rand() % 15;
auto snakeNode = Sprite::create("snake_head.png");
snakeNode->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
snakeNode->setPosition(Vec2(_sHead->col * 32, _sHead->row * 32));
_sHead->nodeSprite = snakeNode;
addChild(snakeNode);
auto foodNode = Sprite::create("snake_food.png");
foodNode->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
foodNode->setPosition(Vec2(_sFood->col * 32, _sFood->row * 32));
_sFood->nodeSprite = foodNode;
addChild(foodNode);
/*
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
*/
this->schedule(SEL_SCHEDULE(&GameScene::logic), 0.2f);
rocker = HRocker::createHRocker("rocker.png", "rockerBG.png", Vec2(70, 70));
rocker->startRocker();
addChild(rocker);
_dir = -1;
return true;
}
/*
bool GameScene::onTouchBegan(Touch * touch, Event * event) {
auto point = touch->getLocation();
int touchRow = (int)(point.y / 32);
int touchCol = (int)(point.x / 32);
if (abs(touchRow - _sHead->row) > abs(touchCol - _sHead->col)) {
if (touchRow > _sHead->row) {
if (_dir != DIR_DEF::DOWN || _dir == -1) {
_dir = DIR_DEF::UP;
_sHead->dir = DIR_DEF::UP;
}
}
else {
if (_dir != DIR_DEF::UP || _dir == -1) {
_dir = DIR_DEF::DOWN;
_sHead->dir = DIR_DEF::DOWN;
}
}
}
else {
if (touchCol > _sHead->col) {
if (_dir != DIR_DEF::LEFT || _dir == -1) {
_dir = DIR_DEF::RIGHT;
_sHead->dir = DIR_DEF::RIGHT;
}
}
else {
if (_dir != DIR_DEF::RIGHT || _dir == -1) {
_dir = DIR_DEF::LEFT;
_sHead->dir = DIR_DEF::LEFT;
}
}
}
return true;
}
*/
void GameScene::logic(float dt) {
if (rocker->_rockerDirection == rocker_up) {
if (_dir != DIR_DEF::DOWN || _dir == -1) {
_dir = DIR_DEF::UP;
_sHead->dir = DIR_DEF::UP;
}
}
else if (rocker->_rockerDirection == rocker_down) {
if (_dir != DIR_DEF::UP || _dir == -1) {
_dir = DIR_DEF::DOWN;
_sHead->dir = DIR_DEF::DOWN;
}
}
else if (rocker->_rockerDirection == rocker_left) {
if (_dir != DIR_DEF::RIGHT || _dir == -1) {
_dir = DIR_DEF::LEFT;
_sHead->dir = DIR_DEF::LEFT;
}
}
else if (rocker->_rockerDirection == rocker_right) {
if (_dir != DIR_DEF::LEFT || _dir == -1) {
_dir = DIR_DEF::RIGHT;
_sHead->dir = DIR_DEF::RIGHT;
}
}
for (int i = _allBody.size() - 1; i >= 0; --i) {
auto sn = _allBody.at(i);
sn->row = sn->preNode->row;
sn->col = sn->preNode->col;
sn->dir = sn->preNode->dir;
}
switch (_sHead->dir) {
case DIR_DEF::UP:
_sHead->row++;
break;
case DIR_DEF::DOWN:
_sHead->row--;
break;
case DIR_DEF::LEFT:
_sHead->col--;
break;
case DIR_DEF::RIGHT:
_sHead->col++;
break;
default:
break;
}
if (_sHead->row >= 10 || _sHead->row < 0 || _sHead->col >= 15 || _sHead->col < 0) {
gameOver();
return;
}
for (int i = _allBody.size() - 1; i >= 0; --i) {
auto sn = _allBody.at(i);
if (_sHead->row == sn->row && _sHead->col == sn->col) {
gameOver();
return;
}
}
for (int i = _allBody.size() - 1; i >= 0; --i) {
auto sn = _allBody.at(i);
sn->nodeSprite->runAction(MoveTo::create(0.2f, Vec2(sn->col * 32, sn->row * 32)));
}
_sHead->nodeSprite->runAction(MoveTo::create(0.2f, Vec2(_sHead->col * 32, _sHead->row * 32)));
if (_sHead->row == _sFood->row && _sHead->col == _sFood->col) {
_sFood->row = rand() % 10;
_sFood->col = rand() % 15;
_sFood->nodeSprite->setPosition(Vec2(_sFood->col * 32, _sFood->row * 32));
auto snakeNode = new SnakeNode();
if (_allBody.empty()) {
snakeNode->preNode = _sHead;
}
else {
snakeNode->preNode = _allBody.back();
}
switch (snakeNode->preNode->dir) {
case DIR_DEF::UP:
snakeNode->row = snakeNode->preNode->row - 1;
snakeNode->col = snakeNode->preNode->col;
break;
case DIR_DEF::DOWN:
snakeNode->row = snakeNode->preNode->row + 1;
snakeNode->col = snakeNode->preNode->col;
break;
case DIR_DEF::LEFT:
snakeNode->row = snakeNode->preNode->row;
snakeNode->col = snakeNode->preNode->col + 1;
break;
case DIR_DEF::RIGHT:
snakeNode->row = snakeNode->preNode->row;
snakeNode->col = snakeNode->preNode->col - 1;
break;
default:
break;
}
auto nodeSprite = Sprite::create("snake_head.png");
nodeSprite->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
nodeSprite->setPosition(Vec2(snakeNode->col * 32, snakeNode->row * 32));
snakeNode->nodeSprite = nodeSprite;
addChild(nodeSprite);
_allBody.pushBack(snakeNode);
}
}
void GameScene::menuCallBack(Ref * pSender) {
Director::getInstance()->getScheduler()->unschedule(schedule_selector(GameScene::logic), this);
Director::getInstance()->replaceScene(StartScene::createScene());
}
void GameScene::gameOver() {
this->unschedule(SEL_SCHEDULE(&GameScene::logic));
auto visibleSize = Director::getInstance()->getVisibleSize();
auto label = Label::createWithTTF("Game Over", "fonts/Marker Felt.ttf", 48);
label->setAnchorPoint(Point::ANCHOR_MIDDLE);
label->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
addChild(label);
this->scheduleOnce(SEL_SCHEDULE(&GameScene::menuCallBack), 2.0f);
}
Cocos2d-x贪吃蛇代码

【Cocos2d-x贪吃蛇代码】是一个基于Cocos2d-x 3.14版本和Visual Studio 2013开发的经典游戏项目。Cocos2d-x是一款开源的游戏开发框架,它允许开发者使用C++、Lua或者JavaScript进行游戏编程,并能跨平台运行在iOS、Android、Windows等操作系统上。这个项目特别之处在于它实现了大家熟知的“贪吃蛇”游戏,一个简单却极具挑战性的游戏,玩家需要控制一条蛇在有限的空间内不断觅食,每次吃到食物后,蛇的身体会变长,操作不当则会导致蛇头碰到自己的身体而游戏结束。
在Cocos2d-x中,游戏的核心逻辑主要通过继承自`cc.Node`的类来实现,比如`SnakeBody`表示蛇的身体节点,`Food`表示食物节点,以及`GameScene`作为游戏场景。每个`SnakeBody`节点都包含位置信息,通过改变这些节点的位置来实现蛇的移动。`Food`随机生成在游戏区域,当蛇头碰到食物时,分数增加,蛇身增长。游戏场景`GameScene`负责游戏状态的管理,如初始化、更新、碰撞检测和游戏结束判断。
在VS2013中,开发者可以利用Cocos2d-x提供的构建工具创建项目,编写源代码,并通过IDE进行调试。Cocos2d-x的事件处理系统使得添加用户交互变得简单,例如,通过监听触摸事件来控制蛇的移动方向。
在实现贪吃蛇的过程中,关键的技术点包括:
1. **精灵(Sprite)和批处理(Batch Node)**:Cocos2d-x中的精灵用于表示游戏中的可视化元素,如蛇的身体和食物。批处理节点可以将多个具有相同纹理的精灵合并为一个渲染批次,提高游戏性能。
2. **定时器(Scheduler)**:用于控制游戏循环和更新,如蛇的移动、食物的生成等。
3. **碰撞检测**:通过计算蛇头与自身身体各部分的位置关系,判断是否发生碰撞。
4. **物理引擎(可选)**:虽然贪吃蛇的规则相对简单,但可以考虑使用Cocos2d-x的Box2D物理引擎模拟简单的碰撞效果,增加游戏的真实感。
5. **得分系统**:每当蛇吃到食物,分数增加并显示在屏幕上。
6. **游戏状态管理**:使用状态机模式管理游戏的开始、进行和结束状态。
7. **资源管理**:有效地加载和释放图片、音频等资源,防止内存泄漏。
8. **用户输入处理**:响应用户的触摸或键盘输入,改变蛇的移动方向。
9. **动画效果**:通过改变精灵的帧来实现蛇移动的动画效果。
10. **调试与优化**:利用Cocos2d-x的调试工具对游戏性能进行监控和优化,确保游戏在各种设备上流畅运行。
这个项目对于初学者来说是一个很好的学习Cocos2d-x和游戏开发的起点,通过阅读和理解代码,可以深入学习游戏框架的使用,掌握基本的游戏逻辑和编程技巧。同时,对于有经验的开发者,这也是一个拓展和实践现有技能的好机会,可以尝试添加更多的功能,如多人在线对战、不同难度等级、自定义皮肤等,使游戏更加丰富和有趣。

lzmxqh
- 粉丝: 2
最新资源
- 网络安全(PPT36页)(1).ppt
- 论借助sniffer诊断Linux网络故障.docx
- 商务英语教学中网络的地位.doc
- 在市打击治理电信网络新型违法犯罪联席会议上表态发言三篇.doc
- 2023年大学计算机基础期末考试知识点.doc
- 系统安全预测技术.pptx
- 企业信息化建设的重要性和状况.docx
- 遥感数字图像处理考题整理.doc
- 高校师生同上一堂网络安全课观后感心得感悟5篇.docx
- 企业集团财务结算中心与计算机系统设计与会计操作.doc
- 电话网络系统方案.doc
- 九上下册物理第三节:广播-电视和移动通信公开课教案教学设计课件测试卷练习卷课时同步训练练习公开课教案.ppt
- 图像处理:十一表示描述.ppt
- 什么网站工作总结写的比较好.docx
- 项目管理与招标采购培训重点课程.doc
- 有关信息化银行对账问题的探讨【会计实务操作教程】.pptx