zoukankan      html  css  js  c++  java
  • Cocos2dx 入门小游戏实例

    从图书馆借了本木头的书籍,以下实例来自书籍,写在这里仅作笔记。。


    游戏内容大概如下:

    1.一个Sprite在地图上一直在跑,Sprite可以跳跃(其实是地图不断向左滚动)

    2.途中有金币,Sprite吃金币,左上方的Score会++,并且会有+15的字样出现



    1.创建实体类Entity,这是一个基类,主要用来绑定一个精灵,返回一个精灵

    #ifndef Entity_H
    #define Entity_H
    
    #include "cocos2d.h"
    using namespace cocos2d;
    
    class Entity:public CCNode
    {
    public:
    	Entity();
    
    	~Entity();
    
    	CCSprite* getSprite();
    
    	void bindSprite(CCSprite* sprite);
    
    private:
    	CCSprite* m_sprite;
    };
    #endif

    #include "Entity.h"
    
    Entity::Entity()
    {
    	m_sprite=NULL;
    }
    Entity::~Entity()
    {
    
    };
    
    CCSprite* Entity::getSprite()
    {
    	return this->m_sprite;
    }
    void Entity::bindSprite(CCSprite* sprite){
    	this->m_sprite=sprite;
    	this->addChild(m_sprite);
    }



    2.创建一个玩家主角类,可以jump,吃金币等

    #ifndef _Player_H
    #define _Player_H
    
    #include "cocos2d.h"
    #include "Entity.h"
    
    
    using namespace cocos2d;
    
    #define JUMP_ACTION_TAG 1;
    
    class Player:public Entity
    {
    public:
    	Player();
    	~Player();
    	CREATE_FUNC(Player);
    	virtual bool init();
    public:
    	void jump();
    	void jumpEnd();
    	void hit();//主角和怪物撞击(玩家受伤害)
    	int getMoney();
    	CCRect getBoundingBox();/*获取碰撞范围*/
    	void resetData();
    	void actionEnd();
    private:
    	bool m_isJumping;
    	int m_money;/*金钱*/
    
    };
    #endif
    #include "Player.h"
    #include "FlowWord.h"
    
    Player::Player()
    {
    	m_isJumping=false;
    	m_money=0;/*初始金钱为0*/
    }
    Player::~Player()
    {
    
    }
    bool Player::init()
    {
    	return true;
    }
    
    void Player::jump()
    {
    	if(!getSprite())
    	{
    		return;
    	}
    	if(m_isJumping)/*如果主角还在跳跃中,则不重复跳跃*/
    	{
    		return;
    	}
    
    	m_isJumping=true;
    
    	/*创建动作,2s,原地跳跃(即落地的地点相对于起跳地点x偏移0,y偏移0),高度250,弹跳次数1*/
    	CCJumpBy* jump=CCJumpBy::create(1.5f,ccp(0,0),200,1);
    	/*callFunc也是一个动作,作用是调用一个函数*/
    	CCCallFunc* callFunc = CCCallFunc::create(this, callfunc_selector(Player::jumpEnd));
    	/*组合动作*/
    	CCActionInterval* jumpActions=CCSequence::create(jump,callFunc,NULL);
    	
    	runAction(jumpActions);
    }
    
    void Player::jumpEnd()
    {
    	m_isJumping=false;
    }
    void Player::hit()
    {
    	if(getSprite()==NULL)
    	{
    		return;
    	}
    	/*加钱特效提示*/
    	FlowWord* flowword=FlowWord::create();
    	this->addChild(flowword);
    	flowword->showWord("+15",getSprite()->getPosition());
    	
    	m_money+=15;
    
    	/*创建4种动作对象*/
    	CCMoveBy* backMove=CCMoveBy::create(0.1f,ccp(-20,0));
    	CCMoveBy* forwardMove=CCMoveBy::create(0.1f,ccp(20,0));
    	CCRotateBy* backRotate=CCRotateBy::create(0.1f,-5,0);
    	CCRotateBy* forwardRotate=CCRotateBy::create(0.1f,5,0);
    
    	/*分别组合成两种动作(同时执行)*/
    	CCSpawn* backActions=CCSpawn::create(backMove,backRotate,NULL);
    	CCSpawn* forwardActions=CCSpawn::create(forwardMove,forwardRotate,NULL);
    
    	CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(Player::actionEnd));
    
    	CCActionInterval* actions=CCSequence::create(backActions,forwardActions,callFunc,NULL);
    	
    	//this->stopAllActions();
    	//resetData();
    
    	this->runAction(actions);
    
    
    }
    void Player::resetData()
    {
    	if(m_isJumping)
    	{
    		m_isJumping=false;
    	}
    	this->setPosition(ccp(200,500/4));
    	this->setScale(1.0f);
    	setRotation(0);
    }
    int Player::getMoney()
    {
    	return m_money;
    }
    CCRect Player::getBoundingBox()
    {
    	if(getSprite()==NULL){
    		return CCRectMake(0,0,0,0);
    	}
    	/*由于Sprite是放在Player上的,所以要检测Player的碰撞范围*/
    	CCSize spriteSize=getSprite()->getContentSize();
    	CCPoint entityPos=this->getPosition();//获取player中心点
    
    	//获取Player左下角的坐标值
    	int x=entityPos.x-spriteSize.width/2;
    	int y=entityPos.y-spriteSize.height/2;
    
    	return CCRectMake(x,y,spriteSize.width,spriteSize.height);
    }
    
    void Player::actionEnd()
    {
    	this->setScale(1.0f);
    	setRotation(0);
    }




    3.创建怪物类(金币),继承于实体类
    --

    #ifndef _Monster_H_
    #define _Monster_H_
    
    #include "Entity.h"
    #include "cocos2d.h"
    #include "Player.h"
    #include "ccMacros.h"
    
    USING_NS_CC;
    
    class Monster:public Entity
    {
    public:
    	Monster();
    	~Monster();
    	CREATE_FUNC(Monster);
    	virtual bool init();
    	
    public:
    	void show();
    	void hide();
    	void reset();//重置怪物数据
    	bool isAlive();//是否活动状态
    
    	bool isCollideWithPlayer(Player* player);//检测是否碰撞
    private:
    	bool m_isAlive;
    };
    #endif
    #include "Monster.h"
    
    Monster::Monster()
    {
    }
    Monster::~Monster()
    {
    }
    bool Monster::init()
    {
    	return true;
    }
    void Monster::show()
    {
    	if(getSprite()!=NULL)
    	{
    		this->setVisible(true);
    		m_isAlive=true;/*标记为活动状态*/
    	}
    }
    void Monster::hide()
    {
    	if(getSprite()!=NULL)
    	{
    		this->setVisible(false);
    		reset();
    		m_isAlive=false;/*标记为活动状态*/
    	}
    }
    void Monster::reset()
    {
    	if(getSprite()!=NULL)
    	{
    		/*初始化怪物坐标,宽度(800-2800),高度(100-200)*/
    		this->setPosition(ccp(800+CCRANDOM_0_1()*2000,200-CCRANDOM_0_1()*100));
    	}
    }
    bool Monster::isAlive()
    {
    	return m_isAlive;
    }
    bool Monster::isCollideWithPlayer(Player* player)
    {
    	CCRect playerRect=player->getBoundingBox();
    	CCPoint monsterPos=getPosition();
    
    	/*判断是否有交集*/
    	return playerRect.containsPoint(monsterPos);
    }



    4.创建怪物管理器类(MonsterManger),用来管理怪物的显示和隐藏


    #ifndef __MonsterManger_H__
    #define __MonsterManger_H__
    
    #include "cocos2d.h"
    #include "Player.h"
    USING_NS_CC;
    
    #define MAX_MONSTER_NUM 10
    
    class MonsterManger:public CCNode
    {
    public:
    	MonsterManger();
    	~MonsterManger();
    	CREATE_FUNC(MonsterManger);
    	virtual bool init();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      	virtual void update(float dt);/*重写update函数*/
    	void bindPlayer(Player* player);
    private:
    	void createMonsters();/*创建Monster对象*/
    private:
    	CCArray* m_monsterArr;/*存放怪物数组*/
    	Player* m_player;
    };
    
    #endif

    #include "MonsterManger.h"
    #include "Monster.h"
    
    MonsterManger::MonsterManger(){}
    
    MonsterManger::~MonsterManger(){}
    
    bool MonsterManger::init()
    {
    	bool bRet=false;
    	do 
    	{
    		createMonsters();/*创建怪物*/
    		this->scheduleUpdate();/*启用update*/
    		bRet=true;
    	} while (0);
    	return bRet;
    	
    }
    
    
    void MonsterManger::createMonsters()
    {
    	m_monsterArr=CCArray::create();
    	m_monsterArr->retain();/*防止数组被释放*/
    
    	Monster* monster=NULL;
    	CCSprite* sprite=NULL;
    
    	for(int i=0;i<MAX_MONSTER_NUM; i++)
    	{
    		monster=Monster::create();
    		monster->bindSprite(CCSprite::create("monster.png"));
    		monster->reset();
    
    		this->addChild(monster);  /*将怪物添加到管理器(CCNode)中*/
    		m_monsterArr->addObject(monster);/*添加到数组中,便于管理*/
    	}
    }
    
    void MonsterManger::update(float dt)
    {
    	CCObject* obj=NULL;
    	Monster* monster=NULL;
    	
    	CCARRAY_FOREACH(m_monsterArr,obj)/*循环遍历怪物数组,重复出现在屏幕上*/
    	{
    		monster=(Monster*) obj;
    		if(monster->isAlive())/*活动状态*/
    		{
    			monster->setPositionX(monster->getPositionX()-3);//左移
    			if(monster->getPositionX()<0)
    			{
    				monster->hide();
    
    			}else if(monster->isCollideWithPlayer(m_player)){
    				m_player->hit();
    				monster->hide();
    			}
    		
    		}else/*非活动状态*/
    		{
    			monster->show();//
    		}
    	}
    }
    void MonsterManger::bindPlayer(Player* player)
    {
    	this->m_player=player;
    	this->m_player->retain();//引用计数 +1
    }



    5.创建文字飘动效果,(在主角身上显示"+15"特效)

    #ifndef __FlowWord_H__
    #define __FlowWord_H__
    
    #include "cocos2d.h"
    USING_NS_CC;
    
    class FlowWord:public CCNode
    {
    public:
    	FlowWord();
    	~FlowWord();
    	CREATE_FUNC(FlowWord);
    	virtual bool init();
    public:
    	void showWord(const char* text, CCPoint pos);
    	void flowEnd();
    private:
    	CCLabelTTF* m_textLab;
    };
    
    #endif


    #include "FlowWord.h"
    
    FlowWord::FlowWord(){}
    
    FlowWord::~FlowWord(){}
    
    bool FlowWord::init()
    {
    	m_textLab=CCLabelTTF::create("","Arial",30);
    	m_textLab->setColor(ccc3(255,0,0));
    	m_textLab->setVisible(false);
    
    	this->addChild(m_textLab);
    
    	return true;
    }
    
    void FlowWord::showWord(const char* str,CCPoint pos)
    {
    	m_textLab->setString(str);
    	m_textLab->setPosition(pos);
    	m_textLab->setAnchorPoint(ccp(1,0));
    	m_textLab->setVisible(true);
    
    	//先放大后缩小
    	CCActionInterval* scaleLarge=CCScaleTo::create(0.3f,2.5f,2.5f);
    	CCActionInterval* scaleSmall=CCScaleTo::create(0.4f,0.5f,0.5f);
    	//回调动作,移除效果
    	CCCallFunc* callFunc=CCCallFunc::create(this,callfunc_selector(FlowWord::flowEnd));
    
    	CCActionInterval* actions=CCSequence::create(scaleLarge,scaleSmall,callFunc,NULL);
    
    	m_textLab->runAction(actions);
    }
    
    void FlowWord::flowEnd()
    {
    	m_textLab->setVisible(false);
    	/*true: 从父节点移除,并移除节点的动作和回调函数*/
    	m_textLab->removeFromParentAndCleanup(true);
    }

    6.创建游戏场景类,所有游戏的效果都在这上面展示

    #ifndef __TollgateScene_H__
    #define __TollgateScene_H__
    
    #include "cocos2d.h"
    #include "cocos-ext.h"
    #include "Player.h"
    using namespace cocos2d;
    using namespace cocos2d::extension;
    
    
    class TollgateScene : public CCLayer {
    public:
    	static CCScene* scene();
    	virtual bool init();
    	CREATE_FUNC(TollgateScene);
    
    	virtual void update(float delta);
    
    private:
    	void initBG();  /* 初始化关卡背景 */
    	void createJumpBtn();/*创建跳跃按钮*/
    	void jumpEvent(CCObject* pSender,CCControlEvent event);/*响应按钮点击事件*/
    
    	void createScoreLab();/*创建分数标签*/
    	void createTimeSlider();/*创建时间条*/
    private:
    	CCSprite* m_bgSprite1;
    	CCSprite* m_bgSprite2;
    
    	Player* m_player;
    
    	CCLabelTTF* m_scoreLab;//分数标签
    	CCControlSlider* m_TimeSlider;//时间条
    
    	int m_score;	/*得分*/
    	int m_curTime; /*当前时间*/
    };
    
    #endif

    #include "TollgateScene.h"
    #include "MonsterManger.h"
    
    CCScene* TollgateScene::scene() {
    	CCScene* scene = NULL;
    	do 
    	{
    		scene = CCScene::create();
    		CC_BREAK_IF(!scene);
    
    		TollgateScene* layer = TollgateScene::create();
    		CC_BREAK_IF(!layer);
    
    		scene->addChild(layer, 1);
    	} while (0);
    
    	return scene;
    }
    
    bool TollgateScene::init() {
    	bool bRet = false;
    
    	do 
    	{
    		CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    
    		/*游戏标题图片*/
    // 		CCSprite* titleSprite = CCSprite::create("title.png");
    // 		titleSprite->setPosition(ccp(visibleSize.width / 2, visibleSize.height - 50));
    // 		this->addChild(titleSprite, 2);
    
    		/*创建猪脚*/
    		CCSprite* sprite = CCSprite::create("sprite.png");
    		//sprite->setFlipX(true);
    		m_player = Player::create();
    		m_player->bindSprite(sprite);
    		m_player->setPosition(ccp(200, visibleSize.height / 4));
    		
    		this->addChild(m_player,1);
    		
    		/*初始化背景图片*/
    		initBG();
    
    		/*创建按钮*/
    		createJumpBtn();
    
    		/*设置启用CCNode的update()函数,游戏会在每一帧调用update()函数*/
    		this->scheduleUpdate();
    
    		/*创建怪物管理器(管理器里面放了很多怪物)*/
    		MonsterManger* monsterManger=MonsterManger::create();
    		monsterManger->bindPlayer(m_player);
    		this->addChild(monsterManger,4);
    
    		/*创建分数标签*/
    		createScoreLab();
    		/*创建时间条*/
    		createTimeSlider();
    
    		bRet = true;
    	} while (0);
    
    	return bRet;
    }
    
    void TollgateScene::initBG() {
    	CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    
    	m_bgSprite1 = CCSprite::create("tollgateBG.jpg");
    	m_bgSprite1->setPosition(ccp(visibleSize.width / 2, visibleSize.height / 2));
    	this->addChild(m_bgSprite1, 0);
    
    	m_bgSprite2 = CCSprite::create("tollgateBG.jpg");
    	m_bgSprite2->setPosition(ccp(visibleSize.width + visibleSize.width / 2, visibleSize.height / 2));
    	m_bgSprite2->setFlipX(true);
    	this->addChild(m_bgSprite2, 0);
    }
    
    void TollgateScene::update(float delta)
    {
    	CCSize mapSize=m_bgSprite1->getContentSize();//地图大小
    
    	int posX1=m_bgSprite1->getPositionX();  //地图1的x坐标
    	int posX2=m_bgSprite2->getPositionX();	//地图2的x坐标
    
    	int iSpeed = 2;	//地图滚动的速度
    
    	posX1-=iSpeed;	//两张地图一起向左滚动
    	posX2-=iSpeed;
    
    	//创建无限循环
    	if(posX1<=-mapSize.width/2)
    	{
    		posX1=mapSize.width+mapSize.width/2;
    		posX2=mapSize.width/2;
    	}
    	if(posX2<=-mapSize.width/2)
    	{
    		posX1=mapSize.width/2;
    		posX2=mapSize.width+mapSize.width/2;
    	}
    
    	m_bgSprite1->setPositionX(posX1);
    	m_bgSprite2->setPositionX(posX2);
    
    	/*分数增加*/
    	m_score=m_player->getMoney();
    	m_scoreLab->setString(CCString::createWithFormat("Score:%d",m_score)->getCString());
    
    	m_TimeSlider->setValue(--m_curTime);
    	
    }
    void TollgateScene::createJumpBtn()
    {
    	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
    
    	/*按钮标题*/
    	CCLabelTTF* jumpLabel=CCLabelTTF::create("Jump","Arial",35);
    
    	/*按钮状态图片*/
    	CCScale9Sprite* jumpNorBG=CCScale9Sprite::create("button.png");
    	CCScale9Sprite* jumpLightBG=CCScale9Sprite::create("buttonHighlighted.png");
    	
    	/*创建按钮*/
    	CCControlButton* jumpBtn=CCControlButton::create(jumpLabel,jumpNorBG);
    	jumpBtn->setPosition(ccp(visibleSize.width-80,50));
    	jumpBtn->setBackgroundSpriteForState(jumpLightBG,CCControlStateHighlighted);
    	
    	/*添加事件*/
    	jumpBtn->addTargetWithActionForControlEvents(this,
    		cccontrol_selector(TollgateScene::jumpEvent),
    		CCControlEventTouchDown);
    
    	this->addChild(jumpBtn);
    }
    
    void TollgateScene::jumpEvent(CCObject* pSender,CCControlEvent event)
    {
    	m_player->jump();
    }
    
    void TollgateScene::createScoreLab()
    {
    	m_score=m_player->getMoney();
    	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
    	m_scoreLab=CCLabelTTF::create("Score:"+m_score,"Arial",35);
    	m_scoreLab->setAnchorPoint(ccp(0,1));
    	m_scoreLab->setPosition(ccp(0,visibleSize.height));
    	this->addChild(m_scoreLab);
    
    }
    
    void TollgateScene::createTimeSlider()
    {
    	CCSize visibleSize=CCDirector::sharedDirector()->getVisibleSize();
    	m_curTime=10000;
    	m_TimeSlider=CCControlSlider::create(
    		CCSprite::create("background.png"),
    		CCSprite::create("progress.png"),
    		CCSprite::create("sliderThumb.png")
    		);
    	m_TimeSlider->setPosition(ccp(
    		m_TimeSlider->getContentSize().width/2,
    		visibleSize.height-m_TimeSlider->getContentSize().height-m_scoreLab->getContentSize().height
    		));
    	m_TimeSlider->setTouchEnabled(false);
    	m_TimeSlider->setMaximumValue(10000);
    	m_TimeSlider->setMinimumValue(0);
    	m_TimeSlider->setValue(m_curTime);
    	this->addChild(m_TimeSlider,3);
    }



    运行效果如下




    源码

  • 相关阅读:
    Android API之android.provider.ContactsContract.Data
    Android API之android.provider.ContactsContract
    Android API之android.provider.ContactsContract.Contacts
    Android API之android.os.Parcelable
    Android网络开发之基本介绍
    wpf小技巧——datagrid 滚动条问题
    C# List去重的三种方法(转)
    spring jwt springboot RESTful API认证方式
    Springboot 实现api校验和登录验证
    SpringBoot系列
  • 原文地址:https://www.cnblogs.com/fzll/p/3954611.html
Copyright © 2011-2022 走看看