笔记:利用 Cocos2dx 3.2 与 Box2D制作一个跑酷游戏

最近写lua写得没有力气了,所以想让脑袋放松一下,刚好看到有人在用swift做游戏:

Swift游戏实战-跑酷熊猫

于是脑子一短路,就想到了利用这些素材来做一个游戏。

本来不想记笔记的,但是由于选择物理引擎的时候遇到诸多问题,所以选择记录下来,目前只做了个雏形,需要再完善一点。

需要知识:

1 cocos2dx-3.2 基本知识

2 box2d有一定的了解。

由于比较简单,所以把所有代码给上了先,然后再简单介绍下遇到的问题之类的东西。

首先是主角,熊猫类:

Panda.h

 1 #ifndef __PANDA_H__
 2 #define __PANDA_H__
 3
 4 #include "cocos2d.h"
 5 USING_NS_CC;
 6
 7 class Panda : public cocos2d::Node
 8 {
 9 public:
10     Vector<SpriteFrame*> run_frames;
11     Vector<SpriteFrame*> jump_effect_frames;
12     Vector<SpriteFrame*> roll_frames;
13     Vector<SpriteFrame*> jump_frames;
14     Animation * run_anim;
15     Animation * jump_anim;
16     Animation * jump_effect_anim;
17     Animation * roll_anim;
18     Sprite * shape;
19     Animation * anim;
20     int cur_state;//current state
21     // Here‘s a difference. Method ‘init‘ in cocos2d-x returns bool, instead of returning ‘id‘ in cocos2d-iphone
22     virtual bool init();
23     //play status RUM||ROLL||JUMP etc
24     void play(unsigned int state);
25
26     void updateState();
27     // implement the "static create()" method manually
28     CREATE_FUNC(Panda);
29
30     int getCurrentState();
31     //panda 4 states
32     enum {
33         RUN = 1,
34         JUMP = 2,
35         JUMP2 = 3
36     };
37 };
38
39 #endif // __PANDA_H__

 1 #include "Panda.h"
 2 #include "cocos2d.h"
 3
 4 USING_NS_CC;
 5
 6 bool Panda::init()
 7 {
 8     if(!Node::init())
 9         return false;
10
11     run_frames = Vector<SpriteFrame*>(8);
12     roll_frames = Vector<SpriteFrame*>(8);
13     jump_effect_frames = Vector<SpriteFrame*>(4);
14     jump_frames = Vector<SpriteFrame*>(8);
15     char str[40] = {0};
16     for(int i=1; i<=8;i++)
17     {
18         sprintf(str,"jump.atlas/panda_jump_0%d.png",i);
19         auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
20         if( frame != NULL )
21         {
22             jump_frames.pushBack(frame);
23         }
24
25         sprintf(str,"roll.atlas/panda_roll_0%d.png",i);
26         auto frame_0 = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
27         if( frame_0 != NULL )
28         {
29             roll_frames.pushBack(frame_0);
30         }
31
32         sprintf(str,"run.atlas/panda_run_0%d.png",i);
33         auto frame_1 = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
34         if( frame_1 != NULL )
35         {
36             run_frames.pushBack(frame_1);
37         }
38
39         sprintf(str,"jump_effect.atlas/jump_effect_0%d.png",i);
40         auto frame_2 = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
41         if( frame_2 != NULL )
42         {
43             jump_effect_frames.pushBack(frame_2);
44         }
45     }
46
47     run_anim = Animation::createWithSpriteFrames(run_frames,0.05f);
48     run_anim->retain();
49     roll_anim = Animation::createWithSpriteFrames(roll_frames,0.05f);
50     roll_anim->retain();
51     jump_anim = Animation::createWithSpriteFrames(jump_frames,0.05f);
52     jump_anim->retain();
53     jump_effect_anim = Animation::createWithSpriteFrames(jump_effect_frames,0.05f);
54     jump_effect_anim->retain();
55     shape= Sprite::createWithSpriteFrameName("run.atlas/panda_run_01.png");
56     addChild(shape);
57     return true;
58 }
59
60 void Panda::play(unsigned int state)
61 {
62     Action * animate;
63     switch(state)
64     {
65     case RUN:
66         cur_state = Panda::RUN;
67         animate = RepeatForever::create(Animate::create(run_anim));
68         animate->setTag(100);
69         shape->runAction(animate);
70         break;
71     case JUMP:
72         cur_state = Panda::JUMP;
73         animate = Animate::create(jump_anim);
74         animate->setTag(200);
75         shape->stopActionByTag(100);
76         shape->runAction(animate);
77         break;
78     case JUMP2:
79         animate = Sequence::create(Animate::create(jump_effect_anim),Animate::create(roll_anim));
80         animate->setTag(300);
81         cur_state = Panda::JUMP2;
82         shape->runAction(animate);
83         break;
84     }
85 }
86
87 int Panda::getCurrentState()
88 {
89     return cur_state;
90 }
91
92 void Panda::updateState()
93 {
94     if (shape->getActionByTag(200) == nullptr && shape->getActionByTag(300) == nullptr)
95     {
96         play(Panda::RUN);
97     }
98 }

Panda.cpp

然后是场景类,里面有一些逻辑处理:

 1 #ifndef __GAMEMAIN_H__
 2 #define __GAMEMAIN_H__
 3
 4 #include "cocos2d.h"
 5 #include "Panda.h"
 6 #include "Box2D\Box2D.h"
 7 #include "GLES-Render.h"
 8
 9 USING_NS_CC;
10 //whether show assets
11 #define SHOW_DEBUG true
12 //draw scale of physics world
13 #define DRAW_SCALE 30.0f
14 #define ALL_ALHA 0.5f
15
16 class GameMain : public cocos2d::Layer
17 {
18 public:
19     //physic engine related
20     b2World * world;
21     Map<b2Body,Sprite> * map;
22     b2Body * panda_body;
23     //objects move speed
24     float speed;
25     Sprite * far_bg;
26     Sprite * middle_bg_0;
27     Sprite * middle_bg_1;
28     Size cSize;
29     Size visibleSize;
30     Layer * platform_container;
31     Panda * panda;
32     GLESDebugDraw * debugDraw;
33     // there‘s no ‘id‘ in cpp, so we recommend returning the class instance pointer
34     static cocos2d::Scene* createScene();
35
36     // Here‘s a difference. Method ‘init‘ in cocos2d-x returns bool, instead of returning ‘id‘ in cocos2d-iphone
37     virtual bool init();
38
39     virtual void onEnter();
40
41     virtual void onExit();
42
43     void update(float dt);
44
45     virtual bool onTouchBegan(Touch * touch, Event * event);
46     virtual void onTouchEnded(Touch * touch, Event * event);
47     virtual void onTouchMoved(Touch * touch, Event * event);
48
49     virtual bool onContactBegin(const PhysicsContact& contact);
50     // implement the "static create()" method manually
51     CREATE_FUNC(GameMain);
52
53      //
54     // Overrides
55     //
56     virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
57 private:
58     void create_ground();
59     void gen_step(const std::string& res, float posX, float posY);
60     void init_physics_world();
61 };
62
63 #endif // __HELLOWORLD_SCENE_H__

GameMain.h

  1 #include "GameMain.h"
  2 #include "cocos2d.h"
  3 #include "Box2D\Box2D.h"
  4 #include "GLES-Render.h"
  5 USING_NS_CC;
  6
  7 Scene* GameMain::createScene()
  8 {
  9     auto scene = Scene::create();
 10     auto layer = GameMain::create();
 11     scene->addChild(layer);
 12     return scene;
 13 }
 14
 15
 16 bool GameMain::init()
 17 {
 18     if ( !Layer::init() )
 19     {
 20         return false;
 21     }
 22     speed = 5.0f;
 23     auto listener = EventListenerTouchOneByOne::create();
 24     listener->onTouchBegan = CC_CALLBACK_2(GameMain::onTouchBegan,this);
 25     listener->onTouchEnded = CC_CALLBACK_2(GameMain::onTouchEnded,this);
 26     listener->onTouchMoved = CC_CALLBACK_2(GameMain::onTouchMoved,this);
 27
 28     Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
 29
 30     visibleSize = Director::getInstance()->getVisibleSize();
 31     Vec2 origin = Director::getInstance()->getVisibleOrigin();
 32     SpriteFrameCache::getInstance()->addSpriteFramesWithFile("panda.plist");//add panda animate
 33     SpriteFrameCache::getInstance()->addSpriteFramesWithFile("scene.plist");//add scene resources
 34
 35     middle_bg_0 = Sprite::create("bbg_snow_bone.jpg");
 36     cSize = middle_bg_0->getContentSize();
 37     middle_bg_0->setPosition(visibleSize.width*0.5, visibleSize.height*0.5);
 38     middle_bg_0->setVisible(SHOW_DEBUG);
 39     addChild(middle_bg_0);
 40
 41     init_physics_world();
 42
 43     //gen_step();
 44     create_ground();
 45
 46     //init panda and its physics data
 47     Point p(visibleSize.width/2,visibleSize.height/2);
 48     b2BodyDef bodyDef;
 49     bodyDef.type = b2_dynamicBody;
 50     bodyDef.position.Set(p.x/DRAW_SCALE, p.y/DRAW_SCALE);
 51     panda_body = world->CreateBody(&bodyDef);
 52     b2MassData massdata;
 53     massdata.mass = 100.0f;
 54     panda_body->SetMassData(&massdata);
 55
 56     b2PolygonShape shape;
 57     shape.SetAsBox(50.0f/DRAW_SCALE, 100.0f/DRAW_SCALE);
 58
 59     b2FixtureDef fixtureDef;
 60     fixtureDef.shape = &shape;
 61     fixtureDef.density = 1.0f;
 62     fixtureDef.friction = 0.3f;
 63     panda_body->CreateFixture(&fixtureDef);
 64
 65     panda = Panda::create();
 66     panda->setPosition(visibleSize.width/2, visibleSize.height/2);
 67     Size panda_size = Size(50.0f,100.0f);
 68     panda->play(Panda::RUN);
 69     this->addChild(panda);
 70     panda_body->SetUserData(panda);
 71     panda->setVisible(SHOW_DEBUG);
 72
 73     gen_step("platform_l.png",51.0,100.0f);
 74     gen_step("platform_m.png",196.0f,100.0f);
 75     gen_step("platform_r.png",392.0f,100.0f);
 76     return true;
 77 }
 78
 79 void GameMain::init_physics_world()
 80 {
 81     b2Vec2 gravity;
 82     gravity.Set(0.0f,-10.0f);
 83     world = new b2World(gravity);
 84     world->SetAllowSleeping(true);
 85     world->SetContinuousPhysics(true);
 86     debugDraw = new GLESDebugDraw(DRAW_SCALE);
 87     uint32 flags = 0;
 88     flags += GLESDebugDraw::e_shapeBit;
 89     flags += GLESDebugDraw::e_aabbBit;
 90     flags += GLESDebugDraw::e_centerOfMassBit;
 91     debugDraw->SetFlags(flags);
 92     world->SetDebugDraw(debugDraw);
 93 }
 94
 95 void GameMain::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
 96 {
 97     world->DrawDebugData();
 98     Layer::draw(renderer,transform,flags);
 99 }
100
101 void GameMain::create_ground()
102 {
103     b2BodyDef ground_def;
104     ground_def.position.Set(visibleSize.width/2/DRAW_SCALE, visibleSize.height/2/DRAW_SCALE);
105
106     b2Body * ground_body = world->CreateBody(&ground_def);
107
108     /***/
109     //bottom
110     b2PolygonShape ground_shape;
111     ground_shape.SetAsBox(visibleSize.width/2/DRAW_SCALE,0,b2Vec2(0,-visibleSize.height/2/DRAW_SCALE),0);
112     ground_body->CreateFixture(&ground_shape,0);
113     //top
114     ground_shape.SetAsBox(visibleSize.width/2/DRAW_SCALE,0,b2Vec2(0,visibleSize.height/2/DRAW_SCALE),0);
115     ground_body->CreateFixture(&ground_shape,0);
116     //left
117     ground_shape.SetAsBox(0,visibleSize.height/2/DRAW_SCALE,b2Vec2(-visibleSize.width/2/DRAW_SCALE,0),0);
118     ground_body->CreateFixture(&ground_shape,0);
119     //right
120     ground_shape.SetAsBox(0,visibleSize.height/2/DRAW_SCALE,b2Vec2(visibleSize.width/2/DRAW_SCALE,0),0);
121     ground_body->CreateFixture(&ground_shape,0);
122 }
123
124 bool GameMain::onTouchBegan(Touch * touch, Event * event)
125 {
126     Sprite * ball = Sprite::create("apple.png");
127     ball->setVisible(SHOW_DEBUG);
128     Size contentSize = ball->getContentSize();
129     addChild(ball);
130     b2BodyDef ballDef;
131     ballDef.type = b2_dynamicBody;
132     ballDef.position.Set(touch->getLocation().x/DRAW_SCALE, touch->getLocation().y/DRAW_SCALE);
133     b2Body * ballBody = world->CreateBody(&ballDef);
134     ballBody->SetUserData(ball);
135     b2MassData massData;
136     massData.center = b2Vec2(contentSize.width/2/DRAW_SCALE,contentSize.height/2/DRAW_SCALE);
137     massData.mass = 50;
138     b2CircleShape ballShape;
139     ballShape.ComputeMass(&massData,1.5f);
140     ballShape.m_radius=45.0f/DRAW_SCALE;
141     b2FixtureDef ballFixture;
142     ballFixture.density = 10.0f;
143     ballFixture.friction = 1.0f;
144     ballFixture.restitution = 0.6f;
145     ballFixture.shape = &ballShape;
146
147     ballBody->CreateFixture(&ballFixture);
148     ballBody->SetGravityScale(10);
149     /**
150     float vx = touch->getLocation().x > panda->getPositionX() ? 100.0f : -100.0f;
151     panda->updateState();
152     int cur_state = panda->getCurrentState();
153     if( cur_state == Panda::RUN )
154     {
155         panda_body->ApplyForce(b2Vec2(vx,1000),panda_body->GetPosition(),true);
156         panda->play(Panda::JUMP);
157     }else if(cur_state == Panda::JUMP)
158     {
159         panda_body->ApplyForce(b2Vec2(vx,800),panda_body->GetPosition(),true);
160         panda->play(Panda::JUMP2);
161     }*/
162     return true;
163 }
164
165 void GameMain::update(float dt)
166 {
167     world->Step(dt,10,10);
168     b2Body* b = world->GetBodyList();
169     while (b)
170     {
171         b2Body* bNext = b->GetNext();
172         Sprite * sp = (Sprite *)b->GetUserData();
173         if( sp != nullptr )
174             sp->setPosition(b->GetPosition().x*DRAW_SCALE,b->GetPosition().y*DRAW_SCALE);
175
176         b = bNext;
177     }
178 }
179
180 //generate floors
181 void GameMain::gen_step(const std::string& res, float posX, float posY)
182 {
183     Sprite * sp = Sprite::create(res);
184     sp->setPosition(posX, posY);
185     addChild(sp);
186
187     Size contentSize = sp->getContentSize();
188
189     b2BodyDef bodyDef;
190     bodyDef.position.Set(posX/DRAW_SCALE, posY/DRAW_SCALE);
191     b2Body * body = world->CreateBody(&bodyDef);
192
193     b2PolygonShape shape;
194     shape.SetAsBox(contentSize.width/DRAW_SCALE, contentSize.height/DRAW_SCALE);
195
196     b2FixtureDef fixtureDef;
197     fixtureDef.shape = &shape;
198     fixtureDef.density = 1.0f;
199     fixtureDef.friction = 0.3f;
200     body->CreateFixture(&fixtureDef);
201     sp->setVisible(SHOW_DEBUG);
202 }
203
204 bool GameMain::onContactBegin(const PhysicsContact& contact)
205 {
206     log("Contacted...");
207     return true;
208 }
209
210 void GameMain::onTouchEnded(Touch * touch, Event * event)
211 {
212
213 }
214
215 void GameMain::onTouchMoved(Touch * touch, Event * event)
216 {
217
218 }
219
220 void GameMain::onEnter()
221 {
222     Layer::onEnter();
223     this->schedule(schedule_selector(GameMain::update),0.03f);
224 }
225
226 void GameMain::onExit()
227 {
228     delete world;
229     delete debugDraw;
230     Layer::onExit();
231     this->unschedule(schedule_selector(GameMain::update));
232 }

GameMain.cpp

需要注意:

1 所有的熊猫动作打包成一个plist,所有的场景素材打包到另一个plist

这就是我们在场景类的init方法里面预加载的两个文件:

1 SpriteFrameCache::getInstance()->addSpriteFramesWithFile("panda.plist");//add panda animate
2     SpriteFrameCache::getInstance()->addSpriteFramesWithFile("scene.plist");//add scene resources

资源目录应该是这样的:

2 去cocos2d-x-3.2\tests\cpp-tests\Classes\Box2DTestBed下面将GLES-Render.hGLES-Render.cpp拷到项目里面来,因为Box2d没有b2Debug的实现,这个是我们手头上需要的实现。

3 使用Box2d的时候极有可能会出现编译连接错误,找不到Box2d相关的类,这个时候需要将cocos2d-x-3.2\external\Box2D编译一下,然后在项目的连接器中加入引用:

4 通过b2World::SetDebugDraw(b2Draw * draw)GLESDebugDraw实例设置为worlddebugDraw之后,每帧调用world->DrawDebugData()是不会生效的,只有复写Layer::draw()方法并在其中调用此方法才会显示debugDraw

由于debugDraw是调用显卡去渲染的,所以debugDraw是位于场景最底层的,当你把所有场景内的显示对象的通过setVisible设置为false的时候,你就可以看到了。

可以设置SHOW_DEBUG的值来设置显示对象的visible

如下:

可以看到下面的debugDraw有点测漏了。

5 cocos2dx 3.2内置了chipmunk物理引擎,用起来比较简单,但是我之前学习ActionScript的时候有用过Box2d,并且Box2d的功能比较强大一些,所以选择了Box2dActionScript还有一个效率比Box2d稍强的无力引擎:Nape

以下是一开始用chipmunk实现的一些功能的代码:

  1 #include "GameMain.h"
  2 #include "cocos2d.h"
  3
  4 USING_NS_CC;
  5
  6 Scene* GameMain::createScene()
  7 {
  8     auto scene = Scene::createWithPhysics();
  9     scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
 10     scene->getPhysicsWorld()->setUpdateRate(0.5);
 11     auto layer = GameMain::create();
 12     scene->addChild(layer);
 13     return scene;
 14 }
 15
 16
 17 bool GameMain::init()
 18 {
 19     if ( !Layer::init() )
 20     {
 21         return false;
 22     }
 23
 24     speed = 5.0f;
 25
 26     auto listener = EventListenerTouchOneByOne::create();
 27     listener->onTouchBegan = CC_CALLBACK_2(GameMain::onTouchBegan,this);
 28     listener->onTouchEnded = CC_CALLBACK_2(GameMain::onTouchEnded,this);
 29     listener->onTouchMoved = CC_CALLBACK_2(GameMain::onTouchMoved,this);
 30
 31     auto contact_listener = EventListenerPhysicsContact::create();
 32     contact_listener->onContactBegin = CC_CALLBACK_1(GameMain::onContactBegin,this);
 33
 34     Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
 35     Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(contact_listener,1);
 36
 37     visibleSize = Director::getInstance()->getVisibleSize();
 38     Vec2 origin = Director::getInstance()->getVisibleOrigin();
 39     SpriteFrameCache::getInstance()->addSpriteFramesWithFile("panda.plist");//add panda animate
 40     SpriteFrameCache::getInstance()->addSpriteFramesWithFile("scene.plist");//add scene resources
 41
 42     middle_bg_0 = Sprite::create("bbg_snow_bone.jpg");
 43     cSize = middle_bg_0->getContentSize();
 44     middle_bg_0->setPosition(visibleSize.width*0.5, visibleSize.height*0.5);
 45     middle_bg_1 = Sprite::create("bbg_snow_bone.jpg");
 46     middle_bg_1->setPosition(visibleSize.width*1.5, visibleSize.height*0.5);
 47     addChild(middle_bg_0);
 48     addChild(middle_bg_1);
 49
 50     gen_floor();
 51
 52     panda = Panda::create();
 53     panda->setPosition(visibleSize.width/2, visibleSize.height/2);
 54     Size panda_size = Size(50.0f,100.0f);
 55     panda->play(Panda::RUN);
 56     auto panda_body = PhysicsBody::createBox(panda_size);
 57     panda_body->retain();
 58     panda->setPhysicsBody(panda_body);
 59     this->addChild(panda);
 60
 61     auto edge_sp = Sprite::create();
 62     auto edge_body = PhysicsBody::createEdgeBox(visibleSize,PHYSICSBODY_MATERIAL_DEFAULT,3);
 63     edge_sp->setPosition(visibleSize.width/2, visibleSize.height/2);
 64     edge_sp->setPhysicsBody(edge_body);
 65     edge_sp->setTag(0);
 66     addChild(edge_sp);
 67     return true;
 68 }
 69
 70 bool GameMain::onContactBegin(const PhysicsContact& contact)
 71 {
 72     log("Contacted...");
 73     return true;
 74 }
 75
 76 bool GameMain::onTouchBegan(Touch * touch, Event * event)
 77 {
 78     log("Touched.....");
 79     int cur_state = panda->getCurrentState();
 80     panda->getPhysicsBody()->applyForce(Vect(500.0f,500.0f));
 81     if( cur_state == Panda::RUN )
 82     {
 83         panda->play(Panda::JUMP);
 84     }else if(cur_state == Panda::JUMP)
 85     {
 86         panda->play(Panda::JUMP2);
 87     }
 88     return true;
 89 }
 90
 91 void GameMain::onTouchEnded(Touch * touch, Event * event)
 92 {
 93
 94 }
 95
 96 void GameMain::onTouchMoved(Touch * touch, Event * event)
 97 {
 98
 99 }
100
101 void GameMain::update(float dt)
102 {
103     /**
104     middle_bg_0->setPositionX(middle_bg_0->getPositionX()-speed);
105
106     if(middle_bg_0->getPositionX() < -cSize.width*0.5)
107     {
108         middle_bg_0->setPositionX(cSize.width*1.5);
109     }
110
111     middle_bg_1->setPositionX(middle_bg_1->getPositionX()-speed);
112     if(middle_bg_1->getPositionX() < -cSize.width*0.5)
113     {
114         middle_bg_1->setPositionX(cSize.width*1.5);
115     }*/
116 }
117
118 void GameMain::onEnter()
119 {
120     Layer::onEnter();
121     this->schedule(schedule_selector(GameMain::update),0.05f);
122 }
123
124 void GameMain::onExit()
125 {
126     Layer::onExit();
127     this->unschedule(schedule_selector(GameMain::update));
128 }
129
130 void GameMain::createFloor(int posx,int posy,int w,int h)
131 {
132
133 }
134 //generate floors
135 void GameMain::gen_floor()
136 {
137     Sprite * sp_l = Sprite::create("platform_l.png");
138     auto body_l = PhysicsBody::createBox(sp_l->getContentSize());
139     body_l->setDynamic(false);
140     sp_l->setPhysicsBody(body_l);
141     sp_l->setPosition(50.0f,150);
142     addChild(sp_l);
143
144     Sprite * sp_m = Sprite::create("platform_m.png");
145     auto body_m = PhysicsBody::createBox(sp_m->getContentSize());
146     body_m->setDynamic(false);
147     sp_m->setPhysicsBody(body_m);
148     sp_m->setPosition(sp_l->getPositionX() + (sp_l->getContentSize().width+sp_m->getContentSize().width)/2,150);
149     addChild(sp_m);
150
151     Sprite * sp_r = Sprite::create("platform_r.png");
152     auto body_r = PhysicsBody::createBox(sp_r->getContentSize());
153     body_r->setDynamic(false);
154     sp_r->setPhysicsBody(body_r);
155     sp_r->setPosition(sp_m->getPositionX() + (sp_m->getContentSize().width+sp_r->getContentSize().width)/2,150);
156     addChild(sp_r);
157 }

GameMain.cpp

建议:

不想吐槽搜索引擎,建议大家遇到问题先尝试自己解决,解决不了的然后可以用国外的搜索引擎搜索一下,或者可以直接去StackFlow去搜索

参考文章:

(翻译)介绍Box2D的Cocos2D 2.X教程:弹球
[Cocos2D-x For WP8]Box2D物理引擎
How to enable Box2d debug draw with Coco2d-x 3.0 beta 2
时间: 2024-10-07 06:10:32

笔记:利用 Cocos2dx 3.2 与 Box2D制作一个跑酷游戏的相关文章

用Phaser来制作一个html5游戏——flappy bird (一)

Phaser是一个简单易用且功能强大的html5游戏框架,利用它可以很轻松的开发出一个html5游戏.在这篇文章中我就教大家如何用Phaser来制作一个前段时间很火爆的游戏:Flappy Bird,希望大家看后也能做出自己的html5游戏.大家可以先点击这里来试玩一下我已经做好的这个游戏,感受一下Phaser的游戏效果,游戏的完整代码我已经放到github上了.支持的浏览器:IE9+.Firefox.Chrome.Opera.Safari以及移动端的能支持html5的浏览器,推荐使用谷歌浏览器,

Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

提要 此篇是一个国外教程的翻译,虽然有点老,但是适合新手入门.自己去写代码,debug,布置场景,可以收获到很多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一篇中,我们学会了怎么在Unity中搭建游戏的场景,并且设置模型的物理属性. 在第二篇中,我们学会了怎么在unity中使用脚本,并且创建了大部分的游戏逻辑,包括投球和得分! 在这最后一节中,我们将会为用户创建一个菜单系统,并且和GameController进行交互,我们开始吧. 在设备上测试 到目前为止,

Android学习笔记(十二)——实战:制作一个聊天界面

//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 运用简单的布局知识,我们可以来尝试制作一个聊天界面. 一.制作 Nine-Patch 图片 : Nine-Patch图片是一种被特殊处理过的 png 图片,能够指定哪些区域可以被拉伸而哪些区域不可以.一般用来作为聊天信息的背景.在此我们先准备一张png图片.然后在 Android sdk 目录下有一个 tools 文件夹,在这个文件夹中找到 draw9patch.bat文件. 双击打开之后, 在导航栏点击 File→

14、Cocos2dx 3.0三,找一个小游戏开发Scene and Layer:游戏梦想

发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/30474393 Scene :场景 了解了Director 之后,接下来介绍 Scene 这个与它紧密相关的游戏组件. 通过之前的学习,我们已经了解了场景以及它在流程控制中的地位. 在 Cocos2d-x 中,Scene 定义了一个场景.场景仅仅是层的容器.包括了全部须要显示的游戏元素. 因此相对于其它游戏元素,Scene 并没有提供什么特别的功能,就是一

凡科互动,3分钟就能制作一个H5游戏

H5游戏是现在很多企业和商家都喜欢的一个活动宣传推广手段,听着好像很高大上,其实它的制作非常"白痴",3分钟就能完成,重点是还可以免费使用,这样的好东西怎么能不和大家分享呢? 首先注册并登陆凡科账号,找到"游戏营销"并点击进入. 然后我们就可以看到有很多种游戏展示在我们面前,把鼠标放在某个游戏的页面,就可以看到游戏的动画效果,这个功能是新加进去的,非常实用,这样可节省我们选择游戏的时间. 点击创建后,依次对"基础设置"."奖项设置&qu

4、Cocos2dx 3.0三,找一个小游戏开发Hello World 分析

尊重开发人员的劳动成果.转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27186557 Hello World 分析 打开新建的"findmistress"项目,能够看到项目文件是由多个代码文件及目录组成的.当中 Hello World 的代码文件直接存放于该项目目录中.以下我们来具体介绍一下项目的文件组成. 1."resource" 该目录主要用于存放游戏中须要的图片.音频和配置等资源文件

8、Cocos2dx 3.0三,找一个小游戏开发3.0存储器管理的版本号

重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27693365 复杂的内存管理 移动设备上的硬件资源十分有限,内存尤为宝贵.开发人员必须十分谨慎地利用内存,避免不必要的消耗.更要防止内存泄漏. 基于 Cocos2d-iPhone 的 Objective-C风格的内存管理是 Cocos2d-x 的一个特色. 把 Objective-C 的内存管理方式引入 C++,使得游戏开发的内存管理难度下降了个层次

使用Unity3D制作一个转盘游戏

今天我们来做点和游戏无关的事情吧!因为博主在找工作的过程中遇到些挫折,所以难免会有些失落,因此实在心情和精力再去完成新的游戏案例,希望大家能够谅解啊.博主今天想和大家分享的是一个叫做幸运转盘的案例.我们知道平时在节假日商场为了促销商品,通常都会推出诸如转盘抽奖这样的游戏.在学了概率以后,虽然我们都知道中奖是一个小概率事件,可是人们对买彩票中奖这样的事情仍然乐此不疲.就像腾讯通过今年的春晚成功地为微信支付培养了大量忠实用户一样,虽然大家抢红包抢到的钱都不算多,可是大家都还是愿意去抢红包啊.为什么呢

教你用php制作一个缩略图教程

在web应用程序飞速发展的今天,各大网站如雨后春笋般壮大起来,然而缩略图是绝大多数网站不可缺少的内容,那么如何利用web应用程序代码去制作一个缩略图呢?下面我就教大家用php代码来制作缩略图的方法! <?php header('Content-Type:image/jpeg'); //设置页面的MIME类型为jpg图片类型. list($width,$height) = getimagesize('yuzhuo520.com.jpg'); //获取原来图片的长和高,getimagesize()函