0
\$\begingroup\$

I have a vertical scrolling rhythm game, here is the commented code of the basic logic of the game neccesary to understand the question

int scrollSpeed = 500 //time in ms that take the note to get from the top to the bottom
float currentTime = 0 //time in ms of the song playing
List<int> noteTimings = new List() //List of the time in ms that the player should hit them, sorted in ascending order

for(i=0; i<noteTimings.Count; i++) {
    int noteTiming = noteTimings[i];
    float notePosition = (noteTiming-currentTime) / scrollSpeed;
}

The note position will be a value, 1 meaning the note is at the top of the screen and 0 at the bottom where the player should hit it.

What I want to do

I want to make a multiplier that will multiply the speed of the notes. With the actual code multiplying the note speed while playing will make the notes jump, for example if I multiply the note speed by two the notes will have the double of separation than before, and that would look like the notes moved INSTANTLY, but I want that double separation to be done before changing the speed so it looks linear and well when playing

edit: here's an example of how I want it to look: https://youtube.com/watch?v=ZBtNjb8E1n4 As you can see it changes velocity, this is done by changing the timing points so the velocity slow down or speed up depending on a multiplier

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Each note needs a velocity property, which is responsible for moving the note by a given amount on each frame.

The note has a direction of travel, the y axis, let's calls this vy Its current position on any given frame is y, so the speed of the note is:

y += vy

Then, on each frame of the animation you need to alter the speed (the distance the note moves in one frame) of the note.

You can do this by assigning an acceleration a property to each note. e.g. acceleration = 0.125 where the value represents the number of pixels you want to accelerate/decelerate by per frame.

Then, if you add acceleration to the direction on each frame:

vx += acceleration

and then add this to the note's position

y += vy

The note will accelerate in a linear manner.

I don't program in C# but here's the code in JavaScript running on the x axis rather than the y. The bit you want is in the loop:

// move and accelerate the shape
  // if the shape hasn't reached the end of the canvas
  if (x <= canvas.width + 16) {
    vx += acceleration; // add accelaration to the velocity
    x += vx; // move the shape with the new velocity value
  } else {
    // the shape reached the end of the canvas
    vx = 0; // reset the velocity
    x = 0; // repostion the shape at the begining of the canvas
  }

// A canvas element for the animation
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d"); // we draw on the context
canvas.style.backgroundColor = "#555";
canvas.height = 100;

// **** Canvas Animation **** \\
// some vars to help us move something on canvas
let x = 0,
  vx = 1, // velocity
  acceleration = 0.125; // acceleration

// A loop so that we can animate something on the canvas
loop();
function loop() {
  // loop the animation at 60fps
  requestAnimationFrame(loop);
  // fill the width of the page with the canvas
  canvas.width = document.body.clientWidth;

  // clear the canvas so we can redraw everyframe
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // draw a shape on the canvas
  ctx.fillStyle = "lightblue";
  ctx.beginPath();
  ctx.rect(x, 16, 16, canvas.height - 35);
  ctx.fill();

  // move and accelerate the shape
  // if the shape hasn't reached the end of the canvas
  if (x <= canvas.width + 16) {
    vx += acceleration; // add accelaration to the velocity
    x += vx; // move the shape with the new velocity value
  } else {
    // the shape reached the end of the canvas
    vx = 0; // reset the velocity
    x = 0; // repostion the shape at the begining of the canvas
  }
}
* {
  margin: 0;
  padding: 0;
}

body {
  background-color: rgb(28, 26, 26);
  color: white;
}
<canvas id="canvas"></canvas>

If you wanted to accelerate in a non-linear manner, you would just need to implement an easing algorithm.

Note: In the above example, we are just painting pixels, where the top left corner of the shape is at x, y. At the start of each new frame, we clear the canvas and start to repaint the shape at a new x position which is calculated as vx + acceleration and then incrementing the value of x by x += vx thus, we are setting this speed and acceleration globally. We are not able to assign any properties to this shape because it does not exist as an object, its just a load of pixels!

If, as I presume (I can't make any comments to ask questions at the moment, as I am new to this site) you want to alter the speed and acceleration of individual notes, I would make the shape, or note as an object that I can assign properties to. Then you can tweak the property values with your game logic.

e.g. using JavaScript, I may have a note object that has properties like these:

let note = {
  // physical dimensions and position of circle center
  radius: 16,
  x: 16,
  y: 16,

  // styling props
  fillColor: "blue",
  lineColor: "black",

  // physics props
  vx: 0, // velocity in x direction
  vy: 0, // velocity in y direction
  acc: 0, // acceleration
  friction: 1, // friction
};

then in our set up, we can set the objects properties as desired

// set up
note.vy = 1;
note.acc = 0.125;

and then in our game loop we can use game logic to move the note as and when we want

// the animation loop
function gameLoop() {
    // function to ask the browser to repaint the screen / canvas
  requestAnimationFrame(gameLoop);

  // **** game logic here **** \\
  if (a condition is true)
  // increment the values in each new frame
  note.vy += note.acc; // increment the velocity by acceleration
  note.y += note.vy; // increment the note's position by the velocity
}
```
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.