这个例子改编来自Cocos2d-x by Example.

相当于一个简单的桌上足球游戏,可以通过触摸的方式碰撞红色的球,进入对方的球门就可以加一分。

#ifndef  _APP_DELEGATE_H_
#define  _APP_DELEGATE_H_#include "cocos2d.h"/**
@brief    The cocos2d Application.Private inheritance here hides part of interface from Director.
*/
class  AppDelegate : private cocos2d::Application
{
public:AppDelegate();virtual ~AppDelegate();virtual void initGLContextAttrs();/**@brief    Implement Director and Scene init code here.@return true    Initialize success, app continue.@return false   Initialize failed, app terminate.*/virtual bool applicationDidFinishLaunching();/**@brief  Called when the application moves to the background@param  the pointer of the application*/virtual void applicationDidEnterBackground();/**@brief  Called when the application reenters the foreground@param  the pointer of the application*/virtual void applicationWillEnterForeground();
};#endif // _APP_DELEGATE_H_
#include "AppDelegate.h"
#include "HelloWorldScene.h"
#include "GameLayer.h"
#include "TestLayer.h"#include "SimpleAudioEngine.h"
using namespace CocosDenshion;using namespace cocos2d;USING_NS_CC;// static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320);
static cocos2d::Size designResolutionSize = cocos2d::Size(720, 1280);
static cocos2d::Size smallResolutionSize = cocos2d::Size(480, 320);
static cocos2d::Size mediumResolutionSize = cocos2d::Size(1024, 768);
static cocos2d::Size largeResolutionSize = cocos2d::Size(2048, 1536);AppDelegate::AppDelegate()
{
}AppDelegate::~AppDelegate()
{
}// if you want a different context, modify the value of glContextAttrs
// it will affect all platforms
void AppDelegate::initGLContextAttrs()
{// set OpenGL context attributes: red,green,blue,alpha,depth,stencilGLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};GLView::setGLContextAttrs(glContextAttrs);
}// if you want to use the package manager to install more packages,
// don't modify or remove this function
static int register_all_packages()
{return 0; //flag for packages manager
}bool AppDelegate::applicationDidFinishLaunching() {// initialize directorauto director = Director::getInstance();auto glview = director->getOpenGLView();if(!glview) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)glview = GLViewImpl::createWithRect("GameDemo", cocos2d::Rect(0, 0, designResolutionSize.width, designResolutionSize.height));
#elseglview = GLViewImpl::create("GameDemo");
#endifdirector->setOpenGLView(glview);}// turn on display FPSdirector->setDisplayStats(false);// set FPS. the default value is 1.0/60 if you don't call thisdirector->setAnimationInterval(1.0f / 60);glview->setFrameSize(720, 1280);// Set the design resolutionglview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::EXACT_FIT);/*auto frameSize = glview->getFrameSize();// if the frame's height is larger than the height of medium size.if (frameSize.height > mediumResolutionSize.height){        director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));}// if the frame's height is larger than the height of small size.else if (frameSize.height > smallResolutionSize.height){        director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));}// if the frame's height is smaller than the height of medium size.else{        director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));}*/register_all_packages();// preload sound effects// SimpleAudioEngine::sharedEngine()->preloadEffect("standard/hit.wav");// SimpleAudioEngine::sharedEngine()->preloadEffect("standard/score.wav");auto fileUtils = FileUtils::getInstance();std::vector<std::string> searchPaths;searchPaths.push_back("standard");fileUtils->setSearchPaths(searchPaths);auto audioEngine = SimpleAudioEngine::getInstance();audioEngine->preloadEffect(fileUtils->fullPathForFilename("hit.wav").c_str());audioEngine->preloadEffect(fileUtils->fullPathForFilename("score.wav").c_str());audioEngine->setBackgroundMusicVolume(0.5f);audioEngine->setEffectsVolume(0.5f);// create a scene. it's an autorelease objectauto scene = HelloWorld::createScene();// auto scene = GameLayer::createScene();// auto scene = TestLayer::createScene();// rundirector->runWithScene(scene);return true;
}// This function will be called when the app is inactive. Note, when receiving a phone call it is invoked.
void AppDelegate::applicationDidEnterBackground() {Director::getInstance()->stopAnimation();// if you use SimpleAudioEngine, it must be paused// SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {Director::getInstance()->startAnimation();// if you use SimpleAudioEngine, it must resume here// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
#include "GameLayer.h"
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;bool GameLayer::init()
{if (!Layer::init())return false;_players = Vector<GameSprite*>(2);_player1Score = 0;_player2Score = 0;_screenSize = Director::getInstance()->getWinSize();Vec2 origin = Director::getInstance()->getVisibleOrigin();auto court = Sprite::create("court.png");court->setPosition(Vec2(_screenSize.width * 0.5, _screenSize.height * 0.5));this->addChild(court);_player1 = GameSprite::gameSpriteWithFile("mallet.png");_player1->setPosition(Vec2(_screenSize.width/2, _player1->radius()*2));_players.pushBack(_player1);this->addChild(_player1);_player2 = GameSprite::gameSpriteWithFile("mallet.png");_player2->setPosition(Vec2(_screenSize.width/2, _screenSize.height - _player1->radius()*2));_players.pushBack(_player2);;this->addChild(_player2);_ball = GameSprite::gameSpriteWithFile("puck.png");_ball->setPosition(Vec2(_screenSize.width/2, _screenSize.height/2 - _ball->radius()*2));this->addChild(_ball);_player1ScoreLabel = Label::createWithTTF("0", "fonts/arial.ttf", 40);_player1ScoreLabel->setPosition(Vec2(_screenSize.width/4*3, _screenSize.height/2 - 50));_player1ScoreLabel->setAnchorPoint(Vec2(0.5, 0.5));_player1ScoreLabel->setRotation(90);this->addChild(_player1ScoreLabel);_player2ScoreLabel = Label::createWithTTF("0", "fonts/arial.ttf", 40);_player2ScoreLabel->setPosition(Vec2(_screenSize.width/4*3, _screenSize.height/2 + 50));_player2ScoreLabel->setAnchorPoint(Vec2(0.5, 0.5));_player2ScoreLabel->setRotation(90);this->addChild(_player2ScoreLabel);auto listener = EventListenerTouchAllAtOnce::create();listener->onTouchesBegan =CC_CALLBACK_2(GameLayer::onTouchesBegan,this);listener->onTouchesMoved =CC_CALLBACK_2(GameLayer::onTouchesMoved, this);listener->onTouchesEnded =CC_CALLBACK_2(GameLayer::onTouchesEnded, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);// create main loopthis->scheduleUpdate();return true;
}Scene *GameLayer::createScene()
{Scene* scene = Scene::create();GameLayer* layer = GameLayer::create();scene->addChild(layer);return scene;
}void GameLayer::onTouchesBegan(const std::vector<Touch *> &touches, Event *event)
{for (auto touch : touches) {if (touch != nullptr) {auto tap = touch->getLocation();for (auto player : _players) {if (player->boundingBox().containsPoint(tap)) {player->setTouch(touch);}}}}
}void GameLayer::onTouchesMoved(const std::vector<Touch *> &touches, Event *event)
{for (auto touch : touches) {if (touch != nullptr) {auto tap = touch->getLocation();for (auto player : _players) {if (player->getTouch() != nullptr && player->getTouch() == touch) {Point nextPosition = tap;if (nextPosition.x < player->radius())nextPosition.x = player->radius();if (nextPosition.x > _screenSize.width - player->radius())nextPosition.x = _screenSize.width - player->radius();if (nextPosition.y < player->radius())nextPosition.y = player->radius();if (nextPosition.y > _screenSize.height - player->radius())nextPosition.y = _screenSize.height - player->radius();//keep player inside its courtif (player->getPositionY() < _screenSize.height* 0.5f) {if (nextPosition.y > _screenSize.height* 0.5 -player->radius()) {nextPosition.y = _screenSize.height* 0.5 -player->radius();}} else {if (nextPosition.y < _screenSize.height* 0.5 +player->radius()) {nextPosition.y = _screenSize.height* 0.5 +player->radius();}}player->setNextPosition(nextPosition);player->setVector(Vec2(tap.x - player->getPositionX(),tap.y - player->getPositionY()));}}}}
}void GameLayer::onTouchesEnded(const std::vector<Touch *> &touches, Event *event)
{for (auto touch : touches) {if (touch != nullptr) {auto tap = touch->getLocation();for (auto player : _players) {if (player->getTouch() != nullptr && player->getTouch() == touch) {//if touch ending belongs to this player, clear itplayer->setTouch(nullptr);player->setVector(Vec2(0,0));}}}}
}void GameLayer::update(float dt)
{CCPoint ballNextPosition = _ball->getNextPosition();CCPoint ballVector = _ball->getVector();ballVector = ccpMult(ballVector, 0.98f);ballNextPosition.x += ballVector.x;ballNextPosition.y += ballVector.y;//test for puck and mallet collisionfloat squared_radii = pow(_player1->radius() + _ball->radius(), 2);GameSprite * player;CCPoint playerNextPosition;CCPoint playerVector;for (int p = 0; p < 2; p++) {player = _players.at(p);playerNextPosition = player->getNextPosition();playerVector = player->getVector();float diffx = ballNextPosition.x - player->getPositionX();float diffy = ballNextPosition.y - player->getPositionY();float distance1 = pow(diffx, 2) + pow(diffy, 2);float distance2 = pow(_ball->getPositionX() - playerNextPosition.x, 2) + pow(_ball->getPositionY() - playerNextPosition.y, 2);if (distance1 <= squared_radii || distance2 <= squared_radii) {float mag_ball = pow(ballVector.x, 2) + pow(ballVector.y, 2);float mag_player = pow (playerVector.x, 2) + pow (playerVector.y, 2);float force = sqrt(mag_ball + mag_player);float angle = atan2(diffy, diffx);ballVector.x = force * cos(angle);ballVector.y = (force * sin(angle));ballNextPosition.x = playerNextPosition.x + (player->radius() + _ball->radius() + force) * cos(angle);ballNextPosition.y = playerNextPosition.y + (player->radius() + _ball->radius() + force) * sin(angle);SimpleAudioEngine::sharedEngine()->playEffect("hit.wav");}}//check collision of ball and sidesif (ballNextPosition.x < _ball->radius()) {ballNextPosition.x = _ball->radius();ballVector.x *= -0.8f;SimpleAudioEngine::sharedEngine()->playEffect("hit.wav");}if (ballNextPosition.x > _screenSize.width - _ball->radius()) {ballNextPosition.x = _screenSize.width - _ball->radius();ballVector.x *= -0.8f;SimpleAudioEngine::sharedEngine()->playEffect("hit.wav");}//ball and top of the courtif (ballNextPosition.y > _screenSize.height - _ball->radius()) {if (_ball->getPosition().x < _screenSize.width * 0.5f - GOAL_WIDTH * 0.5f ||_ball->getPosition().x > _screenSize.width * 0.5f + GOAL_WIDTH * 0.5f) {ballNextPosition.y = _screenSize.height - _ball->radius();ballVector.y *= -0.8f;SimpleAudioEngine::sharedEngine()->playEffect("hit.wav");}}//ball and bottom of the courtif (ballNextPosition.y < _ball->radius() ) {if (_ball->getPosition().x < _screenSize.width * 0.5f - GOAL_WIDTH * 0.5f ||_ball->getPosition().x > _screenSize.width * 0.5f + GOAL_WIDTH * 0.5f) {ballNextPosition.y = _ball->radius();ballVector.y *= -0.8f;SimpleAudioEngine::sharedEngine()->playEffect("hit.wav");}}//finally, after all checks, update ball's vector and next position_ball->setVector(ballVector);_ball->setNextPosition(ballNextPosition);//check for goals!if (ballNextPosition.y  < -_ball->radius() * 2) {this->playerScore(2);}if (ballNextPosition.y > _screenSize.height + _ball->radius() * 2) {this->playerScore(1);}//move pieces to next position_player1->setPosition(_player1->getNextPosition());_player2->setPosition(_player2->getNextPosition());_ball->setPosition(_ball->getNextPosition());}void GameLayer::playerScore(int player)
{SimpleAudioEngine::sharedEngine()->playEffect("score.wav");_ball->setVector(CCPointZero);char score_buffer[10];//if player 1 scored...if (player == 1) {_player1Score++;sprintf(score_buffer,"%i", _player1Score);_player1ScoreLabel->setString(score_buffer);//move ball to player 2 court_ball->setNextPosition(ccp(_screenSize.width * 0.5, _screenSize.height * 0.5 + 2 * _ball->radius()));//if player 2 scored...} else {_player2Score++;sprintf(score_buffer,"%i", _player2Score);_player2ScoreLabel->setString(score_buffer);//move ball to player 1 court_ball->setNextPosition(ccp(_screenSize.width * 0.5, _screenSize.height * 0.5 - 2 * _ball->radius()));}//move players to original position_player1->setPosition(ccp(_screenSize.width * 0.5, _player1->radius() * 2));_player2->setPosition(ccp(_screenSize.width * 0.5, _screenSize.height - _player1->radius() * 2));//clear current touches_player1->setTouch(NULL);_player2->setTouch(NULL);
}GameLayer::GameLayer()
{}GameLayer::~GameLayer()
{}
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"class HelloWorld : public cocos2d::Layer
{
public:static cocos2d::Scene* createScene();virtual bool init();// a selector callbackvoid menuCloseCallback(cocos2d::Ref* pSender);// implement the "static create()" method manuallyCREATE_FUNC(HelloWorld);
};#endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include "GameLayer.h"
#include "RocketThrough/RocketThrough.h"USING_NS_CC;Scene* HelloWorld::createScene()
{// 'scene' is an autorelease objectauto scene = Scene::create();// 'layer' is an autorelease objectauto layer = HelloWorld::create();// add layer as a child to scenescene->addChild(layer);// return the scenereturn scene;
}// on "init" you need to initialize your instance
bool HelloWorld::init()
{//// 1. super init firstif ( !Layer::init() ){return false;}auto _screenSize = Director::getInstance()->getWinSize();auto visibleSize = Director::getInstance()->getVisibleSize();Vec2 origin = Director::getInstance()->getVisibleOrigin();/// 2. add a menu item with "X" image, which is clicked to quit the program//    you may modify it.// add a "close" icon to exit the progress. it's an autorelease objectauto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,origin.y + closeItem->getContentSize().height/2));// create menu, it's an autorelease objectauto menu = Menu::create(closeItem, NULL);menu->setPosition(Vec2::ZERO);this->addChild(menu, 1);// create menuMenu, which game to chooseauto menuItem1 = MenuItemFont::create("Air Hockey");menuItem1->setFontSizeObj(60);menuItem1->setPosition(Vec2(_screenSize.width/2, _screenSize.height/5*4));menuItem1->setCallback([&](Ref *sender){auto director = Director::getInstance();director->replaceScene(GameLayer::createScene());});auto menuItem2 = MenuItemFont::create("Rocket Through");menuItem2->setFontSizeObj(60);menuItem2->setPosition(Vec2(_screenSize.width/2, _screenSize.height/5*3));menuItem2->setCallback([&](Ref *sender) {Director::getInstance()->replaceScene(RocketThrough::createScene());});auto menuItem3 = MenuItemFont::create("");cocos2d::Vector<MenuItem *> menuItems;menuItems.pushBack(menuItem1);menuItems.pushBack(menuItem2);auto menu1 = Menu::createWithArray(menuItems);menu1->setPosition(Vec2::ZERO);this->addChild(menu1);return true;
}void HelloWorld::menuCloseCallback(Ref* pSender)
{//Close the cocos2d-x game scene and quit the applicationDirector::getInstance()->end();#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)exit(0);
#endif/*To navigate back to native iOS screen(if present) without quitting the application  ,do not use Director::getInstance()->end() and exit(0) as given above,instead trigger a custom event created in RootViewController.mm as below*///EventCustom customEndEvent("game_scene_close_event");//_eventDispatcher->dispatchEvent(&customEndEvent);}
#ifndef __GAMESPRITE_H__
#define __GAMESPRITE_H__#include "cocos2d.h"using namespace cocos2d;class GameSprite : public Sprite {
public:CC_SYNTHESIZE(Vec2, _nextPosition, NextPosition);CC_SYNTHESIZE(Vec2, _vector, Vector);CC_SYNTHESIZE(Touch*, _touch, Touch);GameSprite();virtual ~GameSprite();static GameSprite* gameSpriteWithFile(const char* pszFileName);virtual void setPosition(const Vec2& pos) override;float radius();
};
#endif
#include "GameSprite.h"GameSprite::GameSprite()
{_vector = Vec2(0, 0);
}GameSprite::~GameSprite()
{}GameSprite *GameSprite::gameSpriteWithFile(const char *pszFileName)
{auto sprite = new GameSprite();if (sprite && sprite->initWithFile(pszFileName)) {sprite->autorelease();return sprite;}CC_SAFE_DELETE(sprite);return sprite = nullptr;
}void GameSprite::setPosition(const Vec2 &pos)
{Sprite::setPosition(pos);if (!_nextPosition.equals(pos)) {_nextPosition = pos;}
}float GameSprite::radius()
{return getTexture()->getContentSize().width * 0.5f;
}

cocos2d-x 提升篇 (17) 简单的桌上足球游戏相关推荐

  1. (17)FPGA面试技能提升篇(System Verilog)

    1.1 FPGA面试技能提升篇17(System Verilog) 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试技能提升篇17(System Verilo ...

  2. 翻译:如何用Cocos2d来开发简单的IPhone游戏教程

    这一周接触到Cocos2D开发,在它的官网上看到Ray Wenderlic写的关于cocos2d开发的文章,感觉写的挺好,翻译了一下.  原文链接地址大家可以在上面看到作者的更多内容 初次翻译文章,望 ...

  3. 菜鸟学习笔记:Java提升篇2(容器2——Map、Set、迭代器)

    菜鸟学习笔记:Java容器2--Map.Set.迭代器 Map容器 HashMap的使用 Hash表讲解 Map实现 Set容器 HashSet的使用 实现 Iterator迭代器 Map容器 Has ...

  4. 极客HTTP协议学习笔记破冰篇(1-7)

    极客HTTP协议学习笔记破冰篇(1-7) 前言 各篇章笔记链接 一.学习笔记 1.HTTP的前世今生 2.HTTP是什么 3.与HTTP相关的各种概念(上) 4.与HTTP相关的各种概念(下) 5.常 ...

  5. SpringCloud(第 002 篇)简单电影微服务类(消费方,而提供方为用户微服务)

    2019独角兽企业重金招聘Python工程师标准>>> SpringCloud(第 002 篇)简单电影微服务类(消费方,而提供方为用户微服务) 一.大致介绍 微服务与微服务之间通过 ...

  6. iOS开发UI篇—UITabBarController简单介绍

    iOS开发UI篇-UITabBarController简单介绍 一.简单介绍 UITabBarController和UINavigationController类似,UITabBarControlle ...

  7. 经典SQL语句大全(提升篇)

    提升篇 1.说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用) 法一:select * into b from a where 1<>1(仅用于SQlServer) ...

  8. iOS开发UI篇—Modal简单介绍

    iOS开发UI篇-Modal简单介绍 一.简单介绍 除了push之外,还有另外一种控制器的切换方式,那就是Modal 任何控制器都能通过Modal的形式展⽰出来 Modal的默认效果:新控制器从屏幕的 ...

  9. SpringCloud(第 054 篇)简单 Quartz-Cluster 微服务,采用注解配置 Quartz 分布式集群...

    2019独角兽企业重金招聘Python工程师标准>>> SpringCloud(第 054 篇)简单 Quartz-Cluster 微服务,采用注解配置 Quartz 分布式集群 一 ...

最新文章

  1. java web 利用ajax 异步向后台提交数据
  2. mysql 后十条_mysql几十条常用命令归纳总结
  3. 一台路由器实现电信ITV与宽带共享上网
  4. 一个servlet,多个dwr.xml配置文件
  5. Servlet之过滤器详解
  6. 分模块的maven项目调试时报Source not found的解决办法
  7. 对string类型字符串操作
  8. UFLDL教程笔记及练习答案五(自编码线性解码器与处理大型图像**卷积与池化)...
  9. 网易邮箱大师如何添加Word附件 添加附件方法步骤详细介绍
  10. Office批量打印精灵4.2入门教程
  11. html九九乘法口诀表代码,JavaScript九九乘法口诀表的简单实现
  12. HTML5 canvas 中的 fillstyle fillrect strokeStyle strokeRect fill stroke rect 的简单理解
  13. python中函数定义的关键字_python中定义函数的关键字是什么
  14. MySQL表的增删改查--你都知道吗?
  15. 伸展树 自底向上 自顶向下
  16. IDEA解决crtl+space与搜狗输入法冲突
  17. i.MX6ULL终结者屏幕背光调节例程程序设计
  18. 【笔记】Android桌面角标Badge官方文档和兼容性解决
  19. 锐捷 Smartweb管理系统 命令执行漏洞
  20. SVM支持向量机的应用

热门文章

  1. 2011考研数学二第(9)题——求极限
  2. EF做后台登录(记住密码)首页
  3. 广西科技大学c语言期末答案,广西科技大学C语言程序设计试题
  4. kindle的xray怎么用_《我的世界》xray模组新手教程 xray模组怎么用?
  5. testflight测试的直播软件,怎么使用 TestFlight 测试 App,注意些什么?
  6. MTK 3G/4G行业设备解决方案MTK8735 核心板4G 全网通4核64位 物联网方案LTE模块
  7. 【干货】java就业的职务
  8. Linux下C++和Fortran的混编
  9. 双显示器 启动黑屏 黑苹果_黑苹果装机黑屏问题解决方案5500xt
  10. 求解在线教育长期价值 夸克想让拍题更快,错题本更智能