chapter8 實驗手冊
《chapter8 實驗手冊》由會員分享,可在線閱讀,更多相關《chapter8 實驗手冊(14頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、第八章 碰撞檢測與運動模擬基于Box2D的游戲?qū)嵗ㄒ唬┗A知識物理模擬、精靈的繪制與移動、觸摸事件的應用(1) 繪制游戲界面(2) 通過單點觸摸屏幕,球桿瞄準目標(3) 設置能量條(觸屏檢測)(4) 球桿擊球(5) 碰撞檢測(物理模擬)(二)游戲配置文件游戲需要新建一個Config.h的頭文件,此文件用來定義游戲中需要的參數(shù)。#include cocos2d.hUSING_NS_CC;using namespace cocos2d;#define PTM_RATIO 32 / 定義32像素代表1米static const int SLIDER_BG_TAG = 1000;static con
2、st int SLIDER_TAG = 1001;static const int DASH_LINE_TAG = 1002;static const int MAIN_BILLIARDS_TAG = 1003;static const int AIM_ICON_TAG = 1004;static const int AIM_GAN_TAG = 1005;static const int MAX_SPEED = 2600;static const std:string ball5 = Chapter07/Ball/3.png,Chapter07/Ball/4.png,Chapter07/Bal
3、l/5.png,Chapter07/Ball/6.png,Chapter07/Ball/10.png;static const Vec2 ballPos = Vec2(300,500),Vec2(500,300),Vec2(100,600),Vec2(600,100),Vec2(800,500);(三)物理場景的繪制由PhysicsScene.h類實現(xiàn),這里具體給出其實現(xiàn),定義均在實現(xiàn)文件中實現(xiàn)了。PhysicsScene.cpp#include PhysicsScene.hPhysicsScene:PhysicsScene()PhysicsScene:PhysicsScene()bool P
4、hysicsScene:init()if (!Layer:init()return false;/ physics sceneSize visibleSize = Director:getInstance()-getVisibleSize();Vec2 origin = Director:getInstance()-getVisibleOrigin();/ 定義世界的邊界auto body = PhysicsBody:createEdgeBox(visibleSize,PHYSICSBODY_MATERIAL_DEFAULT,5.0f); auto edgeNode = Node:create
5、(); edgeNode-setPosition(Vec2(visibleSize.width/2,visibleSize.height/2); edgeNode-setPhysicsBody(body); this-addChild(edgeNode); / 屏幕觸摸auto listener = EventListenerTouchOneByOne:create();listener-onTouchBegan = CC_CALLBACK_2(PhysicsScene:onTouchBegan, this);Director:getInstance()-getEventDispatcher(
6、)-addEventListenerWithSceneGraphPriority(listener, this);return true;Scene* PhysicsScene:createScene()/ 創(chuàng)建物理世界auto scene = Scene:createWithPhysics();/ 繪制調(diào)試遮罩/ scene-getPhysicsWorld()-setDebugDrawMask(PhysicsWorld:DEBUGDRAW_ALL);auto layer = PhysicsScene:create();scene-addChild(layer);return scene;bo
7、ol PhysicsScene:onTouchBegan(Touch *touch, Event *unused_event)Vec2 location = touch-getLocation();addNewSpriteAtPosition(location);return false;void PhysicsScene:addNewSpriteAtPosition(Vec2 p)int picpath = rand() % 11;auto sp = Sprite:create(StringUtils:format(Chapter07/Ball/%d.png,picpath); sp-set
8、Tag(1);auto body = PhysicsBody:createCircle(sp-getContentSize().width / 2);/ auto body = PhysicsBody:createBox(sp-getContentSize(); sp-setPhysicsBody(body);sp-setPosition(p);this-addChild(sp);(四)物理物體的封裝,桌球的實現(xiàn)由BilliardSprite.h類實現(xiàn),這里具體給出其實現(xiàn),定義均在實現(xiàn)文件中實現(xiàn)了。BilliardSprite.cpp#include BilliardSprite.hBilli
9、ardSprite:BilliardSprite()void BilliardSprite:update(float t)_sprite-setPosition(Vec2(_body-GetPosition().x * PTM_RATIO,_body-GetPosition().y * PTM_RATIO);_sprite-setRotation(-1 * CC_RADIANS_TO_DEGREES(_body-GetAngle();BilliardSprite:BilliardSprite()if (_name != NULL)_name = NULL;BilliardSprite* Bil
10、liardSprite:create(char* name, bool isStatic, bool isBullet, b2World* world, std:string picPath, Vec2 position, float density /*= 1.0*/, float friction /*= 0.1*/, float restitution /*= 0.78 */)BilliardSprite *pRet = new(std:nothrow) BilliardSprite();if (pRet & pRet-init(name, isStatic, isBullet, wor
11、ld, picPath, position, density, friction, restitution) pRet-autorelease();return pRet;else delete pRet;pRet = NULL;return NULL;bool BilliardSprite:init(char* name, bool isStatic, bool isBullet, b2World* world, std:string picPath, Vec2 position, float density /*= 1.0*/, float friction /*= 0.1*/, floa
12、t restitution /*= 0.78*/)if (!Sprite:init()return false;_name = name;/ 創(chuàng)建精靈_sprite = Sprite:create(picPath);this-addChild(_sprite);/ bodyDefb2BodyDef bodyDef;if (!isStatic)bodyDef.type = b2_dynamicBody;if (isBullet)bodyDef.bullet = true;bodyDef.position.Set(position.x / PTM_RATIO,position.y / PTM_RA
13、TIO);/ 創(chuàng)建body_body = world-CreateBody(&bodyDef); _body-SetUserData(this);b2CircleShape circle;circle.m_radius = (_sprite-getContentSize().width / 2 ) / PTM_RATIO;if (isStatic)/ 靜態(tài)_body-CreateFixture(&circle,0.0f); else/ 動態(tài)b2FixtureDef fixtureDef;fixtureDef.shape = &circle;fixtureDef.density = densit
14、y;fixtureDef.friction = friction;fixtureDef.restitution = restitution;_body-CreateFixture(&fixtureDef);this-scheduleUpdate();return true;(五)碰撞監(jiān)聽由GameContactListener.h類實現(xiàn),這里具體給出其實現(xiàn),定義均在實現(xiàn)文件中實現(xiàn)了。GameContactListener.cpp#include GameContactListener.h#include BilliardSprite.hGameContactListener:GameConta
15、ctListener()GameContactListener:GameContactListener()void GameContactListener:BeginContact(b2Contact*contact)CCLOG(%s,static_cast(contact-GetFixtureA()-GetBody()-GetUserData()-getName();CCLOG(%s,static_cast(contact-GetFixtureB()-GetBody()-GetUserData()-getName();void GameContactListener:EndContact(b
16、2Contact* contact)/ handle end eventvoid GameContactListener:PreSolve(b2Contact* contact,const b2Manifold* oldManifold)/ handle pre-solve eventvoid GameContactListener:PostSolve(b2Contact* contact,const b2ContactImpulse* impulse)/ handle post-solve eventvoid GameContactListener:deleteBody()(六)初始化物理世
17、界PhysicsBox2dScene.cpp文件中void PhysicsBox2dScene:initPhysics()Size s = Director:getInstance()-getVisibleSize();_ContactListener = new GameContactListener();/ gravityb2Vec2 gravity;gravity.Set(0.0f, 0.0f);/ create world_world = new b2World(gravity);_world-SetContactListener(_ContactListener); / 碰撞/ al
18、low sleep_world-SetAllowSleeping(true);/ physics test 避免碰撞檢測不連續(xù)產(chǎn)生碰撞穿透_world-SetContinuousPhysics(true);/ groundb2BodyDef groundBodyDef;/ left downgroundBodyDef.position.Set(0, 0);/ create groundb2Body* groundBody = _world-CreateBody(&groundBodyDef);groundBody-SetUserData(boundary);/ shapeb2EdgeShape
19、 groundBox;/ downgroundBox.Set(b2Vec2(0,0),b2Vec2(s.width/PTM_RATIO,0);groundBody-CreateFixture(&groundBox,0);/ upgroundBox.Set(b2Vec2(0,s.height/PTM_RATIO),b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO);groundBody-CreateFixture(&groundBox,0);/ leftgroundBox.Set(b2Vec2(0,s.height/PTM_RATIO),b2Vec2(0,0
20、);groundBody-CreateFixture(&groundBox,0);/ rightgroundBox.Set(b2Vec2(s.width - 60)/PTM_RATIO,s.height/PTM_RATIO),b2Vec2(s.width - 60)/PTM_RATIO,0);groundBody-CreateFixture(&groundBox,0);(七)初始化場景初始化:PhysicsBox2dScene:PhysicsBox2dScene()_world = NULL;_aim = false;_angle = 0.0f;_curPower = 0.0f;_powerE
21、nd = false;_sliderSpeed = 0.0f;_aimPos = Vec2(-1,-1);_canAim = true;在PhysicsBox2dScene.cpp文件中init函數(shù)中初始化場景:1、繪制能量條/ slider bgauto slider_bg = Sprite:create(Chapter07/slider/bg-f.png);slider_bg-setPosition(Vec2(visibleSize.width - 30, visibleSize.height/2);this-addChild(slider_bg, 2, SLIDER_BG_TAG);/
22、init power slider rect_powerRect = Rect(visibleSize.width - 58, 0, 58,visibleSize.height);/ sliderauto slider = Sprite:create(Chapter07/slider/fg-f.png);this-addChild(slider, 3, SLIDER_TAG);slider-setVisible(false);/ slider leftauto slider_left = Sprite:create(Chapter07/slider/bg-left.png);slider_le
23、ft-setPosition(Vec2(visibleSize.width - 60, visibleSize.height/2);this-addChild(slider_left, 2);2、繪制非物理世界邊界/ slider leftauto slider_left = Sprite:create(Chapter07/slider/bg-left.png);slider_left-setPosition(Vec2(visibleSize.width - 60, visibleSize.height/2);this-addChild(slider_left, 2);/ boundary l
24、eftauto boundary_left = Sprite:create(Chapter07/slider/bg-left.png);boundary_left-setPosition(Vec2(3, visibleSize.height/2);this-addChild(boundary_left);/ boundary rightauto boundary_right = Sprite:create(Chapter07/slider/bg-left.png);boundary_right-setPosition(Vec2(visibleSize.width - 2, visibleSiz
25、e.height/2);this-addChild(boundary_right, 2);3、初始化瞄準區(qū)域(物理世界大?。? init aim rect_aimRect = Rect(0, 0, visibleSize.width - 60, visibleSize.height);4、初始化物理世界/ init physics worldthis-initPhysics();5、初始化桌球/ 白球_mainBilliards = BilliardSprite:create(main, false, true, _world, Chapter07/Ball/8.png, Vec2(200,v
26、isibleSize.height/2);this-addChild(_mainBilliards, 10, MAIN_BILLIARDS_TAG);for (int i=0;iaddChild(ballSprite);6、初始化添加瞄準線、瞄準圖片和球桿/ dash lineauto dashLine = Sprite:create(Chapter07/aim/dot_line.png);this-addChild(dashLine, 2, DASH_LINE_TAG);dashLine-setAnchorPoint(Vec2(0.5, 0);dashLine-setVisible(fals
27、e);/ aim iconauto aim_icon = Sprite:create(Chapter07/aim/aim.png);this-addChild(aim_icon, 10, AIM_ICON_TAG);aim_icon-setScale(0.4f);aim_icon-setVisible(false);/ 球桿auto aim_gan = Sprite:create(Chapter07/aim/gan-f.png);this-addChild(aim_gan, 10, AIM_GAN_TAG);aim_gan-setAnchorPoint(Vec2(0.5, 0);aim_gan
28、-setScale(0.6f);aim_gan-setVisible(false);(八)能量條的控制1、能量條區(qū)域觸摸響應事件的設置設置觸摸開始時響應的事件:bool PhysicsBox2dScene:onTouchBegan(Touch *touch, Event *unused_event)if (_aimRect.containsPoint(touch-getLocation() & _canAim)_aim = true;auto start_p = changePos(_mainBilliards-getPosition();auto end_p = touch-getLocat
29、ion();updateLine(start_p, end_p);_powerEnd = false;return true;設置觸摸移動時響應的事件,分為兩種情況,一種是當觸摸移動的區(qū)域的是非物理世界時,改變的是能量條的狀態(tài);另一種情況是當觸摸移動的區(qū)域的是物理世界區(qū)域時,改變的是球桿瞄準的方向:void PhysicsBox2dScene:onTouchMoved(Touch *touch, Event *unused_event)auto slider_bg = (Sprite*)getChildByTag(SLIDER_BG_TAG);if (_powerRect.containsPo
30、int(touch-getStartLocation() & _aim)_curPower = touch-getStartLocation().y - touch-getLocation().y;if (_curPower slider_bg-getContentSize().height )_curPower = slider_bg-getContentSize().height;updatePowerSlider(_curPower);else if (_aimRect.containsPoint(touch-getStartLocation() & _canAim)if (_aimRe
31、ct.containsPoint(touch-getLocation()auto start_p = changePos(_mainBilliards-getPosition();auto end_p = touch-getLocation();updateLine(start_p, end_p);設置觸摸結(jié)束時響應的事件:void PhysicsBox2dScene:onTouchEnded(Touch *touch, Event *unused_event)if (_powerRect.containsPoint(touch-getLocation() & _aim)auto slider
32、_bg = (Sprite*)getChildByTag(SLIDER_BG_TAG);_sliderSpeed = _curPower / slider_bg-getContentSize().height * 50.0f;/ 擊球auto start_p = changePos(_mainBilliards-getPosition();auto end_p = _aimPos;auto v = changePos(end_p - start_p).getNormalized();float q = _curPower / slider_bg-getContentSize().height;
33、/ 設置白球速度_mainBilliards-SetLinearVelocity(b2Vec2(v.x * q * MAX_SPEED, v.y * q * MAX_SPEED);auto dash_line = (Sprite*)getChildByTag(DASH_LINE_TAG);dash_line-setVisible(false);auto aim_icon = (Sprite*)getChildByTag(AIM_ICON_TAG);aim_icon-setVisible(false);auto aim_gan = (Sprite*)getChildByTag(AIM_GAN_T
34、AG);aim_gan-setVisible(false);/ 擊球運動后,在所有物體都靜止之前無法再進行瞄準和擊球_canAim = false;_aim = false;_powerEnd = true; / 進度條可以消除2、為控制條添加監(jiān)聽在PhysicsBox2dScene.cpp文件中init函數(shù)中/ add touch listenerauto listener = EventListenerTouchOneByOne:create();listener-onTouchBegan = CC_CALLBACK_2(PhysicsBox2dScene:onTouchBegan, th
35、is);listener-onTouchMoved = CC_CALLBACK_2(PhysicsBox2dScene:onTouchMoved, this);listener-onTouchEnded = CC_CALLBACK_2(PhysicsBox2dScene:onTouchEnded, this);Director:getInstance()-getEventDispatcher()-addEventListenerWithSceneGraphPriority(listener,this);(九)改變球桿方向b2Vec2 PhysicsBox2dScene:changePos(Ve
36、c2 pos)return b2Vec2(pos.x/PTM_RATIO, pos.y/PTM_RATIO);cocos2d:Vec2 PhysicsBox2dScene:changePos(b2Vec2 pos)return Vec2(pos.x*PTM_RATIO, pos.y*PTM_RATIO);(十)更新瞄準線的位置和球桿位置void PhysicsBox2dScene:updateLine(Vec2 start_p, Vec2 end_p)_aimPos = end_p;/ update line_angle = (_aimPos - start_p).getNormalized(
37、).getAngle() ;auto dashLine = (Sprite*)getChildByTag(DASH_LINE_TAG);dashLine-setPosition(start_p);dashLine-setTextureRect(Rect(0,0,2,abs(end_p - start_p).getLength();dashLine-setRotation(CC_RADIANS_TO_DEGREES(-_angle) + 90.0f);dashLine-setVisible(true);/ update aim iconauto aim_icon = (Sprite*)getCh
38、ildByTag(AIM_ICON_TAG);aim_icon-setPosition(_aimPos);aim_icon-setVisible(true);/ 計算球桿位置auto aim_gan_pos = Vec2(end_p - start_p).getLength() + 45) * start_p.x - 45 * end_p.x) / (end_p - start_p).getLength(),(end_p - start_p).getLength() + 45) * start_p.y - 45 * end_p.y) / (end_p - start_p).getLength(
39、);auto aim_gan = (Sprite*)getChildByTag(AIM_GAN_TAG);aim_gan-setPosition(aim_gan_pos);aim_gan-setRotation(CC_RADIANS_TO_DEGREES(-_angle) - 90.0f);aim_gan-setVisible(true);(十一)實現(xiàn)碰撞檢測(物理模擬)1、碰撞檢測(物理模擬)的實現(xiàn)函數(shù)void PhysicsBox2dScene:update(float delta)float timeStep = 1.0f / 60.0f; / 時間同步int32 velocityIte
40、rations = 8; / 速度迭代次數(shù)int32 positionIterations = 1; / 位置迭代次數(shù)_world-Step(timeStep,velocityIterations,positionIterations);_ContactListener-deleteBody(); / 循環(huán)判定游戲輸贏for (b2Body* Cur = _world-GetBodyList(); Cur; Cur = Cur-GetNext() )if ( Cur-GetType() = b2_dynamicBody & Cur-IsAwake() = true )/ 模擬阻力Cur-Set
41、LinearVelocity(b2Vec2(Cur-GetLinearVelocity().x * 0.989, Cur-GetLinearVelocity().y * 0.989);if( abs(Cur-GetLinearVelocity().x) GetLinearVelocity().y) SetAwake(false);if (_powerEnd)/ 滑塊消失if (_curPower !=0)_curPower -= _sliderSpeed; else if (_curPower GetBodyList(); Cur; Cur = Cur-GetNext() )if ( Cur-GetType() = b2_dynamicBody & Cur-IsAwake() = true )awak +;if (awak = 0)_canAim = true;2、在PhysicsBox2dScene.cpp文件中init函數(shù)中添加定時刷新函數(shù),實現(xiàn)物理模擬,碰撞檢測/ main loopthis-scheduleUpdate();(十二)游戲運行效果如圖。
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工程經(jīng)濟課件(情境2資金的時間價值)
- 手術講解模板路德維希氏咽峽炎引流術課件
- 房屋構(gòu)造-變形縫課件
- 生活中的致癌食物
- ISO90012000質(zhì)量管理體系—要求(ppt 33)
- ISO9000標準解釋第七節(jié)產(chǎn)品實現(xiàn)
- 律師辦公室職業(yè)禮儀實操培訓
- 基于FGA的片上系統(tǒng)的無線保密通信終端
- 5S管理之方針、目標及推行計劃(ppt 39頁)
- 4測量系統(tǒng)分析
- 第七章 鹵代烴(3)-88
- “一杯子”網(wǎng)站策劃方案書
- 1.4二次函數(shù)的應用
- 培訓教程質(zhì)量管理安規(guī)基本概念(一)
- scm供應鏈管理概述PPT課件