Moving Object in a Curved Line?

I’m going through the lessons and I want to keep practicing by improving on the Pong tutorial. Is there a way I can spice the game up by having the ball travel in a curve? I was looking for functions to use (I found lengthdir and other sin/cos functions), but I’m not sure where I should plug them into my code.

At the moment, the ball just moves at a constant speed while its X and Y coordinates are updated in the loop function. While it does ‘bounce’, its always predictable. Help? Thank you!

There’s nothing really built into the library that will allow you to translate something across a curved line like in things like Game Maker or Unity…

What you’d need to do is figure out a way to determine the path for the curve and apply that mathematical function to the Y of the ball at position X. For instance, if you want to make it curve like a sinusoidal wave, you can change the Y value to match that of the sin() function. I think the best thing to do is just add the value of sin() so that the ball will move both up and down.

Adding the sin(x)

image

to your movement will give you something like this…

image

3 Likes

If you’ve ever struggled with sin and cosine (like I used to),
I recommend reading about the unit circle:

https://www.mathsisfun.com/geometry/unit-circle.html

It makes sin and cos make a lot more sense.

1 Like

I’m trying to add sin(x) as part of the Y value, but its not showing the results I thought it would.

At the moment, the ball’s is manipulated by altering its X and Y coordinates by a Speed value (1) in a loop. Its basically ‘bouncing’ by changing that value to either 1 or -1 in order to have it move left/right/up/down.

Whenever the ball hits a paddle, I add a 1-time ‘bump’ of additional (or negative) Y value so that the ‘angle’ varies. Nonetheless, the ball just changes in a predictive line patterns. Where can I add the sin() value to add some variety to the trajectory? Do I also need to at cos() or tan() for the X value as well?

Perhaps if you post/link to your code and/or describe exactly what sort of effect you’re after (perhaps with some diagrams if possible) it would be easier for us to help.

For a start, I suspect your x and y values are using integer types instead of floating point types, which would make sin and cos almost inneffective.


If you haven’t posted code before:

```cpp
this
```

Becomes:

this

Though if there’s a lot of code and you’ve got a github account, it might be easier to link to a repo/gist.

Here’s a snippet of my code that controls the speed and direction of the ball.

      //Control the speed the ball moves on screen
      float ballspeedx = 1;
      float ballspeedy = 1;

      //Move the ball right
      if(ballright == 1) {
        ballx = ballx + ballspeedx;
      }
      //Move the ball left
      if(ballright == -1) {
        ballx = ballx - ballspeedx;
      }
      //Move the ball down
      if(balldown == 1) {
        bally = bally + ballspeedy;
      }
      //Move the ball up
      if(balldown == -1) {
        bally = bally - ballspeedy;
      }

I change the ball’s direction by altering its X/Y coordinates. I already see I might have a conflict if the coordinates are INT while the speed that changes the variable is in FLOAT. Besides that, I’m trying to figure out a way to give the ball curvature when it changes direction. I’ve played around with adding curvature to the travel by having the balldpeedy = sin/cos/tan values. While that does give me a curved travel path, its not behaving exactly how I’d like (especially when it comes to the ricochet off walls).

Perhaps as an alternative, I can have the ball travel toward a specific X,Y coordinate? Is that possible, or would I need to create my own function for that?

Basically, I think this is what you want to do:

  1. Add 2 new variables, the paddle y speed variable, and the ball y acceleration variable.

  2. Calculate a paddle y speed variable. This is the paddle’s new y position - it’s old position. Could be zero, positive or negative.

  3. If the paddle hits the ball, set the ball y acceleration = paddle y speed / “some constant”. You’ll have to play around with the constant value - it may have to be negative…

  4. Add the bally acceleration to the ballspeedy every frame.

  5. Then add the ballspeedy to the bally as before.

Maybe it could look something like this:

//Control the speed the ball moves on screen
// init ?
float ballspeedx = ballright;
float ballspeedy = balldown;
float paddlespeedy = 0;
float ballaccely = 0;
// if paddle moved
paddlespeedy = newpaddley - oldpaddley;

  // when the paddle hits the ball
  ballaccely = paddlespeedy / magic_constant   // try 16?
 
 
 // every frame
    ballx = ballx + ballspeedx; // move the ball in x
	ballspeedy += ballaccely;   // change the balls y speed
    bally = bally + ballspeedy; // move the ball in y

Does this make any sense?

Catsfolly

edit: With this scheme, the ballx and bally positions would have to be floats also. (Or you could convert the whole program to fixed point.)

1 Like

intellp

This is how it looked when I did something similar on the Intellivision.

Yes, that would be a problem.
bally and ballx would have to be float as well, otherwise everything after the decimal point gets discarded.

That’s perfectly possible but would be more complicated.

What kind of behaviour are you expecting?
It would help if you gave some kind of a diagram or something.

Also it would be good to see the code that you’re using to assign ballspeedy and ballspeedx.
At present we don’t know what parameter you’re using for the input to sin and cos.

Seeing your code will usually tell us more than you can with just words alone.


@Catsfolly wasn’t expecting to see you here :P

I have a library for that, guaranteed to work on Arduboy out of the box. It’s even available from the IDE.

2 Likes