Cocos2dx 3.2 横版过关游戏Brave学习笔记(一)

作者: douxt

最近看了一下《使用Quick-Cocos2d-x搭建一个横版过关游戏》这个教程。当然这个游戏的名字叫做Brave

我不太懂lua,但感觉代码意思基本能看出来,就想用C++重新写一下这个示例,一方面了解一下lua,另一方面还可以熟悉一下用C++的开发。本人小白,免不了会犯些愚蠢的错误,不过犯了错只要能发现就是进步。

环境:
Cocos2dx 3.2
VS2012
Win32平台

资源及源码:
https://github.com/douxt/Brave_cpp   (不包含cocos2d文件夹,大概4.3MB)
点击 Download Zip 即可下载。
强烈建议自己新建项目,可以避免一些版本相关的错误。

目录

Cocos2dx 3.2  横版过关游戏Brave学习笔记(一)
Cocos2dx 3.2  横版过关游戏Brave学习笔记(二)
Cocos2dx 3.2  横版过关游戏Brave学习笔记(三)
Cocos2dx 3.2  横版过关游戏Brave学习笔记(四)
Cocos2dx 3.2  横版过关游戏Brave学习笔记(五)
Cocos2dx 3.2  横版过关游戏Brave学习笔记(六)
Cocos2dx 3.2  横版过关游戏Brave学习笔记(七)
Cocos2dx 3.2  横版过关游戏Brave学习笔记(八)

1.创建工程

打开命令行,输入:

cocos new -l cpp -d e:/projects/   Brave_cpp

这个命令会帮你创建一个新的HelloWorld工程,而且把整个cocos2d的源码给你拷了一份放在工程下面。

运行一下这个工程,什么,竟然报错了。果断关闭所有VS窗口,重新打开运行,发现竟然正常运行了。
将资源文件复制到Resource文件夹下面备用。
删除掉init中按钮,精灵,标签等代码,让程序变成只显示一个黑屏。

给游戏添加角色

添加背景:

加入代码,加完后init函数内容如下:

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
   
    Sprite* background = Sprite::create("image/background.png");
    background->setPosition(origin + visibleSize/2);
    this->addChild(background);

    return true;
}

这样应该就可以显示出背景了。咦,Vec2类型竟然可以直接与Size类型相加?Size可以支持除法?这是怎么一回事呢?看一下Size源码,Size类定义了除法运算,Vec2难道定义了对Size的加法?不对,Vec2里没有关于Size的加法运算符。那就是Size可以自动转化成Vec2了?看到Size中有个如下的定义:

public:
    operator Vec2() const
    {
        return Vec2(width, height);
    }

精确的含义我没查到,不过应该可以理解为:如果有人把Size当作Vec2,就按这个方法给他一个Vec2.

冥冥之中自有天意,本来应该是一时的手误竟然背后还隐藏着道理……另外,Size还重载了=操作符,可以用Vec2给Size赋值。

导入精灵帧资源
继续在init函数中加入:

 SpriteFrameCache::getInstance()->addSpriteFramesWithFile("image/role.plist","image/role.pvr.ccz");

这个资源里包含了一些玩家、敌人动作的精灵帧,需要提前导入缓存。

显示玩家和怪物

玩家应该是一个类,可以继承自Sprite。原文中为Player建立了一个类,为Enemy1也建立了一个类,然后在后面出现Enemy2的时候又建立了一个类。
我觉得这几个类可以用一个类代替,因为他们属性十分类似,目前只是贴图不同,仅仅因为这个就建立这么多类不太划算。
添加的Player.h如下:

#ifndef __Player__
#define __Player__
#include "cocos2d.h"
USING_NS_CC;

class Player : public Sprite
{
public:
 enum PlayerType
 {
  PLAYER,
  ENEMY1,
  ENEMY2
 };

 bool initWithPlayerType(PlayerType type);

 static Player* create(PlayerType type);


};

#endif

目前先考虑三类角色,player , enemy1, enemy2。创建时,用枚举类型指定是哪一种。

Player.cpp 如下:

#include "Player.h"

bool Player::initWithPlayerType(PlayerType type)
{
 std::string spName = "";
 switch(type)
 {
 case PlayerType::PLAYER:
  spName = "player1-1-1.png";
  break;
 case PlayerType::ENEMY1:
  spName = "enemy1-1-1.png";
  break;
 case PlayerType::ENEMY2:
  spName = "enemy2-1-1.png";
  break;
 }
 this->initWithSpriteFrameName(spName);
 return true;
}


Player* Player::create(PlayerType type)
{
 Player* player = new Player();
 if(player && player->initWithPlayerType(type))
 {
  player->autorelease();
  return player;
 }
 else
 {
  delete player;
  player = NULL;
  return NULL;
 }
}

可以看出,其核心就是根据不同的角色类型,用不同的SpriteFrameName来初始化精灵。

继续在HelloWorld的init类中加入:

 Player* player = Player::create(Player::PlayerType::PLAYER);
 player->setPosition(origin.x + player->getContentSize().width/2, origin.y + visibleSize.height/2);
 this->addChild(player);

 Player* enemy1 = Player::create(Player::PlayerType::ENEMY1);
 enemy1->setPosition(origin.x + visibleSize.width - player->getContentSize().width/2, origin.y + visibleSize.height/2);
 this->addChild(enemy1);

运行程序,结果如下:



刚开始用git,发现项目目录下好多文件是不需要提交的,比如lib文件什么的。虽说可以靠只add需要的文件来实现,但系统总是有提示。
在项目目录下建立一个.gitignore文件,可以使其忽略没必要上传的文件。
例如:


  1. *.[oa]
  2. *.lib
  3. *.sdf
  4. *.opensdf
  5. cocos2d/
  6. .git*
  7. proj.win32/Debug.win32/
  8. proj.android/
  9. proj.ios_mac/
  10. proj.linux/
  11. proj.wp8-xaml/

这样提交,上传就感觉顺多了。

标签: none

?>