PuzzleSDK
ChipmunkTest.cpp
浏览该文件的文档.
1/****************************************************************************
2 Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
3
4 http://www.cocos2d-x.org
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 ****************************************************************************/
24
25//
26// Accelerometer + Chipmunk physics + multi touches example
27// a cocos2d example
28// http://www.cocos2d-x.org
29//
30
31#include "chipmunk/chipmunk.h"
32
33#include "ChipmunkTest.h"
34
37
38enum {
40};
41
42enum {
44};
45
46// callback to remove Shapes from the Space
47
49{
50#if CC_ENABLE_CHIPMUNK_INTEGRATION
51 // enable events
52
53 auto touchListener = EventListenerTouchAllAtOnce::create();
54 touchListener->onTouchesEnded = CC_CALLBACK_2(ChipmunkTest::onTouchesEnded, this);
55 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
56
57 Device::setAccelerometerEnabled(true);
58 auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(ChipmunkTest::onAcceleration, this));
59 _eventDispatcher->addEventListenerWithSceneGraphPriority(accListener, this);
60
61 // title
62 auto label = Label::createWithTTF("Multi touch the screen", "fonts/Marker Felt.ttf", 36.0f);
63 label->setPosition(VisibleRect::center().x, VisibleRect::top().y - 30);
64 this->addChild(label, -1);
65
66 // reset button
68
69 // init physics
71
72#if 1
73 // Use batch node. Faster
74 auto parent = SpriteBatchNode::create("Images/grossini_dance_atlas.png", 100);
75 _spriteTexture = parent->getTexture();
76#else
77 // doesn't use batch node. Slower
78 _spriteTexture = Director::getInstance()->getTextureCache()->addImage("Images/grossini_dance_atlas.png");
79 auto parent = Node::create();
80#endif
81 addChild(parent, 0, kTagParentNode);
82
83 addNewSpriteAtPosition(cocos2d::Vec2(200.0f,200.0f));
84
85 // menu for debug layer
86 MenuItemFont::setFontSize(18);
87 auto item = MenuItemFont::create("Toggle debug", CC_CALLBACK_1(ChipmunkTest::toggleDebugCallback, this));
88
89 auto menu = Menu::create(item, nullptr);
90 this->addChild(menu);
91 menu->setPosition(VisibleRect::right().x-100, VisibleRect::top().y-60);
92
93 scheduleUpdate();
94#else
95 auto label = Label::createWithTTF("Should define CC_ENABLE_CHIPMUNK_INTEGRATION=1\n to run this test case",
96 "fonts/arial.ttf",
97 18);
98 auto size = Director::getInstance()->getWinSize();
99 label->setPosition(size.width/2, size.height/2);
100
101 addChild(label);
102
103#endif
104
105}
106
108{
109#if CC_ENABLE_CHIPMUNK_INTEGRATION
110 _debugLayer->setVisible(! _debugLayer->isVisible());
111#endif
112}
113
115{
116#if CC_ENABLE_CHIPMUNK_INTEGRATION
117 // manually Free rogue shapes
118 for( int i=0;i<4;i++) {
119 cpShapeFree( _walls[i] );
120 }
121
122#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
123 cpSpaceFree(_space);
124#else
125 cpHastySpaceFree(_space);
126#endif
127
128 Device::setAccelerometerEnabled(false);
129#endif
130}
131
133{
134#if CC_ENABLE_CHIPMUNK_INTEGRATION
135 // init chipmunk
136 //cpInitChipmunk();
137
138#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
139 _space = cpSpaceNew();
140#else
141 _space = cpHastySpaceNew();
142 cpHastySpaceSetThreads(_space, 0);
143#endif
144
145 cpSpaceSetGravity(_space, cpv(0.0f, -100.0f));
146
147 //
148 // rogue shapes
149 // We have to free them manually
150 //
151 // bottom
152 _walls[0] = cpSegmentShapeNew( cpSpaceGetStaticBody(_space),
155
156 // top
157 _walls[1] = cpSegmentShapeNew( cpSpaceGetStaticBody(_space),
159 cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f);
160
161 // left
162 _walls[2] = cpSegmentShapeNew( cpSpaceGetStaticBody(_space),
164 cpv(VisibleRect::leftTop().x,VisibleRect::leftTop().y), 0.0f);
165
166 // right
167 _walls[3] = cpSegmentShapeNew( cpSpaceGetStaticBody(_space),
169 cpv(VisibleRect::rightTop().x, VisibleRect::rightTop().y), 0.0f);
170
171 for( int i=0;i<4;i++) {
172
173 cpShapeSetElasticity(_walls[i], 1.0f);
174 cpShapeSetFriction(_walls[i], 1.0f);
175 cpSpaceAddShape(_space, _walls[i]);
176 }
177
178 // Physics debug layer
179 _debugLayer = PhysicsDebugNode::create(_space);
180 this->addChild(_debugLayer, Z_PHYSICS_DEBUG);
181#endif
182}
183
184void ChipmunkTest::update(float delta)
185{
186 // Should use a fixed size step based on the animation interval.
187 int steps = 2;
188 float dt = Director::getInstance()->getAnimationInterval()/(float)steps;
189
190 for(int i=0; i<steps; i++){
191
192#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
193 cpSpaceStep(_space, dt);
194#else
195 cpHastySpaceStep(_space, dt);
196#endif
197 }
198}
199
201{
202 auto reset = MenuItemImage::create("Images/r1.png", "Images/r2.png", CC_CALLBACK_1(ChipmunkTest::reset, this));
203
204 auto menu = Menu::create(reset, nullptr);
205
206 menu->setPosition(VisibleRect::center().x, VisibleRect::bottom().y + 30);
207 this->addChild(menu, -1);
208}
209
210void ChipmunkTest::reset(Ref* sender)
211{
213}
214
216{
217#if CC_ENABLE_CHIPMUNK_INTEGRATION
218 int posx, posy;
219
220 auto parent = getChildByTag(kTagParentNode);
221
222 posx = CCRANDOM_0_1() * 200.0f;
223 posy = CCRANDOM_0_1() * 200.0f;
224
225 posx = (posx % 4) * 85;
226 posy = (posy % 3) * 121;
227
228
229 int num = 4;
230 cpVect verts[] = {
231 cpv(-24,-54),
232 cpv(-24, 54),
233 cpv( 24, 54),
234 cpv( 24,-54),
235 };
236
237 cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero, 0.0f));
238
239 cpBodySetPosition(body, cpv(pos.x, pos.y));
240 cpSpaceAddBody(_space, body);
241
242 cpShape* shape = cpPolyShapeNew(body, num, verts, cpTransformIdentity, 0.0f);
243 cpShapeSetElasticity(shape, 0.5f);
244 cpShapeSetFriction(shape, 0.5f);
245 cpSpaceAddShape(_space, shape);
246
247 auto sprite = PhysicsSprite::createWithTexture(_spriteTexture, cocos2d::Rect(posx, posy, 85, 121));
248 parent->addChild(sprite);
249
250 sprite->setCPBody(body);
251 sprite->setPosition(pos);
252#endif
253}
254
256{
258}
259
260void ChipmunkTest::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
261{
262 //Add a new body/atlas sprite at the touched location
263
264 for( auto &touch: touches)
265 {
266 auto location = touch->getLocation();
267
268 addNewSpriteAtPosition( location );
269 }
270}
271
272void ChipmunkTest::onAcceleration(Acceleration* acc, Event* event)
273{
274 static float prevX=0, prevY=0;
275
276#define kFilterFactor 0.05f
277
278 float accelX = (float) acc->x * kFilterFactor + (1- kFilterFactor)*prevX;
279 float accelY = (float) acc->y * kFilterFactor + (1- kFilterFactor)*prevY;
280
281 prevX = accelX;
282 prevY = accelY;
283
284 auto v = cocos2d::Vec2( accelX, accelY);
285 v = v * 200;
286 cpSpaceSetGravity(_space, cpv(v.x, v.y));
287}
288
289ChipmunkTests::ChipmunkTests()
290{
292}
293
#define ADD_TEST_CASE(__className__)
Definition: BaseTest.h:211
#define kFilterFactor
USING_NS_CC_EXT
@ kTagParentNode
USING_NS_CC
@ Z_PHYSICS_DEBUG
void onEnter() override
void addNewSpriteAtPosition(cocos2d::Vec2 p)
void toggleDebugCallback(cocos2d::Ref *sender)
void createResetButton()
void reset(cocos2d::Ref *sender)
cpSpace * _space
Definition: ChipmunkTest.h:59
cpShape * _walls[4]
Definition: ChipmunkTest.h:60
void update(float dt) override
virtual void onAcceleration(cocos2d::Acceleration *acc, cocos2d::Event *event)
cocos2d::Texture2D * _spriteTexture
Definition: ChipmunkTest.h:55
void initPhysics()
void onTouchesEnded(const std::vector< cocos2d::Touch * > &touches, cocos2d::Event *event)
TestSuite * getTestSuite() const
Definition: BaseTest.h:83
virtual void onEnter() override
Definition: BaseTest.cpp:430
virtual void restartCurrTest()
Definition: BaseTest.cpp:299
static cocos2d::Vec2 top()
Definition: VisibleRect.cpp:57
static cocos2d::Vec2 leftTop()
Definition: VisibleRect.cpp:75
static cocos2d::Vec2 center()
Definition: VisibleRect.cpp:69
static cocos2d::Vec2 bottom()
Definition: VisibleRect.cpp:63
static cocos2d::Vec2 rightTop()
Definition: VisibleRect.cpp:81
static cocos2d::Vec2 rightBottom()
Definition: VisibleRect.cpp:93
static cocos2d::Vec2 leftBottom()
Definition: VisibleRect.cpp:87
static cocos2d::Vec2 right()
Definition: VisibleRect.cpp:51