本篇文章游戏代码来源于网上,原名《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.运行效果图: