I have a tire in my screen and I would like to have a rope connected to the top of the tire and to the top of the screen. I have incorporated physics into my game with chipmunk+spaceManager so I need to some how have this rope react to the physics also. I just need it to move back and forth with the tire when it gets hit. I have used a cpConstraintNode to get a line drawn to use it as a rope up to this point but everything I have seen and looked into, there is no way to attach a CCSprite to a constraint. So my question is How would I go about creating this rope and have it react the same as the tire when it is moving? Here is my code that I have done with the constraint: I am using cocos2d and chipmunk + spaceManger
//The "rope"
cpVect a1 = cpv(0,30); //Local coordinates of tire
cpVect a2 = cpv(70,320); //World coordinates (staticBody is at (0,0))
//calculate the length of the rope
float max = cpvdist(cpBodyLocal2World(upper->body, a1), a2);
cpConstraint *rope = [game.spaceManager addSlideToBody:upper->body fromBody:game.spaceManager.staticBody toBodyAnchor:a1 fromBodyAnchor:a2 minLength:1 maxLength:max];
cpConstraintNode *ropeNode = [cpConstraintNode nodeWithConstraint:rope];
ropeNode.color = ccBLUE;
This post presents a great way to draw ropes in Cocos2D using Verlet Integration.
The only drawback is that the example uses Box2D. But the code can be ported to chipmunk.
If you're wanting to use the VRope project on github to integrate VRope and chipmunk, I've created a new branch that does just that. You'll find it at:
VRope Chipmunk Branch
An example of using it is:
Creation
pinPointJoint =
cpSlideJointNew(body,
body2,
body.anchorPoint,
body2.anchorPoint,
minimumLength,
maximumLength);
cpSpaceAddConstraint(space, pinPointJoint);
rope = [[VRope alloc] init:pinPointJoint batchNode:ropeBatchNode];
Updating
[rope update:delta];
Related
For the past days, I've been trying to make a ping pong like game. I have 2 paddles and a ball. All dynamic sprites. Everything's been working well except for one issue I'm having. The ball tends to bounce on the same angle at some point. So there would be times when the player can simply move the paddle on a specific part and the game can go on for a while or might be forever, since the ball doesn't change its angular velocity regardless of which part of the paddle it hits. I'm using a combination of linear and angular velocity to keep the ball moving like so:
if(_isPaused == FALSE)
{
_world->Step(dt, 10, 10);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *sprite = (CCSprite *)b->GetUserData();
if(sprite.tag == 2)
{
b2Vec2 dir = b->GetLinearVelocity();
dir.Normalize();
float currentSpeed = dir.Length();
int maxSpeed = 60;
float accelerate = vel;
if(currentSpeed <= maxSpeed)
{
b->SetLinearVelocity(accelerate * dir);
}
sprite.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
//Keep sprite from bouncing in a straight angle
b->SetAngularVelocity(_body->GetAngle());
}}}
So my question is, how can I manipulate the angular velocity to keep the ball bouncing on different angles everytime it collides with my paddle? I'm thinking something like getting the current angular velocity then multiplying it with some value but I'm not sure if that's the right way to approach the issue I'm having. Any suggestions or ideas would be greatly appreciated. Thanks in advanced.
The way I see it, you have two options:
Check the location of a collision. If it's close to the top/bottom edge of the paddle, deflect the outgoing velocity by an angular amount proportional to the surface "curvature" at that point. Of course, this is cheating, but if the artwork and code are in agreement, it looks correct. And graphics is "the art of cheating without getting caught".
You could take into account the current velocity of the paddle as well as that of the ball. Eg: if the ball is moving downwards and to the right, and the paddle is moving down, then you can compute the outgoing direction using conservation of linear momentum. Just make sure you restrict the paddle's change in momentum along the horizontal axis to be zero.
Finally, you could combine the above techniques, but now you'd have to use accurate collision detection (not the hack I described in (1) above).
Hope that helps!
A few pointers, you should use SetLinearVelocity() and SetAngularVelocity() rarely. Each alters a property of the body definition, which could make you run into problems later on when things get more complex. It would be better to use ApplyForceToCenter() or ApplyLinearImpulse() in the place of SetLinearVelocity() as these two are much more versatile functions and are a bit more coder-friendly. In my opinion, I don't think you should use b->SetAngularVelocity(_body->GetAngle()); If you wanted to change the angular velocity each time it collided, you could, in your beginContact method, write that every time the body collides with the paddle body, a random angular impulse is applied to the ball, using ApplyAngularImpulse().Hope that helps.
I've had to completely revamp this question as I don't think I was explicit enough about my problem.
I'm attempting to learn the ropes of Box2D Web. I started having problems when I wanted to learn how to put multiple shapes in one rigid body (to form responsive concave bodies). One of the assumptions I made was that this kind of feature would only really be useful if I could change the positions of the shapes (so that I can be in control of what the overall rigid body looked like). An example would be creating an 'L' body with two rectangle shapes, one of which was positioned below and to-the-right of the first shape.
I've gotten that far in so-far-as I've found the SetAsOrientedBox method where you can pass the box its position in the 3rd argument (center).
All well and good. But when I tried to create two circle shapes in one rigid body, I found undesirable behaviour. My instinct was to use the SetLocalPosition method (found in the b2CircleShape class). This seems to work to an extent. In the debug draw, the body responds physically as it should do, but visually (within the debug) it doesn't seem to be drawing the shapes in their position. It simply draws the circle shapes at the centre position. I'm aware that this is probably a problem with Box2D's debug draw logic - but it seems strange to me that there is no online-patter regarding this issue. One would think that creating two circle shapes at different positions in the body's coordinate space would be a popular and well-documented phenomina. Clearly not.
Below is the code I'm using to create the bodies. Assume that the world has been passed to this scope effectively:
// first circle shape and def
var fix_def1 = new b2FixtureDef;
fix_def1.density = 1.0;
fix_def1.friction = 0.5;
fix_def1.restitution = .65;
fix_def1.bullet = false;
var shape1 = new b2CircleShape();
fix_def1.shape = shape1;
fix_def1.shape.SetLocalPosition(new b2Vec2(-.5, -.5));
fix_def1.shape.SetRadius(.3);
// second circle def and shape
var fix_def2 = new b2FixtureDef;
fix_def2.density = 1.0;
fix_def2.friction = 0.5;
fix_def2.restitution = .65;
fix_def2.bullet = false;
var shape2 = new b2CircleShape();
fix_def2.shape = shape2;
fix_def2.shape.SetLocalPosition(new b2Vec2(.5, .5));
fix_def2.shape.SetRadius(.3);
// creating the body
var body_def = new b2BodyDef();
body_def.type = b2Body.b2_dynamicBody;
body_def.position.Set(5, 1);
var b = world.CreateBody( body_def );
b.CreateFixture(fix_def1);
b.CreateFixture(fix_def2);
Please note that I'm using Box2D Web ( http://code.google.com/p/box2dweb/ ) with the HTML5 canvas.
It looks like you are not actually using the standard debug draw at all, but a function that you have written yourself - which explains the lack of online-patter about it (pastebin for posterity).
Take a look in the box2dweb source and look at these functions for a working reference:
b2World.prototype.DrawDebugData
b2World.prototype.DrawShape
b2DebugDraw.prototype.DrawSolidCircle
You can use the canvas context 'arc' function to avoid the need for calculating points with sin/cos and then drawing individual lines to make a circle. It also lets the browser use the most efficient way it knows of to render the curve, eg. hardware support on some browsers.
Since it seems like you want to do custom rendering, another pitfall to watch out for is the different call signatures for DrawCircle and DrawSolidCircle. The second of these takes a parameter for the axis direction, so if you mistakenly use the three parameter version Javascript will silently use the color parameter for the axis, leaving you with an undefined color parameter. Hours of fun!
DrawCircle(center, radius, color)
DrawSolidCircle(center, radius, axis, color)
I have a maze game that using cocos2d
I have one main sprite that can save "friend" sprite
Once "friend" sprite collide with main sprite, the "friend" sprite will follow main sprite everywhere.
Now I dont know how to make "friend" sprite follow main sprite with static distance and smooth movement.
I mean if main sprite going up, "friend" will be at behind the main sprite.
If main sprite going left, "friend" sprite will be at right of main sprite.
Please help me and share me some code...
You can implement the following behaviour by using the position of your main sprite as the target for the friend sprite. This would involve implementing separation (maintaining a min distance), cohesion (maintaining max distance) and easing (to make the movement smooth).
The exact algorithms (and some more) are detailed in a wonderful behavior animation paper by Craig Reynolds. There are also videos of the individual features and example source code (in C++).
The algorithm you need (it is a combination of multiple simpler ones) is Leader following
EDIT : I have found two straightforward implementations of the algorithms mentioned in the paper with viewable source code here and here. You will need to slightly recombine them from flocking (which is mostly following a centroid) to following a single leader. The language is Processing, resembling java-like pseudcode, so I hope the comprehension should be no problem. The C++ sourcecode I mentioned earlier is also downloadable but does not explicitly feature leader following.
I am not aware of any cocos2d implementations out there.
I have a simple solution kind of working fine. Follow the cocos2d document getting started lesson 2, Your first game. After implement the touch event. Use the following code to set seeker1 to follow cocosGuy:
- (void) nextFrame:(ccTime)dt {
float dx = cocosGuy.position.x - seeker1.position.x;
float dy = cocosGuy.position.y - seeker1.position.y;
float d = sqrt(dx*dx + dy*dy);
float v = 100;
if (d > 1) {
seeker1.position = ccp( seeker1.position.x + dx/d * v *dt,
seeker1.position.y + dy/d * v *dt);
} else {
seeker1.position = ccp(cocosGuy.position.x, cocosGuy.position.y);
}
}
The idea is at every step, the follower just need to move towards the leader at a certain speed. The direction towards the leader can be calculated by shown in the code.
I am using enableRetinaDisplay in my project and it is working very well except when I use this code.
//+++VRope
//create batchnode to render rope segments
CCSpriteBatchNode *ropeSegmentSprite = [CCSpriteBatchNode batchNodeWithFile:#"rope.png" ];
[game addChild:ropeSegmentSprite];
//Create two cgpoints for start and end point of rope
CGPoint pointA = ccp(73, 330); //Top
CGPoint pointB = ccp(self.position.x +5, self.position.y +30); //Bottom
//create vrope using initWithPoints method
verletRope = [[VRope alloc] initWithPoints:pointA pointB:pointB spriteSheet:ropeSegmentSprite];
Instead of drawing one high-res image of the rope, this code is drawing two rope images. I know that it is the retina display that is causing this because I tested it on an iphone 3gs and the simulator and it works great... until I test it on my iphone 4 then it draws two ropes instead of one. Am I doing something wrong?
I know it's too late but I found this question on the first page when searching google so I'll post this answer for others to find in the future.
In VRope.mm search for
[[[spriteSheet textureAtlas] texture] pixelsHigh]
and replace with
[[[spriteSheet textureAtlas] texture] pixelsHigh]/CC_CONTENT_SCALE_FACTOR()
That's it.
Hi i want to develop game like 'Doodle jump'.But i have some problem with the following features-
1.How to move background scene/image.
2.How to detect collision between object.Is it needed a physics engine like box2d or i should just use manual collision.
3.what should be the size of the background image.
4.In fact i have no idea how does background move .So i need a explanation from someone.
Background Movement
A) You could create a TMX Tilemap and then make a very high Tiled-Map.
B) You could create one texture and then cycle the texture coords instead of really moving it.
Detect it manually. Best is detect it via "Point in Boundingbox" or "Rect in Rect".
For more detail visit my blog entry for collision detection with cocos2d : http://www.anima-entertainment.de/?p=262
Size of an Image
Keep in Mind that textures are always at power of 2 in the memory. If you want to create one Background-Image at retina highresolution (960x640 Pixel) in the memory will be a texture of 1024x1024. If possible use smaller Background-Images and stretch them. (like 512x512). But I really would recommend for big scrolling images the TMX Support.
CCTMXTiledMap * tmxNode = [CCTMXTiledMap tiledMapWithGMXFile:#"Level.tmx"];
// lets say you want to move it 50 pixels down in 1 second :
[tmxNode runAction:[CCMoveBy actionWithDuration:1.0 position:ccp(0,-50)];
To create a tilemap : http://www.mapeditor.org/
In the folder of cocos2d, you could get many demos of tilemap.
TileMapTest.h
TileMapTest.m
refer this tutorial this will helpful for you.
http://www.raywenderlich.com/2343/how-to-drag-and-drop-sprites-with-cocos2d
this is used screen movement with pan recognizer