「cocos2d-x」垂直射击游戏之宇智波鼬 VS 九尾狐(1)
本来打算分多个模块实现的,后来想想看cocos2d一个多月,还是先学会走路,等走稳了再学跑步。
游戏的主要内容是:
- 显示Logo画面,并模拟了一个资源加载的进度条;
- “资源加载”完成后会进行场景切换,切换到主场景;
- 主场景的下方有宇智波鼬, 上方是几只九尾狐,宇智波鼬通过发射手里剑攻击敌人。
代码结构如下:
LoadingScene是Logo显示及“资源加载”场景
GameScene是游戏的主场景,主要实现了背景的无限滚动
InputLayer是用户输入层,玩家通过虚拟摇杆控制游戏,但这次的游戏逻辑也实现在了这里,这次没加入碰撞检测,可以看到手里剑和敌人擦肩进过,下次加入新功能后会重构代码结构。
游戏效果如下:
http://www.56.com/u49/v_OTE4NTUxNDI.html
代码下载地址:
http://vdisk.weibo.com/s/Cjiy3/1369105760
LoadingScene的代码可以参考我以前写的关于进度条的文章,GameScene可参考背景的无限滚动。主要贴一下InputLayer的代码:
InputLayer.h
#include "cocos2d.h"typedef enum {HudLayerTag = 2,GameLayerTag =1,}GameLayersTags;using namespace cocos2d;class InputLayer : public cocos2d::CCLayer { public:InputLayer(); //构造函数声明~InputLayer(); //析构函数声明CREATE_FUNC(InputLayer); //类似于cocos2d中的node方法,返回一个autorelease对象virtual bool init(); //本类对象初始化void InitJoystick(); //初始化摇杆void InitHero(); //初始化主角精灵//void InitBullet(); //初始化子弹void InitFox(); //初始化敌人-9尾狐void update(float dt); //定时器void Shootupdate(float dt); //发射子弹定时器//主角精灵发射子弹void shootBulletFromHero(CCSprite *bullet, cocos2d::CCPoint point);void menuCloseCallback(CCObject* pSender); //退出游戏按钮//触摸事件处理virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);float heronsformula(float x1, float y1, float x2, float y2, float x3, float y3); bool triangleContainPoint(float x1, float y1, float x2, float y2, float x3, float y3, float px, float py); void setPlayerPosition(cocos2d::CCPoint position); //设置玩家位置 CC_SYNTHESIZE(cocos2d::CCSprite*, _player, Player);//CC_SYNTHESIZE(); private:void Moving(float dt);cocos2d::CCSprite *joystick;cocos2d::CCSprite *joystick1;cocos2d::CCSize size;//cocos2d::CCSpriteBatchNode *_spritebatchnode; cocos2d::CCPoint velocity;cocos2d::CCSprite *bullet;cocos2d::CCPoint O; //中心点O float R; //大圆半径 //精灵移动的速度分量值 float speedX; float speedY; //是否移动的标志 bool IsMoving; CCMotionStreak* _strike; //主角精灵的CCMotionStreak变量CCMotionStreak* _bulletstrike; //手里剑的CCMotionStreak变量 };
InputLayer.cpp:
#include "InputLayer.h"InputLayer::InputLayer() {//初始化需要的变量IsMoving = false;speedX = speedY = 0;size = CCDirector::sharedDirector()->getWinSize(); }InputLayer::~InputLayer() {}bool InputLayer::init() {bool bRet = false;do{//先初始化父类,如果失败则break循环CC_BREAK_IF(! CCLayer::init());//创建一个关闭按钮菜单置于屏幕右下角CCMenuItemLabel *txtmenItem = CCMenuItemLabel::create(CCLabelTTF::create("EXIT", "Arial", 20), this, menu_selector(InputLayer::menuCloseCallback));CC_BREAK_IF(! txtmenItem);txtmenItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - txtmenItem->getContentSize().width/2, 20));CCMenu* pMenu = CCMenu::create(txtmenItem, NULL);pMenu->setPosition(CCPointZero);CC_BREAK_IF(! pMenu);// Add the menu to HelloWorld layer as a child layer.this->addChild(pMenu, 10);this->InitHero(); //初始化精灵this->setTouchEnabled(TRUE); //打开触摸事件处理this->InitJoystick(); //初始化摇杆//this->InitBullet(); //初始化子弹this->InitFox(); //初始化敌人-9尾狐//每帧要执行的函数 this->schedule(schedule_selector(InputLayer::Moving));this->schedule(schedule_selector(InputLayer::Shootupdate));bRet = true;}while(0);return bRet;}void InputLayer::menuCloseCallback(CCObject* pSender) {CCDirector::sharedDirector()->end(); }void InputLayer::InitJoystick() {//创建摇杆下面部分 joystick1 = CCSprite::create("joystick1.png"); //设置透明度,锚点,位置joystick1->setOpacity(150);joystick1->setAnchorPoint(ccp(0, 0));joystick1->setPosition(ccp(0, 0));joystick1->setColor(ccGREEN);//大圆半径R=joystick1->getContentSize().width/2; //中心点 O = ccp(R, R); //添加进布景 this->addChild(joystick1, 3);//创建摇杆上面圆圈部分 joystick = CCSprite::create("joystick2.png");//设置位置为摇杆中心点并添加进布景joystick->setPosition(ccp(O.x, O.y));joystick->setColor(ccRED);joystick->setScale(0.5f);this->addChild(joystick, 4);} void InputLayer::InitHero() {CCSize size = CCDirector::sharedDirector()->getWinSize();this->setPlayer(CCSprite::create("hartnett.jpg"));_player->setScale(0.3f);float picsize = _player->getContentSize().width * 0.3f;_strike = CCMotionStreak::create(0.5f, picsize, picsize, ccWHITE, "hartnett.jpg");this->addChild(_strike);CCSize spSize = _player->getContentSize();_player->setPosition(ccp(size.width/2, spSize.height * 0.5f * 0.3f));this->addChild(_player); } void InputLayer::Moving(float dt) { if (IsMoving && (speedX != 0 || speedY != 0)){ //精灵移动CCPoint position = ccp(_player->getPosition().x + speedX * 3, _player->getPosition().y + speedY * 3);CCSize size = CCDirector::sharedDirector()->getWinSize();CCSize spSize = _player->getContentSize();CCRect rect = CCRectMake(spSize.width * 0.5f * 0.3f, spSize.height * 0.5f * 0.3f, size.width - spSize.width * 0.5f * 0.3f * 2, size.height - spSize.height * 0.5f * 0.3f * 2); //判断触摸点是否在屏幕内 if(rect.containsPoint(position)){ _player->setPosition(position);_strike->setPosition(position);} } } float InputLayer::heronsformula(float x1, float y1, float x2, float y2, float x3, float y3) { //求边长a float a = sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)); //求边长b float b = sqrt(pow(x2 - x3, 2) + pow(y2 - y3, 2)); //求边长c float c = sqrt(pow(x3 - x1, 2) + pow(y3 - y1, 2)); //求半周长s float s = (a + b + c) / 2; //根据海伦公式返回三角形面积 return sqrt(s * (s - a) * (s - b) * (s - c)); } //判断三个新三角形面积和是否等于原先三角形面积的函数的实现 bool InputLayer::triangleContainPoint(float x1, float y1, float x2, float y2, float x3, float y3, float px, float py) { //求S1的面积 float s1=heronsformula(x1, y1, x2, y2, px, py); //求S2的面积 float s2=heronsformula(x2, y2, x3, y3, px, py); //求S3的面积 float s3=heronsformula(x3, y3, x1, y1, px, py); //求S的面积 float s=heronsformula(x1, y1, x2, y2, x3, y3); //返回S是否等于S1,S2,S3的和 return abs(s - (s1 + s2 + s3)) < 0.001f; } void InputLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) {CCTouch *touch = (CCTouch*)pTouches->anyObject(); CCPoint location = touch->getLocation(); CCRect rect = joystick->boundingBox(); if (rect.containsPoint(location)) { IsMoving = true; } }void InputLayer::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) {CCTouch *touch = (CCTouch*)pTouches->anyObject(); CCPoint location = touch->getLocation(); //判断触摸滑动点是否在摇杆范围内 bool inRange = pow(O.x - location.x, 2) + pow(O.y - location.y, 2) < pow(R, 2); if (IsMoving && inRange){ CCPoint position=_player->getPosition(); joystick->setPosition(location); float r = R * 2 / 6; float d = R * 2 / 3; //上,区域2或5 if(triangleContainPoint(O.x, O.y, O.x - r, O.y + r, O.x +r, O.y + r, location.x, location.y) || CCRectMake(O.x - r, O.y + r, d, d).containsPoint(location)){ speedX = 0; speedY = 1; } //下,区域6或11 else if (triangleContainPoint(O.x, O.y, O.x - r, O.y - r, O.x + r, O.y - r, location.x, location.y) || CCRectMake(O.x - r, O.y - r - d, d, d).containsPoint(location)){ speedX = 0; speedY = -1; } //左,区域4或7 else if (triangleContainPoint(O.x, O.y, O.x - r, O.y + r, O.x - r, O.y - r, location.x, location.y) || CCRectMake(O.x - r - d, O.y - r, d, d).containsPoint(location)){ speedX = -1; speedY = 0; } //右,区域9或8 else if (triangleContainPoint(O.x, O.y, O.x + r, O.y + r, O.x + r, O.y - r, location.x, location.y) || CCRectMake(O.x + r, O.y - r, d, d).containsPoint(location)){ speedX = 1; speedY = 0; } //右上,区域3 else if (location.x - (O.x + r) > 0 && location.y - (O.y + r) > 0){ speedX = 0.7f; speedY = 0.7f; } //左上,区域1 else if (location.x - (O.x - r) < 0 && location.y - (O.y + r) > 0){ speedX =- 0.7f; speedY = 0.7f; } //左下,区域10 else if (location.x - (O.x - r) < 0 && location.y - (O.y - r) < 0){ speedX = -0.7f; speedY = -0.7f; } //右下,区域12 else if (location.x - (O.x + r) > 0 && location.y - (O.y - r) < 0){ speedX = 0.7f; speedY = -0.7f; }} }void InputLayer::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) {IsMoving = false; joystick->setPosition(O); speedX = speedY = 0; } /* void InputLayer::InitBullet() {_spritebatchnode = CCSpriteBatchNode::create("bullet.png");_spritebatchnode->setPosition(ccp(size.width, size.height/2));this->addChild(_spritebatchnode, 12);for (int i = 0; i < 200; i++){CCSprite *bullet = CCSprite::create("bullet.png");bullet->setPosition(ccp(-50, -50)); //置于屏幕外面bullet->setScale(0.3f);_spritebatchnode->addChild(bullet);} } */ void InputLayer::InitFox() {CCSprite *tmpfox = CCSprite::create("fox.png");CCSize foxsize = tmpfox->getContentSize();//tmpfox->setPosition(ccp(size.width/2, size.height/2));//tmpfox->setScale(0.3f);//this->addChild(tmpfox);//CCLOG("Fox num %d", (int)(size.width / foxsize.width / 0.3f));int foxnum = (int)(size.width / foxsize.width / 0.3f);for (int i = 0; i < foxnum; i++){CCSprite *fox = CCSprite::create("fox.png");fox->setScale(0.3f);fox->setPosition(ccp(foxsize.width * 0.3f * 0.5f + i * foxsize.width * 0.3f, size.height - foxsize.height * 0.5f * 0.3f));this->addChild(fox);} }void InputLayer::shootBulletFromHero(CCSprite *bullet, cocos2d::CCPoint point) {float spread = (CCRANDOM_0_1() + 12.5f) * 0.5f;velocity = ccp(0, spread);bullet->setPosition(ccp(point.x, point.y + this->getPlayer()->getContentSize().height * 0.5f * 0.3f));bullet->setVisible(true);CCRotateBy* rotate = CCRotateBy::actionWithDuration(1, 360 * 5);bullet->runAction(rotate);this->scheduleUpdate(); }void InputLayer::update(float dt) {bullet->setPosition(ccpAdd(bullet->getPosition(), velocity));_bulletstrike->setPosition(ccpAdd(bullet->getPosition(), velocity));if (bullet->getPosition().y > size.height){bullet->setVisible(false);this->unscheduleAllSelectors();this->schedule(schedule_selector(InputLayer::Moving));this->schedule(schedule_selector(InputLayer::Shootupdate));}}void InputLayer::Shootupdate(float dt) {this->unschedule(schedule_selector(InputLayer::Shootupdate));bullet = CCSprite::create("bullet.png");bullet->setPosition(ccp(-50, -50)); //置于屏幕外面bullet->setScale(0.3f);this->addChild(bullet);float picsize = bullet->getContentSize().width * 0.5f;_bulletstrike = CCMotionStreak::create(0.5f, picsize, picsize, ccRED, "bullet.png");this->addChild(_bulletstrike);this->shootBulletFromHero(bullet, this->getPlayer()->getPosition()); }
转载于:https://www.cnblogs.com/awakenjoys/archive/2013/05/21/cocos2d_shooting_1.html
「cocos2d-x」垂直射击游戏之宇智波鼬 VS 九尾狐(1)相关推荐
- 小白使用Docker实现每周「自动领取」 Epic 免费游戏
只有不断地在steam买游戏,才能不断地在epic白嫖. 知乎用户:晨晨 每周的epic免费游戏,已经成了我的快乐源泉!游戏可以不玩,但是不可以不领! 白嫖的快乐,懂得都懂
- 游戏封面html模板,「社区分享」自定义Steam游戏封面收集和自制的封面
1.自定义封面教程 首先更新steam,操作方法如图 点击左侧steam标志,再点击设置 弹出新的窗口后点击更改,在新弹出的窗口点击参与测试栏中的 steam beta update. 效果图 等待更 ...
- 「牛角书」鸿蒙页面游戏角色介绍
我做的是一个关于游戏角色的网页,在首页通过对自己想看游戏角色的点击,之后跳转到游戏角色的介绍页面. 我主要写了两个游戏的部分角色. 首先对于主页面的一个框架构成用css来确定页面的格式 主要是对div ...
- 从游戏智能到疾病诊断,腾讯「绝悟」AI 从虚拟走向现实
感谢阅读腾讯 AI Lab 微信号第 160 篇文章.本文介绍腾讯 AI Lab 决策智能AI「绝悟」从虚拟走向现实,首次验证了强化学习用于超大尺寸全片扫描病理图像诊断的可能性. 近年,游戏 AI 大 ...
- 国产游戏手机的「押宝」之战:众雄起跑,谁来破局?
5G风口下的云游戏浪潮将会进一步催生游戏手机的市场需求,当大众消费市场被打开,需求多点开花的时候,机会就悄然而至. 作者| 咸鱼鱼 编辑| 吴怼怼 2018年,被称为国产游戏手机的起跑之年. 自黑鲨拉 ...
- 用YOLO玩「吃鸡」?搭载AI的自瞄外挂来了!一枪爆头!又快又准...
转载自:新智元 来源:Twitter 编辑:Emil 好困 [导读]科技树被点歪?好好的AI不去做CV,反而去搞游戏外挂.结果,不仅表现出众,还很难被发现,堪称物理外挂界的「SOTA」.不过,好孩子可 ...
- 视频教程-C++游戏编程实例精讲--3D射击游戏作弊-C/C++
C++游戏编程实例精讲--3D射击游戏作弊 80后,游戏作弊工程师,从事C++开发14年,擅长语言:C,C++ 领域:服务器开发,精通MFC,STL,Boost,熟悉TCP/IP协议,熟练运用IOCP ...
- 黄仁勋专访:经济不景气又怎样?未来元宇宙将「全民免费」!
作者丨David 来源丨新智元 [导读]面对凶猛矿难和难看的财报,英伟达掌门人黄仁勋依然对元宇宙未来信心满满:「可能你还没意识到,它已经免费了」. 英伟达最近发布的Q2财报很不好看. 财报显示,公司P ...
- 「芭比娃娃.com」
「芭比娃娃.com」于今年5月正式开站,短短2个月内已达300万会员,目前以每天5万名新会员的鬼速继续攀升.这则新闻已成为美国网络界在这星期被讨论得最热烈的消息. 但,放眼望去所有的部落客与新闻 媒体 ...
- 浙大提出会打德扑的「自我博弈」AI,还会玩射击游戏
选自arXiv, 机器之心编译 人工智能已在围棋这样的完美信息游戏上实现了远超人类的水平,但在信息未完全披露的多人对战游戏上还无法战胜人类.近年来,OpenAI 和 DeepMind 在 DOTA2 ...
最新文章
- IOS固定IP对动态IP用pre-share
- xcode 学习笔记2:动态添加view
- COJ 1170 A Simple Problem
- 安装phpcms时出现Warning: ob_start(): output handler \'ob_gzhandler\' conflicts with \'zlib
- 能力的齿轮每一次卡不上点的时候都是下一个批评的开始
- 8086和8088微处理器之间的区别
- sliverlight+WCF项目发布到IIS
- fine-tune 微调 Transfer learning 迁移学习 动手学深度学习v2
- java sjis_java乱码分析
- eclipse中文包和控制台中文显示乱码
- 屏幕共享的实现与应用
- c# FlexCell自动换行
- iOS设置基于ikev2的协议连接企业虚拟专用网络
- grasp设计模式应用场景_设计模式 GRASP GoF
- 设计模式——七大原则
- 漫画:什么是哥德巴赫猜想?
- nginx 如何将 https 请求转发到 http
- .9图片设置不拉伸的区域被拉伸的问题
- ai不同形状的拼版插件_ai自动拼版脚本插件下载 Illustrator相同形状的ai文档阵列方式拼版...
- 将 dev 分支强推到 master
热门文章
- 快速生成树协议(spanning-tree)
- python微信机器人之小i
- 编译内核报错——*** 没有规则可制作目标“debian/canonical-revoked-certs.pem”,由“certs/x509_revocation_list” 需求。 停止。
- Android实现九宫格图片控件
- python setup.py build develop_python setup.py build develop编译出错
- 2020-12-28 微信支付二面
- 【React】facebook最新状态管理库Recoil
- 【高级数据结构】线段树 | 求区间和
- C++语法基础(1/3)
- 【Idea】Process finished with exit code 0 是什么意思?