void Player::Initialize(void) { // Load the texture if (!(this->m_Texture = this->m_Hge->Texture_Load("data/particles.png"))) { MessageBox(NULL, "Can't load particles.png texture.", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL); this->m_Engine->Shutdown(); return; } // Create the player sprite this->m_Sprite = new hgeSprite(this->m_Texture, 60, 40, 20, 20); this->m_Sprite->SetColor(this->m_Color); this->m_Sprite->SetHotSpot(10, 10); // Create the particle sprite this->m_ParticleSprite = new hgeSprite(this->m_Texture, 20, 20, 20, 20); this->m_ParticleSprite->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHAADD | BLEND_NOZWRITE); this->m_ParticleSprite->SetHotSpot(10, 10); // Create the particle system this->m_ParticleSystem = new hgeParticleSystem("data/trail.psi", this->m_ParticleSprite); this->m_ParticleSystem->Fire(); // Initialize the weapon slots this->m_Weaponslots = (Weapon**) malloc(sizeof(Weapon*) * NUM_WEAPON_SLOTS); for (int i = 0 ; i < NUM_WEAPON_SLOTS ; ++i) { this->m_Weaponslots[i] = 0; } this->m_Weaponslots[0] = new Neoshooter(this, this->m_Engine->GetWorld()); // Initialize physics { // Define moment cpFloat moment = cpMomentForCircle(1, 0, 10, cpvzero); // Fetch the physics space cpSpace *space = this->m_Engine->GetWorld()->GetSpace(); // Add the physics body this->m_Body = cpSpaceAddBody(space, cpBodyNew(1, moment)); cpBodySetPos(this->m_Body, this->m_Position); // Add the physics shape this->m_Shape = cpSpaceAddShape(space, cpCircleShapeNew(this->m_Body, 10, cpvzero)); this->m_Shape->data = this; this->m_Shape->collision_type = COLLISION_TYPE_GO; cpShapeSetElasticity(this->m_Shape, 1.0f); cpShapeSetFriction(this->m_Shape, 0.7); // Define the collision handlers for various types of collisions cpSpaceAddCollisionHandler(space, COLLISION_TYPE_GO, COLLISION_TYPE_ACTIVATOR, BeginCollisionD, NULL, NULL, SeparateCollisionD, this); cpSpaceAddCollisionHandler(space, COLLISION_TYPE_GO, COLLISION_TYPE_BULLET, BeginCollisionD, NULL, NULL, NULL, this); } }
void Phys::init() { // Create physics space; space = cpSpaceNew(); cpSpaceSetDamping( space, 0.0 ); cpSpaceAddCollisionHandler( space, utAll, utPlant, DynamiUint_begin, NULL, NULL, DynamiUint_separate, NULL ); cpSpaceAddCollisionHandler( space, utAll, utEntity, DynamiUint_begin, NULL, NULL, DynamiUint_separate, NULL ); cpSpaceAddCollisionHandler( space, utAll, utPlayer, DynamiUint_begin, NULL, NULL, DynamiUint_separate, NULL ); cpSpaceAddCollisionHandler( space, utAll, utCorpse, DynamiUint_begin, NULL, NULL, DynamiUint_separate, NULL ); }
World_t *world_create(void) { World_t *out = obj_create_autoreleased(&Class_World); out->cpSpace = cpSpaceNew(); out->cpSpace->data = out; cpSpaceAddCollisionHandler(out->cpSpace, 0, 0, collisionWillBegin, NULL, collisionDidBegin, collisionDidEnd, NULL); out->entities = obj_retain(llist_create((InsertionCallback_t)&obj_retain, &obj_release)); // Create the static entity out->staticEntity = obj_create(&Class_WorldEntity); out->staticEntity->world = out; out->staticEntity->owner = out; out->staticEntity->cpBody = out->cpSpace->staticBody; out->staticEntity->luaUpdateHandler = -1; out->staticEntity->luaPreCollisionHandler = -1; out->staticEntity->luaCollisionHandler = -1; out->staticEntity->luaPostCollisionHandler = -1; out->cpSpace->staticBody->data = out->staticEntity; out->staticEntity->shapes = obj_retain(llist_create((InsertionCallback_t)&obj_retain, &obj_release)); return out; }
static cpSpace *initSpace(void) { int i; cpBody *staticBody; cpShape *shape; cpVect cannonPos; cpResetShapeIdCounter(); g_Space = cpSpaceNew(); g_Space->iterations = 30; g_Space->gravity = cpv(0, -300); staticBody = &g_Space->staticBody; shape = cpSpaceAddShape(g_Space, cpSegmentShapeNew(staticBody, cpv(-400,-290), cpv(-400,300), 0.0f)); shape->e = 1.0f; shape->u = 0.0f; shape->collision_type = PLATFORM_TYPE; cannonPos = cpv(-350, -215); g_Cannon = createCannon(cannonPos, 30.0f, 6.0f); g_Cannon->ai = 0; for (i = 0; i < MAX_PROJECTILES; ++i) { g_Cannon->ammo[i] = createProjectile(6.0f, 1.0f); } platforms[0] = createPlatform(staticBody, cpv(-390, -240), cpv(1600, -240), 10.0f); fprintf(stderr, "Loading dominoes disabled\n"); InitializeDominoes(); cpSpaceAddCollisionHandler(g_Space, PROJECTILE_TYPE, DOMINO_OBJECT_TYPE, NULL, NULL, postSolveProjectileDomino, NULL, NULL); return g_Space; }
// Updates all nescessary sprites, images, buttons etc. void update(void) { static _Bool called = false; GDATAPTR game = get_game_data(); update_background(); if(game->gamestarted && game->paused) { paused(score, survival_time, lives); } else if(lives == 0) { gameover(score, survival_time); } else if(game->gamestarted) { if(!called) { //cpSpaceResizeStaticHash(get_global_cpSpace(), 700.0, 4*10); cpSpaceAddCollisionHandler(get_global_cpSpace(), 1, 2, collision_begin, NULL, NULL, NULL, NULL); cpSpaceAddCollisionHandler(get_global_cpSpace(), 0, 2, collision_static_begin, NULL, NULL, NULL, NULL); cpSpaceAddCollisionHandler(get_global_cpSpace(), 0, 1, collision_static_begin, NULL, NULL, NULL, NULL); called = false; } logic(); update_clouds(); cpSpaceStep(get_global_cpSpace(), 1.0f/60.0f); cpSpaceEachBody(get_global_cpSpace(), &update_sprites, NULL); update_ground(); update_lives(); add_element_to_render_queue(NULL, 0, 0, 0, RCOLOR(0, 0, 0, 255), update_score); add_element_to_render_queue(NULL, 290, 0, 0, RCOLOR(0, 0, 0, 255), update_survivaltime); } else if(game->options) { options(); } else if(game->howtoplay) { howtoplay(); } else if(game->highscores) { highscores(); } }
void Physics::addCollisionHandler(cpCollisionType typeA, cpCollisionType typeB, cpCollisionBeginFunc beginFunc, cpCollisionSeparateFunc separateFunc) { cpCollisionHandler * handler = cpSpaceAddCollisionHandler(mSpace, typeA, typeB); if (beginFunc != NULL) { handler->beginFunc = beginFunc; } if (separateFunc != NULL) { handler->separateFunc = separateFunc; } }
void Space::addCollisionHandler(cpCollisionType a,cpCollisionType b,const CollisionBeginFunc & begin,const CollisionPreSolveFunc & preSolve,const CollisionPostSolveFunc & postSolve,const CollisionSeparateFunc & separate,void *data) { CollisionHandler& handler = collisionHandlers[std::make_pair(a,b)]; handler.begin = begin; handler.preSolve = preSolve; handler.postSolve = postSolve; handler.separate = separate; handler.data = data; cpSpaceAddCollisionHandler(space, a, b, !begin ? 0 : internal_CollisionBeginFunc , !preSolve ? 0 : internal_CollisionPreSolveFunc , !postSolve ? 0 : internal_CollisionPostSolveFunc , !separate ? 0 : internal_CollisionSeparateFunc , &handler); }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Sticky collisions using the cpArbiter data pointer."; cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 10); cpSpaceSetGravity(space, cpv(0, -1000)); cpSpaceSetCollisionSlop(space, 2.0); cpBody *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340,-260), cpv(-340, 260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv( 340,-260), cpv( 340, 260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340,-260), cpv( 340,-260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-340, 260), cpv( 340, 260), 20.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); for(int i=0; i<200; i++){ cpFloat mass = 0.15f; cpFloat radius = 10.0f; cpBody *body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero))); cpBodySetPos(body, cpv(cpflerp(-150.0f, 150.0f, frand()), cpflerp(-150.0f, 150.0f, frand()))); cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius + STICK_SENSOR_THICKNESS, cpvzero)); cpShapeSetFriction(shape, 0.9f); cpShapeSetCollisionType(shape, COLLIDE_STICK_SENSOR); } cpSpaceAddCollisionHandler(space, COLLIDE_STICK_SENSOR, COLLIDE_STICK_SENSOR, NULL, StickyPreSolve, NULL, StickySeparate, NULL); return space; }
static cpSpace * init(void) { cpResetShapeIdCounter(); space = cpSpaceNew(); space->iterations = 10; space->gravity = cpv(0, -100); cpBody *body, *staticBody = &space->staticBody; cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; // Add our one way segment shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-100), cpv(160,-100), 10.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->collision_type = 1; shape->layers = NOT_GRABABLE_MASK; // We'll use the data pointer for the OneWayPlatform struct platformInstance.n = cpv(0, 1); // let objects pass upwards platformInstance.passThruList = cpArrayNew(0); shape->data = &platformInstance; // Add a ball to make things more interesting cpFloat radius = 15.0f; body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero))); body->p = cpv(0, -200); body->v = cpv(0, 170); shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); shape->e = 0.0f; shape->u = 0.9f; shape->collision_type = 2; cpSpaceAddCollisionHandler(space, 1, 2, NULL, preSolve, NULL, NULL, NULL); return space; }
static int l_physics_onPreSolve(lua_State* state) { l_physics_PhysicsData* data = (l_physics_PhysicsData*)lua_touserdata(state, 1); uint32_t a_type = l_tools_toNumberOrError(state, 2); uint32_t b_type = l_tools_toNumberOrError(state, 3); moduleData.handler = cpSpaceAddCollisionHandler(data->physics->space, a_type, b_type); moduleData.handler->preSolveFunc = preSolve; lua_pushboolean(state, moduleData.onPreSolve); moduleData.onPreSolve = false; return 1; }
static cpSpace * init(void) { cpResetShapeIdCounter(); space = cpSpaceNew(); space->iterations = 10; space->gravity = cpv(0, -100); cpBody *staticBody = &space->staticBody; cpShape *shape; // Data structure for our ball emitter // We'll use two sensors for it, one to see if the emitter is blocked // a second to catch the balls and add them back to the emitter emitterInstance.queue = 5; emitterInstance.blocked = 0; emitterInstance.position = cpv(0, 150); // Create our blocking sensor, so we know when the emitter is clear to emit another ball shape = cpSpaceAddShape(space, cpCircleShapeNew(staticBody, 15.0f, emitterInstance.position)); shape->sensor = 1; shape->collision_type = BLOCKING_SENSOR_TYPE; shape->data = &emitterInstance; // Create our catch sensor to requeue the balls when they reach the bottom of the screen shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-2000, -200), cpv(2000, -200), 15.0f)); shape->sensor = 1; shape->collision_type = CATCH_SENSOR_TYPE; shape->data = &emitterInstance; cpSpaceAddCollisionHandler(space, BLOCKING_SENSOR_TYPE, BALL_TYPE, blockerBegin, NULL, NULL, blockerSeparate, NULL); cpSpaceAddCollisionHandler(space, CATCH_SENSOR_TYPE, BALL_TYPE, catcherBarBegin, NULL, NULL, NULL, NULL); return space; }
void TestColliderDetector::initWorld() { //! create physic space space = cpSpaceNew(); //! set space gravity as no gravity space->gravity = cpv(0, 0); //! Physics debug layer CCPhysicsDebugNode *debugLayer = CCPhysicsDebugNode::create(space); this->addChild(debugLayer, INT_MAX); //! get size of bullet CCSize size = bullet->getContentSize(); //! define bullet's collider body int num = 4; cpVect verts[] = { cpv(-size.width/2,-size.height/2), cpv(-size.width/2,size.height/2), cpv(size.width/2,size.height/2), cpv(size.width/2,-size.height/2), }; //! build body as verts' shape cpBody *body = cpBodyNew(1.0f, cpMomentForPoly(1.0f, num, verts, cpvzero)); cpSpaceAddBody(space, body); cpShape* shape = cpPolyShapeNew(body, num, verts, cpvzero); shape->collision_type = eBulletTag; cpSpaceAddShape(space, shape); bullet->setCPBody(body); //! define armature2's body,get shape from armature data body = cpBodyNew(INFINITY, INFINITY); cpSpaceAddBody(space, body); armature2->setCPBody(body); shape = body->shapeList_private; while(shape){ cpShape *next = shape->next_private; shape->collision_type = eEnemyTag; shape = next; } cpSpaceAddCollisionHandler(space, eEnemyTag, eBulletTag, beginHit, NULL, NULL, endHit, NULL); }
int maininit() { ship_list.clear(); shell_list.clear(); rshell = 0; nrshell = 0; space = cpSpaceNew(); last_time_updated = gtime(); dt = 1.; paused = 0; last_pressed = 0; cpCollisionHandler *handler = cpSpaceAddCollisionHandler(space, 1, 2); handler->beginFunc = scorecollision; last_frame_deltas = new float[frame_time_count]; for (int i = 0; i < frame_time_count; i++) last_frame_deltas[i] = 1; return 0; }
void RCPCollision::create() { if (RCPWorld::instance()) { cpSpace * space = RCPWorld::instance()->space(); cpCollisionHandler *handler = cpSpaceAddCollisionHandler(space, mTypeA, mTypeB); RScene * s = scene(); if (!mBeginFunctionName.empty() && s) { mBeginFunc = s->getEventCollisionCallback(mBeginFunctionName); } if (mBeginFunc) { handler->beginFunc = beginFunc; } if (!mPreSolveFunctionName.empty() && s) { mPreSolveFunc = s->getEventCollisionCallback(mPreSolveFunctionName); } if (mPreSolveFunc) { handler->preSolveFunc = preSolveFunc; } if (!mPostSolveFunctionName.empty() && s) { mPostSolveFunc = s->getEventCollisionCallback(mPostSolveFunctionName); } if (mPostSolveFunc) { handler->postSolveFunc = postSolveFunc; } if (!mSeparateFunctionName.empty() && s) { mSeparateFunc = s->getEventCollisionCallback(mSeparateFunctionName); } if (mSeparateFunc) { handler->separateFunc = separateFunc; } handler->userData = this; } mCreated = true; }
// make cpSpace object to pass to GUI cpSpace * core_create_space () { //create and return new cpSpace cpSpace *space; space = cpSpaceNew (); core_set_gravity ( space, DEFAULT_GRAVITY ); cpSpaceAddCollisionHandler ( space, ASTEROID_COLLISION_TYPE, GOAL_COLLISION_TYPE, core_begin_collision, NULL, NULL, NULL, NULL ); BodyInfo * bi = body_info_new ( 0 ); bi->index = 0; space->staticBody->data = bi; // sets index of static body to 0 GameInfo *gameInfo = game_info_new (); cpSpaceSetUserData(space, ( cpDataPointer ) gameInfo); cpEnableSegmentToSegmentCollisions (); return space; }
ETERM *space_subscribe_collision(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *typeap = erl_element(2, argp); ETERM *typebp = erl_element(3, argp); ETERM *pidp = erl_element(4, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); erlmunk_subscriber *subscriber = (erlmunk_subscriber *) malloc(sizeof(erlmunk_subscriber)); subscriber->client = get_current_client(); subscriber->from = erl_copy_term(pidp); cpCollisionHandler *handler = cpSpaceAddCollisionHandler(s->space, ERL_INT_VALUE(typeap), ERL_INT_VALUE(typebp)); handler->beginFunc = handle_collision; handler->userData = subscriber; return NULL; }
void GameInst::LoadLevel() { sf::Vector2f windowDim = m_GUIMgr.GetWindowDim(); //-------------------------------------- chipmunk physics // cpVect is a 2D vector and cpv() is a shortcut for initializing them. cpVect gravity = cpv(0, 980); // Create a physworld m_pSpace = cpSpaceNew(); cpSpaceSetGravity(m_pSpace, gravity); cpFloat offSet = 0; //top m_WorldBounds.Top = cpSegmentShapeNew(m_pSpace->staticBody, cpv(offSet,offSet), cpv(cpFloat(windowDim.x)+offSet,offSet), 1); cpShapeSetFriction(m_WorldBounds.Top, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Top); cpShapeSetCollisionType(m_WorldBounds.Top, SURFACE_BOTTOM); //bottom m_WorldBounds.Bottom = cpSegmentShapeNew(m_pSpace->staticBody, cpv(offSet,cpFloat(windowDim.y)+offSet), cpv(cpFloat(windowDim.x)+offSet,cpFloat(windowDim.y)+offSet), 1); cpShapeSetFriction(m_WorldBounds.Bottom, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Bottom); cpShapeSetCollisionType(m_WorldBounds.Bottom, SURFACE_TOP); //left m_WorldBounds.Left = cpSegmentShapeNew(m_pSpace->staticBody, cpv(offSet,offSet), cpv(offSet,cpFloat(windowDim.y)+offSet), 1); cpShapeSetFriction(m_WorldBounds.Left, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Left); cpShapeSetCollisionType(m_WorldBounds.Left, SURFACE_RIGHT); //right m_WorldBounds.Right = cpSegmentShapeNew(m_pSpace->staticBody, cpv(cpFloat(windowDim.x)+offSet,offSet), cpv(cpFloat(windowDim.x)+offSet,cpFloat(windowDim.y)+offSet), 1); cpShapeSetFriction(m_WorldBounds.Right, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Right); cpShapeSetCollisionType(m_WorldBounds.Right, SURFACE_LEFT); //player-surface collision callbacks cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_TOP,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_BOTTOM,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_LEFT,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_RIGHT,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); //load level data from file std::fstream file; file.open(("media/level1.txt")); std::string line; int curLine = 0; while( std::getline(file,line) ) { // for(unsigned int i = 0; i < line.size();i++) { bool playerMade = false; char c = line[i]; switch(c) { case('p'): { //create player if (!playerMade) { m_pPlayer = new Player(m_ResMgr, *m_pSpace); m_pPlayer->SetPosition(float(i)*32, float(curLine)*32); m_Renderer.AddDrawableSprite(m_pPlayer->GetSprite()); playerMade = true; } break; } case('#'): { Block *block = new Block(m_ResMgr, *m_pSpace, Block::BLOCK_SOLID, sf::Vector2f(float(i)*32,float(curLine)*32) ); m_blocks.push_back(block); m_Renderer.AddDrawableSprite(block->GetSprite()); break; } case('>'): { Emitters.push_back(new Emitter(m_ResMgr, *m_pSpace, sf::Vector2f(float(i * 32), float(curLine * 32)) )); Emitters.back()->Show(); break; } case('<'): { /*Emitters.push_back(new Emitter(m_ResMgr, *m_pSpace)); Emitters.back()->SetPosition(i * 32, curLine * 32); m_Renderer.AddDrawableSprite(Emitters.back()->GetSprite());*/ Block *block = new Block(m_ResMgr, *m_pSpace, Block::BLOCK_END, sf::Vector2f(float(i)*32,float(curLine)*32) ); m_blocks.push_back(block); m_Renderer.AddDrawableSprite(block->GetSprite()); catcherPositions.push_back(block->GetSprite()->sprite->getPosition()); break; } } // } curLine++; } file.close(); //enable user input to the player m_pPlayer->SetInputHandler(m_pInputHandler); //rebuild static level geometry //cpSpaceRehashStatic(); }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Control the crane by moving the mouse. Press the down arrow to release."; space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -100)); cpSpaceSetDamping(space, 0.8); cpBody *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); // Add a body for the dolly. dollyBody = cpSpaceAddBody(space, cpBodyNew(10, INFINITY)); cpBodySetPos(dollyBody, cpv(0, 100)); // Add a block so you can see it. cpSpaceAddShape(space, cpBoxShapeNew(dollyBody, 30, 30)); // Add a groove joint for it to move back and forth on. cpSpaceAddConstraint(space, cpGrooveJointNew(staticBody, dollyBody, cpv(-250, 100), cpv(250, 100), cpvzero)); // Add a pivot joint to act as a servo motor controlling it's position // By updating the anchor points of the pivot joint, you can move the dolly. dollyServo = cpSpaceAddConstraint(space, cpPivotJointNew(staticBody, dollyBody, cpBodyGetPos(dollyBody))); // Max force the dolly servo can generate. cpConstraintSetMaxForce(dollyServo, 10000); // Max speed of the dolly servo cpConstraintSetMaxBias(dollyServo, 100); // You can also change the error bias to control how it slows down. //cpConstraintSetErrorBias(dollyServo, 0.2); // Add the crane hook. cpBody *hookBody = cpSpaceAddBody(space, cpBodyNew(1, INFINITY)); cpBodySetPos(hookBody, cpv(0, 50)); // Add a sensor shape for it. This will be used to figure out when the hook touches a box. shape = cpSpaceAddShape(space, cpCircleShapeNew(hookBody, 10, cpvzero)); cpShapeSetSensor(shape, cpTrue); cpShapeSetCollisionType(shape, HOOK_SENSOR); // Add a slide joint to act as a winch motor // By updating the max length of the joint you can make it pull up the load. winchServo = cpSpaceAddConstraint(space, cpSlideJointNew(dollyBody, hookBody, cpvzero, cpvzero, 0, INFINITY)); // Max force the dolly servo can generate. cpConstraintSetMaxForce(winchServo, 30000); // Max speed of the dolly servo cpConstraintSetMaxBias(winchServo, 60); // TODO cleanup // Finally a box to play with cpBody *boxBody = cpSpaceAddBody(space, cpBodyNew(30, cpMomentForBox(30, 50, 50))); cpBodySetPos(boxBody, cpv(200, -200)); // Add a block so you can see it. shape = cpSpaceAddShape(space, cpBoxShapeNew(boxBody, 50, 50)); cpShapeSetFriction(shape, 0.7); cpShapeSetCollisionType(shape, CRATE); cpSpaceAddCollisionHandler(space, HOOK_SENSOR, CRATE, (cpCollisionBeginFunc)HookCrate, NULL, NULL, NULL, NULL); return space; }
void GameScene::onEnter() { Scene::onEnter(); auto& winSize = cocos2d::Director::getInstance()->getWinSize(); auto& contentRect = Game::getContentRect(); string fontName = "DolceVita.ttf"; int x1 = contentRect.origin.x + wallThickness; int x2 = x1 + contentRect.size.width - wallThickness * 2; int y1 = contentRect.origin.y + wallThickness; int y2 = y1 + contentRect.size.height - wallThickness * 2; // Music CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("Song.mp3", true); // Stretched big background auto bg2 = cocos2d::LayerColor::create(cocos2d::Color4B(208, 204, 202, 255)); bg2->setScale(2); this->addChild(bg2, -1); // Actual background auto bg = cocos2d::LayerColor::create(cocos2d::Color4B(218, 214, 212, 255), contentRect.size.width, contentRect.size.height); bg->setPosition(contentRect.origin); this->addChild(bg, 0); // Labels stringstream ss; ss << "Score: " << score; scoreLabel = cocos2d::Label::createWithTTF(ss.str().c_str(), fontName, 45); scoreLabel->setAnchorPoint(cocos2d::Vec2(0, 1)); scoreLabel->setPosition(x1 + labelPadding, y2 - labelPadding); scoreLabel->setColor(cocos2d::Color3B(128, 128, 128)); this->addChild(scoreLabel, 1); auto sceneLabel = cocos2d::Label::createWithTTF("Game Scene", fontName, 200); sceneLabel->setColor(cocos2d::Color3B(128, 128, 128)); sceneLabel->setPosition(Game::centralize(0, 228)); this->addChild(sceneLabel, 1); sceneLabel->runAction(cocos2d::Sequence::create( cocos2d::FadeOut::create(5), cocos2d::RemoveSelf::create(), nullptr )); // Touch listners auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher(); auto listener = cocos2d::EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = [this] (const vector<cocos2d::Touch*>& touches, cocos2d::Event* event) {this->touchHandler("began", touches, event);}; dispatcher->addEventListenerWithSceneGraphPriority(listener, this); // Start physics space = cpSpaceNew(); space->gravity = cpv(0, gravity); // Walls createPhysicsBox(x1, y1, x2, contentRect.origin.y, 0.9, 0, collisionTypeWall); // bottom createPhysicsBox(x1, y2, x2, y2 + wallThickness, 0.9, 0, collisionTypeWall); // top createPhysicsBox(contentRect.origin.x, contentRect.origin.y, x1, y2 + wallThickness, 0.9, 0, collisionTypeWall); // left createPhysicsBox(x2, contentRect.origin.y, x2 + wallThickness, y2 + wallThickness, 0.9, 0, collisionTypeWall); // right // Ball ball = cocos2d::Sprite::create("Ball.png"); createPhysicsSprite(ball, cocos2d::Vec2(winSize.width * 0.5f, winSize.height * 0.5f), 1.0f, 0.0f, collisionTypeBall); this->addChild(ball, 1); // Collision handler cpSpaceAddCollisionHandler(space, collisionTypeBall, collisionTypeWall, nullptr, nullptr, nullptr, GameScene::onCollision, nullptr); // Update this->scheduleUpdate(); }
void PlayLayer::addCollisionFunc() { DoodleTruck *doodleTruck = DoodleTruck::sharedDoodleTruck(); cpSpaceAddCollisionHandler(doodleTruck->getSpace(), STONE_COLLISION, BODY_COLLISION, stoneAndTruckStrikeSlove, NULL, NULL, NULL, NULL); cpSpaceAddCollisionHandler(doodleTruck->getSpace(), STONE_COLLISION, GROUND_COLLISION, stoneAndGroundStrikeSlove, NULL, NULL, NULL, NULL); }
void CDynamics2DEngine::Init(TConfigurationNode& t_tree) { try { /* Init parent */ CPhysicsEngine::Init(t_tree); /* Parse XML */ GetNodeAttributeOrDefault(t_tree, "static_cell_size", m_fStaticHashCellSize, m_fStaticHashCellSize); GetNodeAttributeOrDefault(t_tree, "active_cell_size", m_fActiveHashCellSize, m_fActiveHashCellSize); GetNodeAttributeOrDefault(t_tree, "static_cells", m_nStaticHashCells, m_nStaticHashCells); GetNodeAttributeOrDefault(t_tree, "active_cells", m_nActiveHashCells, m_nActiveHashCells); GetNodeAttributeOrDefault(t_tree, "elevation", m_fElevation, m_fElevation); if(NodeExists(t_tree, "boundaries")) { /* Parse the boundary definition */ TConfigurationNode& tBoundaries = GetNode(t_tree, "boundaries"); SBoundarySegment sBoundSegment; CVector2 cLastPoint, cCurPoint; std::string strConnectWith; TConfigurationNodeIterator tVertexIt("vertex"); /* Get the first vertex */ tVertexIt = tVertexIt.begin(&tBoundaries); if(tVertexIt == tVertexIt.end()) { THROW_ARGOSEXCEPTION("Physics engine of type \"dynamics2d\", id \"" << GetId() << "\": you didn't specify any <vertex>!"); } GetNodeAttribute(*tVertexIt, "point", cLastPoint); m_vecVertices.push_back(cLastPoint); /* Go through the other vertices */ ++tVertexIt; while(tVertexIt != tVertexIt.end()) { /* Read vertex data and fill in segment struct */ GetNodeAttribute(*tVertexIt, "point", cCurPoint); m_vecVertices.push_back(cCurPoint); sBoundSegment.Segment.SetStart(cLastPoint); sBoundSegment.Segment.SetEnd(cCurPoint); GetNodeAttribute(*tVertexIt, "connect_with", strConnectWith); if(strConnectWith == "gate") { /* Connect to previous vertex with a gate */ sBoundSegment.Type = SBoundarySegment::SEGMENT_TYPE_GATE; GetNodeAttribute(*tVertexIt, "to_engine", sBoundSegment.EngineId); } else if(strConnectWith == "wall") { /* Connect to previous vertex with a wall */ sBoundSegment.Type = SBoundarySegment::SEGMENT_TYPE_WALL; sBoundSegment.EngineId = ""; } else { /* Parse error */ THROW_ARGOSEXCEPTION("Physics engine of type \"dynamics2d\", id \"" << GetId() << "\": unknown vertex connection method \"" << strConnectWith << "\". Allowed methods are \"wall\" and \"gate\"."); } m_vecSegments.push_back(sBoundSegment); /* Next vertex */ cLastPoint = cCurPoint; ++tVertexIt; } /* Check that the boundary is a closed path */ if(m_vecVertices.front() != m_vecVertices.back()) { THROW_ARGOSEXCEPTION("Physics engine of type \"dynamics2d\", id \"" << GetId() << "\": the specified path is not closed. The first and last points of the boundaries MUST be the same."); } } /* Initialize physics */ cpInitChipmunk(); cpResetShapeIdCounter(); /* Used to attach static geometries so that they won't move and to simulate friction */ m_ptGroundBody = cpBodyNew(INFINITY, INFINITY); /* Create the space to contain the movable objects */ m_ptSpace = cpSpaceNew(); /* Subiterations to solve constraints. The more, the better for precision but the worse for speed */ m_ptSpace->iterations = GetIterations(); /* Resize the space hash. This has dramatic effects on performance. TODO: - find optimal parameters automatically (average entity size) cpSpaceReindexStaticHash(m_ptSpace, m_fStaticHashCellSize, m_nStaticHashCells); cpSpaceResizeActiveHash(m_ptSpace, m_fActiveHashCellSize, m_nActiveHashCells); */ /* Gripper-Gripped callback functions */ cpSpaceAddCollisionHandler( m_ptSpace, SHAPE_GRIPPER, SHAPE_GRIPPABLE, BeginCollisionBetweenGripperAndGrippable, ManageCollisionBetweenGripperAndGrippable, NULL, NULL, NULL); /* Add boundaries, if specified */ if(! m_vecSegments.empty()) { cpShape* ptSegment; for(size_t i = 0; i < m_vecSegments.size(); ++i) { if(m_vecSegments[i].Type == SBoundarySegment::SEGMENT_TYPE_WALL) { ptSegment = cpSpaceAddShape( m_ptSpace, cpSegmentShapeNew( m_ptGroundBody, cpv(m_vecSegments[i].Segment.GetStart().GetX(), m_vecSegments[i].Segment.GetStart().GetY()), cpv(m_vecSegments[i].Segment.GetEnd().GetX(), m_vecSegments[i].Segment.GetEnd().GetY()), 0.0f)); ptSegment->e = 0.0f; // no elasticity ptSegment->u = 1.0f; // max friction } else { /* There is at least a gate, transfer is activated */ m_bEntityTransferActive = true; } } } } catch(CARGoSException& ex) { THROW_ARGOSEXCEPTION_NESTED("Error initializing the dynamics 2D engine \"" << GetId() << "\"", ex); } }
void GameInst::LoadLevel() { sf::Vector2f windowDim = m_GUIMgr.GetWindowDim(); //-------------------------------------- chipmunk physics // cpVect is a 2D vector and cpv() is a shortcut for initializing them. cpVect gravity = cpv(0, 980); // Create a physworld m_pSpace = cpSpaceNew(); cpSpaceSetGravity(m_pSpace, gravity); cpFloat offSet = -16; //top m_WorldBounds.Top = cpSegmentShapeNew(m_pSpace->staticBody, cpv(offSet,offSet), cpv(cpFloat(windowDim.x)+offSet,offSet), 1); cpShapeSetFriction(m_WorldBounds.Top, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Top); cpShapeSetCollisionType(m_WorldBounds.Top, SURFACE_BOTTOM); //bottom m_WorldBounds.Bottom = cpSegmentShapeNew(m_pSpace->staticBody, cpv(offSet,cpFloat(windowDim.y)+offSet), cpv(cpFloat(windowDim.x)+offSet,cpFloat(windowDim.y)+offSet), 1); cpShapeSetFriction(m_WorldBounds.Bottom, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Bottom); cpShapeSetCollisionType(m_WorldBounds.Bottom, SURFACE_TOP); //left m_WorldBounds.Left = cpSegmentShapeNew(m_pSpace->staticBody, cpv(offSet,offSet), cpv(offSet,cpFloat(windowDim.y)+offSet), 1); cpShapeSetFriction(m_WorldBounds.Left, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Left); cpShapeSetCollisionType(m_WorldBounds.Left, SURFACE_RIGHT); //right m_WorldBounds.Right = cpSegmentShapeNew(m_pSpace->staticBody, cpv(cpFloat(windowDim.x)+offSet,offSet), cpv(cpFloat(windowDim.x)+offSet,cpFloat(windowDim.y)+offSet), 1); cpShapeSetFriction(m_WorldBounds.Right, 0.5); cpSpaceAddShape(m_pSpace, m_WorldBounds.Right); cpShapeSetCollisionType(m_WorldBounds.Right, SURFACE_LEFT); //player-surface collision callbacks cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_TOP,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_BOTTOM,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_LEFT,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); cpSpaceAddCollisionHandler(m_pSpace,PLAYER, SURFACE_RIGHT,cpCollisionBeginFunc(PlayerSurfaceCollision),NULL,NULL,NULL,NULL); //create player m_pPlayer = new Player(m_ResMgr, *m_pSpace); m_pPlayer->SetPosition(900, 600); m_Renderer.AddDrawableSprite(m_pPlayer->GetSprite()); //load level data from file std::fstream file; file.open(("media/level1.txt")); std::string line; int curLine = 0; while( std::getline(file,line) ) { // for(unsigned int i = 0; i < line.size(); i++) { char c = line[i]; switch(c) { case('#'): { Block *block = new Block(m_ResMgr, *m_pSpace, Block::BLOCK_SOLID, sf::Vector2f(float(i)*32,float(curLine)*32) ); m_blocks.push_back(block); //block->SetPosition(); m_Renderer.AddDrawableSprite(block->GetSprite()); break; } case('>'): { Emitters.push_back(new Emitter(m_ResMgr, *m_pSpace, sf::Vector2f(float(i * 32), float(curLine * 32)) )); Emitters.back()->Show(); break; } case('<'): { /*Emitters.push_back(new Emitter(m_ResMgr, *m_pSpace)); Emitters.back()->SetPosition(i * 32, curLine * 32); m_Renderer.AddDrawableSprite(Emitters.back()->GetSprite());*/ break; } } // } curLine++; } file.close(); file.open(("media/level1_binds.txt")); while( std::getline(file,line) ) { char buffer[32]; //char* tokenBuffer; sprintf_s(buffer, 32, line.c_str()); // Get the block IDs to link them //int block1 = atoi(strtok_s(buffer,",", &tokenBuffer)) + atoi(strtok_s(NULL ,"=", &tokenBuffer)) * 32; //int block2 = atoi(strtok_s(NULL,",", &tokenBuffer)) + atoi(strtok_s(NULL,",", &tokenBuffer)) * 32; // Link them //m_blocks[block1]->SetOutput(block2); } file.close(); //rebuild static level geometry //cpSpaceRehashStatic(); }
cpSpace *Buoyancy::Init() { ChipmunkDemo::Init(); space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -500)); // cpSpaceSetDamping(space, 0.5); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpSpaceSetCollisionSlop(space, 0.5f); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); { // Add the edges of the bucket cpBB bb = cpBBNew(-300, -200, 100, 0); cpFloat radius = 5.0f; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(bb.l, bb.b), cpv(bb.l, bb.t), radius)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(bb.r, bb.b), cpv(bb.r, bb.t), radius)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(bb.l, bb.b), cpv(bb.r, bb.b), radius)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); // Add the sensor for the water. shape = cpSpaceAddShape(space, cpBoxShapeNew2(staticBody, bb, 0.0)); cpShapeSetSensor(shape, cpTrue); cpShapeSetCollisionType(shape, 1); } { cpFloat width = 200.0f; cpFloat height = 50.0f; cpFloat mass = 0.3*FLUID_DENSITY*width*height; cpFloat moment = cpMomentForBox(mass, width, height); body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); cpBodySetPosition(body, cpv(-50, -100)); cpBodySetVelocity(body, cpv(0, -100)); cpBodySetAngularVelocity(body, 1); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height, 0.0)); cpShapeSetFriction(shape, 0.8f); } { cpFloat width = 40.0f; cpFloat height = width*2; cpFloat mass = 0.3*FLUID_DENSITY*width*height; cpFloat moment = cpMomentForBox(mass, width, height); body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); cpBodySetPosition(body, cpv(-200, -50)); cpBodySetVelocity(body, cpv(0, -100)); cpBodySetAngularVelocity(body, 1); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height, 0.0)); cpShapeSetFriction(shape, 0.8f); } cpCollisionHandler *handler = cpSpaceAddCollisionHandler(space, 1, 0); handler->preSolveFunc = (cpCollisionPreSolveFunc)WaterPreSolve; handler->userData = this; return space; }
void Space::addCollisionHandler(cpCollisionType a,cpCollisionType b,cpCollisionBeginFunc begin,cpCollisionPreSolveFunc preSolve,cpCollisionPostSolveFunc postSolve,cpCollisionSeparateFunc separate,void *data) { cpSpaceAddCollisionHandler(space,a,b,begin,preSolve,postSolve,separate,data); }
static cpSpace * init(void) { staticBody = cpBodyNew(INFINITY, INFINITY); cpResetShapeIdCounter(); space = cpSpaceNew(); space->iterations = 10; space->gravity = cpv(0, -1500); cpBody *body; cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; // add some other segments to play with shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-200), cpv(-220,240), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(320,-200), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(200,-240), cpv(320,-100), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; shape = cpSpaceAddStaticShape(space, cpSegmentShapeNew(staticBody, cpv(-220,-80), cpv(200,-80), 0.0f)); shape->e = 1.0f; shape->u = 1.0f; shape->layers = NOT_GRABABLE_MASK; shape->collision_type = 2; // Set up the player cpFloat radius = 15.0f; body = cpSpaceAddBody(space, cpBodyNew(10.0f, INFINITY)); body->p = cpv(0, -220); body->velocity_func = playerUpdateVelocity; shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); shape->e = 0.0f; shape->u = 2.0f; shape->collision_type = 1; playerInstance.u = shape->u; playerInstance.shape = shape; playerInstance.groundShapes = cpArrayNew(0); shape->data = &playerInstance; cpSpaceAddCollisionHandler(space, 1, 2, begin, preSolve, NULL, separate, NULL); return space; }
void cpgoSpaceAddSeparateCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b, void *data) { cpSpaceAddCollisionHandler(space, a, b, NULL, NULL, NULL, &cpgoGenericPostAndSeparateHandler, data); }
void cpgoSpaceAddPreSolveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b, void *data) { cpSpaceAddCollisionHandler(space, a, b, NULL, &cpgoGenericBeginAndPreHandler, NULL, NULL, data); }