I've used this same exact code before, and it worked perfect every time. However, I'm trying to use it to move the paddle sprite along a horizontal path at position 100 for y and it updates with the location of my touch but for some reason it's not moving at all. I can't spot what's wrong. Can someone take a look and let me know?
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches){
CGPoint location = [touch locationInNode:self];
CGPoint newPosition = CGPointMake(location.x, 100);
//stop the paddle from going too far
if (newPosition.x < self.paddle.size.width/ 2) {
newPosition.x = self.paddle.size.width/ 2;
}
if (newPosition.x > self.size.width - (self.paddle.size.width/ 2)) {
newPosition.x = self.size.width - (self.paddle.size.width/ 2);
}
self.paddle.position = newPosition;
}
}
-(void) addPlayer:(CGSize)size {
SKSpriteNode *paddle = [SKSpriteNode spriteNodeWithImageNamed:#"paddle"];
//resize sprite
paddle.size = CGSizeMake(125, 31.25);
//position sprite
paddle.position = CGPointMake(size.width/2, 100);
//add physics body to paddle
paddle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:paddle.frame.size];
//change to static so wont be moved by physics
paddle.physicsBody.dynamic = NO;
//add sprite to scene
[self addChild:paddle];
}
-(instancetype)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]){
self.backgroundColor = [SKColor colorWithRed:(29.0f/255) green:(29.0f/255) blue:(29.0f/255) alpha:1.0];
//change gravity
self.physicsWorld.gravity = CGVectorMake(0, 0);
//add physics body to scene
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
[self addPlayer:size];
[self addBricks:size];
[self addBall:size];
}
return self;
}
Related
Current Situation
View loads, loads backgroundImage
Shows the reticle BOOL as false
-(void)didMoveToView:(SKView *)view {
/* Setup your scene here */
self.anchorPoint = CGPointMake(0.5, 0.5);
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
//Add background
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"backgroundTemp" ofType:#"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:bundle];
SKTexture *texture = [SKTexture textureWithImage:image];
backgroundImage = [SKSpriteNode spriteNodeWithTexture:texture];
backgroundImage.size = CGSizeMake(self.frame.size.width, self.frame.size.height);
backgroundImage.position = CGPointMake(0.5, 0.5);
backgroundImage.zPosition = 0;
[self addChild:backgroundImage];
//END Add Background
removeArray = [[NSMutableArray alloc] init];
reticleShow = false;
}
So after the background image has been loaded, displayed. The only other option is to press the screen to result in an enlargement of backgroundImage as well as loading the reticle image.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
if (reticleShow == false) {
//Add Reticle
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"reticle_001" ofType:#"png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:bundle];
SKTexture *texture = [SKTexture textureWithImage:image];
SKSpriteNode *reticle = [SKSpriteNode spriteNodeWithTexture:texture];
reticle.zPosition = 1;
reticle.size = CGSizeMake(self.frame.size.width, self.frame.size.height);
reticle.position = CGPointMake(0.5, 0.5);
[self addChild:reticle];
[removeArray addObject:reticle];
//End Add Reticle
//Enlarge background
backgroundImage.size = CGSizeMake(self.frame.size.width*3, self.frame.size.height*3);
//End Enlarge background
reticleShow = true;
} else {
// //Remove reticle
// backgroundImage.size = CGSizeMake(self.frame.size.width, self.frame.size.height);
// [self removeChildrenInArray:removeArray];
// reticleShow = false;
// //end remove reticle
//enable drag
//end enable drag
}
}
Now that provides the enlargement and the boolean prevents from further sprites being added, as well as providing the reticle image.
Now, after this has loaded. Or the initial press has been made. I now want to be able to drag the background. i.e move the background and keep the reticle centred.
So I've made this,
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if ([node.name isEqualToString:backgroundImage]) { <--- ERROR HERE sksprite node to type nsstring
CGPoint previousLocation = [touch previousLocationInNode:self];
float diff = location.y - previousLocation.y;
CGPoint newPosition = CGPointMake(node.position.x, node.position.y +diff);
if (newPosition.y > 230) {
newPosition.y = 230;
}
node.position = newPosition;
}
}
}
Three questions
How to drag an image on a lesser z-index? i.e drag background instead of reticle?
How to move the background image after it has been enlarged?
How to pass the sknode & nsstring error? backgroundImage.name = #"backgroundImage";
Question One
Drag on lesser Z-Index
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
SKNode *node = [backgroundImage nodeAtPoint:location];
if ([node.name isEqualToString:#"backgroundImage"]) {
CGPoint previousLocation = [touch previousLocationInNode:self];
float ydiff = location.y - previousLocation.y;
float xdiff = location.x - previousLocation.x;
CGPoint newPosition = CGPointMake(node.position.x - xdiff, node.position.y - ydiff);
if (newPosition.y > 230) {
newPosition.y = 230;
}
node.position = newPosition;
}
}
}
Insert this
reticle.userInteractionEnabled = NO;
Question Two
Doesn't affect it by enlarging
Question Three
Naming the SkSpriteNode for detection
backgroundImage.name = #"backgroundImage";
I want to create a new sprite in a grid if the field is empty. I also want this new sprite to be centred in the empty field. Let's say the field is:
1 1 1
1 1 0
1 1 1
Whenever I click on one of the fields that is filled with a 1, the sprite disappears (this is what I want and this works fine).
Whenever I click on the 0, a new sprite is added with the following code:
UITouch *touch = [touches anyObject];
CGPoint positionInScene = [touch locationInNode:self];
SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:positionInScene];
if(touchedNode.position.x == 0) { // x is 0 when I click an empty field, aka background
[self addThing:positionInScene];
}
And:
-(void)addThing:(CGPoint)newLocation{
SKSpriteNode *thing = [SKSpriteNode spriteNodeWithImageNamed:#"thing"];
thing.location = newLocation;
[self addChild:thing];
thing.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:thing.size.width/2];
thing.physicsBody.dynamic = NO;
thing.physicsBody.categoryBitMask = somethingCategory;
thing.physicsBody.contactTestBitMask = somethingElseCategory;
thing.physicsBody.collisionBitMask = 0;
}
However, this sprite is centred in the exact coordinates I click, rather than the centre point of the empty field. How can I make this happen?
The following creates an N x M grid with a sprite at each row and column. When the user touches one of the sprites, it rotates the sprite and then removes it from the scene. If a sprite is not found at the touch location, a sprite is added there.
#define kBoardMinX 25
#define kBoardMinY 25
#define kNumCols 3
#define kNumRows 3
#define kSpacing 40
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
[self addPiecesToScene];
}
return self;
}
// Convert row and col to the appropriate point (in scene coordinates) in the grid
- (CGPoint) pointFromRow:(NSInteger)row andCol:(NSInteger)col
{
return CGPointMake(kBoardMinX+col*kSpacing, kBoardMinY+(kNumRows-row-1)*kSpacing);
}
// If a sprite is found at (row, col) rotate it, else add a sprite there
- (void) rotatePieceAtRow:(NSInteger)row andCol:(NSInteger)col
{
SKSpriteNode *node = (SKSpriteNode *)[self nodeAtPoint:[self pointFromRow:row andCol:col]];
if (node && (SKNode *)node != self) {
SKAction *rotate = [SKAction rotateByAngle:M_PI*2 duration:2];
SKAction *remove = [SKAction removeFromParent];
SKAction *rotateThenRemove = [SKAction sequence:#[rotate,remove]];
[node runAction:rotateThenRemove];
}
else {
[self addPieceAtRow:row andCol:col];
}
}
- (void) togglePieceAtTouchLocation:(CGPoint)location
{
// Convert touch location to row and column
NSInteger col = (NSInteger)roundf((location.x - kBoardMinX) / kSpacing);
NSInteger row = kNumRows - (NSInteger)roundf((location.y - kBoardMinY) / kSpacing) - 1;
// Check if the touch was within the grid
if (col >= 0 && col < kNumCols && row >= 0 && row < kNumRows) {
[self rotatePieceAtRow:row andCol:col];
}
}
- (void) addPieceAtRow:(NSInteger)row andCol:(NSInteger)col
{
CGSize size = CGSizeMake(32, 32);
SKColor *color = [SKColor whiteColor];
SKSpriteNode *node = [SKSpriteNode spriteNodeWithColor:color size:size];
node.position = [self pointFromRow:row andCol:col];
[self addChild:node];
}
- (void) addPiecesToScene
{
for (int row=0;row<kNumRows;row++) {
for (int col=0;col<kNumCols;col++) {
[self addPieceAtRow:row andCol:col];
}
}
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
[self togglePieceAtTouchLocation:location];
}
}
So I have a shipNode (which is initially facing right) with two children called _laserCannon1(and 2) that are configured by the method below:
-(void)initializeLaserCannonLocations
{
CGSize size = CGSizeMake(4.0, 4.0);
_laserCannon1 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:size];
_laserCannon2 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:size];
_laserCannon1.position = CGPointMake(self.size.width/2, self.size.height/2 + 15);
_laserCannon2.position = CGPointMake(self.size.width/2, self.size.height/2 - 15);
[self addChild:_laserCannon1];
[self addChild:_laserCannon2];
}
Then I am later "firing" lasers from them based off of the ship's zRotation as follows
-(void)fireLocalLaser
{
CGVector standardLaserVelocity = CGVectorMake(700*cosf(_myShip.zRotation - _myShip.laserCannon1.zRotation),
700*sinf(_myShip.zRotation - _myShip.laserCannon2.zRotation));
[self spawnLaserFrom:CGPointAdd(_myShip.laserCannon1.position, ship.position); withVelocity:standardLaserVelocity fromShip:_myShip];
[self spawnLaserFrom:CGPointAdd(_myShip.laserCannon2.position, ship.position); withVelocity:standardLaserVelocity fromShip:_myShip];
}
Now everything works fine when the ships is facing directly left or right, but for some odd reason as the ship begins to face more towards the top or bottom the shots are fired increasingly towards the middle of the ship, to the point that once the ship is facing vertically both shots are fired from the middle.position.x of the ship. Does it have to do with something from where I placed my _laserCannons?
I hope my math teacher doesn't see this!
Your problem is with the relative position of your 2 laser cannons as they rotate. I have included a picture so I don't have to go into a long winded description of what is happening.
I have included code for a kinda, sorta, duct tape solution on how you can do this if you really want to. It ain't pretty but it works. The code is good from 0 to 90 degrees so you should be able to work out the rest from there if you have your heart set on having 2 cannons. BUT I would strongly suggest your Mighty Space Empire invest in single cannon ships, as it will make your coding job a whole lot easier!
#implementation MyScene {
SKSpriteNode *ship1;
SKShapeNode *turret1;
SKShapeNode *turret2;
}
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size]) {
self.physicsWorld.contactDelegate = self;
[self createSpaceships];
}
return self;
}
-(void)createSpaceships {
ship1 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(50, 50)];
ship1.position = CGPointMake(300, 150);
ship1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ship1.size];
ship1.physicsBody.dynamic = NO;
[self addChild:ship1];
SKSpriteNode *frontOfShip = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(2, 50)];
frontOfShip.position = CGPointMake(25, 0);
[ship1 addChild:frontOfShip];
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
// touch the left side of the screen to rotate the ship by +0.0785398 radians
// touch the right hand side of the screen to fire lasers
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self.scene];
if(touchLocation.x < self.size.width/2) // left side of screen
{
SKAction *block0 = [SKAction runBlock:^{
ship1.zRotation = ship1.zRotation +0.0785398;
}];
[self runAction:block0];
} else // right side of screen
{
float turret1offsetX = 0;
float turret1offsetY = 0;
float turret2offsetX = 0;
float turret2offsetY = 0;
if((ship1.zRotation >0) && (ship1.zRotation <=0.785399))
{
turret1offsetX = (14/0.785398) * ship1.zRotation;
turret1offsetY = (23/0.785398) * ship1.zRotation;
turret2offsetX = (-20/0.785398) * ship1.zRotation;
turret2offsetY = (10/0.785398) * ship1.zRotation;
}
if((ship1.zRotation >0.785399) && (ship1.zRotation <=1.570797))
{
turret1offsetX = (14 - (9/0.785398)) * ship1.zRotation;
turret1offsetY = -4 + (27/0.785398) * ship1.zRotation;
turret2offsetX = (3 - (25/0.785398)) * ship1.zRotation;
turret2offsetY = 20 - (10/0.785398) * ship1.zRotation;
}
int x = ship1.position.x + 1000 * cos(ship1.zRotation);
int y = ship1.position.y + 1000 * sin(ship1.zRotation);
turret1 = [SKShapeNode node];
CGMutablePathRef pathToDraw = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw, NULL, (ship1.position.x+20)+turret1offsetX, (ship1.position.y-25)+turret1offsetY);
CGPathAddLineToPoint(pathToDraw, NULL, x, y);
turret1.path = pathToDraw;
[turret1 setStrokeColor:[UIColor redColor]];
[self addChild:turret1];
turret2 = [SKShapeNode node];
CGMutablePathRef pathToDraw2 = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw2, NULL, (ship1.position.x+20)+turret2offsetX, (ship1.position.y+25)+turret2offsetY);
CGPathAddLineToPoint(pathToDraw2, NULL, x, y);
turret2.path = pathToDraw2;
[turret2 setStrokeColor:[UIColor redColor]];
[self addChild:turret2];
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[turret1 removeFromParent];
[turret2 removeFromParent];
}
#end
Yes as sangony put it, it really just has to do with your relative positioning of the _laserCannons from your shipNode. I would personally just start with a singular laserCannon for now, and get more comfortable with the math involved until you feel ready to move on to adding more.
I am trying to make an animated character that can reach out for things on the screen, without moving his torso.
If he can not reach than his hand should go the maximal amount in this direction and then be counteracted by the physical limitation of his static torso.
So in my code the green rectangle (hand) moves where I click and the torso follows.
I would like to be able to make the red rect (body) stationary and make the green rectangle "point" at the touch point position.
I have tried to apply a fixed joint to between the scene and the red body rectangle, but this did not seem to work.
- (void) createSceneContent
{
SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:body];
body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];
body.physicsBody.affectedByGravity = NO;
body.physicsBody.dynamic = YES;
self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(150, 20)];
self.hand.position = CGPointMake(body.position.x + body.size.width / 2 + self.hand.size.width / 2, body.position.y);
[self addChild:self.hand];
self.hand.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.hand.size];
self.hand.physicsBody.dynamic = NO;
self.scene.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
[self.physicsWorld addJoint:[SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:self.hand.physicsBody anchor:CGPointMake(body.position.x + body.size.width / 2, body.position.y)]];
[self.hand runAction:[SKAction moveByX:100 y:10 duration:0.1]];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
[self.hand runAction:[SKAction moveTo:location duration:0.1]];
}
First of all, you don't really need to use physics here, if you only want the arm to point at the touched location.
Just change the arm node's anchorPoint to the shoulder (where you would put the pin on the joint) and rotate it around that point (the point is held in a helper shoulderNode, so that it's easy to convert to its coordinates later). You can calculate the rotation angle using atan2f. Here's the code:
- (void) createSceneContent
{
SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:body];
self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(150, 20)];
self.hand.position = CGPointMake(body.position.x + body.size.width*0.5, body.position.y);
self.hand.anchorPoint = CGPointMake(0, 0.5);
[self addChild:self.hand];
SKNode *shoulderNode = [SKNode node];
shoulderNode.position = self.hand.position;
shoulderNode.name = #"shoulderNode";
[self addChild:shoulderNode];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
CGPoint locationConv = [self convertPoint:location toNode:[self childNodeWithName:#"shoulderNode"]];
self.hand.zRotation = (atan2f(locationConv.y, locationConv.x));
}
On the other hand, if you ever need to use physics bodies here, it's probably a bad idea to use SKActions to move the arm, and you also might want to set body.physicsBody.dynamic = NO to make the torso static. Then, make sure you add the pin joint correctly, and set its frictionTorque property to a high value to get less dangling. One of the ways to make the hand point at the right location is its velocity vector set in the update method - just use the converted location coordinates (here they are relative to the body node's centre). Full example code:
- (void) createSceneContent {
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:body];
body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];
body.physicsBody.dynamic = NO;
body.physicsBody.affectedByGravity = YES;
self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(20, 150)];
// experiment with the anchorPoint for different results
self.hand.anchorPoint = CGPointMake(0.5, 0);
self.hand.position = CGPointMake(body.position.x, body.position.y);
[self addChild:self.hand];
self.hand.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.hand.size];
self.hand.physicsBody.dynamic = YES;
self.hand.physicsBody.affectedByGravity = NO;
SKPhysicsJointPin *pinHand = [SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:self.hand.physicsBody anchor:CGPointMake(body.position.x, body.position.y-5)];
[self.physicsWorld addJoint:pinHand];
// experiment with the friction torque value to achieve desired results
pinHand.frictionTorque = 1.0;
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
location = [touch locationInNode:self];
}
-(void)update:(CFTimeInterval)currentTime {
CGPoint locationConv = [self convertPoint:location toNode:body];
// experiment with the multiplier (here: 10) for faster/slower movement
self.hand.physicsBody.velocity = CGVectorMake(locationConv.x*10, locationConv.y*10);
}
Hope that helps!
I want to move one object over another object without bounce when they collide.
In Simple i have one ball(body) and i have one Rectangular line image(body), the image is slope 45 degree.
The ball fall from the top speed is 20 when the ball touch on the slope image(Static Body) it will bounce always and continue running.
When the ball come over the line image it will not bounce and slow down the speed according to the collision and ball stop in the end. Same as it happens in real world when ball collide with something , the ball speed will slow down and it turn according to the collision and then stop due to decreasing speed of collision.
I am doing this, but cant achieve the result what i want.
-(id) init
{
if( (self=[super init])) {
CGSize winSize = [CCDirector sharedDirector].winSize;
// Create a world
b2Vec2 gravity = b2Vec2(0.0f, 0.0f);
_world = new b2World(gravity);
///////////////////////// Ball ///////////////////////////////
// Create sprite and add it to the layer
CCSprite *ball = [CCSprite spriteWithFile:#"ball.png"];
ball.position = ccp(100, 200);
ball.tag = 1;
[self addChild:ball];
// Create ball body
b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(127/PTM_RATIO, 210/PTM_RATIO);
ballBodyDef.userData = ball;
ballBody = _world->CreateBody(&ballBodyDef); // b2Body * ballBody
// Create circle shape
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
// Create shape definition and add to body
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 15.0f;
ballShapeDef.friction = 2.f;
ballShapeDef.restitution = 0.0f;
_ballFixture = ballBody->CreateFixture(&ballShapeDef);
b2Vec2 force = b2Vec2(73, -52);
ballBody->ApplyLinearImpulse(force, ballBodyDef.position);
//ballBody->SetLinearVelocity(b2Vec2(10,0)); // try
// ballBody->SetAngularVelocity(0); // try
///////////////////////// Ball ///////////////////////////////
// Create paddle and add it to the layer
CCSprite *paddle = [CCSprite spriteWithFile:#"paddle.png"];
paddle.position = ccp(winSize.width/2, 50);
[self addChild:paddle];
// Create paddle body
b2BodyDef paddleBodyDef;
paddleBodyDef.type = b2_staticBody; //b2_staticBody, b2_dynamicBody
paddleBodyDef.position.Set(winSize.width/2/PTM_RATIO, 50/PTM_RATIO);
paddleBodyDef.userData = paddle;
paddleBodyDef.angle = 75;
_paddleBody = _world->CreateBody(&paddleBodyDef);
// Create paddle shape
b2PolygonShape paddleShape;
paddleShape.SetAsBox(paddle.contentSize.width/PTM_RATIO/2, paddle.contentSize.height/PTM_RATIO/2);
// Create shape definition and add to body
b2FixtureDef paddleShapeDef;
paddleShapeDef.shape = &paddleShape;
paddleShapeDef.density = 25.0f;
paddleShapeDef.friction = 1.1f;
paddleShapeDef.restitution = 0.1f;
_paddleFixture = _paddleBody->CreateFixture(&paddleShapeDef);
// Restrict paddle along the x axis
b2PrismaticJointDef jointDef;
b2Vec2 worldAxis(0.0f, 0.0f);
jointDef.collideConnected = true;
jointDef.Initialize(_paddleBody, _groundBody, _paddleBody->GetWorldCenter(), worldAxis);
_world->CreateJoint(&jointDef);
[self schedule:#selector(tick:)];
self.touchEnabled = YES;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (_mouseJoint != NULL) return;
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
if (_paddleFixture->TestPoint(locationWorld)) {
b2MouseJointDef md;
md.bodyA = _groundBody;
md.bodyB = _paddleBody;
md.target = locationWorld;
md.collideConnected = true;
md.maxForce = 1000.0f * _paddleBody->GetMass();
_mouseJoint = (b2MouseJoint *)_world->CreateJoint(&md);
_paddleBody->SetAwake(true);
}
// [self kick];
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
if (_mouseJoint == NULL) return;
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);
_mouseJoint->SetTarget(locationWorld);
}
Ok so You have mad very small mistak, problem is with gravity.
change it to
b2Vec2 gravity = b2Vec2(0.0f, -10.0f);