chapter8 實(shí)驗(yàn)手冊(cè)

上傳人:z*** 文檔編號(hào):104014981 上傳時(shí)間:2022-06-09 格式:DOC 頁(yè)數(shù):14 大?。?37KB
收藏 版權(quán)申訴 舉報(bào) 下載
chapter8 實(shí)驗(yàn)手冊(cè)_第1頁(yè)
第1頁(yè) / 共14頁(yè)
chapter8 實(shí)驗(yàn)手冊(cè)_第2頁(yè)
第2頁(yè) / 共14頁(yè)
chapter8 實(shí)驗(yàn)手冊(cè)_第3頁(yè)
第3頁(yè) / 共14頁(yè)

下載文檔到電腦,查找使用更方便

10 積分

下載資源

還剩頁(yè)未讀,繼續(xù)閱讀

資源描述:

《chapter8 實(shí)驗(yàn)手冊(cè)》由會(huì)員分享,可在線閱讀,更多相關(guān)《chapter8 實(shí)驗(yàn)手冊(cè)(14頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。

1、第八章 碰撞檢測(cè)與運(yùn)動(dòng)模擬 基于Box2D的游戲?qū)嵗? (一)基礎(chǔ)知識(shí) 物理模擬、精靈的繪制與移動(dòng)、觸摸事件的應(yīng)用 (1) 繪制游戲界面 (2) 通過(guò)單點(diǎn)觸摸屏幕,球桿瞄準(zhǔn)目標(biāo) (3) 設(shè)置能量條(觸屏檢測(cè)) (4) 球桿擊球 (5) 碰撞檢測(cè)(物理模擬) (二)游戲配置文件 游戲需要新建一個(gè)Config.h的頭文件,此文件用來(lái)定義游戲中需要的參數(shù)。 #include "cocos2d.h" USING_NS_CC; using namespace cocos2d; #define PTM_RATIO 32 // 定義32像素代表1米 static c

2、onst int SLIDER_BG_TAG = 1000; static const 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 ball

3、[5] = { "Chapter07/Ball/3.png", "Chapter07/Ball/4.png", "Chapter07/Ball/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) }; (三)物理場(chǎng)景的繪制 由PhysicsScene.h類實(shí)現(xiàn)

4、,這里具體給出其實(shí)現(xiàn),定義均在實(shí)現(xiàn)文件中實(shí)現(xiàn)了。 PhysicsScene.cpp #include "PhysicsScene.h" PhysicsScene::PhysicsScene(){} PhysicsScene::~PhysicsScene(){} bool PhysicsScene::init() { if (!Layer::init()) { return false; } // physics scene Size visibleSize = Director::getInstance()->getVisibleSize();

5、 Vec2 origin = Director::getInstance()->getVisibleOrigin(); // 定義世界的邊界 auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT,5.0f); auto edgeNode = Node::create(); edgeNode->setPosition(Vec2(visib

6、leSize.width/2,visibleSize.height/2)); edgeNode->setPhysicsBody(body); this->addChild(edgeNode); // 屏幕觸摸 auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBA

7、CK_2(PhysicsScene::onTouchBegan, this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); return true; } Scene* PhysicsScene::createScene() { // 創(chuàng)建物理世界 auto scene = Scene::createWithPhysics(); // 繪制調(diào)試遮罩 // scene->getPhysicsWor

8、ld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); auto layer = PhysicsScene::create(); scene->addChild(layer); return scene; } bool PhysicsScene::onTouchBegan(Touch *touch, Event *unused_event) { Vec2 location = touch->getLocation(); addNewSpriteAtPosition(location); return fal

9、se; } void PhysicsScene::addNewSpriteAtPosition(Vec2 p) { int picpath = rand() % 11; auto sp = Sprite::create(StringUtils::format("Chapter07/Ball/%d.png",picpath)); sp->setTag(1); auto body = PhysicsBody::createCircle(sp->getContentSize().width / 2); // auto body = PhysicsBody::cre

10、ateBox(sp->getContentSize()); sp->setPhysicsBody(body); sp->setPosition(p); this->addChild(sp); } (四)物理物體的封裝,桌球的實(shí)現(xiàn) 由BilliardSprite.h類實(shí)現(xiàn),這里具體給出其實(shí)現(xiàn),定義均在實(shí)現(xiàn)文件中實(shí)現(xiàn)了。 BilliardSprite.cpp #include "BilliardSprite.h" BilliardSprite::BilliardSprite(){} void BilliardSpri

11、te::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; } } Bi

12、lliardSprite* BilliardSprite::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) B

13、illiardSprite(); if (pRet && pRet->init(name, isStatic, isBullet, world, picPath, position, density, friction, restitution)) { pRet->autorelease(); return pRet; } else { delete pRet; pRet = NULL; return NULL; } } bool BilliardSprite::init(char* name, bool isStatic,

14、 bool isBullet, b2World* world, std::string picPath, Vec2 position, float density /*= 1.0*/, float friction /*= 0.1*/, float restitution /*= 0.78*/) { if (!Sprite::init()) { return false; } _name = name; // 創(chuàng)建精靈 _sprite = Sprite::create(picPath); th

15、is->addChild(_sprite); // bodyDef b2BodyDef bodyDef; if (!isStatic) { bodyDef.type = b2_dynamicBody; } if (isBullet) { bodyDef.bullet = true; } bodyDef.position.Set(position.x / PTM_RATIO,position.y / PTM_RATIO); // 創(chuàng)建body _body = world->CreateBody(&bodyDef); _bo

16、dy->SetUserData(this); b2CircleShape circle; circle.m_radius = (_sprite->getContentSize().width / 2 ) / PTM_RATIO; if (isStatic) { // 靜態(tài) _body->CreateFixture(&circle,0.0f); } else { // 動(dòng)態(tài) b2FixtureDef fixtureDef; fixtureDef.shape = &circle; fixtureDef.density = densit

17、y; fixtureDef.friction = friction; fixtureDef.restitution = restitution; _body->CreateFixture(&fixtureDef); } this->scheduleUpdate(); return true; } (五)碰撞監(jiān)聽 由GameContactListener.h類實(shí)現(xiàn),這里具體給出其實(shí)現(xiàn),定義均在實(shí)現(xiàn)文件中實(shí)現(xiàn)了。 GameContactListener.cpp #include "GameContactListener.h" #include "B

18、illiardSprite.h" GameContactListener::GameContactListener(){} GameContactListener::~GameContactListener(){} void GameContactListener::BeginContact(b2Contact*contact) { CCLOG("%s",static_cast(contact->GetFixtureA()->GetBody()->GetUserData())->getName()); CCLOG("%s",stat

19、ic_cast(contact->GetFixtureB()->GetBody()->GetUserData())->getName()); } void GameContactListener::EndContact(b2Contact* contact) { // handle end event } void GameContactListener::PreSolve(b2Contact* contact,const b2Manifold* oldManifold) { // handle pre-solve event }

20、 void GameContactListener::PostSolve(b2Contact* contact,const b2ContactImpulse* impulse) { // handle post-solve event } void GameContactListener::deleteBody(){} (六)初始化物理世界 PhysicsBox2dScene.cpp文件中 void PhysicsBox2dScene::initPhysics() { Size s = Director::getInstance()->getVisibleS

21、ize(); _ContactListener = new GameContactListener(); // gravity b2Vec2 gravity; gravity.Set(0.0f, 0.0f); // create world _world = new b2World(gravity); _world->SetContactListener(_ContactListener); // 碰撞 // allow sleep _world->SetAllowSleeping(true); // physics test 避

22、免碰撞檢測(cè)不連續(xù)產(chǎn)生碰撞穿透 _world->SetContinuousPhysics(true); // ground b2BodyDef groundBodyDef; // left down groundBodyDef.position.Set(0, 0); // create ground b2Body* groundBody = _world->CreateBody(&groundBodyDef); groundBody->SetUserData("boundary"); // shape b2EdgeShape groundB

23、ox; // down groundBox.Set(b2Vec2(0,0),b2Vec2(s.width/PTM_RATIO,0)); groundBody->CreateFixture(&groundBox,0); // up groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO)); groundBody->CreateFixture(&groundBox,0); // left groundBox.Set(b2Vec2

24、(0,s.height/PTM_RATIO),b2Vec2(0,0)); groundBody->CreateFixture(&groundBox,0); // right groundBox.Set(b2Vec2((s.width - 60)/PTM_RATIO,s.height/PTM_RATIO),b2Vec2((s.width - 60)/PTM_RATIO,0)); groundBody->CreateFixture(&groundBox,0); } (七)初始化場(chǎng)景 初始化: PhysicsBox2dScene::PhysicsBox2dScene(

25、) { _world = NULL; _aim = false; _angle = 0.0f; _curPower = 0.0f; _powerEnd = false; _sliderSpeed = 0.0f; _aimPos = Vec2(-1,-1); _canAim = true; } 在PhysicsBox2dScene.cpp文件中init函數(shù)中初始化場(chǎng)景: 1、繪制能量條 // slider bg auto slider_bg = Sprite::create("Chapter07/slider/bg-f.png"); sli

26、der_bg->setPosition(Vec2(visibleSize.width - 30, visibleSize.height/2)); this->addChild(slider_bg, 2, SLIDER_BG_TAG); // init power slider rect _powerRect = Rect(visibleSize.width - 58, 0, 58,visibleSize.height); // slider auto slider = Sprite::create("Chapter07/slider/fg-f.png")

27、; this->addChild(slider, 3, SLIDER_TAG); slider->setVisible(false); // slider left auto slider_left = Sprite::create("Chapter07/slider/bg-left.png"); slider_left->setPosition(Vec2(visibleSize.width - 60, visibleSize.height/2)); this->addChild(slider_left, 2); 2、繪制非物理世界邊界 // slider

28、 left auto 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 left auto boundary_left = Sprite::create("Chapter07/slider/bg-left.png"); boundary_left->se

29、tPosition(Vec2(3, visibleSize.height/2)); this->addChild(boundary_left); // boundary right auto boundary_right = Sprite::create("Chapter07/slider/bg-left.png"); boundary_right->setPosition(Vec2(visibleSize.width - 2, visibleSize.height/2)); this->addChild(boundary_right, 2); 3、初始化瞄準(zhǔn)區(qū)域

30、(物理世界大?。? // init aim rect _aimRect = Rect(0, 0, visibleSize.width - 60, visibleSize.height); 4、初始化物理世界 // init physics world this->initPhysics(); 5、初始化桌球 // 白球 _mainBilliards = BilliardSprite::create("main", false, true, _world, "Chapter07/Ball/8.png", Vec2(200,visibleSize.height/2));

31、 this->addChild(_mainBilliards, 10, MAIN_BILLIARDS_TAG); for (int i=0;i<5;i++) { auto ballSprite = BilliardSprite::create("ball",false, false, _world, ball[i], ballPos[i]); this->addChild(ballSprite); } 6、初始化添加瞄準(zhǔn)線、瞄準(zhǔn)圖片和球桿 // dash line auto dashLine = Sprite::create("Chapter07/aim/do

32、t_line.png"); this->addChild(dashLine, 2, DASH_LINE_TAG); dashLine->setAnchorPoint(Vec2(0.5, 0)); dashLine->setVisible(false); // aim icon auto aim_icon = Sprite::create("Chapter07/aim/aim.png"); this->addChild(aim_icon, 10, AIM_ICON_TAG); aim_icon->setScale(0.4f); aim_icon->setVis

33、ible(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->setScale(0.6f); aim_gan->setVisible(false); (八)能量條的控制 1、能量條區(qū)域觸摸響應(yīng)事件的設(shè)置 設(shè)置觸摸開始時(shí)響應(yīng)的事件: bool PhysicsBox2dScene::on

34、TouchBegan(Touch *touch, Event *unused_event) { if (_aimRect.containsPoint(touch->getLocation()) && _canAim) { _aim = true; auto start_p = changePos(_mainBilliards->getPosition()); auto end_p = touch->getLocation(); updateLine(start_p, end_p); } _powerEnd = false; r

35、eturn true; } 設(shè)置觸摸移動(dòng)時(shí)響應(yīng)的事件,分為兩種情況,一種是當(dāng)觸摸移動(dòng)的區(qū)域的是非物理世界時(shí),改變的是能量條的狀態(tài);另一種情況是當(dāng)觸摸移動(dòng)的區(qū)域的是物理世界區(qū)域時(shí),改變的是球桿瞄準(zhǔn)的方向: void PhysicsBox2dScene::onTouchMoved(Touch *touch, Event *unused_event) { auto slider_bg = (Sprite*)getChildByTag(SLIDER_BG_TAG); if (_powerRect.containsPoint(touch->getStartLocation()) &&

36、 _aim) { _curPower = touch->getStartLocation().y - touch->getLocation().y; if (_curPower<0) { _curPower = 0; } else if( _curPower > slider_bg->getContentSize().height ) { _curPower = slider_bg->getContentSize().height; } updatePowerSlider(_curPower); } else if (_

37、aimRect.containsPoint(touch->getStartLocation()) && _canAim) { if (_aimRect.containsPoint(touch->getLocation())) { auto start_p = changePos(_mainBilliards->getPosition()); auto end_p = touch->getLocation(); updateLine(start_p, end_p); } } } 設(shè)置觸摸結(jié)束時(shí)響應(yīng)的事件: void PhysicsBox

38、2dScene::onTouchEnded(Touch *touch, Event *unused_event) { if (_powerRect.containsPoint(touch->getLocation()) && _aim) { auto slider_bg = (Sprite*)getChildByTag(SLIDER_BG_TAG); _sliderSpeed = _curPower / slider_bg->getContentSize().height * 50.0f; // 擊球 auto start_p = changePos(_m

39、ainBilliards->getPosition()); auto end_p = _aimPos; auto v = changePos((end_p - start_p).getNormalized()); float q = _curPower / slider_bg->getContentSize().height; // 設(shè)置白球速度 _mainBilliards->SetLinearVelocity(b2Vec2(v.x * q * MAX_SPEED, v.y * q * MAX_SPEED)); auto dash_line = (

40、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_TAG); aim_gan->setVisible(false); // 擊球運(yùn)動(dòng)后,在所有物體都靜止之前無(wú)法再進(jìn)行瞄準(zhǔn)和擊球 _canAim = false;

41、 _aim = false; _powerEnd = true; // 進(jìn)度條可以消除 } } 2、為控制條添加監(jiān)聽 在PhysicsBox2dScene.cpp文件中init函數(shù)中 // add touch listener auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(PhysicsBox2dScene::onTouchBegan, this); listener->onTouchMoved = CC_CA

42、LLBACK_2(PhysicsBox2dScene::onTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(PhysicsBox2dScene::onTouchEnded, this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,this); (九)改變球桿方向 b2Vec2 PhysicsBox2dScene::changePos(Vec2 pos) { r

43、eturn 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); } (十)更新瞄準(zhǔn)線的位置和球桿位置 void PhysicsBox2dScene::updateLine(Vec2 start_p, Vec2 end_p) { _aimPos = end_p; // update line _angle = (_

44、aimPos - start_p).getNormalized().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->setVisibl

45、e(true); // update aim icon auto aim_icon = (Sprite*)getChildByTag(AIM_ICON_TAG); aim_icon->setPosition(_aimPos); aim_icon->setVisible(true); // 計(jì)算球桿位置 auto aim_gan_pos = Vec2( (((end_p - start_p).getLength() + 45) * start_p.x - 45 * end_p.x) / (end_p - start_p).getLength(), ((

46、(end_p - start_p).getLength() + 45) * start_p.y - 45 * end_p.y) / (end_p - start_p).getLength()); 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); } (十一)實(shí)現(xiàn)碰撞檢測(cè)

47、(物理模擬) 1、碰撞檢測(cè)(物理模擬)的實(shí)現(xiàn)函數(shù) void PhysicsBox2dScene::update(float delta) { float timeStep = 1.0f / 60.0f; // 時(shí)間同步 int32 velocityIterations = 8; // 速度迭代次數(shù) int32 positionIterations = 1; // 位置迭代次數(shù) _world->Step(timeStep,velocityIterations,positionIterations); _ContactListener->deleteBo

48、dy(); // 循環(huán)判定游戲輸贏 for (b2Body* Cur = _world->GetBodyList(); Cur; Cur = Cur->GetNext() ) { if ( Cur->GetType() == b2_dynamicBody && Cur->IsAwake() == true ) { // 模擬阻力 Cur->SetLinearVelocity(b2Vec2(Cur->GetLinearVelocity().x * 0.989, Cur->GetLinearVelocity().y * 0.989)); if( ab

49、s(Cur->GetLinearVelocity().x) < 0.5f && abs(Cur->GetLinearVelocity().y) < 0.5f ) { Cur->SetAwake(false); } } } if (_powerEnd) { // 滑塊消失 if (_curPower !=0) { _curPower -= _sliderSpeed; } else if (_curPower <= 0) { _curPower = 0.0f; } updatePowerSli

50、der(_curPower); } // 所有球靜止才可以進(jìn)行瞄準(zhǔn) int awak = 0; for (b2Body* Cur = _world->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í)刷新函數(shù),實(shí)現(xiàn)物理模擬,碰撞檢測(cè) // main loop this->scheduleUpdate(); (十二)游戲運(yùn)行效果如圖。

展開閱讀全文
溫馨提示:
1: 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

相關(guān)資源

更多
正為您匹配相似的精品文檔
關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號(hào):ICP2024067431號(hào)-1 川公網(wǎng)安備51140202000466號(hào)


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺(tái),本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請(qǐng)立即通知裝配圖網(wǎng),我們立即給予刪除!