I want to make trigger so that user can stretch the trigger and give the direction and then trigger hit to the ball and the ball will go accordingly.
The Ball speed and direction will depend on the trigger.
I am new in box2d.
Please check the link what I want.
http://dc694.4shared.com/img/Nw7YYLNL/s7/pool.png?async&0.2852371991612017
-(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);
// Create sprite and add it to the layer
CCSprite *Trigger = [CCSprite spriteWithFile:#"Trigger.png"];
Trigger.position = ccp(10, 50);
Trigger.tag = 1;
[self addChild:Trigger];
// Create Trigger body
b2BodyDef TriggerBodyDef;
TriggerBodyDef.type = b2_dynamicBody;
TriggerBodyDef.position.Set(127/PTM_RATIO, 210/PTM_RATIO);
TriggerBodyDef.userData = ball;
TriggerBody = _world->CreateBody(&TriggerBodyDef); // b2Body * ballBody
// Create circle shape
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
// Create shape definition and add to body
b2FixtureDef TriggerShapeDef;
TriggerShapeDef.shape = &circle;
TriggerShapeDef.density = 15.0f;
TriggerShapeDef.friction = 2.f;
TriggerShapeDef.restitution = 0.0f;
_TriggerFixture = TriggerBody->CreateFixture(&TriggerShapeDef);
b2Vec2 force = b2Vec2(10, -12);
TriggerBody->ApplyLinearImpulse(force, TriggerBodyDef.position);
///////////////////////// 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);
}
I am not able to make trigger and not able to apply physics on trigger image. How to apply physics on trigger body? And how the ballbody will move according to trigger?
I have implemented this as follow:
HelloWorldLayer.h
#import "cocos2d.h"
#import "Box2D.h"
#define PTM_RATIO 32.0
#interface HelloWorldLayer : CCLayer {
b2World *_world;
b2Body *_body;
CCSprite *_ball;
CGPoint firstlocation;
CGPoint lastlocation;
b2Vec2 pre_velocity;
}
+ (id) scene;
- (void)kick;
#end
HelloWorldLayer.m
#import "HelloWorldLayer.h"
#implementation HelloWorldLayer
+ (id)scene {
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild:layer];
return scene;
}
- (id)init {
if ((self=[super init])) {
CGSize winSize = [CCDirector sharedDirector].winSize;
_ball = [CCSprite spriteWithFile:#"ball.png" rect:CGRectMake(0, 0, 52, 52)];
_ball.position = ccp(100, 100);
[self addChild:_ball];
//create world
b2Vec2 gravity = b2Vec2(0.0f, -8.0f);
_world = new b2World(gravity);
// Create ball body and shape
b2BodyDef ballBodyDef;
ballBodyDef.type = b2_dynamicBody;
ballBodyDef.position.Set(26/PTM_RATIO, 26/PTM_RATIO);
ballBodyDef.userData = _ball;
_body = _world->CreateBody(&ballBodyDef);
b2CircleShape circle;
circle.m_radius = 26.0/PTM_RATIO;
b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 1.0f;
ballShapeDef.friction = 0.2f;
ballShapeDef.restitution = 0.8f;
_body->CreateFixture(&ballShapeDef);
//ground edge
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0,0);
b2Body *groundBody = _world->CreateBody(&groundBodyDef);
b2EdgeShape groundEdge;
b2FixtureDef boxShapeDef;
boxShapeDef.shape = &groundEdge;
//wall definitions
groundEdge.Set(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
groundEdge.Set(b2Vec2(0,0), b2Vec2(0,winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundEdge.Set(b2Vec2(0, winSize.height/PTM_RATIO),
b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO));
groundBody->CreateFixture(&boxShapeDef);
groundEdge.Set(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO),
b2Vec2(winSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&boxShapeDef);
[self schedule:#selector(tick:)];
// [self schedule:#selector(kick) interval:3.0];
self.isTouchEnabled = YES;
self.isAccelerometerEnabled = YES;
}
return self;
}
-(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration{
b2Vec2 gravity(acceleration.y * 30, -acceleration.x * 30);
_world->SetGravity(gravity);
}
- (void)tick:(ccTime) dt {
_world->Step(dt, 10, 1);
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
CCSprite *ballData = (CCSprite *)b->GetUserData();
ballData.position = ccp(b->GetPosition().x * PTM_RATIO,
b->GetPosition().y * PTM_RATIO);
ballData.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
- (void)kick {
b2Vec2 force = b2Vec2(-30, 30);
_body->ApplyLinearImpulse(force,_body->GetPosition());
}
- (void)ccTouchesBegan:(NSSet *)touch withEvent:(UIEvent *)event {
/* b2Vec2 force = b2Vec2(-30, -30);
_body->ApplyLinearImpulse(force, _body->GetPosition());*/
UITouch *touchpoint = [touch anyObject];
firstlocation = [touchpoint locationInView:[touchpoint view]];
firstlocation = [[CCDirector sharedDirector] convertToGL:firstlocation];
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touchpoint = [touches anyObject];
lastlocation = [touchpoint locationInView:[touchpoint view]];
lastlocation = [[CCDirector sharedDirector] convertToGL:lastlocation];
//NSLog(#"start location %2f %2f",firstlocation.x,firstlocation.y);
//NSLog(#"last location %2f %2f",lastlocation.x,lastlocation.y);
GLfloat y = firstlocation.y - lastlocation.y;
GLfloat x = firstlocation.x - lastlocation.x;
GLfloat lengthOfFlick = sqrt(x*x + y*y);
NSLog(#"%2f",lengthOfFlick);
/* GLfloat basAngle = atan2(-x, -y);
GLfloat radians = (basAngle + (180/3.14));
//GLfloat angle = 180 + radians;*/
//GLfloat theta = atan2(y,x)* 180 / 3.14;
//NSLog(#"theta: %2f",theta);
float ratio = lengthOfFlick/90;
NSLog(#"%f",ratio);
if(ratio > 1){
ratio = 1;
}
NSLog(#"%f",ratio);
if(firstlocation.x > lastlocation.x){
if(firstlocation.y > lastlocation.y){
b2Vec2 force = b2Vec2((int)(45 * ratio),(int)(45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}else{
b2Vec2 force = b2Vec2((int)( -1 * 45 * ratio), (int)(45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}
}else{
if(firstlocation.y > lastlocation.y){
b2Vec2 force = b2Vec2((int)( -1 * 45 * ratio),(int)(45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}else{
b2Vec2 force = b2Vec2((int)(-1* 45 * ratio),(int)(-1 * 45 * ratio));
_body->ApplyLinearImpulse(force, _body->GetPosition());
}
}
}
-(void)dealloc{
delete _world;
_body = NULL;
_world = NULL;
[super dealloc];
}
#end
Or you can download this code from:4shared.com/zip/PRv8c1Pz/BOX2D.html
I'm new in cocos2d and I'm working in a coloring app, I'm Using CCRenderTexture for drawing:
target = [[CCRenderTexture alloc] initWithWidth:size.width height:size.height pixelFormat:kCCTexture2DPixelFormat_RGBA8888];
[target setPosition:ccp(size.width/2, size.height/2)];
[target clear:255 g:255 b:255 a:1];
[self addChild:target];
but I need to move the position of the drawing area (CCRenderTexture) a little up to show a submenu that hides in the bottom of the screen, so im using CCMove:
[CCMoveTo actionWithDuration:0.2 position:ccp(self.position.x, self.position.y+menuOffset)]
the rendertexture moves up as expected, but the "touchable area" stays in the same place, so when im touching the submenu area(outside the rendertexture frame) im still drawing inside the rendertexture.
this is the method for drawing
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint start = [touch locationInView: [touch view]];
start = [[CCDirector sharedDirector] convertToGL: start];
CGPoint end = [touch previousLocationInView:[touch view]];
end = [[CCDirector sharedDirector] convertToGL:end];
// begin drawing to the render texture
[target begin];
// scale/rotation/offset
float distance = ccpDistance(start, end);
if (distance > 1)
{
int d = (int)distance;
for (int i = 0; i < d; i++)
{
float difx = end.x - start.x;
float dify = end.y - start.y;
float delta = (float)i / distance;
[brush setPosition:ccp(start.x + (difx * delta), start.y + (dify * delta))];
[brush setRotation:rand()%360];
[brush setScale:drawratio];
[brush setColor:brush.color];
[brush visit];
}
}
[target end];
}
so, how can I change the position of CCRendertexture in a proper way?
Thanks in advance.
You just need to convert the GL coordinates to your target object's node space
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint start = [touch locationInView: [touch view]];
start = [[CCDirector sharedDirector] convertToGL: start];
start = [target convertToNodeSpace: start];
CGPoint end = [touch previousLocationInView:[touch view]];
end = [[CCDirector sharedDirector] convertToGL:end];
end = [target convertToNodeSpace: end];
// begin drawing to the render texture
[target begin];
// scale/rotation/offset
float distance = ccpDistance(start, end);
if (distance > 1)
{
int d = (int)distance;
for (int i = 0; i < d; i++)
{
float difx = end.x - start.x;
float dify = end.y - start.y;
float delta = (float)i / distance;
[brush setPosition:ccp(start.x + (difx * delta), start.y + (dify * delta))];
[brush setRotation:rand()%360];
[brush setScale:drawratio];
[brush setColor:brush.color];
[brush visit];
}
}
[target end];
}
I have a problem in the Touch Event.
I have 5 sprites and I want to move a single sprite and only the selected sprite. But in this when i move touch then only one Sprite is move How move only select Sprite..
in .h file
CCSprite *puzzButton1,*puzzButton2,*puzzButton3;
in .m file
// create and initialize our seeker sprite, and add it to this layer
puzzButton1 = [CCSprite spriteWithFile: #"ingame_button_idal.png"];
puzzButton1.position = ccp( 480/2, 320/2 );
[self addChild:puzzButton1];
// create and initialize our seeker sprite, and add it to this layer
puzzButton2 = [CCSprite spriteWithFile: #"ingame_button_idal.png"];
puzzButton2.position = ccp( 100, 200 );
[self addChild:puzzButton2];
// create and initialize our seeker sprite, and add it to this layer
puzzButton3 = [CCSprite spriteWithFile: #"ingame_button_idal.png"];
puzzButton3.position = ccp( 100, 300 );
[self addChild:puzzButton3];
and in
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return TRUE;
}
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
CGPoint location = [self convertTouchToNodeSpace: touch];
[puzzButton1 stopAllActions];
[puzzButton1 runAction: [CCMoveTo actionWithDuration:0.1 position:location]];
}
Try this:
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGRect touchpoint = CGRectMake(160, 66, 564, 220); // your sprite position
if(CGRectContainsPoint(touchpoint, location))
{
yoursprite.position = ccp(location.x,location.y);// write move code
//here and check same
//condition for all
//your sprite.
}
}
or assign tags for your sprits and check them.
I am using following code for sprite animation in cocos2d
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
#"AnimBear.plist"];
CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode
batchNodeWithFile:#"AnimBear.png"];
[self addChild:spriteSheet];
NSMutableArray *walkAnimFrames = [NSMutableArray array];
for(int i = 1; i <= 8; ++i) {
[walkAnimFrames addObject:
[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
[NSString stringWithFormat:#"bear%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation
animationWithFrames:walkAnimFrames delay:0.1f];
CGSize winSize = [CCDirector sharedDirector].winSize;
self.bear = [CCSprite spriteWithSpriteFrameName:#"bear1.png"];
_bear.position = ccp(winSize.width/2, winSize.height/2);
self.walkAction = [CCRepeatForever actionWithAction:
[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
[_bear runAction:_walkAction];
[spriteSheet addChild:_bear];
I need not getting clear idea about CCSpriteBatchNode why this is used here?
You do not need to use the CCSpriteBatchNode for a single animation.
The CCSpriteBatchNode is used when you want to display many objects taken from the same sprite sheet. In this case rendering the stuff is much faster than rendering individual sprites.
As long as you use a single sprite there is no speed up since the sprites in an animation are displayed in separate frames.
Forgive my elementary question as I'm pretty new to cocos2d, but I'm having an issue moving a sprite around. The method seems to do what I want...as long as it's moving in a positive x and positive y direction (top right corner). If I try to move it down or left, it doesn't work.
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint point = [myTouch locationInView:[myTouch view]];
point = [[CCDirector sharedDirector] convertToGL:point]; //create point location
CCNode *sprite = [self getChildByTag:kTagSprite]; //set sprite
CGRect spriteRect = CGRectMake(sprite.position.x, sprite.position.y, sprite.contentSize.width, sprite.contentSize.height); //create box around sprite and get position
if(CGRectContainsPoint(spriteRect, point)){
[sprite setPosition:point]; //if my pointer is inside of the sprite box, move the sprite
}
}
Thank you.
edit: adding my init and tag reference
-(id) init{
if((self = [super init])){
self.isTouchEnabled = YES;
CCSprite *mySprite = [CCSprite spriteWithFile:#"sprite.png"];
mySprite.position = ccp(240, 40);
[self addChild:mySprite z:0 tag:kTagSprite];
}
return self;
}
and i declared the kTagSprite in:
enum{
kTagSprite
};
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint point = [myTouch locationInView:[myTouch view]];
point = [[CCDirector sharedDirector] convertToGL:point]; //create point location
CCSprite *sprite = [self getChildByTag:kTagSprite]; //set sprite
if(CGRectContainsPoint([sprite boundingBox], point)){
[sprite setPosition:point]; //if my pointer is inside of the sprite box, move the sprite CCLOG(#"THIS WILL BE CALLED");
}
}
run the code and look at the console to see if the log will be called..