本篇文章游戏代码来源于网上,原名《newGame》,在此感谢作者。

1.程序执行入口:

AppDelegate.cpp

#include "cocos2d.h"
#include "CCEGLView.h"
#include "AppDelegate.h"
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "Game.h"
using namespace CocosDenshion;

USING_NS_CC;

AppDelegate::AppDelegate()
{
}

AppDelegate::~AppDelegate()
{
    SimpleAudioEngine::end();
}

bool AppDelegate::applicationDidFinishLaunching()
{
    // 初始化导演
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());

    // 打开FPS
    pDirector->setDisplayStats(true);

    // 设置刷新频率
    pDirector->setAnimationInterval(1.0 / 60);

    // 创建一个场景
    CCScene *pScene = Game::scene();

    // 导演运行场景
    pDirector->runWithScene(pScene);
    return true;
}

// 程序切换到后台
void AppDelegate::applicationDidEnterBackground()
{
	 //整个游戏停止动画
    CCDirector::sharedDirector()->stopAnimation();
	//暂停音乐
    SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
}

//程序从后台切换到前台
void AppDelegate::applicationWillEnterForeground()
{
	//开始动画
    CCDirector::sharedDirector()->startAnimation();
	//重新播放音乐
    SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
}

2.游戏实现:

Game.cpp:

#include "Game.h"
#include "CCDirector.h"
#include "cocoa\CCObject.h"
#include <string>
#include <sstream>
#include <stdlib.h>
#include "GameOverScene.h"
using namespace cocos2d;
using namespace CocosDenshion;

//实现构造方法
Game::Game():_targets(NULL),_projectiles(NULL){
	//杀敌数
	_projectilesDestroyed=0;

}

//返回一个场景
CCScene* Game::scene(){
	CCScene* cs=NULL;
	cs=CCScene::create();//新版本的coco许多类都用create来初始化。其实就是返回一个对象。并调用它的init()方法。并自动回收
	Game *mm=Game::create();
	//添加layer
	cs->addChild(mm);
	return cs;
}

//初始化layer
bool Game::init(){

	bool bRet=false;
	do{

		//初始化数组-数组保存子弹和怪物
		_targets=new CCArray();
		_projectiles=new CCArray();

		//播放背景音乐
		//预先加载背景音乐和音效
		SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic("217.ogg");
		SimpleAudioEngine::sharedEngine()->preloadEffect("002.ogg");
		//开始播放(循环播放)
		SimpleAudioEngine::sharedEngine()->playBackgroundMusic("217.ogg",true);
		//CC_BREAK_IF就是假如父类没有初始化成功就退出
		CC_BREAK_IF(!CCLayerColor::initWithColor(ccc4(255,255,255,255)));
		//关闭按钮
		CCMenuItemImage* pCloseItem=CCMenuItemImage::create(
			"CloseNormal.png",//正常是的图片
			"CloseSelected.png",//点击后的图片
			this,
			menu_selector(Game::menuCloseCallback)//绑定点击事件
			);
		CC_BREAK_IF(! pCloseItem);
		//按钮定位
		pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
		//按钮要加到Menu上的
		CCMenu* pMenu=CCMenu::create(pCloseItem,NULL);
		//CCPointZero表示原点0,0
		pMenu->setPosition(CCPointZero);
		CC_BREAK_IF(!pMenu);
		//这里的1代表显示优先级。优先级为2的图片会盖在1上
		addChild(pMenu,1);
		//主角图片  CCREectMake是画矩形。用来切割图片。
		CCSprite *player = CCSprite::create("017.png",
			CCRectMake(0, 0, 63, 83) );
		//得到屏幕大小
		CCSize pSize=CCDirector::sharedDirector()->getWinSize();
		player->setPosition(ccp(player->getContentSize().width/2,pSize.height/2));
		addChild(player);
		//开启触屏
		this->setTouchEnabled(true);
		//开启update方法 不断刷新屏幕
		this->scheduleUpdate();
	}while(0);
	//定时器 每1.0秒调用一次gameLogic方法
	this->schedule( schedule_selector(Game::gameLogic), 1.0 );
	return true;
}

//按钮关闭方法
void Game::menuCloseCallback(CCObject * pSender){
	CCDirector::sharedDirector()->end();
}

//生成怪物
void Game::addTarget(){
	//怪物图片
	CCSprite* target=CCSprite::create("104.png",CCRectMake(190, 0, 55, 60));
	//----------从右边随机高度出现怪物 ----------//
	//怪物出现的最低位置
	int minY = target->getContentSize().height/2;
	//获得屏幕尺寸
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	//怪物出现的最高位置
	int maxY = winSize.height- target->getContentSize().height/2;
	//高度范围
	int rangeY = maxY - minY;
	//随机生成怪物出现的纵坐标
	int actualY = ( rand() % rangeY ) + minY;
	//设置怪物出现的位置
	target->setPosition(	ccp(winSize.width - (target->getContentSize().width/2), actualY) );
	//设置标志
	target->setTag(1);
	//将怪物加入数组
	_targets->addObject(target);
	//将怪物加到层里面
	this->addChild(target);
	//确定随机时间
	int minDuration = (int)2.0;
	//int maxDuration = (int)4.0;
	int maxDuration = (int)6.0;
	int rangeDuration = maxDuration - minDuration;
	int actualDuration = ( rand() % rangeDuration )+minDuration;
	//创建移动动作,从出现位置向左边边界移动
	CCFiniteTimeAction* actionMove=CCMoveTo::create(actualDuration,ccp(0-target->getContentSize().width/2,actualY));
	//创建回调动作
	CCFiniteTimeAction* actionMoveDone=CCCallFuncN::create(this,callfuncN_selector(Game::spriteMoveFinished));
	//怪物运行动作
	target->runAction(CCSequence::create(actionMove,actionMoveDone,NULL));

}

//怪物走到左边时触发
void Game::spriteMoveFinished(CCNode* sender){
	//获得在左边消失的怪物对象

	CCSprite* sprite=(CCSprite*)sender;
	this->removeChild(sprite,true);
	//判断是怪物
	if(sprite->getTag()==1){
		_targets->removeObject(sprite);
		//创建scene
		GameOverScene *gameOverScene =GameOverScene::create();
		//设置失败界面的显示文字
		gameOverScene->getLayer()->getLabel()->setString("You Lose");
		//跳转scene
		CCDirector::sharedDirector()->replaceScene(gameOverScene);
	}
	else if(sprite->getTag()==2){//判断是子弹
		_projectiles->removeObject(sprite);
	}

}

void Game::gameLogic(float ct){
	this->addTarget();
}

//触摸事件
void Game::ccTouchEnded(CCTouch* pTouch,CCEvent* pEvent){
	CCPoint local=pTouch->getLocation();
	CCLog("local, x = %f y = %f",local.x,local.y);
	//转换坐标
	//local=CCDirector::sharedDirector()->convertToGL(local);
	//音效
	SimpleAudioEngine::sharedEngine()->playEffect("002.ogg");
	//获取屏幕尺寸
	CCSize winSize = CCDirector::sharedDirector()->getWinSize();
	//创建飞镖
	CCSprite *projectile = CCSprite::create("017.png",CCRectMake(251, 122, 28, 15));
	//设置飞镖的起始位置
	projectile->setPosition( ccp(20, winSize.height/2) );
	//设置标签
	projectile->setTag(2);
	//加入数组
	_projectiles->addObject(projectile);
	//飞镖横坐标(x轴)偏移量
	int offX = local.x - projectile->getPosition().x;
	//计算怪物消失坐标和速度
	int offY = local.y - projectile->getPosition().y;
	//点击了主角的后方返回,点击事件无效,不作处理
	if (offX <= 0) return;
	//将飞镖加到层里面
	this->addChild(projectile);
	//飞镖飞行的角度
	float ratio = (float)offY / (float)offX;
	//飞镖中心点移动到边界上,再加上一半的宽度,整体移动出去
	int realX = winSize.width+ (projectile->getContentSize().width/2);
	//通过横坐标和角度计算出纵坐标的值
	//计算方法有待商榷,当x值非常小时,y的值会非常巨大,如果这样的飞镖数量特别大的话,飞镖一直没有从内存移除,占用内存
	int realY = (realX * ratio) + projectile->getPosition().y;
	CCLog("touch, x = %d y = %d",realX,realY);
	//飞镖的目的地
	CCPoint realDest = ccp(realX, realY);
	//出界的位置
	int offRealX = realX - projectile->getPosition().x;
	int offRealY = realY - projectile->getPosition().y;
	//飞行的距离
	float length = sqrtf((offRealX * offRealX)+ (offRealY*offRealY));
	//飞行速度
	float velocity = 480/1;
	//飞行时间=飞行距离/飞行速度
	float realMoveDuration = length/velocity;

	projectile->runAction( CCSequence::create(//创建动作学列,即几个动作结合在一起
		CCMoveTo::create(realMoveDuration, realDest),//在realMoveDuration时间里面移动到realDest点的动作
		CCCallFuncN::create(this,callfuncN_selector(Game::spriteMoveFinished)),//平移动作结束后,回调spriteMoveFinished()方法
		NULL) );

}

bool Game::ccTouchBegan(CCTouch* pTouch,CCEvent* pEvent){
	return true;
}

void Game::ccTouchMoved(CCTouch* pTouch,CCEvent* pEvent){

}

//注册触屏事件
void Game::registerWithTouchDispatcher()
{
	//注册触屏事件
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}

//Game的析构函数
Game::~Game(){
	//怪物数组
	if(_targets){
		_targets->release();//凡是通过new出来的对象都要release 、create出来的就不用了
		_targets=NULL;
	}
	//飞镖数组
	if(_projectiles){
		_projectiles->release();
		_projectiles=NULL;
	}
}

//碰撞检测函数
void Game::update(float delta){
	//CCArray* projectilesToDelete=new CCArray();
	//CCArray* targetsToDelete=new CCArray();
	CCObject* objpro=NULL;
	CCObject* objtar=NULL;
	//循环遍历_projecttitles
	CCARRAY_FOREACH(_projectiles,objpro){
		//
		CCSprite *projectile =(CCSprite*)objpro;
		//飞镖所在的矩形
		CCRect projectileRect = CCRectMake(
			projectile->getPosition().x - (projectile->getContentSize().width/2),//飞镖左下角的x坐标
			projectile->getPosition().y - (projectile->getContentSize().height/2),//飞镖左下角的y坐标
			projectile->getContentSize().width,projectile->getContentSize().height);
		//循环遍历怪物数组
		CCARRAY_FOREACH(_targets,objtar){
			CCSprite* target=(CCSprite*)objtar;
			//怪物所在的矩形
			CCRect targetRect = CCRectMake(
				target->getPosition().x - (target->getContentSize().width/2),//怪物左下角的x坐标
				target->getPosition().y -(target->getContentSize().height/2),//怪物左下角的y坐标
				target->getContentSize().width,
				target->getContentSize().height);
			//碰撞检测
			if(projectileRect.intersectsRect(targetRect)){
				//从层里面移除怪物
				this->removeChild(target);
				//从层里面移除飞镖
				this->removeChild(projectile);
				//从数组里面移除飞镖
				_projectiles->removeObject(projectile);
				//从数组里面移除怪物
				_targets->removeObject(target);
				//杀敌数加1
				_projectilesDestroyed++;
				//如果杀敌数超过30,则游戏获胜
				if (_projectilesDestroyed > 30)
				{
					//创建游戏结束的场景
					GameOverScene *gameOverScene =GameOverScene::create();
					//设置游戏结束场景的文字信息
					gameOverScene->getLayer()->getLabel()->setString("You Win!");
					//导演切换场景
					CCDirector::sharedDirector()->replaceScene(gameOverScene);
				}
			}
		}
	}
}

3.游戏结束画面的实现:

GameOverScene.cpp:

#include "GameOverScene.h"
#include "Game.h"
using namespace cocos2d;
bool GameOverScene::init()
{
	//父类初始化
	if( CCScene::init() )
	{
		//新建层
		this->_layer=GameOverLayer::create();
		//内存计数器加1
		this->_layer->retain();
		//添加层
		this->addChild(_layer);
		return true;
	}
	else
	{
		return false;
	}
}

//析构函数
GameOverScene::~GameOverScene()

{
	if (_layer)
	{
		//释放层
		_layer->release();
		_layer = NULL;
	}

}
bool GameOverLayer::init()
{
	//
	if ( CCLayerColor::initWithColor( ccc4(255,255,255,255) ) )
	{
		//屏幕尺寸
		CCSize winSize = CCDirector::sharedDirector()->getWinSize();
		//文字信息
		this->_label = CCLabelTTF::create("","Artial", 32);
		//内存计数器加1
		_label->retain();
		//设置颜色
		_label->setColor( ccc3(0, 0, 0) );
		//设置位置
		_label->setPosition(ccp(winSize.width/2, winSize.height/2));
		//场景里面添加层
		this->addChild(_label);
		//运行动作
		this->runAction( CCSequence::create(
			CCDelayTime::create(3),//延时3秒
			CCCallFunc::create(this,callfunc_selector(GameOverLayer::gameOverDone)),//回调方法
			NULL));
		return true;
	}
	else
	{
		return false;
	}
}

//游戏结束是的回调方法
void GameOverLayer::gameOverDone()
{
	//回调游戏界面
	CCDirector::sharedDirector()->replaceScene(Game::scene());
}

//析构函数,释放层
GameOverLayer::~GameOverLayer()
{
	if (_label)
	{
		_label->release();
		_label = NULL;
	}
}

4.运行效果图: