From ab68fa2b82c211fd7424306e36f514c200027788 Mon Sep 17 00:00:00 2001 From: Rinceri Date: Tue, 23 Jun 2026 21:22:12 +0100 Subject: [PATCH 1/7] add transform docs --- docs/moving-around.md | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 docs/moving-around.md diff --git a/docs/moving-around.md b/docs/moving-around.md new file mode 100644 index 0000000..631700e --- /dev/null +++ b/docs/moving-around.md @@ -0,0 +1,83 @@ +# Moving around + +Now that we have entities in our world, we would like to move them around. This +can involve two aspects: +1. Moving them around visually +2. Using player input to trigger their movement (amongst other things) + + +Each entity has a `Transform` object property that stores its position in the world. +This is stored in a `Vector3` property called `position` with the `Transform`. + +The `Vector3` is a struct that stores the `X`, `Y`, and `Z` coordinates of the entity. +While the `X` and `Y` coordinates correspond to a position on our 2D screen, the `Z` +coordinate represents the layer in which the object exists. That is, it determines, +when objects overlap, which sprite overlaps another. + +> [!NOTE] +> The Z coordinate must be between 0 and 1000, otherwise the object won't appear. All +> these coordinates are `double`s, so they can even be a decimal number. + +When creating an Entity, you can pass in a `Vector3` as a spawn position: +```c# +Vector3 topStarPosition = new(10, 10, 1); +Entity topStar = new(topStarPosition); + +Entity defaultStar = new(); + +... // adding sprite components and adding them to the world +``` +Here, `topStar` spawns at coordinates `(x: 10, y: 10)` and is in "layer" 1. On the other +hand, `defaultStar` appears at `(x: 0, y: 0, z: 0)`, which is the default spawn if not set. +This will be the bottom left corner of the screen, at layer 0. + +Now, time to move these entities around! We can do them in two ways: +1. Setting the position of the entity +2. Attaching a `PhysicsBody` component to let physics properties move them around + +### Setting the position of the entity +This is relatively straightforward: +```c# +topStar.position = new Vector3(20, 10, 1); +``` +This will change the position of `topStar` to `x: 20` from `x: 10`. However, this will simply +"teleport" the object there. + +We would instead want the object to move smoothly that distance. This is where we use `PhysicsBody` +component, which will deal with the visual movement based on given parameters. + +### Using `PhysicsBody` +This is a component that handles the physics operations for an Entity. We may just want to set a +velocity and let this component handle the actual movement. So lets do that. +```c# +// moving the star at a velocity of (x: 200, y: 0) per second +Vector2 starVelocity = new(200, 0); + +PhysicsBody starBody = new(); +topStar.AddComponent(starBody); + +starBody.Velocity = starVelocity +``` + +The star will now move at 200 pixels to the right every **physics tick**. + +> [!TIP] +> A physics tick is its own unit of time used by our game engine for physics operations +> This allows us to do physics operations periodically but independently of the framerate. + +##### Moving a given distance +To move the star a specific distance at a specific velocity, we can use the `MoveDistance` method. +```c# +Vector2 starDistanceVelocity = new(50, 0); + +// set the independent velocity to zero otherwise this would add to the starDistanceVelocity +// for the purpose of this demo, we just want the star to move by MoveDistance +starBody.Velocity = Vector2.Zero; +starBody.MoveDistance(velocity: starDistanceVelocity, distance: 200, thisDirectionOnly: true); +``` + +Now, you will notice the star moves to the right over 4 seconds, and then stops. + +There is one parameter here that might sound confusing: `thisDirectionOnly`. This will be broken down +in this next section. + From e93955029b9ef7584ffc551534f378534859c7c8 Mon Sep 17 00:00:00 2001 From: Rinceri Date: Thu, 25 Jun 2026 22:04:42 +0100 Subject: [PATCH 2/7] remove unused import --- samples/pong/Soldier.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/pong/Soldier.cs b/samples/pong/Soldier.cs index 6a7850d..4a6a784 100644 --- a/samples/pong/Soldier.cs +++ b/samples/pong/Soldier.cs @@ -3,7 +3,6 @@ using rasdaq.Graphics; using rasdaq.Inputs; using rasdaq.Logging; -using rasdaq.Resources; using rasdaq.Transformations; namespace pong; From f43310a0c4510d6244d041c66d5a19742d2b5788 Mon Sep 17 00:00:00 2001 From: Rinceri Date: Thu, 25 Jun 2026 22:04:57 +0100 Subject: [PATCH 3/7] add remaining docs about input based movement --- docs/moving-around.md | 50 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/docs/moving-around.md b/docs/moving-around.md index 631700e..7ec44eb 100644 --- a/docs/moving-around.md +++ b/docs/moving-around.md @@ -58,14 +58,14 @@ topStar.AddComponent(starBody); starBody.Velocity = starVelocity ``` - + The star will now move at 200 pixels to the right every **physics tick**. > [!TIP] > A physics tick is its own unit of time used by our game engine for physics operations > This allows us to do physics operations periodically but independently of the framerate. -##### Moving a given distance +#### Moving a given distance To move the star a specific distance at a specific velocity, we can use the `MoveDistance` method. ```c# Vector2 starDistanceVelocity = new(50, 0); @@ -73,7 +73,7 @@ Vector2 starDistanceVelocity = new(50, 0); // set the independent velocity to zero otherwise this would add to the starDistanceVelocity // for the purpose of this demo, we just want the star to move by MoveDistance starBody.Velocity = Vector2.Zero; -starBody.MoveDistance(velocity: starDistanceVelocity, distance: 200, thisDirectionOnly: true); +starBody.MoveDistance(velocity: starDistanceVelocity, distance: 200, thisDirectionOnly: false); ``` Now, you will notice the star moves to the right over 4 seconds, and then stops. @@ -81,3 +81,47 @@ Now, you will notice the star moves to the right over 4 seconds, and then stops. There is one parameter here that might sound confusing: `thisDirectionOnly`. This will be broken down in this next section. +#### Moving a given distance in a particular direction only +Now if we want to make sure the star covers the required distance in the direction provided by the velocity, +we set the `thisDirectionOnly` to true. + +The difference here is that it doesn't count any component of distance travelled in another direction. + +So if you were to have another "velocity" on the star in the opposite direction, of lets say (40, 0) then for +each second, it will only count 10 units of distance covered. + +#### Moving once +If you want to move a specific velocity for one physics tick, you can call the `MoveOnce` method. This is ideal for +input-based movement, as you can call this everytime the user presses a key. +```c# +// creating a component so that we can use its Update method +class StarComponent : Component +{ + public override void Update(double deltaTime) + { + base.Update(deltaTime); + + PhysicsBody? body = Entity?.GetComponent(); + + if (Input.IsKeyDown(Keys.W)) + { + body?.MoveOnce(new Vector2(0, 100)); + } + if (Input.IsKeyDown(Keys.S)) + { + body?.MoveOnce(new Vector2(0, -100)); + } + } +} + +... + +// somewhere in application start, we add our custom component to our desired entity +StarComponent starComponent = new() +topStar.AddComponent(starComponent); +``` + +Here, when the Update method (which is called every physics tick on all components) is called, and the `W` key is pressed +by the user, it will call `MoveOnce` on the `PhysicsBody` component of the entity it's attached to (in this case it will be `topStar`). + +So in simple words, everytime `W` is pressed, the entity is moved once at (0, 100) velocity, allowing for input-based movement! From 7ea0db34a5ea63afb2db0ea351a5b313176d651e Mon Sep 17 00:00:00 2001 From: Rinceri Date: Sun, 28 Jun 2026 12:26:15 +0100 Subject: [PATCH 4/7] update for review comments --- docs/moving-around.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/moving-around.md b/docs/moving-around.md index 7ec44eb..abb8af1 100644 --- a/docs/moving-around.md +++ b/docs/moving-around.md @@ -6,8 +6,9 @@ can involve two aspects: 2. Using player input to trigger their movement (amongst other things) -Each entity has a `Transform` object property that stores its position in the world. -This is stored in a `Vector3` property called `position` with the `Transform`. +Each entity has a `Transform` property, which holds attributes like position, rotation, and scale. + +We'll begin our tutorial by focusing on `position`, which is stored in a `Vector3` property. The `Vector3` is a struct that stores the `X`, `Y`, and `Z` coordinates of the entity. While the `X` and `Y` coordinates correspond to a position on our 2D screen, the `Z` @@ -16,7 +17,7 @@ when objects overlap, which sprite overlaps another. > [!NOTE] > The Z coordinate must be between 0 and 1000, otherwise the object won't appear. All -> these coordinates are `double`s, so they can even be a decimal number. +> these coordinates are `double`, so they can even be a decimal number. When creating an Entity, you can pass in a `Vector3` as a spawn position: ```c# @@ -90,7 +91,7 @@ The difference here is that it doesn't count any component of distance travelled So if you were to have another "velocity" on the star in the opposite direction, of lets say (40, 0) then for each second, it will only count 10 units of distance covered. -#### Moving once +#### Moving once / using player input to trigger movement If you want to move a specific velocity for one physics tick, you can call the `MoveOnce` method. This is ideal for input-based movement, as you can call this everytime the user presses a key. ```c# From e524916671a16b01e824ce732a97374900a2ed35 Mon Sep 17 00:00:00 2001 From: Rinceri Date: Tue, 30 Jun 2026 00:50:19 +0100 Subject: [PATCH 5/7] add camera docs --- docs/moving-around.md | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/moving-around.md b/docs/moving-around.md index abb8af1..a8c964f 100644 --- a/docs/moving-around.md +++ b/docs/moving-around.md @@ -126,3 +126,47 @@ Here, when the Update method (which is called every physics tick on all componen by the user, it will call `MoveOnce` on the `PhysicsBody` component of the entity it's attached to (in this case it will be `topStar`). So in simple words, everytime `W` is pressed, the entity is moved once at (0, 100) velocity, allowing for input-based movement! + +### Moving the camera +Now that we have learned about movement, let us learn how to move the camera so it tracks `topStar` such that it +doesn't disappear from the screen. + +This is fairly straightforward. All we have to do is get the instance of `Camera`, which is a property +of the singleton `Renderer`, and set its coordinates in the world. + +Note that the coordinates we set here is of the **bottom left corner** of the camera. + +``` + +---------------------------------+ + | | + | | + | Window | + | | + | | + +---------------------------------+ + (x, y) + ^ + | +Camera coordinates +``` + +> [!NOTE] +> This feature will soon be changed to use center of the camera window as coordinates + +```c# +// somewhere in a frame update loop +... +// getting entity's x/y position... +// and then offsetting its coordinates by half of window size... +// so the entity is in the center of camera window +var cameraX = Entity?.Transform.position.X - (Application.WindowSize?.X / 2) ?? 0; +var cameraY = Entity?.Transform.position.Y - (Application.WindowSize?.Y / 2) ?? 0; +Renderer.Instance.Camera.SetPosition(x, y); +``` + +Now when moving around you will notice the entity doesn't appear to move, due to the camera tracking +its position. + +### Rotation + +### Scaling From c1af80943656954b6baa3444de1ce5d5b997835d Mon Sep 17 00:00:00 2001 From: Rinceri Date: Wed, 1 Jul 2026 00:14:40 +0100 Subject: [PATCH 6/7] tidy up removed rotation and scaling sections as they are self explanatory --- docs/moving-around.md | 6 +----- src/rasdaq/Transformations/Transform.cs | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/moving-around.md b/docs/moving-around.md index a8c964f..8647013 100644 --- a/docs/moving-around.md +++ b/docs/moving-around.md @@ -164,9 +164,5 @@ var cameraY = Entity?.Transform.position.Y - (Application.WindowSize?.Y / 2) ?? Renderer.Instance.Camera.SetPosition(x, y); ``` -Now when moving around you will notice the entity doesn't appear to move, due to the camera tracking +Now when moving around you will notice the entity doesn't appear to move, which is due to the camera tracking its position. - -### Rotation - -### Scaling diff --git a/src/rasdaq/Transformations/Transform.cs b/src/rasdaq/Transformations/Transform.cs index 5e3e7b6..b96ec97 100644 --- a/src/rasdaq/Transformations/Transform.cs +++ b/src/rasdaq/Transformations/Transform.cs @@ -17,8 +17,8 @@ public class Transform(Vector3 spawnPosition) /// public Vector3 position = spawnPosition; /// - /// Scale of the entity. (1,1) is the default, and means the image will be rendered at its original size - /// The X and Y components of the scale are applied to the width and height of the entity respectively + /// Scale of the entity. (1, 1) is the default, and means the image will be rendered at its original size. + /// The (X, Y) components of the scale are applied to the width and height of the entity respectively /// public Vector2 scale = new(1, 1); /// From 871e3600680af40a481969bb1fb51dbca9df221d Mon Sep 17 00:00:00 2001 From: Rinceri Date: Wed, 1 Jul 2026 01:13:08 +0100 Subject: [PATCH 7/7] fix todos --- docs/moving-around.md | 26 +++++++++++++++-------- src/rasdaq/Transformations/PhysicsBody.cs | 2 +- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/docs/moving-around.md b/docs/moving-around.md index 8647013..8798f6a 100644 --- a/docs/moving-around.md +++ b/docs/moving-around.md @@ -3,7 +3,7 @@ Now that we have entities in our world, we would like to move them around. This can involve two aspects: 1. Moving them around visually -2. Using player input to trigger their movement (amongst other things) +2. Using player input to trigger their movement (amongst other ways) Each entity has a `Transform` property, which holds attributes like position, rotation, and scale. @@ -44,7 +44,7 @@ topStar.position = new Vector3(20, 10, 1); This will change the position of `topStar` to `x: 20` from `x: 10`. However, this will simply "teleport" the object there. -We would instead want the object to move smoothly that distance. This is where we use `PhysicsBody` +We would instead want the object to smoothly move that distance. This is where we use `PhysicsBody` component, which will deal with the visual movement based on given parameters. ### Using `PhysicsBody` @@ -59,17 +59,20 @@ topStar.AddComponent(starBody); starBody.Velocity = starVelocity ``` - -The star will now move at 200 pixels to the right every **physics tick**. +The star will now move at 200 pixels per millisecond. The actual distance it moves here +would be determined by the time the **physics tick** takes (since distance is a product +of speed and time). > [!TIP] > A physics tick is its own unit of time used by our game engine for physics operations > This allows us to do physics operations periodically but independently of the framerate. +> +> The tick is timed in milliseconds, hence the speed being mentioned in pixels per millisecond. #### Moving a given distance To move the star a specific distance at a specific velocity, we can use the `MoveDistance` method. ```c# -Vector2 starDistanceVelocity = new(50, 0); +Vector2 starDistanceVelocity = new(30, 0); // set the independent velocity to zero otherwise this would add to the starDistanceVelocity // for the purpose of this demo, we just want the star to move by MoveDistance @@ -77,19 +80,24 @@ starBody.Velocity = Vector2.Zero; starBody.MoveDistance(velocity: starDistanceVelocity, distance: 200, thisDirectionOnly: false); ``` -Now, you will notice the star moves to the right over 4 seconds, and then stops. +Now, you will notice the star moves to the right until it covers that distance, and then stops. There is one parameter here that might sound confusing: `thisDirectionOnly`. This will be broken down in this next section. #### Moving a given distance in a particular direction only -Now if we want to make sure the star covers the required distance in the direction provided by the velocity, +Things get complicated if the star is being pushed by more than one force at the same time. Let's say +we have another "velocity" on the star in a perpendicular direction, in `(0, 40)`. How does the game calculate +when the star has covered 200 pixels? This is determined by `thisDirectionOnly`. + +If we want to make sure the star covers the required distance only in the direction provided by the velocity, we set the `thisDirectionOnly` to true. The difference here is that it doesn't count any component of distance travelled in another direction. -So if you were to have another "velocity" on the star in the opposite direction, of lets say (40, 0) then for -each second, it will only count 10 units of distance covered. +So if `thisDirectionOnly` is set to true, it will only count 30 units of distance covered per unit time. +On the other hand, if `thisDirectionOnly` is set to false, the distance counted as covered would be 50 units +(30 horizontal and 40 from vertical velocity, and so a diagonal distance of 50 units). #### Moving once / using player input to trigger movement If you want to move a specific velocity for one physics tick, you can call the `MoveOnce` method. This is ideal for diff --git a/src/rasdaq/Transformations/PhysicsBody.cs b/src/rasdaq/Transformations/PhysicsBody.cs index 07233e6..4d8f45b 100644 --- a/src/rasdaq/Transformations/PhysicsBody.cs +++ b/src/rasdaq/Transformations/PhysicsBody.cs @@ -59,7 +59,7 @@ public void MoveDistance(Vector2 velocity, float distance, bool thisDirectionOnl } /// - /// Internally called every frame to get delta movement of entity + /// Internally called every physics update to get delta movement of entity /// /// elapsed time since last frame /// delta vector