鄙人做iOS应用开发有一段时间了,一直对游戏开发有浓厚的兴趣,只是少了游戏入门的方法, 最近在论坛中看到了 极客学院的免费视频(好像是关联邮箱限免一天,我不是在给极客打广告哦,只是觉得视频确实不错.)才得以初窥门径.有些不足的地方希望大神们多多指教.闲话不多说,上代码
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class SnakeSprite;
class BodyScene;
class HelloWorld : public cocos2d::Layer
{
private:
cocos2d::Size visibleSize;
cocos2d::LayerColor *layerColorGB;
SnakeSprite *snake;
BodyScene *food;
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(HelloWorld);
// 判断方向
void handleDirect(cocos2d::Point point);
// 创建背景
void drawBackground();
// 初始化蛇
void initSnake();
// 初始化食物
BodyScene* createFood();
// 长大
void growUp();
};
#endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h"
#include "SnakeScene.h"
#include "BodyScene.h"
USING_NS_CC;
Scene* HelloWorld::createScene()
{
auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
scene->getPhysicsWorld()->setGravity(Vec2(0, 0));
scene->getPhysicsWorld()->setSpeed(10);
auto layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !Layer::init() )
{
return false;
}
visibleSize = Director::getInstance()->getVisibleSize();
drawBackground();
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = (Touch *t, Event *e){
if (e->getCurrentTarget()->getBoundingBox().containsPoint(t->getLocation())) {
Point point = t->getPreviousLocation();
this->handleDirect(point);
return true;
}
return false;
};
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
return true;
}
void HelloWorld::handleDirect(cocos2d::Point point)
{
Direct d = snake->getDirect();
Point p = snake->getPosition();
short xx = point.x - p.x;
short yy = (point.y - (visibleSize.height-visibleSize.width)/2) - p.y;
Direct newDirect = d;
switch (d) {
case Up:
{
if (abs(xx) > abs(yy)) {
if (xx > 0) {
// right
newDirect = Right;
} else {
//left
newDirect = Left;
}
} else {
if (yy < 0) {
// down
// newDirect = Down;
}
}
}
break;
case Down:
{
if (abs(xx) > abs(yy)) {
if (xx > 0) {
// right
newDirect = Right;
} else {
//left
newDirect = Left;
}
} else {
if (yy > 0) {
// up
// newDirect = Up;
}
}
}
break;
case Left:
{
if (abs(yy) > abs(xx)) {
if (yy > 0) {
// up
newDirect = Up;
} else {
//down
newDirect = Down;
}
} else {
if (xx > 0) {
// right
// newDirect = Right;
}
}
}
break;
case Right:
{
if (abs(yy) > abs(xx)) {
if (yy > 0) {
// up
newDirect = Up;
} else {
//down
newDirect = Down;
}
} else {
if (xx < 0) {
// left
// newDirect = Left;
}
}
}
break;
default:
newDirect = d;
break;
}
snake->setDirect(newDirect);
}
void HelloWorld::drawBackground()
{
int width = visibleSize.width;
int height = visibleSize.height;
layerColorGB = cocos2d::LayerColor::create(Color4B(200,200,200,255), width, width);
layerColorGB->setPosition(Point(0, (visibleSize.height-visibleSize.width)/2));
addChild(layerColorGB);
width = width;
height = width;
int column = width/20;
int row = height/20;
for (int i = 0; i < row; i++) {
int y = i * 20;
Point p = Point(0, y);
Size size = Size(width, 1);
LayerColor *line = LayerColor::create(Color4B(255, 0, 255, 200), size.width, size.height);
line->setPosition(p);
layerColorGB->addChild(line);
}
for (int j = 0; j < column; j++) {
int x = j *20;
Point p = Point(x, 0);
Size size = Size(1, height);
LayerColor *line = LayerColor::create(Color4B(255, 0, 255, 200), size.width, size.height);
line->setPosition(p);
layerColorGB->addChild(line);
}
// 创建蛇
initSnake();
}
void HelloWorld::initSnake(){
snake = SnakeSprite::createSnake(1);
// eat
snake->onEat = (SnakeSprite *s, void * v){
this->growUp();
};
// game over
snake->reGameOver = ](void *v){
Director::getInstance()->replaceScene(TransitionFade::create(1, HelloWorld::createScene()));
};
layerColorGB->addChild(snake);
snake->start();
// 创建食物
this->createFood();
snake->setFood(food);
}
BodyScene* HelloWorld::createFood(){
// 加入随机整数
srand((unsigned)time(NULL));
int x = rand()%32 * 20+10;
int y = rand()%32 * 20+10;
x = MIN(x, 630);
y = MIN(y, 630);
Point position = Point(x,y);
Size size = Size(20,20);
food = BodyScene::createBody(position, size);
layerColorGB->addChild(food);
return food;
}
void HelloWorld::growUp(){
__Array *bodys = snake->getBodys();
__Array *newBodys = __Array::create();
newBodys->addObject(food);
food->removeFromParent();
snake->addChild(food);
newBodys->addObjectsFromArray(bodys);
snake->setBodys(newBodys);
createFood();
snake->setFood(food);
}
#ifndef __Snake__SnakeScene__
#define __Snake__SnakeScene__
#include "cocos2d.h"
typedef enum : int {
Up = 0,
Down,
Left,
Right,
} Direct;
class BodyScene;
class SnakeSprite:public cocos2d::Sprite{
private:
int number;
cocos2d::__Array *bodys;
Direct direct;
cocos2d::Point position; //
BodyScene *food;// food 用来判断是否吃到食物
public:
std::function onEat;
std::function reGameOver;
virtual bool init();
// 创建方法
static SnakeSprite *createSnake(int num);
void enemyInit(int num);
CREATE_FUNC(SnakeSprite);
// get set 方向
Direct getDirect();
void setDirect(Direct d);
// 跑的动作
void run(float x);
// 开始跑
bool start();
// 结束
void end();
void setPosition(cocos2d::Point p);
cocos2d::Point getPosition();
cocos2d::__Array *getBodys();
void setBodys(cocos2d::__Array *bs);
BodyScene *getFood();
// 设置food 用来判断是否吃到食物
void setFood(BodyScene *b);
// 判断是否继续游戏
bool GameOver();
// void addBody();
};
#endif /* defined(__Snake__SnakeScene__) */
#include "SnakeScene.h"
#include "BodyScene.h"
#define BODY_WIDTH 20
USING_NS_CC;
bool SnakeSprite::init(){
if ( !Sprite::init() )
{
return false;
}
return true;
}
SnakeSprite *SnakeSprite::createSnake(int num){
SnakeSprite *enemy = new SnakeSprite();
if (enemy && enemy->init()) {
enemy->autorelease();
enemy->enemyInit(num);
return enemy;
}
CC_SAFE_DELETE(enemy);
return NULL;
}
void SnakeSprite::enemyInit(int num){
number = num;
bodys = __Array::create();
bodys->retain();
Point position = Point((640-BODY_WIDTH)/2,(640-BODY_WIDTH)/2);
Size size = Size(BODY_WIDTH, BODY_WIDTH);
BodyScene *body = BodyScene::createBody(position, size);
bodys->addObject(body);
this ->addChild(body);
}
Direct SnakeSprite::getDirect()
{
return direct;
}
void SnakeSprite::setDirect(Direct d)
{
direct = d;
}
bool SnakeSprite::start(){
this->schedule(schedule_selector(SnakeSprite::run), 0.2);
return true;
}
void SnakeSprite::end(){
this->unschedule(schedule_selector(SnakeSprite::run));
CC_SAFE_DELETE(bodys);
}
void SnakeSprite::setPosition(cocos2d::Point p)
{
position = p;
}
cocos2d::Point SnakeSprite::getPosition()
{
return position;
}
cocos2d::__Array* SnakeSprite::getBodys(){
return bodys;
}
void SnakeSprite::setBodys(cocos2d::__Array *bs)
{
CC_SAFE_DELETE(bodys);
bodys = __Array::create();
bodys = bs;
bodys->retain();
}
BodyScene *SnakeSprite::getFood()
{
return food;
}
void SnakeSprite::setFood(BodyScene *b)
{
CC_SAFE_RELEASE(food);
food = b;
food->retain();
}
// 1 2 3 4 5
void SnakeSprite::run(float x){
int space = BODY_WIDTH;
int count = (int)bodys->count();
for (int i = count-1; i >= 0; i--) {
BodyScene *body1 = (BodyScene *)bodys->getObjectAtIndex(i);
if (i > 0) {
BodyScene *body2 = (BodyScene *)bodys->getObjectAtIndex(i-1);
body1->setPosition(body2->getPosition());
} else {
Point position = Point(body1->getPosition().x, body1->getPosition().y + space);
switch (direct) {
case Up:
{
position = Point(body1->getPosition().x, body1->getPosition().y + space);
}
break;
case Down:
{
position = Point(body1->getPosition().x, body1->getPosition().y - space);
}
break;
case Left:
{
position = Point(body1->getPosition().x - space, body1->getPosition().y);
}
break;
case Right:
{
position = Point(body1->getPosition().x+space, body1->getPosition().y);
}
break;
default:
break;
}
setPosition(position);
body1->setPosition(position);
}
}
if (GameOver()) {
end();
reGameOver(NULL);
}
}
bool SnakeSprite::GameOver(){
BodyScene *first = (BodyScene *)bodys->getObjectAtIndex(0);
for (int i = 1; i < bodys->count(); i++) {
BodyScene *body = (BodyScene *)bodys->getObjectAtIndex(i);
if (first->getPosition() == body->getPosition()) {
return true;
}
}
if (first->getPosition().x <= 0 || first->getPosition().y <= 0 || first->getPosition().x >= 640 || first->getPosition().y >= 640) {
return true;
}
log("(x1=%f, y1=%f) (x2=%f, y2=%f)",first->getPosition().x, first->getPosition().y, food->getPosition().x, food->getPosition().y);
if (first->getPosition() == food->getPosition()) {
// eat
onEat(this, NULL);
}
return false;
}
#ifndef __Snake__BodyScene__
#define __Snake__BodyScene__
#include "cocos2d.h"
class BodyScene:public cocos2d::Sprite{
private:
int x, y;
cocos2d::Point position;
cocos2d::Size size;
// 显示背景
cocos2d::LayerColor *layerColorBG;
public:
virtual bool init();
CREATE_FUNC(BodyScene);
static BodyScene *createBody(cocos2d::Point position, cocos2d::Size size);;
static BodyScene *createBody(int x, int y, cocos2d::Size size);;
void enemyInit(cocos2d::Point position, cocos2d::Size size);
};
#endif /* defined(__Snake__BodyScene__) */
#include "BodyScene.h"
USING_NS_CC;
bool BodyScene::init(){
if (!Sprite::init()) {
return false;
}
return true;
}
BodyScene * BodyScene::createBody(cocos2d::Point position, cocos2d::Size size)
{
BodyScene *enemy = new BodyScene();
if (enemy && enemy->init()) {
enemy->autorelease();
enemy->enemyInit(position, size);
return enemy;
}
CC_SAFE_DELETE(enemy);
return NULL;
}
BodyScene *BodyScene::createBody(int x, int y, cocos2d::Size size)
{
BodyScene *enemy = new BodyScene();
if (enemy && enemy->init()) {
enemy->autorelease();
enemy->enemyInit(cocos2d::Point(x,y), size);
return enemy;
}
CC_SAFE_DELETE(enemy);
return NULL;
}
void BodyScene::enemyInit(cocos2d::Point position, cocos2d::Size size)
{
this->x = position.x;
this->y = position.y;
this->position = position;
this->size = size;
this->setContentSize(size);
this->cocos2d::Node::setPosition(position);
layerColorBG = cocos2d::LayerColor::create(Color4B(200, 0, 100, 255), size.width, size.height);
layerColorBG->setPosition(0,0);
this->addChild(layerColorBG);
}
```
源码:https://codeload.github.com/sfwan2014/SnakeDemo/zip/master,1
