0

I want to create a visible object with a trajectory using standard actions (CCMoveBy and e.t.c) which is similar to:

x = sin(y)

My code:

CCMoveBy *moveAction1 = [CCMoveBy actionWithDuration:1.5 position:ccp(300, 0)];
CCEaseInOut *easeInOutAction1 = [CCEaseInOut actionWithAction:moveAction1 rate:2];
CCMoveBy *moveAction2 = [CCMoveBy actionWithDuration:1.5 position:ccp(-300, 0)];
CCEaseInOut *easeInOutAction2 = [CCEaseInOut actionWithAction:moveAction2 rate:2];
CCMoveBy *moveAction3 = [CCMoveBy actionWithDuration:1.5 position:ccp(0, -32)];
CCSpawn *moveActionRight = [CCSpawn actionOne:easeInOutAction1 two:moveAction3];
CCSpawn *moveActionLeft = [CCSpawn actionOne:easeInOutAction2 two:moveAction3];
CCSequence *sequenceOfActions = [CCSequence actionOne:moveActionRight two:moveActionLeft];
CCRepeatForever *finalMoveAction = [CCRepeatForever actionWithAction:sequenceOfActions];
[enemy runAction:finalMoveAction];

This code shows move down only. The problem is that object has a different x and y accelerations and I don't know how to combine them

UPDATED

- (void)tick:(ccTime)dt
{
    CGPoint pos = self.position;
    pos.y -= 50 * dt;
    if (pos.y < activationDistance) {
        pos.x = 240 + sin(angle) * 140;
        angle += dt * 360 * 0.007;
        if (angle >= 360) {
            angle = ((int)angle) % 360;
        }
    }
    self.position = pos;
}

It is my current solution. I can increase activationDistance to adjust the object trajectory. But I want to setup an initial value of the angle variable.

I use numbers instead of variables because they are used inside this function only.

SOLVED

To change the initial angle:

angle = point.x < 240 ? -asin((240 - point.x) / 140) : asin((point.x - 240) / 140);

the main problem was my tiled map has its own coordinates and cover 320x320 part of the screen only

Gargo
  • 704
  • 6
  • 16

1 Answers1

1

I think it will be easier for you to just do it in your frame update method (the one I assume you schedule for updating your objects. So why not just do :

- (void)tick:(ccTime)dt {
   CGPoint pos = myObject.position;
   pos.x = <desired x> + sin(angle);
   pos.y = pos.y - y_acceleration * dt;
   angle += dt * 360 * x_acceleration;
   if (angle >= 360) 
       angle = ((int)angle) % 360;

   myObject.position = pos;
}

And you can apply the same for the y axis of the object

giorashc
  • 13,691
  • 3
  • 35
  • 71
  • I will try your proposal but it is not simpler because you advice to replace intuitive understandable code with a code full of calculations. – Gargo Apr 30 '12 at 08:46
  • Every code is full of calculations. Cocos2d just wraps it up for you so you won't deal with it. But for your purpose using lots of actions is not better than a simple calculation which is much flexible and versatile – giorashc Apr 30 '12 at 08:49
  • According to your logic, why do they use box2d if then can write all the physic calculations manually? – Gargo Apr 30 '12 at 09:00
  • Well as I see it , my solution takes 7 lines of code while yours take 10 lines of code including memory allocations for each action used. So in this particular case I would go with a simple calculation as a solution. – giorashc Apr 30 '12 at 10:13
  • It works but I still can't approve it as an answer because of: 1)you forgot about y movement; 2)additionally, how to setup a concrete start x position? It is not the same as which looks like (0, 0) point. – Gargo May 02 '12 at 06:59
  • About y movement I thought it was obvious (same as x but use a different angle variable for y). And what do you mean by concrete start ? – giorashc May 02 '12 at 07:20
  • I mean starting conditions. For example, if equation is x = sin(y) then 0 = sin(0) means (0, 0) point and the starting condition: angle = 0. But I have a concrete point on a screen, for example (x, [[CCDirector sharedDirector] winSize].height). How to start the motion from this point using your code? – Gargo May 02 '12 at 07:32
  • should be changed to which is the starting point of the motion. Is that what you mean ? (Just put instead of your start x (same for y) – giorashc May 02 '12 at 07:40
  • also multiply sin(angle) with a constant if you want to increase/decrease the object's distance in motion – giorashc May 02 '12 at 07:42
  • omg. Open google and find "sin(x)" then open another window with google and find "sin(x + 1)". Compare these two graphs. If angle begins from 0 then I get the first graph. Using your advices I still get the first graph but in another place of a plane. But I must create the second graph when I have the first graph and (0, y) point of the second graph. Is it clear now? – Gargo May 02 '12 at 08:06
  • You advised me to use these "simply calculations" and now you advice me to find how this works via google because it it not readable and not understable – Gargo May 02 '12 at 08:49
  • Becuase you dont put a bit of effort of understanding it nor do you provide a normal example of what you really want (images for example) you just seemed to be annoyed that the answer is not obvious to you – giorashc May 02 '12 at 08:54
  • Red - object trajectory, blue - coords, 1 - motion before being visible (already created), 2 - after being visible. – Gargo May 02 '12 at 10:06
  • Much better now. So you want the y position of your object to be decremented by using another acceleration parameter while the x position motion is sinus, right ? – giorashc May 02 '12 at 10:24
  • yes. My temporary solution is to begin its motion earlier than it will be visible but I don't like it – Gargo May 03 '12 at 06:21
  • 1
    @Gargo I have edited my answer added y position update as well. Object's y position will move using another acceleration (so you can control x, y speeds separately). – giorashc May 03 '12 at 07:12
  • I have edited my question too. But I still need a way to calculate the initial value of an angle variable – Gargo May 03 '12 at 08:49
  • 1
    try : initial angle value = asin( - 240). – giorashc May 03 '12 at 09:00
  • thanks for your help. I have found a solution but now I should correct my code. – Gargo May 03 '12 at 10:00