uikit and dragging objects around with collision detection.

Official forum for the Chipmunk2D Physics Library.
Post Reply
ozhanlion
Posts: 2
Joined: Mon May 07, 2012 10:29 pm
Contact:

uikit and dragging objects around with collision detection.

Post by ozhanlion »

Hello all,

I am trying to build an application which uses UIViews where user can push/pull/drag around objects like in this video:

http://dl.dropbox.com/u/2070808/IMG_069 ... llular.m4v

I have already brought chipmunk into my project and I set up my project and it even works with collision detection.

Please see the video:
http://dl.dropbox.com/u/2070808/IMG_069 ... llular.m4v

As you can see objects push around each other when they get the shape and body. The problem is though, on the drag I take out the physics and that's why they don't interact. What I need is, when user is dragging those text object around, they should still push each other around and even rotate while dragging based based on where user holds the object.

This is how I create the space update it and also how I create my object:


Code: Select all

// Bootsraps chipmuck and the timer
- (void)setupSpace {
	
    
    // Start chipmuck
	cpInitChipmunk();
	
    
	// Create a space object
	space = cpSpaceNew();
	
    CGSize size = [[self view] bounds].size;
    
	// Define a gravity vector
	space->gravity = cpv(0, 0);
	
	// Add some elastic effects to the simulation
	space->elasticIterations = 10;
    space->damping = 0.1;

    // setup the 'edges' of our world so the bouncing balls don't move offscreen
	cpBody *edge = cpBodyNewStatic();
    cpShape *shape = NULL;
    
    // left
    shape = cpSegmentShapeNew(edge, cpvzero, cpv(20.0f, size.height), 0.0f);
    shape->u = 1.0;
    shape->e = 0.1f;
    cpSpaceAddStaticShape(space, shape);
    
    // top
    shape = cpSegmentShapeNew(edge, cpvzero, cpv(size.width, 0.0f), 0.0f);
    shape->u = 1.0f;
    shape->e = 0.1f;
    cpSpaceAddStaticShape(space, shape);
    
    // right
    shape = cpSegmentShapeNew(edge, cpv(size.width, 0.0f),
                              cpv(size.width, size.height), 0.0f);
    shape->u = 1.0f;
    shape->e = 0.1f;
    cpSpaceAddStaticShape(space, shape);
    
    // bottom
    shape = cpSegmentShapeNew(edge, cpv(0.0f, size.height),
                              cpv(size.width, size.height), 0.0f);
    shape->u = 1.0f;
    shape->e = 0.1f;
    cpSpaceAddStaticShape(space, shape);
 	
}

// Called at each "frame" of the simulation
- (void)tick:(NSTimer *)timer {
	// Tell Chipmuck to take another "step" in the simulation
	cpSpaceStep(space, 1.0f/60.0f);
	// Call our function for each shape
	cpSpaceHashEach(space->activeShapes, &updateShape, nil);
  //  cpSpaceHashEach(space->staticShapes, &updateShape, nil);
}



// Updates a shape's visual representation (i.e. sprite)
void updateShape(void *obj, void* unused) {
    
	// Get our shape
	cpShape *shape = (cpShape*)obj;
	
	// Make sure everything is as expected or tip & exit
	if(shape == nil || shape->body == nil || shape->data == nil) {
		NSLog(@"Unexpected shape please debug here...");
		return;
	}
	
	// Lastly checks if the object is an UIView of any kind
	// and update its position accordingly
	if([(__bridge id)shape->data isKindOfClass:[UIView class]]) {
		[(__bridge UIView *)shape->data setCenter:CGPointMake(shape->body->p.x, 480 - shape->body->p.y)];
     //   NSLog(@"here");

	}
	else
		NSLog(@"The shape data wasn't updateable using this code.");
    
      
}

 IKWordView* word = [[IKWordView alloc] initWithFrame:CGRectMake([[myword valueForKey:@"x"] floatValue],[[myword valueForKey:@"y"] floatValue],[[myword valueForKey:@"width"] floatValue],[[myword valueForKey:@"height"] floatValue])];
           
            word.userInteractionEnabled = YES;
            word.delegate = self;
            word.space = space;
            word.wordTextField.text = myword.name;
   
            [word callResize];
   
            UIPanGestureRecognizer* p = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panning:)];
       
            p.delegate = self;
            self.isDraggable = NO;
            
           CGPoint velocity = CGPointMake(0, 0);
            [word addShapeAndBody:velocity];
}

-(void)addShapeAndBody:(CGPoint)force
{
    float boxWidth = self.wordTextField.frame.size.width;
    float boxHeight = self.wordTextField.frame.size.height;
    
    //create the body and shape for the word 
    self.body = cpBodyNew(BALL_MASS, cpMomentForBox(BALL_MASS, boxWidth, boxHeight));
	body->p = CGPointMake(self.center.x,480-self.center.y); // this dynamic body represents the ball at its center position
	cpSpaceAddBody(space, body);

	
	shape = cpBoxShapeNew(body, boxWidth, boxHeight);
	shape->data = (__bridge void*)self;
	shape->u = 1000;
	shape->e = 0.0f; // bounciness
	cpSpaceAddShape(space, shape);
    //cpBodyApplyForce(body, cpv(-force.x,force.y),cpvzero);
    cpBodyApplyImpulse(body, cpv(force.x,-force.y), cpvzero);
    
    //body->v = cpv(force.x*.1, -force.y*.1);
}


-(void)removeShapeAndBody
{
    cpSpaceRemoveBody(self.space, self.shape->body);
    cpSpaceRemoveShape(self.space, self.shape);
    
    //set the new mass and add it to the static space
    // cpBodySetMass(ballShape->body, INFINITY);
    // cpSpaceAddStaticShape(space, ballShape);
    
    self.shape = nil;    

}

//panning method

- (void) panning: (UIPanGestureRecognizer*) recognizer 
{ 
     NSLog(@"panning");
    IKWordView* word = (IKWordView*)recognizer.view;
    
    if(word.shape){
        [word removeShapeAndBody];
    }
    
    CGPoint translation = [recognizer translationInView:self.view];
    recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, 
                                         recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
    
    if (recognizer.state == UIGestureRecognizerStateEnded) {
        
        CGPoint velocity = [recognizer velocityInView:self.view];
        [word addShapeAndBody:velocity];
    
    }
    
    
    
    
}


I am trying to follow this example http://chipmunk-physics.net/forum/viewt ... ikit#p7668 but I am not sure if I got the mouseBody in the example code.


I would really appreciate any directions. Thanks a lot.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: uikit and dragging objects around with collision detecti

Post by slembcke »

Chipmunk Pro has a nice class, ChipmunkMultiGrab, that nicely wraps mouse and multi-touch interaction.

The MultiTouchObjectiveChipmunk example on the following page shows you how to use it. It's minimally built on top of Cocos2D, but it uses regular UIKit touch input events so it should be easy to port. Secondly, you are going to want to create the illusion of friction as though the objects are resting on a surface parallel to the simulation plane. The iPhoneSnap example will show you how to do that.
http://chipmunk-physics.net/documentation.php
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
ozhanlion
Posts: 2
Joined: Mon May 07, 2012 10:29 pm
Contact:

Re: uikit and dragging objects around with collision detecti

Post by ozhanlion »

Hello,

thanks for the response. I have started working with the examples and converting my project based on those examples.

I have seen in the multi grab example the methods are cocos2d touch methods and multiGrab methods are called inside of these.

I am also looking at this example: http://chipmunk-physics.net/forum/viewt ... grab#p8364

Here the author uses custom methods such as
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

and calling multiGrab from there. Is this only way to go? Does this mean do I have to scratch uigesturerecognizers and go with this path? Just wanted to be sure thanks.
Thanks in advance.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: uikit and dragging objects around with collision detecti

Post by slembcke »

The touchesBegan/Moved/Ended methods are the standard UIView methods for responding to touch events. I guess I've never considered using gesture recognizers for dragging objects around. It seems like they would be a lot more work, although have a couple of nice built in properties like being able to distinguish between a tap and a sustained hold.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests