Cocos2d-x v3.6制作射箭游戏(一)

最近玩了一个叫做大箭师鲍比的射箭游戏,觉得蛮好玩的,对此也产生了强烈的copy情结。所以从今天开始,我们将开始新的篇章,同大家分享这款基于 Cocos2d-x-3.6 引擎的游戏的一些制作心得,希望对大家有所帮助。

下图是原版游戏的效果图,有兴趣的童鞋可以在网上找来玩玩。

PS:之前已写过多次教程,现如今本人当然还是觉得写初级教程要得心应手些(呵呵,毕竟能力所限),不过初级的写的次数多了,也稍微有些厌烦了。所 以,本教程我们将加大进度,游戏中所涉及到的一些基础概念我们将不会做过多的陈述(当然必要的步骤还是会列举出来的)。所以小白同志们注意了,如果根不上 进度的请先看看基础教程哦,这里推荐本人之前写过的 SLG 游戏作为入门教程。

那么,下面我们就正式进入到游戏的开发吧。

前期须知

首先,本游戏所用引擎版本为 Cocos2d-x v3.6 ,开发工具用的是Xcode 5.1

开发环境未配置的童鞋请先移步到这里将环境配置好。

Cocos2d-x 3.6 创建项目的方式与它之前的几个版本并没有什么区别,打开终端(Windows下是打开cmd)进入到引擎文件夹目录,运行setup.py,然后再输入以下命令行就可以创建一个新项目。


1

cocos new arrowGame -p com.cocos2dx.rs -l cpp -d /Users/cocos2d-x/workspace/cocos2dx/projects

new:new后是项目名
-p :-p后是包名
-l :-l后是语言(cpp指c++)
-d :-d后是项目生成路径

项目初配置

在新建的项目中已经有一些默认的文件和类,比如这里的 HelloWorldScene 类。它对于我们是没用的,所以你可以把它删除,然后再新建一个需要的游戏场景类。

在进行以上操作的时候,我们需要修改 AppDelegate.cpp
文件中相应的方法来启动新建的游戏场景。如现在我们新建一个游戏场景类并命名为 GameScene,那么在 AppDelegate.cpp 文件的
applicationDidFinishLaunching() 方法中,我们需要第一个就启动它,而不是启动原来的
HelloWorldScene。所以如下代码所示修改 runWithScene 的场景:


1

2

auto scene = GameScene::createScene();

director->runWithScene(scene);

另外,本游戏所用游戏资源是按 864 * 480 的大小制作的,所以为了让这套资源能应用到市场上各类分辨率大小的移动设备,接下来我们需要做的事是进行分辨率适配。

分辨率适配同样在 applicationDidFinishLaunching 方法中进行,只需添加以下两行代码:


1

2

glview->setDesignResolutionSize(480.0f, 320.0f, ResolutionPolicy::FIXED_HEIGHT);

director->setContentScaleFactor(480.0f / 320.0f);

这里具体的原理我就不解释了,请大家参考我之前的文章。

GameScene 场景分析

GameScene 场景是本游戏的主场景,开始游戏之前,我们先从原游戏的游戏场景中看看我们需要做些什么?

  • 首先,对于游戏地图,这里有一些排布整齐的砖块、箱子、障碍物之类的图块。看到这个你是不是跟我一样,第一反应就是用 TiledMap
    编辑器来编辑。不管你是不是,反正我是了,而且我也决定要用了。这样一来,游戏中玩家和敌人的位置我们也可以通过 TiledMap
    的对象属性来标识了。
  • 然后,游戏中玩家射出去的箭是呈抛物线射出去的,一般大家都会觉得这个功能只要让箭执行贝塞尔动作就可以实现。但不要忘了,箭在按曲线移动的时候它的角度也在不停的变换,所以我们不能单纯的认为很简单,这个需要另辟蹊径,重写自己需要的贝塞尔动作!
  • 当箭射出去后,它碰到砖块、箱子时会有个一定的反弹效果,所以很显然这里我们需要用物理引擎来实现这个模块的功能。

先就分析到这里,下面我们来看看 GameScene 的声明。

GameScene的声明

其实 GameScene 与 HelloWorldScene 差不多,其初定义如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include "cocos2d.h"

USING_NS_CC;

class GameScene : public Layer

{

public:

    GameScene();

    static cocos2d::Scene* createScene();

    virtual bool init();

    void addGameBg();

    CREATE_FUNC(GameScene);

private:

    Size winSize;                  // 窗口尺寸

    TMXTiledMap *map;              // 地图背景对象

    TMXObjectGroup * objectGroup;  // 对象组对象

    float objectPosOffX;           // 对象组X方向上的偏移值

};

在 addGameBg 方法中我们将载入游戏背景,这里我们把游戏背景分为如下的两部分,一部分是背景图片,另一部分是地图背景。这样的组合有利于关卡设计中多样性的搭配。

地图背景

地图背景是用 TiledMap
编辑器制作出来的,本游戏中它是由27*15个相同大小的图块(32*32)组合而来(透明的地方没有图块)。从上图你也可以看出,我们已在地图上设置了
当前关卡地形的大致布局。另外,我们之前不是说好要用 TiledMap 的对象属性来标识玩家和敌人的位置吗,下面就是 TiledMap
中添加了对象的例子。

注意:对象是为了能让开发更方便而设计的,它并不对应于某个地图图片,只是标明了某个透明物体的位置/形状/大小等属性,这样开发者就可以通过相关
API 获取某个对象的位置,从而在相应的位置绘制真实看的见的 Node 对象了。我们在制作 TiledMap
地图时,可以想上图一样给对象取一个标示它的名字,这样我们就可以通过对象的名字来获取到它的位置等信息了。对象常常用于添加除背景以外的游戏元素(如道
具、障碍物等)。

创建教程中的地图大致可分为以下两个步骤

  1. 创建普通图层 “logicLayer”,我们在这上边放置看的到的图块。如地图中的砖块、箱子、草地等等。这里我们可以根据自己的想法,创建出各种类型的地图样式。
  2. 创建对象层“object”,同时在对象层上创建各个对象,并给每个对象添加名字属性。

初学者如果想了解更多详细的地图制作过程,可参考Quick-Cocos2d-x初学者游戏教程(七)一文。

载入程序

介绍了地图背景之后,接下来我们就来看看 addGameBg 的实现,如下所示:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

void GameScene::addGameBg(){

    // 添加图片背景,把它放在屏幕正中间

    Sprite* spGameBg = Sprite::create("bg1.jpg");

    spGameBg->setPosition(Vec2(winSize.width/2, winSize.height/2));

    this->addChild(spGameBg, -1);

    // 添加地图背景,把它放在屏幕正中间   

    map = TMXTiledMap::create("map1.tmx");

    map->setAnchorPoint(Vec2(0.5f, 0.5f));

    map->setPosition(Vec2(winSize.width / 2, winSize.height/2));

    this->addChild(map, -1);

    // 获取 objectGroup 对象(也就是地图中的对象层)

    objectGroup = map->getObjectGroup("object");

    // 计算对象组在 X 方向上的偏移值

    objectPosOffX = -(map->getContentSize().width - winSize.width) / 2;

}

将 TiledMap 制作出的 .tmx 地图文件加载到游戏中需要用到 Cocos2dx 提供的 TMXTiledMap 类,它可以直接通过 .tmx 文件名来创建瓦片地图
TMXTiledMap 类有很多方法可以操控我们的 地图文件,如上代码所示的 getObjectGroup 方法,它可以获取对应名称的对象层。

这里需要特别说明的是 objectPosOffX 这个属性。由于对象组中对象的位置坐标是从屏幕的(0, 0)点开始的,所以当我们把地图背景放置在屏幕中间时,地图可能超出屏幕外或不足填满整个窗口,这时对象的坐标就可能会出现如下图所示的偏移。

所以,我们需要计算出对象的偏移值,以便后面获取对象时修正它的位置。

好了,此时你在 init 方法中调用 addGameBg() 就可以看到游戏背景了。

PS:是不是觉得背景两边被裁减了,是的,不过不要以为出错了,因为我们要的就是这个效果,这是分辨率适配下选择 FIXED_HEIGHT 模式的后遗症。这也是为什么我们要计算对象组在 X 方向上的偏移值的原因。

时间: 2024-08-25 01:46:31

Cocos2d-x v3.6制作射箭游戏(一)的相关文章

Cocos2d-x v3.6制作射箭游戏(二)

上章我们创建并加载了游戏地图,接下来的两章我们将实现如下的效果. 在开始之前,先给大家道个歉,因为前几周忙,没有时间写教程,所以迟迟都没更新,让有些童鞋久等了,见谅哦!! 本章我们的主要任务是创建射箭的弓箭手(也就是游戏猪脚),并且让这个猪脚随着触摸点的改变不断的旋转手中的弓箭. 分析: 对于这个射箭的角色而言,它能不停的射出弓箭.当我们按住屏幕上某点时,会从该角色拿弓箭的手的位置“画”一条标注箭支运动轨迹的红线(看似抛物 线):当在屏幕上滑动手指或鼠标时,这条红线会随着触摸点的位置不停的变换轨

Cocos2d-x v3.6制作射箭游戏(三)

上章我们已经创建好了射箭的游戏角色,接下来这章我们将开始实现射箭的部分. 本章主要内容: 添加玩家的射箭逻辑: 讲解弓箭做曲线运动的原理. 射箭 首先我们来看看射箭时(弓箭离弦之前) Player 的一些逻辑行为吧. 先简单的分析了一下: 当用户触摸结束时,Player 会有一个拔箭准备射箭的动作,等这个动作执行完的时候,会在 Player 拿弓箭的手的地方创建一支箭,并且这支箭会按曲线轨迹飞出去. 但试想一下,如果我们在拔箭动作还没执行完的时候又点击了屏幕,那么还没等上一支弓箭发射出去马上又要

使用UNITY3d制作2048游戏

使用unity的插件NGUI,可以快速的制作2D游戏: 2048这个游戏主要的核心是算法,不管用cocos2d,erget还是其他的引擎,算法基本不变,细节有变化而已: 基本算法图: 数字代表XY坐标,每个格子都有一个特定坐标,首先定义一个4*4的数组来存储这个棋盘格局: 一,界面区目录 UI ROOT(-Number)

使用CocosSharp制作一个游戏 - CocosSharp中文教程

注:本教程翻译自官方<Walkthrough - Building a game with CocosSharp>,官方教程有很多地方说的不够详细,或者代码不全,导致无法继续,本人在看了GoneBananas项目代码后,对本教程进行了部分修改,但当前只涉及Android方面,iOS因没有环境验证代码,暂未修改. 本人博客地址:http://fengyu.name 原文链接:http://fengyu.name/?cat=game&id=295 相关资源: 离线PDF文档:Downloa

Cocos2d-x中由sprite来驱动Box2D的body运动(用来制作平台游戏中多变的机关)

好久都没写文章了,就来一篇吧.这种方法是在制作<胖鸟大冒险>时用到的.<胖鸟大冒险>中使用Box2D来进行物理模拟和碰撞检測,因此对每一个机关须要创建一个b2body.然后<胖鸟>是依据<超级马里奥兄弟>设计的,所以机关能够是各种运动轨迹的平台,绕圈转的乌龟,蹦蹦跳的乌龟等.假设用box2d来做这些运动的话要自己写这些轨迹.可是Cocos2d-x已经提供了非常多的action,自己添加action也非常方便.反过来用sprite去设置box2d的b2body

使用cocos2d-x v3.1开发小游戏(基本框架)

小游戏的组成 欢迎界面 在游戏资源未全部加载完之前就需要载入,避免进入游戏会有一段黑屏时间. 可以用来展示游戏名称或者开发者logo. 开始菜单界面 一般用于显示游戏名称和关卡选择(或者称游戏难度选择). 可以外加一些设置性功能,如声音开关,帮助入口等等. 如果游戏设置内容较多可以把设置作为一个单独界面,在开始菜单上提供入口即可. 有的小游戏是以弹窗方式的菜单 主游戏界面 游戏的中心部分,比如2048游戏的格子滑动界面,扫雷游戏的扫雷界面,贪吃蛇游戏的蛇移动的界面,等等. 小游戏拥有这一个界面也

Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(五)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 为了暂时不影响原来的cat移动方法,我们在CatSprite.m中新建一个移动方法,内容如下,其中考虑了与地图的碰撞情况: -(void)moveTowardOneTile:(CGPoint)location{ CGPoint diff = ccpSub(location, self.position); CGPoint desiredTileCoord = [

Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(二)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 首先在CatMazeV3中新建CatSprite类,继承于Sprite.其中CatSprite.h文件如下所示: #import "CCSprite.h" @class MainScene; @interface CatSprite : CCSprite @property (nonatomic,assign,readonly) NSInteger n

Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(三)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面看一下CatSprite中最复杂的moveToward方法,我们一开始只是想要确保cat在屏幕上正确显示出来,动画正确播放出来,所以可以先不管与地图碰撞检测的问题.于是简化到如下代码: -(void)moveToward:(CGPoint)targetLocation{ CGPoint diff = ccpSub(targetLocation, self.p