# Question
Title: How to implement variable velocity in my rhythm game
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

# Answer
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
}
```

> 1 votes

---
Tags: c#
---


# Question
Title: How to add a texture inside a specific area in a canvas in javascript?
How could I draw a texture between the bottom of the canvas and below the green line, in javascript? I dynamically add coordinates in a canvas, then draw lines between these points.

EDIT : Solution: so I had to do it like this :

```
let path = 'M'+points[i-1].x+' '+points[i-1].y;
path += 'L'+points[i].x+' '+points[i].y;
//etc... with "Z" for closing the path, then :
let p = new Path2D(path);
ctx.fillStyle = ctx.createPattern(imgTexture, "repeat");
ctx.fill(p);

```

# Answer
> 1 votes
Solution: so I had to do it like this :

```
let path = 'M'+points[i-1].x+' '+points[i-1].y;
path += 'L'+points[i].x+' '+points[i].y;
//etc... with "Z" for closing the path, then :
let p = new Path2D(path);
ctx.fillStyle = ctx.createPattern(imgTexture, "repeat");
ctx.fill(p);

```

---
Tags: textures, javascript
---


# Question
Title: Moving ships between two planets along a bezier, missing some equations for acceleration
OK, I already posted this over at math.stackechange.com but didn't get any answers :(

First of here's a picture of my problem, the description follows afterwards:

So I got all the points and values set up.

The ship starts out moving around the left planet `P1` with `S=0.27 Degrees` per gametick, when it reaches `Point A` it starts following the bezier curve till it reaches `Point D`, then it travels around the right planet `P2` with `S=0.42 Degrees` per game tick. The difference in `S` is so that the travel with the same movement speed around the planets.

So far so good, I got that up and running, now my problem.

When `S P1` and `S P2` differ to much, the ship jumps between the two speeds when it reaches it's destination, which looks pretty bad. So I need to accelerate the ship between `Point A` and `Point D` from `S P1` to `S P2`.

The thing I'm missing are in purple, those are:

* A way to calculate the ticks it takes the ship to move along the bezier considering the acceleration.
* And a way to find a position on the bezier curve based on T, again considering the acceleration.

ATM I calculate the length of the bezier by calculating the distance between `N` of its points. So what I *think* I need, is a way to scale the `T` I need to put into my bezier calculation accordingly to the acceleration.

# Answer
> 117 votes
OK, I've got everything working, it took forever, so I'm going to post my detailed solution here.
*Note: All code samples are in JavaScript.*

**So let's break down the problem into the basic parts:**

1. You need to compute the length of, as well as points between `0..1` on the bezier curve
2. You now need to adjust the scaling of your `T` to accelerate the ship from one speed to another

## **Getting the Bezier right**

Finding some code for drawing a Bezier curve is easy, there are a number of different approaches though, one of them is the DeCasteljau Algorithm, but you can also just use the equation for cubic Bézier curves:

```
// Part of a class, a, b, c, d are the four control points of the curve
x: function (t) {
    return ((1 - t) * (1 - t) * (1 - t)) * this.a.x
           + 3 * ((1 - t) * (1 - t)) * t * this.b.x
           + 3 * (1 - t) * (t * t) * this.c.x
           + (t * t * t) * this.d.x;
},

y: function (t) {
    return ((1 - t) * (1 - t) * (1 - t)) * this.a.y
           + 3 * ((1 - t) * (1 - t)) * t * this.b.y
           + 3 * (1 - t) * (t * t) * this.c.y
           + (t * t * t) * this.d.y;
}

```

With this, one can now draw a bezier curve by calling `x` and `y` with `t` which ranges from `0 to 1`, let's take a look:

Uh... that's not really an even distribution of the points, is it?
Due to the nature of the Bézier curve, the points on `0...1` have different `arc lenghts`, so segments near the beginning and the end, are longer than the ones which are near to the middle of the curve.

## **Mapping T evenly on the curve AKA arc-length parameterization**

So what to do? Well in simple terms we need a function to map our `T` onto the `t` of the curve, so that our `T 0.25` results in the `t` that's at `25%` of the length of the curve.

How do we do that? Well, we Google... but it turns out that the term isn't that *googleable*, and at some point you'll hit this PDF. Which sure is a great read, but in the case that you've already forgotten all the math stuff you learned back in school(or you just don't like those mathematical symbols) it's pretty useless.

What now? Well go and Google some more(read: 6 hours), and you finally find a **great** article on the topic(including nice pictures! ^\_^"):
http://www.planetclegg.com/projects/WarpingTextToSplines.html

## **Doing the actual code**

In case you just couldn't resist downloading that PDF's *although* you'd already lost your mathematical knowledge a long, long, time ago(and you managed to skip the *great* article link), you might now think: "God, this will take hundreds of lines of code and tons of CPU"

No, it will not. Because we do what all programmers do, when it comes to math stuff:
**We simply cheat.**

## **Arc-length parameterization, the lazy way**

Let's face it, we don't need endless precision in our game, do we? So unless you're working at Nasa and planning on sending people the the Mars, you won't need a `0.000001 pixel` perfect solution.

So how do we map `T` onto `t`? It's simple and only consists of 3 steps:

1. Calculate `N` points on the curve using `t` and store the `arc-length`(aka the length of the curve) at that position into an array
2. To map `T` onto `t`, first multiply `T` by the total length of the curve to get `u` and then search the array of lengths for the index of the largest value that's smaller than `u`
3. If we had an exact hit, return the array value at that index divided by `N`, if not interpolate a bit between the point we found and the next one, divide the thing once again by `N` and return.

That's all! So now let's take a look at the complete code:

```
function Bezier(a, b, c, d) {
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;

    this.len = 100;
    this.arcLengths = new Array(this.len + 1);
    this.arcLengths[0] = 0;

    var ox = this.x(0), oy = this.y(0), clen = 0;
    for(var i = 1; i <= this.len; i += 1) {
        var x = this.x(i * 0.05), y = this.y(i * 0.05);
        var dx = ox - x, dy = oy - y;
        clen += Math.sqrt(dx * dx + dy * dy);
        this.arcLengths[i] = clen;
        ox = x, oy = y;
    }
    this.length = clen;
}

```

This initializes our new curve and computes the `arg-lenghts`, it also stores the last of the lengths as the `total length` of the curve, key factor here is `this.len` which is our `N`. The higher, the more precise the mapping will be, for a curve of the size in the picture above `100 points` seem to be enough, if you just need a good length estimate, something like `25` will already do the job with being only 1 pixel off in our example, but then you will have a less precise mapping which will result in not so even distribution of `T` when mapped to `t`.

```
Bezier.prototype = {
    map: function(u) {
        var targetLength = u * this.arcLengths[this.len];
        var low = 0, high = this.len, index = 0;
        while (low < high) {
            index = low + (((high - low) / 2) | 0);
            if (this.arcLengths[index] < targetLength) {
                low = index + 1;

            } else {
                high = index;
            }
        }
        if (this.arcLengths[index] > targetLength) {
            index--;
        }

        var lengthBefore = this.arcLengths[index];
        if (lengthBefore === targetLength) {
            return index / this.len;

        } else {
            return (index + (targetLength - lengthBefore) / (this.arcLengths[index + 1] - lengthBefore)) / this.len;
        }
    },

    mx: function (u) {
        return this.x(this.map(u));
    },

    my: function (u) {
        return this.y(this.map(u));
    },

```

The actual mapping code, first we do a simple `binary search` on our stored lengths to find the largest length that's smaller then `targetLength`, then we just return or do the interpolation and return.

```
    x: function (t) {
        return ((1 - t) * (1 - t) * (1 - t)) * this.a.x
               + 3 * ((1 - t) * (1 - t)) * t * this.b.x
               + 3 * (1 - t) * (t * t) * this.c.x
               + (t * t * t) * this.d.x;
    },

    y: function (t) {
        return ((1 - t) * (1 - t) * (1 - t)) * this.a.y
               + 3 * ((1 - t) * (1 - t)) * t * this.b.y
               + 3 * (1 - t) * (t * t) * this.c.y
               + (t * t * t) * this.d.y;
    }
};

```

Again this computes `t` on the curve.

## **Time for results**

By now using `mx` and `my` you get an evenly distributed `T` on the curve :)

Wasn't that hard, was it? Once again, it turns out that a simple(although not perfect solution) will be enough for a game.

In case you want to see the complete code, there's a Gist available:
https://gist.github.com/670236

## **Finally, accelerating the ships**

So all that's left now is to accelerate the ships along their path, by mapping the position onto `T` which we then use to find the `t` on our curve.

First we need two of the equations of motion, namely `ut + 1/2at²` and `(v - u) / t`

In actual code that would look like this:

```
startSpeed = getStartingSpeedInPixels() // Note: pixels
endSpeed = getFinalSpeedInPixels() // Note: pixels
acceleration = (endSpeed - startSpeed) // since we scale to 0...1 we can leave out the division by 1 here
position = 0.5 * acceleration * t * t + startSpeed * t;

```

Then we scale that down to `0...1` by doing:

```
maxPosition = 0.5 * acceleration + startSpeed;
newT = 1 / maxPosition * position;

```

And there you go, the ships are now moving smoothly along the path.

## **In case it doesn't work...**

When you're reading this, everything works fine and dandy, but I initially had some problems with the acceleration part, when explaining the problem to someone in the gamedev chatroom I found the final error in my thinking.

In case you haven't forgotten already about the picture in the original question, I mention `s` there, turns out that `s` is speed in ***degrees***, but the ships move along the path in ***pixels*** and I had forgotten about that fact. So what I needed to do in this case was to convert the displacement in degrees into a displacement in pixels, turns out that this is rather easy:

```
function rotationToMovement(planetSize, rotationSpeed) {
    var r = shipAngle * Math.PI / 180;
    var rr = (shipAngle + rotationSpeed) * Math.PI / 180;
    var orbit = planetSize + shipOrbit;
    var dx = Math.cos(r) * orbit - Math.cos(rr) * orbit;
    var dy = Math.sin(r) * orbit - Math.sin(rr) * orbit;
    return Math.sqrt(dx * dx + dy * dy);
};

```

So and that's all! Thanks for reading ;)

# Answer
> 6 votes
The issue is that a ship would not take that trajectory naturally. So even with it working perfectly it still won't look right.

If you want to simulate the smooth transition between planets I would suggest actually modeling it. The equations are very simple as you only have two significant forces: gravity, and thrust.

You just need to set your constants: Mass of P1, P2, ship

With each game-tick (time: t) you are doing 3 things

1. Calculate the gravity of p1 on ship and p2 on ship, add the resultant vectors to the thrust vector.
2. Calculate your new velocity based on your new acceleration from step 1
3. Move the ship according to your new velocity

Might seem like a lot of work but it can be done in a dozen lines of code and will look very natural.

If you need help with the physics let me know.

# Answer
> 3 votes
This problem is just begging for Newton approximation like recursions.

How to find distance of arc up to precision required?

> First iteration: Find out the distance between both endpoints. Create new points at 1/4 of a distance from 1/4 first control point to 3/4 of second control point, plus 3/4 of a distance from 1st point, plus 1/2 the distance. Measure length of a polyline comprising these five points. Is second distance minus first distance smaller than our tolerance?
>
> * yes =\> return distance
> * no =\> recursion Other iterations: Create points at 1/8, 3/8, 5/8 and 7/8 (or 1/16th, 3/16ths etc., and so on in subsequent iterations) Is new distance - previous distance \< tolerance? Yes/no, return distance/recursion.

In this way not only can you tell what the distance is, but also what is maximum imprecision in your calculation, plus you never calculate more than what is absolutely necessary.

To find the point at t I would strongly suggest using pure Newton's approximation, as this is what it calculates, and within defined toleration.

Pyhon code, created and tested in Blender 2.83 LTS.

```
from math import sqrt
def lengthOfCurve(points, H1, H2, toleration):
    A = points[0]
    E = points[-1]
    if len(points) == 2: # first round
        Ba = [(H1[0] - A[0])*0.25 + A[0], (H1[1] - A[1])*0.25 + A[1], (H1[2] - A[2])*0.25 + A[2]]
        Bb = [(E[0] - H2[0])*0.25 + H2[0], (E[1] - H2[1])*0.25 + H2[1], (E[2] - H2[2])*0.25 + H2[2]]
        B = [(Bb[0] - Ba[0])*0.25 + Ba[0], (Bb[1] - Ba[1])*0.25 + Ba[1], (Bb[2] - Ba[2])*0.25 + Ba[2]]
        Ca = [(H1[0] - A[0])*0.5 + A[0], (H1[1] - A[1])*0.5 + A[1], (H1[2] - A[2])*0.5 + A[2]]
        Cb = [(E[0] - H2[0])*0.5 + H2[0], (E[1] - H2[1])*0.5 + H2[1], (E[2] - H2[2])*0.5 + H2[2]]
        C = [(Cb[0] - Ca[0])*0.5 + Ca[0], (Cb[1] - Ca[1])*0.5 + Ca[1], (Cb[2] - Ca[2])*0.5 + Ca[2]]
        Da = [(H1[0] - A[0])*0.75 + A[0], (H1[1] - A[1])*0.75 + A[1], (H1[2] - A[2])*0.75 + A[2]]
        Db = [(E[0] - H2[0])*0.75 + H2[0], (E[1] - H2[1])*0.75 + H2[1], (E[2] - H2[2])*0.75 + H2[2]]
        D = [(Db[0] - Da[0])*0.75 + Da[0], (Db[1] - Da[1])*0.75 + Da[1], (Db[2] - Da[2])*0.75 + Da[2]]
        points = [A, B, C, D, E]
        originalLength = sizeOfVector(A, E)
        newLength = sizeOfVector(A, B) + sizeOfVector(B, C) + sizeOfVector(C, D) + sizeOfVector(D, E)
        if newLength - toleration < originalLength:
            return(round(newLength/toleration)*toleration)
        return(lengthOfCurve(points, H1, H2, toleration))
    else: # following rounds
        numberOfSegments = len(points) - 1
        points2 = []
        i = numberOfSegments
        while i > 0:
            t = 2*i - 1
            pointA = [(H1[0] - A[0])*(t/(2*numberOfSegments)) + A[0], (H1[1] - A[1])*(t/(2*numberOfSegments)) + A[1], (H1[2] - A[2])*(t/(2*numberOfSegments)) + A[2]]
            pointB = [(E[0] - H2[0])*(t/(2*numberOfSegments)) + H2[0], (E[1] - H2[1])*(t/(2*numberOfSegments)) + H2[1], (E[2] - H2[2])*(t/(2*numberOfSegments)) + H2[2]]
            point = [(pointB[0] - pointA[0])*(t/(2*numberOfSegments)) + pointA[0], (pointB[1] - pointA[1])*(t/(2*numberOfSegments)) + pointA[1], (pointB[2] - pointA[2])*(t/(2*numberOfSegments)) + pointA[2]]
            points2.insert(0, point) # I am prepending, because I am advancing bacwards
            i -= 1
        newPoints = []
        i = 0
        while i < numberOfSegments: # join points and points2 using zipper
            newPoints.append(points[i])
            newPoints.append(points2[i])
            i += 1
        newPoints.append(points[numberOfSegments])
        newLength = 0
        i = numberOfSegments
        while i > 0:
            newLength += sizeOfVector(newPoints[2*i], newPoints[2*i - 1])
            newLength += sizeOfVector(newPoints[2*i - 1], newPoints[2*i - 2])
            i -= 1
        originalLength = 0
        i = int(numberOfSegments/2)
        while i > 0:
            originalLength += sizeOfVector(points[2*i], points[2*i - 1])
            originalLength += sizeOfVector(points[2*i - 1], points[2*i - 2])
            i -= 1
        if newLength - toleration < originalLength:
            return(round(newLength/toleration)*toleration)
        return(lengthOfCurve(newPoints, H1, H2, toleration))

def sizeOfVector(P, Q):
    return(sqrt((P[0] - Q[0])*(P[0] - Q[0]) + (P[1] - Q[1])*(P[1] - Q[1]) + (P[2] - Q[2])*(P[2] - Q[2])))

point1 = [0, 0, 0]
point2 = [1, 0, 0]
handle1 = [0, 1, 0]
handle2 = [1, 1, 0]
toleration = 0.01

print(lengthOfCurve([point1, point2], handle1, handle2, toleration))

```

EDIT: Ok, I got the t working as well, within toleration, as expected. It was far from simple approximation. Let me know if there is dire need for it in English. I did all of this in a single day and I feel a bit exhausted to translate the second chunk from Czech at the moment.

2nd day edit 2: Fixed precision inaccuracy, made as foolproof as possible, translated into EN

```
from math import sqrt
def lengthOfCurve(points, H1, H2, toleration):
    A = points[0]
    E = points[-1]
    if len(points) == 2: # round one
        Ba = [(H1[0] - A[0])*0.25 + A[0], (H1[1] - A[1])*0.25 + A[1], (H1[2] - A[2])*0.25 + A[2]]
        Bb = [(E[0] - H2[0])*0.25 + H2[0], (E[1] - H2[1])*0.25 + H2[1], (E[2] - H2[2])*0.25 + H2[2]]
        B = [(Bb[0] - Ba[0])*0.25 + Ba[0], (Bb[1] - Ba[1])*0.25 + Ba[1], (Bb[2] - Ba[2])*0.25 + Ba[2]]
        Ca = [(H1[0] - A[0])*0.5 + A[0], (H1[1] - A[1])*0.5 + A[1], (H1[2] - A[2])*0.5 + A[2]]
        Cb = [(E[0] - H2[0])*0.5 + H2[0], (E[1] - H2[1])*0.5 + H2[1], (E[2] - H2[2])*0.5 + H2[2]]
        C = [(Cb[0] - Ca[0])*0.5 + Ca[0], (Cb[1] - Ca[1])*0.5 + Ca[1], (Cb[2] - Ca[2])*0.5 + Ca[2]]
        Da = [(H1[0] - A[0])*0.75 + A[0], (H1[1] - A[1])*0.75 + A[1], (H1[2] - A[2])*0.75 + A[2]]
        Db = [(E[0] - H2[0])*0.75 + H2[0], (E[1] - H2[1])*0.75 + H2[1], (E[2] - H2[2])*0.75 + H2[2]]
        D = [(Db[0] - Da[0])*0.75 + Da[0], (Db[1] - Da[1])*0.75 + Da[1], (Db[2] - Da[2])*0.75 + Da[2]]
        points = [A, B, C, D, E]
        originalLength = lengthOfVector(A, E)
        newLength = lengthOfVector(A, B) + lengthOfVector(B, C) + lengthOfVector(C, D) + lengthOfVector(D, E)
        if newLength - toleration < originalLength:
            return(round(newLength/toleration)*toleration)
        return(lengthOfCurve(points, H1, H2, toleration))
    else: # following rounds
        numberOfSegments = len(points) - 1
        points2 = []
        i = numberOfSegments
        while i > 0:
            t = 2*i - 1
            pointA = [(H1[0] - A[0])*(t/(2*numberOfSegments)) + A[0], (H1[1] - A[1])*(t/(2*numberOfSegments)) + A[1], (H1[2] - A[2])*(t/(2*numberOfSegments)) + A[2]]
            pointB = [(E[0] - H2[0])*(t/(2*numberOfSegments)) + H2[0], (E[1] - H2[1])*(t/(2*numberOfSegments)) + H2[1], (E[2] - H2[2])*(t/(2*numberOfSegments)) + H2[2]]
            point = [(pointB[0] - pointA[0])*(t/(2*numberOfSegments)) + pointA[0], (pointB[1] - pointA[1])*(t/(2*numberOfSegments)) + pointA[1], (pointB[2] - pointA[2])*(t/(2*numberOfSegments)) + pointA[2]]
            points2.insert(0, point) # i am prepending because I advance back first
            i -= 1
        newPoints = []
        i = 0
        while i < numberOfSegments: # join points and points2 using zipper method
            newPoints.append(points[i])
            newPoints.append(points2[i])
            i += 1
        newPoints.append(points[numberOfSegments])
        newLength = 0
        i = numberOfSegments
        while i > 0:
            newLength += lengthOfVector(newPoints[2*i], newPoints[2*i - 1])
            newLength += lengthOfVector(newPoints[2*i - 1], newPoints[2*i - 2])
            i -= 1
        originalLength = 0
        i = int(numberOfSegments/2)
        while i > 0:
            originalLength += lengthOfVector(points[2*i], points[2*i - 1])
            originalLength += lengthOfVector(points[2*i - 1], points[2*i - 2])
            i -= 1
        if newLength - toleration < originalLength:
            return(round(newLength/toleration)*toleration)
        return(lengthOfCurve(newPoints, H1, H2, toleration))

def lengthOfVector(P, Q):
    return(sqrt((P[0] - Q[0])*(P[0] - Q[0]) + (P[1] - Q[1])*(P[1] - Q[1]) + (P[2] - Q[2])*(P[2] - Q[2])))

point1 = [0, 0, 0]
point2 = [1, 0, 0]
handle1 = [0, 1, 0]
handle2 = [1, 1, 0]
toleration = 0.01

print("length of curve = ", lengthOfCurve([point1, point2], handle1, handle2, toleration))

def findPoints(points, H1, H2, toleration, lengthOfCurv):
    A = points[0]
    E = points[-1]
    if len(points) == 2: # round one
        Ba = [(H1[0] - A[0])*0.25 + A[0], (H1[1] - A[1])*0.25 + A[1], (H1[2] - A[2])*0.25 + A[2]]
        Bb = [(E[0] - H2[0])*0.25 + H2[0], (E[1] - H2[1])*0.25 + H2[1], (E[2] - H2[2])*0.25 + H2[2]]
        B = [(Bb[0] - Ba[0])*0.25 + Ba[0], (Bb[1] - Ba[1])*0.25 + Ba[1], (Bb[2] - Ba[2])*0.25 + Ba[2]]
        Ca = [(H1[0] - A[0])*0.5 + A[0], (H1[1] - A[1])*0.5 + A[1], (H1[2] - A[2])*0.5 + A[2]]
        Cb = [(E[0] - H2[0])*0.5 + H2[0], (E[1] - H2[1])*0.5 + H2[1], (E[2] - H2[2])*0.5 + H2[2]]
        C = [(Cb[0] - Ca[0])*0.5 + Ca[0], (Cb[1] - Ca[1])*0.5 + Ca[1], (Cb[2] - Ca[2])*0.5 + Ca[2]]
        Da = [(H1[0] - A[0])*0.75 + A[0], (H1[1] - A[1])*0.75 + A[1], (H1[2] - A[2])*0.75 + A[2]]
        Db = [(E[0] - H2[0])*0.75 + H2[0], (E[1] - H2[1])*0.75 + H2[1], (E[2] - H2[2])*0.75 + H2[2]]
        D = [(Db[0] - Da[0])*0.75 + Da[0], (Db[1] - Da[1])*0.75 + Da[1], (Db[2] - Da[2])*0.75 + Da[2]]
        points = [A, B, C, D, E]
        longestSegment = lengthOfVector(A, B)
        lenBC = lengthOfVector(B, C)
        lenCD = lengthOfVector(C, D)
        lenDE = lengthOfVector(D, E)
        if lenBC > longestSegment:
            longestSegment = lenBC
        if lenCD > longestSegment:
            longestSegment = lenBC
        if lenDE > longestSegment:
            longestSegment = lenBC
        if longestSegment < toleration:
            return(points)
        return(findPoints(points, H1, H2, toleration, lengthOfCurv))
    else: # following rounds
        numberOfSegments = len(points) - 1
        points2 = []
        i = numberOfSegments
        while i > 0:
            t = 2*i - 1
            pointA = [(H1[0] - A[0])*(t/(2*numberOfSegments)) + A[0], (H1[1] - A[1])*(t/(2*numberOfSegments)) + A[1], (H1[2] - A[2])*(t/(2*numberOfSegments)) + A[2]]
            pointB = [(E[0] - H2[0])*(t/(2*numberOfSegments)) + H2[0], (E[1] - H2[1])*(t/(2*numberOfSegments)) + H2[1], (E[2] - H2[2])*(t/(2*numberOfSegments)) + H2[2]]
            point = [(pointB[0] - pointA[0])*(t/(2*numberOfSegments)) + pointA[0], (pointB[1] - pointA[1])*(t/(2*numberOfSegments)) + pointA[1], (pointB[2] - pointA[2])*(t/(2*numberOfSegments)) + pointA[2]]
            points2.insert(0, point) # i am prepending because I advance back first
            i -= 1
        newPoints = []
        i = 0
        while i < numberOfSegments: # join points and points2 using zipper method
            newPoints.append(points[i])
            newPoints.append(points2[i])
            i += 1
        newPoints.append(points[numberOfSegments])
        newLength = 0
        i = numberOfSegments
        while i > 0:
            newLength += lengthOfVector(newPoints[2*i], newPoints[2*i - 1])
            newLength += lengthOfVector(newPoints[2*i - 1], newPoints[2*i - 2])
            i -= 1
        originalLength = 0
        i = int(numberOfSegments/2)
        longestSegment = 0
        while i > 0:
            byHowMuch = lengthOfVector(points[2*i], points[2*i - 1])
            if byHowMuch > longestSegment:
                longestSegment = byHowMuch
            originalLength += byHowMuch
            byHowMuch = lengthOfVector(points[2*i - 1], points[2*i - 2])
            if byHowMuch > longestSegment:
                longestSegment = byHowMuch
            originalLength += byHowMuch
            i -= 1
        #print(longestSegment)
        if longestSegment < toleration:
            return(newPoints)
        return(findPoints(newPoints, H1, H2, toleration, lengthOfCurv))

def pointOnCurve(point1, point2, handle1, handle2, placement, toleration, lengthOfCurv):
    aggregateLength = lengthOfCurve([point1, point2], handle1, handle2, toleration)
    lengthOfUnfinishedCurve = aggregateLength*placement
    sequence = findPoints([point1, point2], handle1, handle2, toleration, lengthOfCurv)
    aggregateLength = 0
    for i, s in enumerate(sequence):
        aggregateLength += lengthOfVector([sequence[i][0], sequence[i][1], sequence[i][2]], [sequence[i + 1][0], sequence[i + 1][1], sequence[i + 1][2]])
        if aggregateLength >= lengthOfUnfinishedCurve:
            return([round(sequence[i + 1][0]/toleration)*toleration, round(sequence[i + 1][1]/toleration)*toleration, round(sequence[i + 1][2]/toleration)*toleration])

point1 = [0, 0, 0]
point2 = [1, 0, 0]
handle1 = [0, 1, 0]
handle2 = [1, 1, 0]
toleration = 0.01
placement = 0.3
lengthOfCurv = lengthOfCurve([point1, point2], handle1, handle2, toleration)
print("point on curve = ", pointOnCurve(point1, point2, handle1, handle2, placement, toleration, lengthOfCurv))

```

# Answer
> 2 votes
I found an excellent article explaining a possible solution to this problem with a code example written in javascript. It works by "nudging the t" value into the right direction.

> Instead, we can use the fact that the average leg length d\_avg for any dot distribution is nearly identical to the leg lengths that evenly-spaced dots would produce (this similarity increases as n increases). If we calculate the difference d\_err between the actual leg lengths d and the average leg length d\_avg, then the time parameter t corresponding to each point can be nudged to reduce this difference.

This question has already a lot of cool answers, but i found this solution to be worth noticing.

# Answer
> 1 votes
Thanks for your excellent page describing how you solved this problem. I did something somewhat different than you in one detail, as I was deeply memory constrained: I don't build an array, or have to search it for the right 'segment' with a binary search. This is because I always know I am moving from one end of my Bezier curve to another: Therefore, I simply remember the 'current' segment, and if I see that I am going to go out of bounds of that segment to compute my next position, I compute the next (or previous) segment (based on direction of travel.) This works quite well for my application. The only glitch I had to work out was that, in some curves, the size of the segments were so small that my next plot to point was - at rare times - more than one segment ahead of the current one, so instead of just going to the 'next' or 'previous' segment (based on direction), I had to compute segments forward (or back) until I found the one that my next point was 'in'.

Don't know if this quite makes sense, but this certainly helped me.

# Answer
> 1 votes
***The problem with the accepted solution***

As Bezier an *exponential* function, we expect different rates of advance in different areas of the curve.

Because Ivo's solution *linearly* interpolates between these initial *exponential* samples, inaccuracies will be heavily biased towards ends / middle of the (typically cubic) curve where those deltas are greatest; so unless the sample rate `N` is increased greatly as he suggests, errors are apparent, and at some level of zoom, will *always* be apparent for a given `N`, i.e. the bias is intrinsic for that algorithm. Not good for e.g. vector-based graphics where zoom may be unlimited.

***Countering bias through guided sampling***

An alternative solution is to linearly remap `distance` to `t` after countering the natural bias that the Bezier function produces.

Assuming this is what we ideally want:

```
curve length = 10

t      distance
0.2    2
0.4    4
0.6    6
0.8    8
1.0    10

```

but this is what we get from the Bezier position function:

```
t      distance
0.2    0.12
0.4    1.22
0.6    2.45
0.8    5.81
1.0    10.00

```

By looking at `N` samples taken, we can see where distance deltas are greatest, and resample ("split") midway between the two adjacent distances, increasing `N` by 1. For example, splitting at `t=0.9` (which is midway in the largest delta), we might get:

```
0.8    5.81
0.9    7.39
1.0    10.00

```

We repeat this process for the next largest distance interval until the maximum delta between any two distances in the entire set is below some `minDistanceDelta`, and more specifically, less than `epsilon` away from specific distances we want to map to steps of `t`; we can then linearly map our desired `t` steps to corresponding `distance`s. This produces a hashtable / map which you can cheaply access and whose values you can lerp between, at runtime, without bias.

As the set grows in `N`, the cost to repeat this increases, so ideally do this as a pre-process. Each time `N` increases, add the two new resultant intervals to an `intervals` collection while removing the old, single interval they replaced. This is the structure on which you work to find the next greatest interval to split into two. Keeping `intervals` sorted by distance keeps things easy, as you can just pop next work item off the end, and split etc.

We end up with something like what we ideally wanted:

```
epsilon: 0.01

t            distance
0.200417     2.00417
0.3998132    3.9998132
0.600703     6.00703
0.800001     8.00001
0.9995309    9.995309

```

Since we are taking guesses at every step, we will not get exact the exact distances `2`, `4` etc. we wanted, but through repeat iteration these get close enough to the desired distance values so you can map to your `t` steps with fair accuracy, eliminating bias due to near-equidistant sampling.

You can then retrieve e.g. `t=0.5`, as Ivo does in his answer, i.e. by interpolating between the two nearest values above (`3.9998132` and `6.00703`).

***Conclusion***

For most cases, Ivo's solution will work well, but for cases where bias must be avoided at all costs, be sure that your `distance`s are as evenly scattered as possible, and then linearly mapped to `t`.

Note that splitting could be done stochastically rather than splitting down the middle each time, for example we might have split that first example interval at `t=0.827` rather than at `t=0.9`.

# Answer
> 0 votes
That kind of modeling is strange, and can produce weird illogical results. Especially if the starting planets speed is really slow.

Model the ships with a thrust power.

When the ships are on their last orbit on the starting planet, accelerate with full thrust.

When the ship gets within a certain distance use reverse thrust to slow the ship down to the target planet's orbit speed.

**Edit: Do the entire simulation at once when a node is about to leave the orbit. either send all the data, or send just a few of movement vectors at intervals, and interpolate between them.**

# Answer
> 0 votes
If I understand it correctly, your problem is over-constrained.

I believe that you want the spaceship to travel along a specified path between orbits in some time *t*, and you also want it to accelerate from speed *s1* to speed *s2* in the same time *t*. Unfortunately, you can't (in general) find an acceleration that satisfies both of these constraints simultaneously.

You're going to have to relax your problem a bit to make it solvable.

# Answer
> 0 votes
I came across this answer because I'm looking to distribute points evenly along an svg path that uses a bezier curve.

Despite MDN saying it's deprecated, you can use the `path.getPointAtLength` to get the correct result. https://developer.mozilla.org/en-US/docs/Web/API/SVGPathElement/getPointAtLength

It currently works in Chrome/Safari/Firefox, and should work in IE/Edge as well but I didn't verify those 2.

# Answer
> 0 votes
This thread helped me with my solution. So I'll share the code:

```
   public static List<Vector3> BezierCurvePoints(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, int pointCount = 30)
    {
       var rawPoints = new List<Vector3>();

        length = 0.0f;
        Vector3 lastPoint = BezierPoint(0, p0, p1, p2, p3);

        rawPoints.Add(p0);
        for (int i = 1; i <= pointCount; i++)
        {
            var point = BezierPoint((float)i / (float)pointCount, p0, p1, p2, p3);
            length += Vector3.Distance(point, lastPoint);
            lastPoint = point;
            rawPoints.Add(point);
        }

        rawPoints.Add(p3);

        var adjustedPoints = new List<Vector3>();

        adjustedPoints.Add(p0);
        float segmentLength = length / (pointCount-1); // Because X points translates into X-1 segments
        float forNextAdjustedSegment = segmentLength;
        int rawIndex = 1;
        bool rawSegmentValid = false;
        float rawSegmentLength = 0;
        Vector3 rawPointA = Vector3.zero;
        Vector3 rawPointB = Vector3.zero;

        while (adjustedPoints.Count < pointCount-1)
        {
            if (!rawSegmentValid)
            {
                rawPointA = rawPoints[rawIndex - 1];
                rawPointB = rawPoints[rawIndex];
                rawSegmentLength = Vector3.Distance(rawPointA, rawPointB);
            }

            if (rawSegmentLength >= forNextAdjustedSegment)
            {
                adjustedPoints.Add(Vector3.Lerp(rawPointA, rawPointB, forNextAdjustedSegment / rawSegmentLength));
                forNextAdjustedSegment += segmentLength;
            } else
            {
                forNextAdjustedSegment -= rawSegmentLength;
                rawSegmentValid = false;
                rawIndex++;
                if (rawIndex >= rawPoints.Count)
                {
                    Debug.LogError("Outside of Raw Indexes. Breaking");
                    break;
                }
            }

        }

        adjustedPoints.Add(p3);

        return adjustedPoints;
    }

```

The `forNextAdjustedSegment` may be confusing. The idea is that we are slowly moving from point to point, but keep track of lengths.

To get a position:

```
   public Vector3 GetPoint(float portion, Vector3 start, Vector3 end)
    {
        float pointSection = Mathf.Clamp01(portion) * (points.Count-1);

        var from = points[Mathf.FloorToInt(pointSection)];
        var to = points[Mathf.CeilToInt(pointSection - float.Epsilon * 10)];

        return Vector3.Lerp(from, to, pointSection % 1);
    }

```

---
Tags: 2d, mathematics
---


# Question
Title: How to print out the properties and methods of a class in GDScript?
I want to print the properties and methods of a class into the console with GDScript. In Python, this can be done with the `print(dir(variable))` method.

Is there an analogous function in GDScript?

# Answer
> 6 votes
I made my own `dir` function and it works OK.

```
func dir(class_instance):
    var output = {}
    var methods = []
    for method in class_instance.get_method_list():
        methods.append(method.name)

    output["METHODS"] = methods

    var properties = []
    for prop in class_instance.get_property_list():
        if prop.type == 3:
            properties.append(prop.name)
    output["PROPERTIES"] = properties

    return output

```

---
Tags: godot, gdscript
---


# Question
Title: How can I compute which chunk a coordinate is in?
I am working on a video game. Everything (terrain, entities, particles) is stored in 100 by 100 chunks. Here is the array structure for the chunks:

```
public static final int chunkSize = 100;
public static Chunk [][][] chunks;

```

The world is 20,000 by 20,000.

Given a random coordinate (such as (-1244, 1353)), how can I quickly and efficiently determine what chunk the coordinate is in?

Once I know what chunk a coordinate is in, I can determine which chunks to load around a player.

# Answer
> 4 votes
If a chunk is `C` world units along an axis, you can convert a world unit `W` along that axis to a chunk index along that axis by `floor(W/C)` (or simply rely on integer division to drop the fractional part of the result).

Now, you have to be careful since you can't actually have "negative" indices into the chunk array, which is what you'd get if you have a negative world coordinate.

Thus, you will first want to offset your coordinate system so that there aren't any negative values. If your lowest value on your world axis is -10,000 for example, adding 10,000 to the input will appropriately translate the coordinate system. In general if your world is `WorldWidth` wide, evenly distributed around the origin, then you'd add `0.5 * WorldWidth`.

Overall you'd end up with something like this to get a chunk from a world position:

```
Chunk GetChunkForWorldPosition(Vector3 position) {
  float offset = WorldWidth * 0.5;
  int x = (int)Math.Floor((position.x + offset) / ChunkSizeX);
  int y = (int)Math.Floor((position.y + offset) / ChunkSizeY);
  int z = (int)Math.Floor((position.z + offset) / ChunkSizeZ);

  return chunks[x][y][z];
}

```

# Answer
> 1 votes
**You can use this simple calculation**:

```
int chunkX = playerX / chunkSize + coordinateOriginX;

```

**Where**:

`playerX` is the X-coordinate of the player.
`chunkSize` is the size of the chunk.
`coordinateOriginX` is the in-world horizontal origin of the coordinate system.

*The same can also be used for the Y-index, but you just have to replace the `playerX` value with the Y-coordinate of the player, and the `worldOriginX` with the vertical coordinate origin.*

**You can then** create a method which finds the chunk at a specified coordinate based on the above calculation, pretending that you have a class to hold the chunk data (In this example called `Level`. **Also, note that I use a two-dimensional array here, because I can't really understand the purpose of a three-dimensional array when using two-dimensional coordinates**):

```
public class Level {

    // The array of chunks
    private Chunk[][] chunks;
    // The chunk size, as you mentioned
    private int chunkSize = 100;

    // The world width
    private int worldWidth = 20000;
    // The world height
    private int worldHeight = 20000;

    // The in-world horizontal coordinate origin (the 0, 0 point)
    private int coordinateOriginX = 10000;
    // The in-world vertical coordinate origin (the 0, 0 point)
    private int coordinateOriginY = 10000;

    public Level() {
        // Create the chunk array
        chunks = new Chunk[(int)(worldWidth / chunkSize)][(int)(worldHeight / chunkSize)];
        // TODO POPULATE THE CHUNK ARRAY
    }

    public Chunk getChunkAt(int x, int y) {
        // If the horizontal coordinate is valid and in the world
        if(x >= coordinateOriginX - worldWidth && x <= worldWidth - coordinateOrigin) {
            // If the vertical coordinate is valid and in the world
            if(y >= coordinateOriginY - worldHeight && y <= worldHeight - coordinateOrigin) {
                // Determine the indexes to the chunk
                int xIndex = (int)(x / chunkSize) + coordinateOriginX;
                int yIndex = (int)(y / chunkSize) + coordinateOriginY;

                // Return the chunk at the indexes
                return chunks[x][y];
            }
        }
    }
}

```

This is a very easy-to-use system for getting the chunk at a specific coordinate. It is also very flexible, and easy to extend.

There is one thing I don't understand though, why do you use a three-dimensional array for the chunk array, when you just use a two-dimensional coordinate system for the coordinates?
Just tell me if/what purpose this is for, and I'll update my answer to work with it.

**Good luck!**

# Answer
> 1 votes
I just spent a while writing some code for my 2D game to do this that should work correctly with negative coordinates. I informally checked it against Minecraft's F3 debug menu's chunk offsets, as well as wrote a few simple unit tests that I've provided below.

If anyone knows of a way to simplify or optimize this algorithm, do please comment and let me know!

```
// Copyright 2022 by Dan Bechard
// Your choice of any the following licenses:
// - Public domain
// - Unlicense license
// - MIT

#include <cstdint>
#include <cmath>

#define CLAMP(x, min, max) (MAX((min), MIN((x), (max))))

// Returns chunk index for a given world coord along a single axis
const int16_t Tilemap::CalcChunk(float world) const
{
    float chunk = floorf(world / CHUNK_W / TILE_W);
    return (int16_t)chunk;
}

// Returns a chunk-relative tile index for a given world coord along a single axis
//
// NOTE(dlb): The 0th tile in a chunk is always the "negative most" tile,
// not the tile closest to zero. In 2D, with +x right and +y down, the 0th
// tile along the x and y axes would be the left-most or top-most tile in a
// chunk, respectively.
//
const int16_t Tilemap::CalcChunkTile(float world) const
{
    const float chunk = CalcChunk(world);
    const float chunkStart = chunk * CHUNK_W * TILE_W;
    const float chunkOffset = world - chunkStart;
    const float tile = CLAMP(floorf(chunkOffset / TILE_W), 0, CHUNK_W - 1);
    return (int16_t)tile;
}

// Returns the tile at a given world coordinate
const Tile *Tilemap::TileAtWorld(float x, float y) const
{
    const int chunkX = CalcChunk(x);
    const int chunkY = CalcChunk(y);
    const int tileX = CalcChunkTile(x);
    const int tileY = CalcChunkTile(y);
    assert(tileX >= 0);
    assert(tileY >= 0);
    assert(tileX < CHUNK_W);
    assert(tileY < CHUNK_W);

    // NOTE(dlb): I'm using an std::unordered_map to look up chunks by
    // their x,y offsets in the world. This allows negative chunk
    // offsets. The hash map returns an index into an std::vector which
    // acts as a pool of loaded chunks. This is particularly useful
    // for "infinite" worlds where you may want to generate chunks on
    // the fly, page chunks to disk on the server, or maintain an LRU
    // cache of nearby chunks on the client.
    //
    // NOTE(dlb): Chunk::Hash(x, y) simply packs the two 16-bit ints
    // into a single 32-bit int. You may want to choose a different hash.
    //
    auto iter = chunksIndex.find(Chunk::Hash(chunkX, chunkY));
    if (iter != chunksIndex.end()) {
        size_t chunkIdx = iter->second;
        assert(chunkIdx < chunks.size());
        const Chunk &chunk = chunks[chunkIdx];
        size_t tileIdx = tileY * CHUNK_W + tileX;
        assert(tileIdx < ARRAY_SIZE(chunk.tiles));
        return &chunk.tiles[tileY * CHUNK_W + tileX];
    }
    return 0;
}

```

If you have 16x16 tiles and 16x16 chunks:

`CalcChunk(1)`
`CalcChunkTile(1)`
will return Chunk 0, Tile 0

`CalcChunk(TILE_W)`
`CalcChunkTile(TILE_W)`
will return Chunk 0, Tile 1

`CalcChunk(CHUNK_W * TILE_W)`
`CalcChunkTile(CHUNK_W * TILE_W)`
will return Chunk 1, Tile 0

Negative coordinates are similar, but tile 0 is the "leftmost" tile in a chunk. So:

`CalcChunk(-1)`
`CalcChunkTile(-1)`
i.e. Chunk -1, Tile 15

`CalcChunk(-CHUNK_W * TILE_W)`
`CalcChunkTile(-CHUNK_W * TILE_W)`
i.e. Chunk -1, Tile 0

Some tests:

```
#define CHUNK_W 16
#define TILE_W 16

assert(CalcChunk(0) == 0);
assert(CalcChunk(1) == 0);
assert(CalcChunk(CHUNK_W * TILE_W - 1) == 0);
assert(CalcChunk(CHUNK_W * TILE_W) == 1);

assert(CalcChunk(-1) == -1);
assert(CalcChunk(-(CHUNK_W * TILE_W - 1)) == -1);
assert(CalcChunk(-(CHUNK_W * TILE_W)) == -1);
assert(CalcChunk(-(CHUNK_W * TILE_W + 1)) == -2);

assert(CalcChunkTile(0) == 0);
assert(CalcChunkTile(1) == 0);
assert(CalcChunkTile(TILE_W - 1) == 0);
assert(CalcChunkTile(TILE_W) == 1);

assert(CalcChunkTile(-1) == CHUNK_W - 1);
assert(CalcChunkTile(-(CHUNK_W * TILE_W - 1)) == 0);
assert(CalcChunkTile(-(CHUNK_W * TILE_W)) == 0);
assert(CalcChunkTile(-(CHUNK_W * TILE_W + 1)) == CHUNK_W - 1);

```

P.S. I know `assert` is C, not C++. Take the free code and leave me alone. :D

---
Tags: java, coordinates
---


title: Population growth equation

text:
# Question
Title: Population growth equation
I'm at the very early stages of designing a game in which the population increases / decreases according to other factors (eg. crop yield / food scarcity, industrialization, global warming?, wars, natural disasters / diseases, etc). I'm not a mathematician so I'm searching for equations that might help me incorporate some or all of the above factors.

The number of factors that affect the equation can be limited so as to make the equation easier.

Are other equations that might suit my needs better?

# Answer
> 2 votes
I would start with looking at the Lotke-Voltera equations (https://en.m.wikipedia.org/wiki/Lotka–Volterra\_equations). They can be easily adapted to multiple resources and you can always add fast changing terms for natural desasters and such.

Also make sure to look at https://en.wikipedia.org/wiki/World3. This is a model used for trying to predict the real population growth if the earth.

# Answer
> 0 votes
The simplest method of modeling population growth in a game is to multiply the current population a set amount per step. You can change the growth factor based on available resources and active constraints. The population also determines resource production and consumption per step.

You might also want to separate birth rate and death rate; the birth rate mostly remains static unless cultural changes come into play, while the death rate is more subject to things like diseases, war, etc.

Depending on the timescales involved and how accurate you need it to be, you might also want to track demographics; creating new people at age 0 and storing the population for each age as a separate value in an array. You can modify the birth, death, and resource production/consumption rates based on ages. Young adults are more likely to produce children and old people are more likely to die as they age; prior to modern medicine infant mortality was also much higher, you can account for this by lowering "effective" birth rates for pre-modern civilizations or increasing death among children.

Factoring in demographics will make your program significantly more complicated (and slow) so you might want to avoid this. A lot of games only really take working-age population into account and abstract the child/elderly population as a percentage of that.

---
Tags: game-design, game-mechanics, simulations
---


# Question
Title: Why the object is not rotating smooth slowly to fast and from fast to slowly to stop?
I'm trying to make that the object will start rotating slowly smooth increasing he rotation speed to some max speed then when reaching them ax speed to start slowly smooth decrease the speed back down until stop.

I'm trying to use SmoothStep but maybe I should use some how SmoothDamp ?

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Testings : MonoBehaviour
{
    public Transform text;

    float minimum = 10.0f;
    float maximum = 20.0f;

    float duration = 5.0f;

    float startTime;

    void Start()
    {
        startTime = Time.time;
    }

    void Update()
    {
        float t = (Time.time - startTime) / duration;
        text.rotation = new Quaternion(0, Mathf.SmoothStep(minimum, maximum, t), 0, 0);
    }
}

```

# Answer
You're using the wrong Quaternion method for what you're trying to do.

It looks like you're trying to smoothly damp an angle between a min and max measured in degrees.

The `new Quaternion` constructor does not take angles in degrees as its arguments. The first clue is that it asks for 4 parameters `(x, y, z, w)` not three Euler angles `(x, y, z)` / `(pitch, yaw, roll)` (what on Earth would a "w" angle rotate around?). These 4 parameters describe a point on a unit sphere in 4-dimensional space, so numbers like 20-40 make no sense here at all. And by leaving the w component at 0, you've ensured you can only get 0 or 180 degree rotations out of this expression.

What you want is `Quaternion.Euler`, which *does* accept angles in degrees:

> **Declaration**
> public static Quaternion Euler(float x, float y, float z);
>
> **Description<br>** Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis; applied in that order.

So your corrected code would read like this:

```
text.rotation = Quaternion.Euler(
                             0,
                             Mathf.SmoothStep(minimum, maximum, t),
                             0
                );

```

Also, note that when you compute your time this way:

```
float t = (Time.time - startTime) / duration;

```

...you will lose precision, the longer your game has been running. A better solution is to accumulate `t`, something like this:

```
// We can initialize this to a constant.
// Now we don't even need a Start method to populate it!
float t = 0;

void Update()
{
    // Add an increment to t,
    // proportionate to the high-precision time step since last frame.
    t += Time.deltaTime / duration;
    // ...etc.
}

```
> 1 votes

---
Tags: unity, c#
---


# Question
Title: Set the gravity scale to a certain value in a script
I'm using Unity Version 2020.3.18f1 and I'm making a hextris game (Tetris but each piece is 6 squares instead of 4). I'm trying to make the blocks fall using gravity, and I want to do this via code. I tried `rigidbody2D.GravityScale` but it didn't work. I got this error instead:

**'Component.rigidbody2D' is obsolete: 'Property rigidbody2D has been deprecated. Use GetComponent() instead. (UnityUpgradable)'**

I'm assuming that this means that the `rigidbody2D.GravityScale` is outdated. What can I use?

# Answer
> 0 votes
> I'm assuming that this means that the rigidbody2D.GravityScale is outdated

This is not a sound assumption. The error message does not mention `gravityScale` at all.

You can consult the docs to find that the property is still supported, and is spelled `gravityScale` with a lowercase "g".

Your problem is what the error message tells you:

> `Component.rigidbody2D` is obsolete: Property `rigidbody2D` has been deprecated. Use `GetComponent()` instead. (UnityUpgradable)'

You likely have code that looks something like this (we have to guess because you did not include a minimal complete verifiable example in your question):

```
public class MyClass : MonoBehaviour {

    void Update() {
        rigidbody2D.gravityScale = /* some expression */;
    }
}

```

Note that nowhere in that class did we define a member named `rigidbody2D` \- we're just assuming that one will already exist. That used to be the case in old versions of Unity, but not anymore, which is why the error message is telling you that referring to a `rigidbody2D` member that you have not defined is obsolete.

Instead, you should write something more like this:

```
public class MyClass : MonoBehaviour {

    // Declare a member variable to store the rigidbody.
    Rigidbody2D _body;

    void Start() {
        // Populate it with a valid rigidbody reference,
        // on start-up, or make it serialized and do it at edit time.
        _body = GetComponent<Rigidbody2D>();
    }

    void Update() {
        // Refer to the body variable you've actually declared.
        _body.gravityScale = /* some expression */;
    }
}

```

---
Tags: unity, c#
---


# Question
Title: Tilemap is rendering all tiles as black squares
I'm trying to render a 2D tile map. I've placed a `Tilemap` object in the scene from the create 2D object context menu, set a reference to it to one of my script objects, and tried to render. It's definitely placing tiles, (I can see it go from transparent to drawing something,) but instead of the tiles I'm giving it, it creates a pure black square in every cell.

My tiles are coming from a tileset image, comprised of a 16x16 grid of tiles of 64x64 pixels in size. The tile setup code is as follows:

```
public class GameLevelView : MonoBehaviour
{
    private Tilemap _grid;
    private Tile[] _tiles;
    public MapData Map { get; set; } //supplied in code by an external source

    void Start()
    {
        _grid = GetComponent<Tilemap>();
        _tiles = Resources.LoadAll<Sprite>("tiles").Select(s => new Tile { sprite = s }).ToArray();
    }

    void Update()
    {
        Map.PaintTo(_grid, _tiles);
    }
}

```

The `PaintTo` routine simply loops over every cell, gets a tile index, and calls `tilemap.SetTile(new Vector3Int(x, y, 0), tiles[idx]);`. This seems simple enough that nothing could go wrong... and yet all the tiles are rendering black.

In case it's relevant, using Unity 2020.3.26f1 with the 2D URP. Things I've already verified:

* The tileset image has been imported as a sprite sheet correctly.
* The tile array loading code is working as expected.
* The tiles produced by the tile array have their values set up as expected. For example, their Color property is `(1,1,1,1)` rather than somehow being black.
* The GameObject holding the tile map is active in the scene and positioned correctly on the camera.
* MapData is being set up correctly.

At this point I have no idea what else to look at to try and make this work. Has anyone seen this before and might know how to fix this?

# Answer
> 1 votes
Found the problem. For whatever reason, Unity was creating the `Tilemap` with a Lit material by default, and I didn't have any 2D lights in my scene. I can't help but wonder when this changed; I've done tilemap-based stuff before and never had to care about lighting.

---
Tags: unity, 2d, tilemap
---


# Question
Title: How do I view the test going on in Unity Playmode?
I'm working on a new project using TDD, and I'm doing a good job of checking everything from the ground up including checking physics interactions on instantiated prefab, but I've gotten about to the point I can get without actually seeing what's going on.

I've loaded the scene. I've instantiated a prefab. I've even instantiated a camera and called `.Render()` on it. How do I actually view my tests as they unfold?

# Answer
Look in the Game window. It should be next to Scene. If you want to look at the values too, you can view them through the Inspector.
> 0 votes

---
Tags: unity, camera, scene, testing
---


# Question
Title: Why am I disconnecting from Photon Chat immediately after Connecting?
Hi I am experiencing a rather weird problem wherein which I am disconnecting from Photon Chat immediately after I am connecting to it. Here is the code I am using for Photon Chat.

```
using ExitGames.Client.Photon;
using Photon.Chat;
using Photon.Chat.Demo;
using Photon.Pun;
using System;
using UnityEngine;
using UnityEngine.UI;

public class PhotonChatController : MonoBehaviour, IChatClientListener
{
    [SerializeField] private string nickname;
    [SerializeField] private Text Status;
    private ChatClient chatclient;

    private void Awake()
    {
        nickname = PlayerPrefs.GetString("USERNAME");
        FriendBoxManager.SendInviteEvent += SendInvite;
    }
    void Start()
    {
        chatclient = new ChatClient(this);
        ConnectToPhotonChat();
    }
    private void OnDestroy()
    {
        FriendBoxManager.SendInviteEvent -= SendInvite;
    }

    private void SendInvite(string recepientFriend)
    {
        chatclient.SendPrivateMessage(recepientFriend, "INVITE");
    }

    private void ConnectToPhotonChat()
    {
        Debug.Log("Connect to Photon Chat");
        chatclient.AuthValues = new Photon.Chat.AuthenticationValues(nickname);
        ChatAppSettings chatSettings = PhotonNetwork.PhotonServerSettings.AppSettings.GetChatSettings();
        chatclient.ConnectUsingSettings(chatSettings);
    }

    void Update()
    {
        chatclient.Service();//in the update so that I constantly is connected and receiving messages
    }

    public void SendDirectMessage(string recepient, string message)
    {
        chatclient.SendPrivateMessage(recepient, message);
    }

    public void DebugReturn(DebugLevel level, string message)
    {

    }

    public void OnDisconnected()
    {
        Debug.Log("You have disconnected from the Photon Chat........");
    }

    public void OnConnected()
    {
        Debug.Log("You have connected to the Photon Chat.......");
       // SendDirectMessage("chethan123", "Hi Chethan 123");
    }

    public void OnChatStateChange(ChatState state)
    {

    }

    public void OnGetMessages(string channelName, string[] senders, object[] messages)
    {
    }

    public void OnPrivateMessage(string sender, object message, string channelName)//callback when somebody sends another player a private message
    {
        if (!string.IsNullOrEmpty(message.ToString()))
        {
            //channel name is the format [sender : recepient]
            string[] splitnames = channelName.Split(new char[] { ':' });//here you are seperatign the sender and receiver names
            string senderName = splitnames[0];
            if (!sender.Equals(senderName, StringComparison.OrdinalIgnoreCase))
            {
                Debug.Log($"{sender}:{message}");
                Status.text=$"{sender}:{message}";
            }
        }
    }

    public void OnSubscribed(string[] channels, bool[] results)
    {
    }

    public void OnUnsubscribed(string[] channels)
    {
    }

    public void OnStatusUpdate(string user, int status, bool gotMessage, object message)
    {
    }

    public void OnUserSubscribed(string channel, string user)
    {
    }

    public void OnUserUnsubscribed(string channel, string user)
    {
    }
}

```

Also I am connecting to PUN in another game object using the following code:

```
public class PhotonConnector : MonoBehaviourPunCallbacks

{

  public static Action GetPhotonFriends = delegate { };

  private string Username;

  //public Text MyName;

  public Text StatusText;

  private PhotonView PV;

  private int maxPlayers;

  [SerializeField] private GameObject MessageWindow;

  [SerializeField] private float faderTimeforWindow = 0.3f;//see inspector for final values

  //username and room name is dynamic in future

  void Start()

  {

    Username = PlayerPrefs.GetString("USERNAME");

    // MyName.text = Username;

    ConnectToPhoton(Username);

    maxPlayers = 2;

    PV = GetComponent<PhotonView>();

  }

  private void ConnectToPhoton(string nickName)//username and nickname is the same.,photon uses nickname terminolgy

  {

    Debug.Log($"Connected to Photon as {nickName}");

    Status("Connecting to \n server.....");//message display on the matchMaking Screen

    PhotonNetwork.AuthValues = new AuthenticationValues(nickName);//just does a basic authetication as such

    PhotonNetwork.AutomaticallySyncScene = true;

    PhotonNetwork.NickName = nickName;

    PhotonNetwork.ConnectUsingSettings();

  }

  private void CreatePhotonRoom(string RoomName)

  {

    RoomOptions roomOptions = new RoomOptions();

    roomOptions.IsOpen = true;//room is open for others to join

    roomOptions.IsVisible = true;

    roomOptions.MaxPlayers = (byte)maxPlayers;

    PhotonNetwork.CreateRoom(RoomName, roomOptions, TypedLobby.Default);

  }

 public override void OnConnectedToMaster()//checking whether u r connected to master photon server

  {

    base.OnConnectedToMaster();

    Debug.Log("You have connected to photon Master server");

    Status("Connected to \nServer!");

    if (!PhotonNetwork.InLobby)//if after connected to server if ur not in lobby ,connect to lobby

    {

      PhotonNetwork.JoinLobby();

    }

  }

  public override void OnJoinedLobby()//to verify whether u have joined a lobby

  {

    base.OnJoinedLobby();

    Debug.Log("You have connected to photon Lobby");

    Status(" ");

    // GetPhotonFriends?.Invoke();

  }

  public override void OnCreatedRoom()//called when the first person has joined the room or created it

  {

    base.OnCreatedRoom();

    Debug.Log($"You have created a Photon Room Named {PhotonNetwork.CurrentRoom.Name}");

  }

  public override void OnJoinedRoom()

  {

    base.OnJoinedRoom();

    Debug.Log($"You have Joined a Photon Room Named {PhotonNetwork.CurrentRoom.Name}");

  }

  public override void OnLeftRoom()//when current player left the room

  {

    base.OnLeftRoom();

    Debug.Log("You have left a photon room");

  }

  public override void OnJoinRoomFailed(short returnCode, string message)

  {

    base.OnJoinRoomFailed(returnCode, message);

    Debug.Log($"You failed to join a Photon Room : {message}");

  }

  public override void OnJoinRandomFailed(short returnCode, string message)

  {

    base.OnJoinRandomFailed(returnCode, message);

    Debug.Log($"You failed to join a random Photon Room : {message}");

  }

  public override void OnPlayerEnteredRoom(Player newPlayer)//when another player enters the room

  {

    base.OnPlayerEnteredRoom(newPlayer);

    Debug.Log($"Another player has joined the room->{newPlayer.UserId} and nick name->{newPlayer.NickName}");

  }

  public override void OnPlayerLeftRoom(Player otherPlayer)//when other player leaves the current room ur in

  {

    base.OnPlayerLeftRoom(otherPlayer);

    Debug.Log($"Player has left the room->: {otherPlayer.UserId} and nick name -> {otherPlayer.NickName}");

  }

  public override void OnMasterClientSwitched(Player newMasterClient)//called when the master client in the room leaves

  {

    base.OnMasterClientSwitched(newMasterClient);

    PhotonNetwork.Disconnect();//so that unwanted stuff doesnt happen

    Debug.Log($"New master client is {newMasterClient.NickName}");

  }

  public override void OnDisconnected(DisconnectCause cause)

  {

    base.OnDisconnected(cause);

    Status("Disconnected from \nserver");

  }

```

Also this is what I am getting the error as in the console.I have attached a screenshot for the same

Can we be connected to Photon Pun and Photon Chat at the same time?

# Answer
So the mistake I was doing was connecting to Photon Chat Server with "in" (India) in the server location. Actually for PUN "in" will be alright but for Photon Chat "asia" is the server location to be used(best suited for me)

I got the answer here, hope it helps someone as well

> "There is no IN region for Photon Chat."
>
> https://doc.photonengine.com/en-us/chat/current/connection-and-authentication/regions#available\_regions
> 2 votes

---
Tags: multiplayer, photon
---


# Question
Title: Unity Shaders: Why is it recommended to use Time to animate things inside of a shader instead of DeltaTime?
In the "Built-in shader variables" section of the Unity Manual, underneath the Time header, there is a table that provides information about each time variable: \_Time; \_SinTime; \_CosTime; unity\_DeltaTime. It states to use \_Time to animate things inside of a shader. Why is it recommended to use time instead of delta time, like it's recommended to be used in C# scripts for animating?

Unity Manual/Built-in shader variables/Time

# Answer
> 2 votes
In MonoBehaviours, deltaTime is usually used to advance the internal state of the gameObject from the state of the last frame to the state of the new frame.

But shaders are stateless functions. They are not based on their last frame. Each frame is calculated from scratch based on the input parameters. That makes deltaTime not very useful in shaders. It will be roughly the same each frame, so what do you intend to do with it?

The absolute time, on the other hand, will be different each frame, which makes it far more useful for animations in shaders. A common technique to get cyclic animations is to calculate the modulus of \_Time or to run the current time through a cyclic function like sine or cosine (which is why Unity provides shortcuts for the latter in form of \_SinTime and \_CosTime).

---
Tags: unity, unity-shader-graph
---


title: How to use lerp to change position?

text:
# Question
Title: How to use lerp to change position?
At the top I have a float duration and float t. Also at the top a Rect rectangleReference.

Then in the OnGUI I'm making first a reference to drawn rect

```
rectangleReference = rect;

```

and myCube is a reference so simple 3d cube.

Then doing the Lerp position change

```
DrawScreenRectBorder(rectangleReference, 2, Color.cyan);
var cubeworld = WorldToGuiPoint(myCube.position);
t += Time.deltaTime / duration;
rectangleReference.center = Vector3.Lerp(rectangleReference.center, cubeworld, t);

```

Doing this way the rectangleReference is moving to the cubeworld but at once not smooth slowly as lerp should be working the duration this way have no affect.

Before that I tried it this way

```
rectangleReference.center = Vector3.Lerp(rectangleReference.position, cubeworld, t);

```

This way the lerp is working but the is start moving from another position and nto from where the drawn rect is.

The method WorldToGuiPoint

```
public Vector3 WorldToGuiPoint(Vector3 position)
    {
        var guiPosition = Camera.main.WorldToScreenPoint(position);
        guiPosition.y = Screen.height - guiPosition.y;

        return guiPosition;
    }

```

The complete script

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SC_SelectionManager : MonoBehaviour
{
    public Transform myCube;
    public Texture topLeftBorder;
    public Texture bottomLeftBorder;
    public Texture topRightBorder;
    public Texture bottomRightBorder;
    public float duration;

    private Rect rectangleReference;
    private float t = 0;

    Texture2D _borderTexture;
    Texture2D borderTexture
    {
        get
        {
            if (_borderTexture == null)
            {
                _borderTexture = new Texture2D(1, 1);
                _borderTexture.SetPixel(0, 0, Color.white);
                _borderTexture.Apply();
            }

            return _borderTexture;
        }
    }

    bool selectionStarted = false;
    Vector3 mousePosition1;

    public static List<SC_Selectable> selectables = new List<SC_Selectable>();
    List<int> selectedObjects = new List<int>();

    // Update is called once per frame
    void Update()
    {
        // Begin selection
        if (Input.GetMouseButtonDown(0))
        {
            selectionStarted = true;
            mousePosition1 = Input.mousePosition;
        }
        // End selection
        if (Input.GetMouseButtonUp(0))
        {
            selectionStarted = false;
        }

        if (selectionStarted)
        {
            // Detect which Objects are inside selection rectangle
            Camera camera = Camera.main;
            selectedObjects.Clear();
            for (int i = 0; i < selectables.Count; i++)
            {
                Bounds viewportBounds = GetViewportBounds(camera, mousePosition1, Input.mousePosition);
                if (viewportBounds.Contains(camera.WorldToViewportPoint(selectables[i].transform.position)))
                {
                    selectedObjects.Add(i);
                }
            }
        }
    }

    void OnGUI()
    {
        if (selectionStarted)
        {
            Rect rect = GetScreenRect(mousePosition1, Input.mousePosition);
            DrawScreenRectBorder(rect, 2, Color.cyan);

            rectangleReference = rect;
        }
        else
        {
            DrawScreenRectBorder(rectangleReference, 2, Color.cyan);
            var cubeworld = WorldToGuiPoint(myCube.position);
            t += Time.deltaTime / duration;
            rectangleReference.center = Vector3.Lerp(rectangleReference.center, cubeworld, t);
            //rectangleReference.center = cubeworld;
        }

        // Draw selection edges
        if (selectedObjects.Count > 0)
        {
            Camera camera = Camera.main;
            for (int i = 0; i < selectedObjects.Count; i++)
            {
                DrawSelectionIndicator(camera, selectables[selectedObjects[i]].GetObjectBounds());
            }
        }
    }

    public Vector3 WorldToGuiPoint(Vector3 position)
    {
        var guiPosition = Camera.main.WorldToScreenPoint(position);
        guiPosition.y = Screen.height - guiPosition.y;

        return guiPosition;
    }

    void DrawScreenRectBorder(Rect rect, float thickness, Color color)
    {
        // Top
        DrawBorderRect(new Rect(rect.xMin, rect.yMin, rect.width, thickness), color);
        // Left
        DrawBorderRect(new Rect(rect.xMin, rect.yMin, thickness, rect.height), color);
        // Right
        DrawBorderRect(new Rect(rect.xMax - thickness, rect.yMin, thickness, rect.height), color);
        // Bottom
        DrawBorderRect(new Rect(rect.xMin, rect.yMax - thickness, rect.width, thickness), color);
    }

    void DrawBorderRect(Rect rect, Color color)
    {
        GUI.color = color;
        GUI.DrawTexture(rect, borderTexture);
        GUI.color = Color.white;
    }

    Rect GetScreenRect(Vector3 screenPosition1, Vector3 screenPosition2)
    {
        // Move origin from bottom left to top left
        screenPosition1.y = Screen.height - screenPosition1.y;
        screenPosition2.y = Screen.height - screenPosition2.y;
        // Calculate corners
        var topLeft = Vector3.Min(screenPosition1, screenPosition2);
        var bottomRight = Vector3.Max(screenPosition1, screenPosition2);
        // Create Rect
        return Rect.MinMaxRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y);
    }

    Bounds GetViewportBounds(Camera camera, Vector3 screenPosition1, Vector3 screenPosition2)
    {
        Vector3 v1 = camera.ScreenToViewportPoint(screenPosition1);
        Vector3 v2 = camera.ScreenToViewportPoint(screenPosition2);
        Vector3 min = Vector3.Min(v1, v2);
        Vector3 max = Vector3.Max(v1, v2);
        min.z = camera.nearClipPlane;
        max.z = camera.farClipPlane;

        Bounds bounds = new Bounds();
        bounds.SetMinMax(min, max);
        return bounds;
    }

    void DrawSelectionIndicator(Camera camera, Bounds bounds)
    {
        Vector3 boundPoint1 = bounds.min;
        Vector3 boundPoint2 = bounds.max;
        Vector3 boundPoint3 = new Vector3(boundPoint1.x, boundPoint1.y, boundPoint2.z);
        Vector3 boundPoint4 = new Vector3(boundPoint1.x, boundPoint2.y, boundPoint1.z);
        Vector3 boundPoint5 = new Vector3(boundPoint2.x, boundPoint1.y, boundPoint1.z);
        Vector3 boundPoint6 = new Vector3(boundPoint1.x, boundPoint2.y, boundPoint2.z);
        Vector3 boundPoint7 = new Vector3(boundPoint2.x, boundPoint1.y, boundPoint2.z);
        Vector3 boundPoint8 = new Vector3(boundPoint2.x, boundPoint2.y, boundPoint1.z);

        Vector2[] screenPoints = new Vector2[8];
        screenPoints[0] = camera.WorldToScreenPoint(boundPoint1);
        screenPoints[1] = camera.WorldToScreenPoint(boundPoint2);
        screenPoints[2] = camera.WorldToScreenPoint(boundPoint3);
        screenPoints[3] = camera.WorldToScreenPoint(boundPoint4);
        screenPoints[4] = camera.WorldToScreenPoint(boundPoint5);
        screenPoints[5] = camera.WorldToScreenPoint(boundPoint6);
        screenPoints[6] = camera.WorldToScreenPoint(boundPoint7);
        screenPoints[7] = camera.WorldToScreenPoint(boundPoint8);

        Vector2 topLeftPosition = Vector2.zero;
        Vector2 topRightPosition = Vector2.zero;
        Vector2 bottomLeftPosition = Vector2.zero;
        Vector2 bottomRightPosition = Vector2.zero;

        for (int a = 0; a < screenPoints.Length; a++)
        {
            //Top Left
            if (topLeftPosition.x == 0 || topLeftPosition.x > screenPoints[a].x)
            {
                topLeftPosition.x = screenPoints[a].x;
            }
            if (topLeftPosition.y == 0 || topLeftPosition.y > Screen.height - screenPoints[a].y)
            {
                topLeftPosition.y = Screen.height - screenPoints[a].y;
            }
            //Top Right
            if (topRightPosition.x == 0 || topRightPosition.x < screenPoints[a].x)
            {
                topRightPosition.x = screenPoints[a].x;
            }
            if (topRightPosition.y == 0 || topRightPosition.y > Screen.height - screenPoints[a].y)
            {
                topRightPosition.y = Screen.height - screenPoints[a].y;
            }
            //Bottom Left
            if (bottomLeftPosition.x == 0 || bottomLeftPosition.x > screenPoints[a].x)
            {
                bottomLeftPosition.x = screenPoints[a].x;
            }
            if (bottomLeftPosition.y == 0 || bottomLeftPosition.y < Screen.height - screenPoints[a].y)
            {
                bottomLeftPosition.y = Screen.height - screenPoints[a].y;
            }
            //Bottom Right
            if (bottomRightPosition.x == 0 || bottomRightPosition.x < screenPoints[a].x)
            {
                bottomRightPosition.x = screenPoints[a].x;
            }
            if (bottomRightPosition.y == 0 || bottomRightPosition.y < Screen.height - screenPoints[a].y)
            {
                bottomRightPosition.y = Screen.height - screenPoints[a].y;
            }
        }

        if (topLeftBorder != null && topRightBorder != null &&
            bottomLeftBorder != null && bottomRightBorder != null)
        {
            /*GUI.DrawTexture(new Rect(topLeftPosition.x - 16, topLeftPosition.y - 16, 16, 16), topLeftBorder);
            GUI.DrawTexture(new Rect(topRightPosition.x, topRightPosition.y - 16, 16, 16), topRightBorder);
            GUI.DrawTexture(new Rect(bottomLeftPosition.x - 16, bottomLeftPosition.y, 16, 16), bottomLeftBorder);
            GUI.DrawTexture(new Rect(bottomRightPosition.x, bottomRightPosition.y, 16, 16), bottomRightBorder);
            */
        }
    }
}

```

# Answer
This line of code in your `OnGUI`:

`rectangleReference.center = Vector3.Lerp(rectangleReference.center, cubeworld, t);`

sets the `rectangleReference.center` each time it is executed, which is used as the new starting point for `Lerp` next time it is called, which makes the movement incorrect.

To fix this problem, simply remember the starting `rectangleReference.center` position when you begin the movement. For example, add a private variable:

`private Vector3 rectangleStartPosition = Vector3.zero;`

Then, modify this if statement in your `Update` from this:

```
// End selection
if (Input.GetMouseButtonUp(0))
{
    selectionStarted = false;
}

```

To this:

```
// End selection
if (Input.GetMouseButtonUp(0))
{
    selectionStarted = false;
    rectangleStartPosition = rectangleReference.center; // Remember the current position. Do that elsewhere if you need to start the movement from a different position.
    t = 0; // I assume that you want to reset the movement when you release the mouse
}

```

Finally, in the `OnGUI` method, change the line of code with the lerp to:

```
rectangleReference.center = Vector3.Lerp(rectangleStartPosition, cubeworld, t);

```

Also, `rectangleReference.center` and `rectangleReference.position` are different, with `rectangleReference.center` defining the center of the rectangle, and `rectangleReference.position` defining its top left corner.
> 1 votes

---
Tags: unity, c#
---


# Question
Title: Transfer player's data from scene to scene
so I have a little project where I have 3 scenes - gameplay one with player and it's script, main menu with 2 buttons "Play" and "Shop" and shop scene with 2 buttons "Buy HP" and "Buy Speed". So I want to have an opportunity to change some stats on player from shop scene. I used PlayerPrefs for this and setted values in Start method of player's script.

```
[SerializeField] private int maxHP = 1;
[SerializeField] private int hp = 0;
[SerializeField] private float attackTimer = 2f;

void Start()
    {
        if(maxHP == 1) {
            PlayerPrefs.SetInt("maxHP", maxHP);
        }
        else {
            if(PlayerPrefs.GetInt("maxHP") != null) {
                maxHP = PlayerPrefs.GetInt("maxHP");
            }
        }
        PlayerPrefs.SetFloat("attackCD", attackTimer);
        rb = GetComponent<Rigidbody2D>();
        currentAttackTimer = attackTimer;
        hp = maxHP;
    }

```

so player's Start() method looks like this. Cause attackTimer is changing in the same way, I will put only maxHP as an example:

```
public void BuyHP() {
        if(PlayerPrefs.GetInt("maxHP") < 5) {
            int tmpHP = PlayerPrefs.GetInt("maxHP");
            tmpHP++;
            PlayerPrefs.SetInt("maxHP", tmpHP);
            hpText.text = PlayerPrefs.GetInt("maxHP").ToString() + "/5";
        }
    }

```

this script is on button, it works to change value up to 5 times and rewrite it in "maxHP" key, but at the start of a gameplay scene I have maxHP = 1 anyway. Can somebody help me out and explain, mby I don't really know how PlayerPrefs works? Thx in advance

# Answer
I used static class to transfer data, thx @DMGregory for the link - https://gamedev.stackexchange.com/search?q=%5Bunity%5D+between+scenes
> 0 votes

---
Tags: unity, c#
---


# Question
Title: Alternative to redrawing the background canvas for camera movements?
I have multiple canvases placed on top of each other for different layers (background, game objects, foreground). I was expecting this to allow me to have the background and foreground update at a lower frame rate, because they use either simple animations or static images. But currently, I can't really do that, because all layers still adjust to the player camera (the game camera centers to the movable player). In other words, I still have to redraw the foreground and background in 60fps to smoothly adjust to the camera movement, which seems excessive, since nothing on the canvas is changing that fast.

Is there a less expensive way to move a whole canvas (or everything on the canvas) compared to constantly redrawing the whole context with new offsets? This is for situations where everything on the canvas stays the same. And in case there's no better alternative, is using `putImageData()` for the whole canvas and moving it going to be more efficient than redrawing each image with new offsets?

# Answer
You could make semitransparent canvases larger than the page viewport size, draw the entire canvas area, then move the canvases for camera/parallax using CSS transforms.

You would still have to redraw a canvas whenever the real visible area reaches the edge of the larger already-drawn area, if your world is not finite (and even if it is, drawing the entire area might be too expensive or take too much memory to store all the pixels).

---

Note: That recommendation is based on your canvas being a 2D canvas, (which I assume since you mentioned using `putImageData()`). If instead you were using a WebGL canvas, then the best option would be to just redraw every frame, possibly putting predrawn layers into WebGL *textures.* In that case, you're having the GPU do all the work, which is the *same* work that CSS transforms and multiple canvases would tell the browser's compositor to tell the GPU to do.
> 0 votes

---
Tags: javascript, optimization, html-canvas
---


# Question
Title: How can I add an animation to tile swapping on a tilemap?
I am beginner in Unity and I have created tilemap using new tilemap system in unity which looks like this:

I created a script that lets me swap tiles. First I click on some tile and than I choose second tile, after I click second time, tiles swap their positions. Which will than look like this:

How can I apply some animation to this process? Seems like I have no control over tile object as it is. I can only access TileBase which as I understand is not all information about tile. I can't create any animator controller or access its transform object. I want to add some custom animation when tiles swap their places. Thank you!

# Answer
> 0 votes
The Tilemap with the TilemapRender can only handle tiles at integer tile coordinates. That means that when you want to animate tiles moving across the tilemap in a fluid manner instead of step-by-step, then you have to find a different solution to render them during that movement.

So what you need to do is:

1. Create two new game objects with sprite renderers at the locations of the tiles you want to swap
2. Assign the sprites of those tiles to those sprite renderers (`tilemap.GetSprite(position)`)
3. remove both tiles from the tilemap (`tilemap.SetTile(position, null);`)
4. Animate the swap with the two game objects to their respective new positions
5. Add the tiles back to the tilemap at their new coordinates
6. Destroy the two game objects

Oh, and don't forget to handle the edge-case of the player (or something else) interacting with tiles which are currently empty because they are in the process of being replaced. But that's a subject for a different question.

# Answer
> -1 votes
You can possibly achieve tile animation by using unity's "AnimatedTile" Script which comes with the 2d-Extra repo. This video from unity discusses how to use the AnimatedTile Script. I hope it helps.

> https://github.com/Unity-Technologies/2d-extras/tree/4eff73f468142907629f09b4a88bceb2f0148dc5/Runtime/Tiles/AnimatedTile

---
Tags: unity, 2d, animation, tilemap, tiles
---


# Question
Title: How can I shrink a CheckButton's icon sizes in Godot?
## Background

I am making a `CheckButton` for toggling sound in my game. I have created an on and off icon for this purpose. I have two other `Button`s in a `VBoxContainer` with this `CheckButton`, whose icons are the same size as the icons for my `CheckButton`.

For the regular `Button`s, I was able to check the "Expand Icon" option to make the icons shrink to fit the size of the button.

## Problem

However, the same does not appear to work for the `CheckButton`. For that, I had to override the "icons" in the theme overrides. As far as I can tell, the "Expand Icon" option does not affect these icons.

This results in the following undesirable behavior. All of these icons' backing files are the same size, but only the `CheckButton` (the speaker button at the top) is not shrinking.

I could easily make the icons just smaller, but that feels like a cop-out. Am I missing a setting somewhere?

# Answer
You are not missing any setting. The icons of the `CheckButton` are not meant to scale with the button. They are meant to have a consistent size for all buttons.

*I'm not a fan of not idempotent buttons, and I'd push against anything that can lead to an confusion between state and action, however…*

For what you want, I'd suggest to use `Button`s and have code to change the `icon`.

*By the way, are you not making these icons huge to begin with? You say cop-out, I say optimization.*
> 0 votes

---
Tags: godot
---


title: How to spawn card sprite

text:
# Question
Title: How to spawn card sprite
I have a card sprite that I would like to spawn at a specific transform position but can't get anything to appear

My Code -

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardSpawn : MonoBehaviour
{

    public Transform spawnPoints;
    private int spawnIndex = 0;
    public Sprite cardsToSpawn;

    void Start()
    {
        Spawncard();
    }

    public void Spawncard()
    {
        Instantiate(cardsToSpawn, spawnPoints.transform.position, Quaternion.identity);
    }
}

```

ideally I would like to have a list of spawn positions and then a list of sprites that would spawn at those positions.

# Answer
> 0 votes
`Sprite` is just a representation of the image to be displayed. To spawn it as an object in your scene, you need a `GameObject` with a `SpriteRenderer` or UI `Image` component attached, which then references that `Sprite` and handles getting it drawn to the screen at that location.

You can set up a `GameObject` in your scene that looks the way you want your card to look, then drag that object from your Scene Hierarchy tab into one of your Project tab's Asset folders to save it as a "prefab". Then you can spawn instances of that prefab and override their sprite if needed, like this:

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardSpawn : MonoBehaviour
{
    // Don't pluralize variables that refer to a single item.
    public Transform spawnPoint;

    // Assign this prefab reference in the inspector.
    // Here I'm assuming you want a SpriteRenderer, not a UI Image.
    public SpriteRenderer cardPrefab;

    public Sprite cardSprite;

    void Start()
    {
        Spawncard();
    }

    public void Spawncard()
    {
        // Spawn a copy of the card prefab at your desired location/orientation.
        SpriteRenderer instance = Instantiate(
                                    cardPrefab,
                                    spawnPoint.transform.position,
                                    Quaternion.identity
                                  );

        // Set the sprite on the card to the one you want to display.
        // Note that this means you can re-use the same card prefab
        // for many different sprites.
        instance.sprite = cardSprite;
    }
}

```

---
Tags: unity, 2d
---


# Question
Title: Best practice for detecting enemy death in 3D platformer
I'm building a 3D platformer, and I'm having issues figuring out how I should determine whether the player has effectively jumped on an enemy to kill them.

My current approach uses "hurtboxes" above the enemies like so:

And if the player has a negative velocity and isn't grounded while they collide with that hurtbox, it will kill the enemy. This works pretty well, but isn't ideal because the hurtbox being too big makes killing them easy, but making it too small results in unexpected failure to kill the enemy, which would be frustrating to a player.

Is this typically how 3D platformers deal with this issue, or are there better ways?

# Answer
> 0 votes
If you have a ground detection empty object parented to the player, you can use this,

Do A box cast from ground detection like this,

```
Collider enymyHitInfo  = Physics.BoxCast(origin , size , angle , direction);

```

and if the collider is true and the colliding object has "Enemy" tag then you can Destroy gameobject, like this ,

```
if(enymyHitInfo.collider != null)
{
     if(enymyHitInfo.collider.gameObject.Comparetag("Enemy))
  {
      Destroy(enymyHitInfo.collider.gameObject);
  }
}

```

This is all assuming this is C# and unity the same would apply to any other language but the syntax changes. That's all.

# Answer
> 0 votes
*Note: This is a Unity-specific answer. The question author did not reply to my inquiry if a Unity-specific answer suffices, but I assume it does because the screenshot is from Unity.*

When players and enemies got rigidbodies, then you can implement `OnCollisionEnter(Collision)`.

In this case you probably don't need a separate hitbox, because the Collision-object passed to the function contains a lot of useful data about how exactly the collision happened. The most interesting for this case are perhaps the contact points. You can check if the point coordinates are on top or on the side of the enemy. You can also check the directions the contact normals are facing. What works best depends on what collider shapes you are using for the player and the enemies.

---
Tags: collision-detection, platformer
---


title: How can I unit test rendering output?

text:
# Question
Title: How can I unit test rendering output?
I've been embracing Test-Driven Development (TDD) recently and it's had wonderful impacts on my development output and the resiliency of my codebase. I would like to extend this approach to some of the rendering work that I do in OpenGL, but I've been unable to find any good approaches to this.

I'll start with a concrete example so we know what kinds of things I want to test; lets say I want to create a unit cube that rotates about some axis, and that I want to ensure that, for some number of frames, each frame is rendered correctly.

**How can I create an automated test case for this?** Preferably, I'd even be able to write a test case before writing any code to render the cube (per usual TDD practices.) Among many other things, I'd want to make sure that the cube's size, location, and orientation are correct in each rendered frame. I may even want to make sure that the lighting equations in my shaders are correct in each frame.

The only remotely useful approach to this that I've come across involves comparing rendered output to a reference output, which generally precludes TDD practice, and is very cumbersome.

I could go on about other desired requirements, but I'm afraid the ones I've listed already are out of reach.

# Answer
> 9 votes
This seems like a good application of the Approval Tests framework or something like it.

As stated in the comments, you are still going to have an issue with false positives, if you happen to approve bad output, but this will at LEAST tell you when output has changed significantly.

Since you are using OpenGL, I'm assuming that approvals won't work for you directly, but the idea is sound. Just check the file hash and if it is different, show the failure in an appropriate diff viewer (like an image diff program). If you approve of the new version, update the "approved" file to match the new result.

# Answer
> 7 votes
*I'm not into the game business, so please bear any potential stupid and naive perception*

For me, writing tests that compare fully rendered images are not really *unit* tests, but *full integration* tests, because everything has to work fine for a successful test run.

What about an intermediate layer where you can check that everything is fine? There are two things that come to my mind:

1. Don't draw directly, but issue a *command stream* that is turned into rendering calls down the way. The command stream can be checked for correctness. This is no end-to-end test, but you want *unit* tests, not full integration tests.
2. This is really a variation on 1. Wrap OpenGL, catch all calls to it, strip this down to what you really want to test, and check if output still matches. The OpenGL wrapper can do the check itself if properly configured, and turns into a *mock*.

# Answer
> 4 votes
The problem is that 3d engines aren't required to output an exact image bit-for-bit. Some leeway is tolerated as long as the artifacts caused by it aren't visible to the viewer. A texture being 1% darker than expected is usually not a serious problem... usually. Under some conditions it might be a visual artifact. And that's the problem: It is hard to judge for an automated test which artifacts would be noticed by a human viewer and which are not. Still, automated tests can be used for simple sanity checks when used on very simple geometry.

What you could do is render some simple scenes and then compare the generated image with a reference rendering. That reference rendering could either come from another graphic engine or be an earlier screenshots from the same engine (regression testing).

When some tests fail after a change to the graphic engine, a human tester should compare the output to the reference image and judge for themself if the new output looks just as good as before (or even better). When that's the case, the test should be changed to compare to the new, improved outputs.

Another thing you could check automatically are performance requirements. One such requirement could be that during a self-running demo (simulating a real sequence from the game) the frame-rate must not drop below 40 Fps on the test system. This is something you can test automatically. What you can't test is that the rendering is satisfying. But you can use such tests to prevent your developers from developing a game which looks superb but doesn't run properly on any affordable system until years after launch (hello Crytek).

# Answer
> 0 votes
After creating an OpenGL context (e.g. via Pbuffer) you can render a quad to a framebuffer using a floating point texture with a single pixel as a color attachment. You then render the output of a function call to the pixel in the fragment shader where the fragment shader calls the function and is linked with a code fragment containing the function. I.e. for each test a fragment shader with different method parameters is generated (e.g. using a templating library). glGetTexImage can be used to read out the pixel for comparison in the unit test.

---
Tags: opengl, rendering, testing, unit-testing, test-driven-development
---