cocos2d-x “喵星战争”要点剖析

2024-05-03 04:58
文章标签 剖析 要点 cocos2d 战争

本文主要是介绍cocos2d-x “喵星战争”要点剖析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、喵星战争的游戏规则:

玩家用手指控制主角小猫的移动,当小猫处于被控制状态时,会放出子弹,狗博士不断从屏幕上部出现,玩家要做的就是移动小

猫主角,使小猫的子弹打中狗博士,打中dog可以增加积分。该游戏采用移动游戏中流行的生存方式,集没有关卡的限制,主角有三次失败(撞上狗博士或试管子弹)机会,第三次撞上时game over。

二、喵星战争的游戏框架和界面:

三、主游戏模块组成元素的实现:

1、主角小猫的实现:

由于小猫主体部分没有动画效果,从节约资源角度出发将resources分为四部分:主体,左手,右手,尾巴。其中主体部分的动画由三张图片构成,三张图的明暗度不同,连续播放就有了闪动的效果;小猫向不同方向移动时手臂会有“上扬”的动作,这个效果通过图片的垂直镜像获得;尾巴部分通过旋转动作让它如同座钟的钟摆一样左右摇动。

主角小猫的类定义文件GameObjHero.h

#ifdef example1_1_GameObjHero_h

#define example1_1_GameObjHero_h

#include "cocos2d.h"

using namespace cocos2d;

class GameObjHero : public CCNode,public CCTargetedTouchDelegate{

public:

CCSprite* lefthand; //左手

CCSprite* righthand; //右手

CCPoint offset; // 触摸偏移位置

bool isControl; // 是否在控制主角

GameObjHero(void);

virtual ~GameObjHero();

void releasebullet(); // 释放子弹

CCRect rect();

virtual void onEnter();

vritual void onExit();

bool contrainsTouchLocation(CCTouch* touch);

virtual bool ccTouchBegan(CCTouch* touch , CCEvent* event);

virtual void ccTouchMoved(CCTouch* touch , CCEvent* event);

virtual void ccTouchEnded(CCTouch* touch , CCEvent* event);

virtual void touchDelegateRetain();

virtual void touchDelegateRelease();

};

主角小猫的初始化函数onEnter:

void GameObjHero::onEnter(){

CCNode::onEnter();

this->setContentSize(CCSizeMake(85,90));

CCDirector* pDirector = CCDirector::sharedDirector();

pDirector->getTouchDispatcher()->addTargetedDelegate(this,0,true); //触屏代理

CCSprite* mainSprite = CCSprite::create("catBody1.png"); 

// 主体动画

CCAnimation* animation = CCAnimation::create();

animation->addSpriteFrameWIthFileName("catBoy1.png");

animation->addSpriteFrameWithFileName("catBody2-4.png");

animation->addSpriteFrameWithFileName("catBody3.png");

animation->addSpriteFrameWithFileName("catBody2-4.png");

animation->setDelayPerUnit(0.1f);

animation->setRestoreOriginalFrame(true);

mainSprite->runAction(CCRepeatForever::create(CCAnimate::create(animation)));

addChild(mainSprite);

// 尾巴

CCSprite* tail = CCSprite::create("catTail.png");

tail->setAnchorPoint(ccp(0.5,1));

tail->setScale(0.5);

tail->setRotation(20);

tail->runAction(CCRepreatForever((CCActionInterval*)CCSequence::create(

CCRotateBy::create(0.5,-40),CCRotateBy::create(0.5,40),NULL));

addChild(tail);

// 手

lefthand = CCSprite::create("catHand1.png");

lefthand->setAnchorPoint(ccp(1,0.5));

addChild(lefthand);

righthand = CCSprite::create("catHand2.png");

righthand = setPosition(ccp(18,-20));

righthand->setAnchorPoint(ccp(0,0.5));

addChild(righthand);

offset = ccp(0,0);

isControl = false;

schedule(schecule_selector(GaneObjHero::releasebullet).1.0f);

}

开始触摸函数ccTouchBegan:

bool GameObjHero::ccTouchBegan(CCTouch* touch,CCEvent* event){

if((GameMain*)this->getParent())->isover) //判断主角是否死亡

return false;

if(!containsTouchLocation(touch)){        // 判断触摸点是否在主角的矩形框中

return false;

}else{

isControl = true;

CCPoint touchPoint = touch->locationInView();

touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); // CCTouch获得的是屏幕坐标,需转换成GL坐标

// 获得触点坐标与主角锚点坐标之差,通过此偏移量和触点移动过后的坐标点可计算出主角的新位置

offset.x = touchPoint.x - this->getPosition().x;

offset.y = touchPoint.y - this->getPosition().y;

}

return true;

}

触摸点移动函数ccTouchMoved:

void GameObjHero::ccTouchMoved(CCTouch* touch,CCEvent* event){

if(isControl){

CCPoint touchPoint = touch->locationInView();

touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint);

//设置左右手上下动作

float x = touchPoint.x - offset.x;

float y = touchPoint.y - offset.y;

if(x < this->getPosition().x){

lefthand->setFlipY(true);

righthand->setFlipY(false);

}else{

lefthand->setFlipY(false);

righthand->setFlipY(true);

}

this->setPosition(x,y);

}

}

触摸结束函数ccTouchEnded:

// 手指离开屏幕时,需要将主角的两只手放下并将是否控制主角变量置为false

void GameObjHero::ccTouchEnded(CCTouch* touch,CCEvent* event){

if(isControl){

isControl = false;

lefthand->setFlipY(false);

righthand->setFlip(false);

}

}

2、敌人狗博士的实现

狗博士的逻辑与主角小猫类似,只是不需要拆分成很多部分。狗博士有两张图片,DrDog2.png下部有褶皱,两张图片连续播放就会有动态效果;狗博士死亡时会有爆炸效果,也是一个动画(5张图片)。

敌人狗博士(继承自CCNode)的初始化函数onEnter:

void GameObjEnemy::onEnter(){

CCNode::onEnter();

this->setContentSize(CCSizeMake(99,111));

mainBody = CCSprite::create("DrDog1.png");

// 初始化动画

CCAnimation* animation = CCAnimation::create();

animation->addSpriteFrameWithFileName("DrDog.png");

animation->addSpriteFrameWithFileName("DrDog.png");

animation->setDelayPerUnit(0.1f);

animation->setRestoreOriginalFrame(true);

mainBody->runAction(CCRepeatForever::create(CCAnimate::create(animation)); // 敌人闪烁动画

addChild(mainBody);

boom = CCSprite::create("Boom1.png"); // 定义爆炸精灵对象

addChild(boom);

boom->setVisible(false); // 爆炸不可见

islife = true;

}

设置狗博士死亡函数:

void GameObjEnemy::setdie(){

islft = false;

mainBody->setVisible(false); // 敌人不可见

boom->setVisible(true); // 爆炸可见

this->stopAllActions(); // 继承自CCNode,停止所有动作

//爆炸动画

CCAnimation* boomAnimation = CCAnimation::create();

boomAnimation->addSpriteFrameWithFileName("Boom1.png");

boomAnimation->addSpriteFrameWithFileName("Boom2.png");

boomAnimation->addSpriteFrameWithFileName("Boom3.png");

boomAnimation->addSpriteFrameWithFileName("Boom4.png");

boomAnimation->addSpriteFrameWithFileName("Boom5.png");

booAnimation->setDelayPerUnit(0.1f);

boomAnimation->setRestoreOriginalFrame(true);

boom->runAction(CCSequence::create(CCAnimate::create(boomAnimation)),CCCallFuncN::create(this,

callfuncN_selector(GameObjEnemy::restart)),NULL);

}

爆炸动画后,调用restart,重新设置敌人位置,将主干部分设为可见,爆炸不可见,然后调用movestart设置移动方式:

void GameObjEnemy::restart(){

mainBody->setVisible(true);

boom->setVisible(false);

CCSize size = CCDirector::sharedDirector()->getWinSize();

this->setPosition(ccp(size.width/4 * type,size.height + 50));

islife = true;

mainBody->setVisible(true);

boom->setVisible(false);

this->movestart();

}

void GameObjEnemy::movestart(){

islife = true;

int type = CCRANDOM_0_1() * 4;

// 贝塞尔曲线移动

ccBezierConfig bezier2;

bezier2.controlPoint_1 = CCPointMake(this->getPosition().x-400,300);

bezier2.controlPoint_2 = CCPointMake(this->getPosition().x+480,280);

bezier2.endPosition = CCPointMake(this->getPosition().x,-70);

ccBezierConfig bezier1;

bezier1.controlPoint_1 = CCPointMake(this->getPosition().x+400,330);

bezier1.controlPoint_2 = CCPointMake(this->getPosition().x-400,280);

bezier1.endPosition = CCPointMake(this->getPosition().x,-70);

CCBezierTo* bezierBy1 = CCBezierTo::create(6,bezier1);

switch(type){

case 0:

case 1:

this->runAction(CCSequence::create(CCMoveBy::create(6,ccp(0,-600)),

CCCallFuncN::create(this,callfuncN_selector(GameObjEnemy::restart)),NULL));

break;

case 2:

this->runAction(CCSequence::create(bezierBy2,CCCallFuncN::create(this,

callfuncN_selector(GameObjEnemy::restart)),NULL));

break;

case 3:

this->runAction(CCSequence::create(bezierBy2,CCCallFuncN::create(this,

callfuncN_selector(GameObjEnemy::restart)),NULL));

break;

}

schedule(schedule_selector(GameObjEnemy::releasebullet),1.2f);

}


未完待续...
















这篇关于cocos2d-x “喵星战争”要点剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/955874

相关文章

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

系统优化要点

这是常用的系统优化要考虑的点,在系统设计和代码评审以及代码优化时加以考虑,最大限度提高系统性能:  1. 优化算法,选择合适高效算法,降低不必要递归,循环,多层循环嵌套,避免循环内初始化等。  2. 避免申请过多不必要的内存  3. 及时释放资源,降低资源使用时间,包括内存,IO,网络,数据库等。  4. 使用缓存:缓存常用的,不易变化的。  5. 慎用数据库锁。确

c语言要点!

其他合法的输入:     1.    3空格 空格4空格 空格 空格5 空格 回车     2.    3回车4空格5回车     3.    3(tab键)4回车5回车     例子2     #include<stdio.h>     #include<stdlib.h>     int main()     {     int a,b,c;     s

深度剖析AI情感陪伴类产品及典型应用 Character.ai

前段时间AI圈内C.AI的受够风波可谓是让大家都丈二摸不着头脑,连C.AI这种行业top应用都要找谋生方法了!投资人摸不着头脑,用户们更摸不着头脑。在这之前断断续续玩了一下这款产品,这次也是乘着这个风波,除了了解一下为什么这么厉害的创始人 Noam Shazeer 也要另寻他路,以及产品本身的发展阶段和情况! 什么是Character.ai? Character.ai官网:https://

互联网开发要点

垂直扩展 横向扩展 业务分拆 数据读写分离 缓存读写 异步处理(消息队列)

20151214 要点摘录2

算法: 四火的数据库算法10题 http://www.raychase.net/2810 leetCode解题报告 http://bookshadow.com/leetcode/ 学习算法之路(转) http://blog.csdn.net/sunboy_2050/article/details/5656823 10分钟没有思路的就找例子 http://blog.csdn

20151214 要点摘录1

eclipse用法 --- 涉及到的eclipse的使用 在接口名上按F4 可以看继承关系    按ctrl+T可以找实现类 ctrl+shift+r查找文件 MyBatis的设计主要是把对数据库的增删改查的sql语句和JavaWeb工程的POJO做绑定 1 配置sql语句的映射文件 2 在conf.xml中配置数据库连接并关联sql语句的映射文件 3 在dao中编写代码,加载con

最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)

文章目录 一、自动配置概念二、半自动配置(误~🙏🙏)三、源码分析1、验证DispatcherServlet的自动配置2、源码分析入口@SpringBootApplication3、@SpringBootConfiguration的@Configuration4、@EnableAutoConfiguration的@AutoConfigurationPackage和@Import5、Auto

C语言深度剖析--不定期更新的第四弹

哈哈哈哈哈哈,今天一天两更! void关键字 void关键字不能用来定义变量,原因是void本身就被编译器解释为空类型,编译器强制地不允许定义变量 定义变量的本质是:开辟空间 而void 作为空类型,理论上不应该开辟空间(针对编译器而言),即使开辟了空间,也只是作为一个占位符看待(针对Linux来说) 所以,既然无法开辟空间,也无法作为正常变量使用,既然无法使用,干脆编译器不让它编译变

Java CAS 原理剖析

在Java并发中,我们最初接触的应该就是synchronized关键字了,但是synchronized属于重量级锁,很多时候会引起性能问题,volatile也是个不错的选择,但是volatile不能保证原子性,只能在某些场合下使用。   像synchronized这种独占锁属于悲观锁,它是在假设一定会发生冲突的,那么加锁恰好有用,除此之外,还有乐观锁,乐观锁的含义就是假设没有发生冲突,那么我正