Cocos2dx学习第八章(游戏实例之跑跑跑)

Cocos2dx学习第八章(游戏实例之跑跑跑),第1张

概述这一章是一个简单的实例,当做练习,熟练一下代码。 首先介绍个地图软件,然后就是贴代码。 1.Tiled Map Editor软件 这款软件用于生成tmx格式的地图文件,我们利用他来制作地图。 (1)新建一个文件,会d出下面的提示框,填写自己想要的参数即可: (2)把图片拖到图块窗口,图片包含我们需要的元素,这样,我们就可以利用图片的元素,对新建的文件进行简单的绘图。 (3)最后,点击图块的图片元素

这一章是一个简单的实例,当做练习,熟练一下代码。 首先介绍个地图软件,然后就是贴代码。

1.Tiled Map Editor软件

这款软件用于生成tmx格式的地图文件,我们利用他来制作地图。

(1)新建一个文件,会d出下面的提示框,填写自己想要的参数即可:


(2)把图片拖到图块窗口,图片包含我们需要的元素,这样,我们就可以利用图片的元素,对新建的文件进行简单的绘图。


(3)最后,点击图块的图片元素,再到新建的文件点击,就可以覆盖上面的格子,也就完成画图。


(4)注意要把生成的地图文件tmx和所用的图片放在resource文件夹下,以免找不到资源,报错,需要打开tmx文件,修改png的路径,直接名字就好了。

把tmx文件用文本编辑器打开,这个是最终版本:

<?xml version="1.0" enCoding="UTF-8"?><map version="1.0" orIEntation="orthogonal" renderorder="right-up" wIDth="60" height="10" tilewIDth="70" tileheight="70"> <tileset firstgID="1" name="map" tilewIDth="70" tileheight="70">  <image source="map.png" wIDth="980" height="490"/> </tileset> <tileset firstgID="99" name="Meta_tiles" tilewIDth="70" tileheight="70">  <image source="Meta_tiles.png" wIDth="280" height="70"/>  <tile ID="0">   <propertIEs>    <property name="CollIDable" value="true"/>   </propertIEs>  </tile>  <tile ID="1">   <propertIEs>    <property name="food" value="true"/>   </propertIEs>  </tile>  <tile ID="2">   <propertIEs>    <property name="win" value="true"/>   </propertIEs>  </tile> </tileset> <layer name="块层 1" wIDth="60" height="10">  <data enCoding="base64" compression="zlib">   eJxjYBhZwGOEYW8g9qJKyA1+YM0w6t/hDEb9O7zBqH+HNwD5d6DrQ3pikH8B3KEnZA==  </data> </layer> <objectgroup name="objects">  <object name="PlayerPoint" x="72" y="353.333" wIDth="66.6667" height="70.6667"/>  <object x="94.6667" y="394.667"/> </objectgroup> <layer name="barrIEr" wIDth="60" height="10">  <data enCoding="base64" compression="zlib">   eJxjYBgFowACeAfaATQEvEgYm9hw8zuyv/iQxGCAD0PH0Abo/uVjIC5+h2r84/IvjD3cAK78O5LAcC6vhisaajOfAis=  </data> </layer> <layer name="Meta" wIDth="60" height="10">  <data enCoding="base64" compression="zlib">   eJxjYBgFowACUgbaATQEKUgYm9hw8zuyv5KRxGAgGUPH0Abo/k1mIC1+U2nqOuoDXP6FsWFguMQzrvw7ksBwLq+GKwAAN1oP/Q==  </data> </layer></map>
(5)让生成的图片显示出来,只需加以下一句代码
	TMXTiledMaP* map = TMXTiledMap::create("level101.tmx");	this->addChild(map);

(6)添加对象图层,命名为Objects,如下图:


(6)故名思义,在对象绘制一个矩形,它代表一个对象,顺带设置他的属性,名称。


在代码里面,我们需要加载这个对象层,如何加载呢,且看代码:

TMXObjectGrouP* objGroup = map->getobjectGroup("objects");ValueMap = playerPointMap = objGroup->getobject(PlayerPoint);float playerx = playerPointMap.at("x").asfloat();float playery = playerPointMap.at("y").asfloat();mPlayer->setposition(Point(playerx,playery));

(7)在图层菜单,我们再添加两个图层,首先添加的层命名为barrIEr,把水果放上去,其次,再添加Meta层,把红色格子放上去作为障碍物,并设置红色格子的属性,自己添加属性。


(8)我们把水果添加为食物,只要碰到,就表示吃了水果,水果就自动消失,需要添加属性food。


(9)最后,我们也添加一个win属性的水果,迟到了就表示游戏结束,步骤和上面的一样,然后选中Meta层将该格子覆盖到地图某个格子


2.贴代码由此开始 2.1.创建主角

玩家和怪物有一些共同的 *** 作,我们将他定义为一个实体,作为父类,玩家和怪物都继承他。

#include"cocos2d.h"#include"Controller.h"using namespace cocos2d;class Entity:public Node,public ControllerListener{public:	voID bindSprite(Sprite* sprite);	voID setController(Controller* controller);	virtual voID setTagposition(int x,int y);	virtual Point getTagposition();protected:	Sprite* m_sprite;//bind this sprite	Controller* m_controller;};#endifcpp#include"Entity.h"voID Entity::bindSprite(Sprite* sprite){	m_sprite = sprite;	this->addChild(m_sprite);}voID Entity::setController(Controller* controller)//important{	this->m_controller = controller;	m_controller->setControllerListener(this);}voID Entity::setTagposition(int x,int y)//设置精灵的坐标{	setposition(x,y);}Point Entity::getTagposition()//获取精灵的坐标{	return getposition();}
上面的实体类很简单,用bindsprite来绑定精灵。其余的方法有ControllerListener继承而来,下面会讲到。
#ifndef _CONTRolLERListENER_H_#define _CONTRolLERListENER_H_#include"cocos2d.h"using namespace cocos2d;class ControllerListener  {public:	virtual voID setTagposition(int x,int y) = 0;	virtual Point getTagposition() = 0;};#endif

下面,我们来定义一个玩家类,Player,继承自Entity。

#ifndef _PLAYER_H_#define _PLAYER_H_#include"Entity.h"class Player:public Entity{public:	CREATE_FUNC(Player);	virtual bool init();	voID run();	voID setTiledMap(TMXTiledMaP* map);	voID setVIEwPointByPlayer();	virtual voID setTagposition(int x,int y);private:	TMXTiledMaP* m_map;//用来加载地图文件	bool isJumPing;	TMXLayer* Meta;//检测碰撞的地图层	Point tileCoordForposition(Point pos);//将像素坐标转换为地图格子坐标};#endifcpp文件#include"Player.h"#include"WinScene.h"bool Player::init(){	isJumPing = false;	return true;}voID Player::run()//animation{	SpriteFrameCache* framecache = SpriteFrameCache::getInstance();	framecache->addSpriteFramesWithfile("boys.pList","boys.png");	SpriteFrame* frame = NulL;	Vector<SpriteFrame*> frameList;	for(int i = 1; i <= 15; i++)	{		frame = framecache->getSpriteFrameByname(StringUtils::format("run%d.png",i));		frameList.pushBack(frame);	}	//	Animation* animation = Animation::createWithSpriteFrames(frameList);	animation->setLoops(-1);	animation->setDelayPerUnit(0.08F);	//	Animate* animate = Animate::create(animation);	m_sprite->runAction(animate);}voID Player::setTiledMap(TMXTiledMaP* map)//加载tmx地图文件{	this->m_map = map;	this->Meta = m_map->getLayer("Meta");//直接获取我们加的图层	this->Meta->setVisible(false);}voID Player::setVIEwPointByPlayer()//让主角始终在屏幕中央,地图向后滑动{	if(m_sprite == NulL)		return;	Layer* parent = (Layer*)getParent();	Size tiledSize = m_map->getTileSize();//地图方块数量	Size mapTilednum = m_map->getMapSize();//地图单个格子大小	Size MapSize = Size(mapTilednum.wIDth * tiledSize.wIDth,mapTilednum.height * tiledSize.height);//整个地图的大小	Size visibleSize = Director::getInstance()->getVisibleSize();	Point spritepos = getposition();	float x = std::max(spritepos.x,visibleSize.wIDth/2);	float y = std::max(spritepos.y,visibleSize.height/2);	x = std::min(x,MapSize.wIDth - visibleSize.wIDth/2);	y = std::min(y,MapSize.height - visibleSize.height/2);	Point destPos = Point(x,y);	Point centerpos = Point(visibleSize.wIDth/2,visibleSize.height/2);	Point vIEwPos = centerpos - destPos;	parent->setposition(vIEwPos);}voID Player::setTagposition(int x,int y)//设置精灵的位置,里面包含对碰撞的判断,食物的判断检测{	Size Spritesize = m_sprite->getContentSize();	Point dstPos = Point(x + Spritesize.wIDth/2,y);//主角前方的坐标	Point tiledPos = tileCoordForposition(Point(dstPos.x,dstPos.y));//前方坐标在地图里面格子的位置	int tiledGID = Meta->getTileGIDAt(tiledPos);//获取地图格子唯一的标志	if(tiledGID != 0)//不为0表示存在这个格子	{		Value propertIEs = m_map->getPropertIEsForGID(tiledGID);//获取格子的属性		//Value prop = propertIEs.asValueMap().at("CollIDable");//我们加的属性		ValueMap propMap = propertIEs.asValueMap();		if(propMap.find("CollIDable") != propMap.end())		{			Value prop = propMap.at("CollIDable");			if(prop.asstring().compare("true") == 0 && isJumPing == false)			{				isJumPing = true;				auto jumpBy = JumpBy::create(0.5f,Point(-100,0),80,1);				CallFunc* callfunc = CallFunc::create([&]()				{					isJumPing = false;				});				auto action = Sequence::create(jumpBy,callfunc,NulL);				this->runAction(action);			}		}		//food		if(propMap.find("food") != propMap.end())		{			Value prop = propMap.at("food");			if(prop.asstring().compare("true") == 0)			{				TMXLayer* barrIEr = m_map->getLayer("barrIEr");				barrIEr->removeTileAt(tiledPos);			}		}		if(propMap.find("win") != propMap.end())		{			Value prop = propMap.at("win");			if(prop.asstring().compare("true") == 0)			{				TMXLayer* barrIEr = m_map->getLayer("barrIEr");				barrIEr->removeTileAt(tiledPos);				Director::getInstance()->replaceScene(WinScene::createScene());			}		}	}	Entity::setTagposition(x,y);	setVIEwPointByPlayer();}Point Player::tileCoordForposition(Point pos)//将像素坐标转换为地图格子坐标{	Size mapTilednum = m_map->getMapSize();//地图单个格子大小	Size tiledSize = m_map->getTileSize();//地图方块数量	int x = pos.x/tiledSize.wIDth;	//cocos2d-x的默认y坐标是由下至上的,所以要做一个相减 *** 作	int y = (700 - pos.y)/tiledSize.height;	//格子坐标从0开始计算	if(x > 0)	{		x-=1;	}	if(y > 0)	{		y-=0;	}	return Point(x,y);}
run函数,其实就是一个animation,让精灵看起来是在跑的样子,几张图片轮流播放。 2.2添加控制器

我们把让精灵向前跑作为一个类,为了以后方便扩展,我们首先实现控制器的父类。

#ifndef _CONTRolLER_H_#define _CONTRolLER_H_#include"cocos2d.h"#include"ControllerListener.h"using namespace cocos2d;class Controller:public Node{public:	voID setControllerListener(ControllerListener* controllerListener);protected:	ControllerListener* m_controllerListener;};#endif#include"Controller.h"voID Controller::setControllerListener(ControllerListener* controllerListener){	this->m_controllerListener = controllerListener;}
主要是通过继承这个控制基类,来实现不同的控制需求。
2.3子类控制器

最后,根据需求,制定我们的控制子类。

#ifndef _SIMPLECONTRolLER_H_#define _SIMPLECONTRolLER_H_#include"cocos2d.h"#include"Controller.h"using namespace cocos2d;class SimpleMoveController:public Controller{public:	CREATE_FUNC(SimpleMoveController);	virtual bool init();	virtual voID update(float dt);	voID setxSpeed(int xspeed);	voID setySpeed(int yspeed);private:	int x_speed;	int y_speed;	voID registertouchEvent();};#endif
#include"SimpleMoveController.h"bool SimpleMoveController::init(){	this->x_speed = 0;	this->y_speed = 0;	registertouchEvent();	this->scheduleUpdate();	return true;}voID SimpleMoveController::update(float dt)//update函数,需要在init()那里调用this->scheduleUpdate()才会调用{	if(m_controllerListener == NulL)		return;	Point pos = m_controllerListener->getTagposition();	pos.x += x_speed;	pos.y += y_speed;	m_controllerListener->setTagposition(pos.x,pos.y);}voID SimpleMoveController::setxSpeed(int speed){	this->x_speed = speed;}voID SimpleMoveController::setySpeed(int speed){	this->y_speed = speed;}voID SimpleMoveController::registertouchEvent()//触摸事件处理{	auto Listener = EventListenertouchOneByOne::create();	Listener->ontouchBegan = [](touch* touch,Event* event)	{		return true;	};	Listener->ontouchmoved = [&](touch* touch,Event* event)	{		Point touchPos = Director::getInstance()->convertToGL(touch->getLocationInVIEw());		Point pos = m_controllerListener->getTagposition();//记得引用时,luba里面 【&】		int speed = 0;		if(touchPos.y > pos.y)		{			speed = 1;		}		else		{			speed = -1;		}		setySpeed(speed);	};	Listener->ontouchended = [&](touch* touch,Event* event)	{		setySpeed(0);	};	_eventdispatcher->addEventListenerWithSceneGraPHPriority(Listener,this);//分发事件}
2.4场景代码
#include "HelloWorldScene.h"#include "Player.h"#include "SimpleMoveController.h"USING_NS_CC;Scene* HelloWorld::createScene(){    // 'scene' is an autorelease object    auto scene = Scene::create();        // 'layer' is an autorelease object    auto layer = HelloWorld::create();    // add layer as a child to scene    scene->addChild(layer);    // return the scene    return scene;}// on "init" you need to initialize your instancebool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if ( !Layer::init() )    {        return false;    }	TMXTiledMaP* map = TMXTiledMap::create("level101.tmx");//加载tmx地图文件	this->addChild(map);//将他加到场景	addplayer(map);//把玩家添加到地图    return true;}voID HelloWorld::addplayer(TMXTiledMaP* map){	Size visibleSize = Director::getInstance()->getVisibleSize();	Sprite* playerSprite = Sprite::create("Player.png");	//将精灵绑定到玩家对象上面	Player* mPlayer = Player::create();	mPlayer->bindSprite(playerSprite);	mPlayer->run();	mPlayer->setTiledMap(map);	mPlayer->setposition(Point(100,visibleSize.height/2));	map->addChild(mPlayer);//将Player加到地图	//给玩家设置控制器	SimpleMoveController* smc = SimpleMoveController::create();	smc->setxSpeed(1);	smc->setySpeed(0);	this->addChild(smc);//加到场景,因为继承自Node	mPlayer->setController(smc);}voID HelloWorld::menuCloseCallback(Ref* pSender){#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)	MessageBox("You pressed the close button. windows Store Apps do not implement a close button.","Alert");    return;#endif    Director::getInstance()->end();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)    exit(0);#endif}
2.5效果图

总结

以上是内存溢出为你收集整理的Cocos2dx学习第八章(游戏实例之跑跑跑)全部内容,希望文章能够帮你解决Cocos2dx学习第八章(游戏实例之跑跑跑)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1023645.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存