moving CCRendertexture - cocos2d-iphone

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];
}

Related

How to make stretch body(trigger) and apply physics on it in box2d in iphone?

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

Cocos2D Sprite Relative Movement

I have a problem that I can't seem to solve.
I would like to move a sprite on the screen based on finger movements, but instead of making the sprite move towards the touch position I would like the sprite to move in the same way the finger moves on the screen.
Example:
User puts his/her finger on the screen (any position) and then drags the finger on the screen by 200 pixel to the left, the sprite should also move of 200 pixels to the left.
My approach was to store the position of the player at the start and then calculating the difference between the start position and the current position of the finger to add to the starting position of the sprite itself.
Here is my code
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if([touches count] == 1){
UITouch *touch = [touches anyObject];
CGPoint startPos = [touch locationInView:[touch view]];
startPosition = startPos;
}
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if([touches count] == 1){
UITouch *touch = [touches anyObject];
CGPoint touchPos = [touch locationInView:[touch view]];
CGPoint playerPos = player.position;
float yDifference = startPosition.y - touchPos.y;
playerPos.y = playerPos.y - yDifference;
// just to change to GL coordinates instead of the ones used by Cocos2D
// still doesn't work even if I remove this...
CGPoint convertedPoint = [[CCDirector sharedDirector] convertToGL:playerPos];
[player setPosition:convertedPoint];
}
}
I hope the problem I have is clear but if it is not don't hesitate do ask questions or further explaining. I've been stuck on this for quite a while :'(
Also, if you want it to move "relative" to where it started as opposed to exactly where the touch is:
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if([touches count] == 1){
UITouch *touch = [touches anyObject];
CGPoint startPos = [touch locationInView:[touch view]];
startPosition = startPos;
playerStartPos = playerPos;
}
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if([touches count] == 1){
UITouch *touch = [touches anyObject];
CGPoint touchPos = [touch locationInView:[touch view]];
CGPoint newPlayerPos;
newPlayerPos.x = playerStartPos.x + (touchPos.x - startPosition.x);
newPlayerPos.y = playerStartPos.y + (touchPos.y - startPosition.y);
// just to change to GL coordinates instead of the ones used by Cocos2D
// still doesn't work even if I remove this...
CGPoint convertedPoint = [[CCDirector sharedDirector] convertToGL:newPlayerPos];
[player setPosition:convertedPoint];
}
Your code is looking like it's "feeding back" onto itself by continually adding the difference to the playerPos.y
So just don't use the difference, use the current touch position :
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if([touches count] == 1){
UITouch *touch = [touches anyObject];
CGPoint playerPos = [touch locationInView:[touch view]];
// just to change to GL coordinates instead of the ones used by Cocos2D
// still doesn't work even if I remove this...
CGPoint convertedPoint = [[CCDirector sharedDirector] convertToGL:playerPos];
[player setPosition:convertedPoint];
}

Touch move in Cocos2d

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.

cocos2d ccTouchesMoved moving sprite only to top right corner

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..

Move sprite away from Touch? Cocos2d

Hey everyone,
I'm new to cocos2d and Objective-C so I apologize if there is a simple solution.
I am working on some code for a game I am developing. In this game I have a sprite on screen, and I would like this sprite to move opposite of the touch location.
Example:
Picture Example
So far my code looks like this:
-(void) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
//Determine location of the tap/touch
CGPoint touchLocation = [touch locationInView: [touch view]];
touchLocation = [[CCDirector sharedDirector] convertToGL: touchLocation];
touchLocation = [self convertToNodeSpace:touchLocation];
I add my sprite to the scene in the init method like so:
CGSize screenSize = [[CCDirector sharedDirector] winSize];
Ball* ball = [Ball ball];
ball.position = CGPointMake(ball.contentSize.width / 2, screenSize.height / 2);
[self addChild:ball z:2];
I would like it so that wherever I touch on the screen, the sprite will move 20pixels opposite of that touch location. So if I touch to the left of the sprite, the sprite moves right, if I touch to the top, the sprite will move down..etc.
Thanks for the help!
Use actions. In your touch began method create an action:
CGPoint vector;
vector.x = ball.position.x - touchLocation.x;
vector.y = ball.position.y - touchLocation.y;
float vectorLength = sqrt(vector.x*vector.x + vector.y*vector.y);
if (fabs(vectorLength) < 0.1) return; //tapped directly to the center of sprite
vector.x *= 20 / vectorLength;
vector.y *= 20 / vectorLength;
id action = [CCMoveBy actionWithDuration: 0.5 position: vector];
[ball runAction: action];