108 lines
3.4 KiB
Markdown
108 lines
3.4 KiB
Markdown
---
|
|
title: "Magic Values"
|
|
date: 2019-05-23T15:51:58-07:00
|
|
weight: 25
|
|
---
|
|
|
|
Our code right now is violating one more good architecture principle.
|
|
|
|
```cs
|
|
...
|
|
|
|
if (keyboardState.IsKeyDown(Keys.Down))
|
|
{
|
|
SendMessage(
|
|
new MotionMessage(playerInputEntity,
|
|
new System.Numerics.Vector2(0, 10 * (float)dt))
|
|
);
|
|
}
|
|
|
|
...
|
|
```
|
|
|
|
*Magic values* refer to numbers that have been placed directly in the code. That 10 above is a magic value. Why are magic values bad?
|
|
|
|
Magic values introduce the possibility of duplication. Let's say I start adding my code to be able to move paddles down. Now I have to change the numbers in two different places. If I ever change one without changing the other, I have introduced a bug.
|
|
|
|
There's another reason to avoid magic values too. Suppose I haven't looked at the InputEngine for a while, but I suddenly decide that the paddles are moving too slow. Intuitively, I would want to look for a Component that contains those values, but instead, they would be hidden in the InputEngine. This isn't what you would really expect - why should Input have anything to do with the speed of the paddles?
|
|
|
|
Organizing your information consistently is crucial to being able to easily find things that you need to change. You'll thank yourself later.
|
|
|
|
Let's make a new Component.
|
|
|
|
Create a file: **PongFE/Components/PaddleMoveSpeedComponent.cs**
|
|
|
|
```cs
|
|
using Encompass;
|
|
|
|
namespace PongFE.Components
|
|
{
|
|
public struct PaddleMoveSpeedComponent : IComponent
|
|
{
|
|
public float Speed { get; }
|
|
|
|
public PaddleMoveSpeedComponent(float speed)
|
|
{
|
|
Speed = speed;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
And let's add it to our paddle Entity.
|
|
|
|
In **PongFEGame.cs**
|
|
|
|
```cs
|
|
...
|
|
|
|
WorldBuilder.SetComponent(paddle, new PlayerInputComponent(PongFE.Components.PlayerIndex.One));
|
|
WorldBuilder.SetComponent(paddle, new PaddleMoveSpeedComponent(10));
|
|
WorldBuilder.SetComponent(paddle, new PositionComponent(new MoonTools.Structs.Position2D(5, 5)));
|
|
|
|
...
|
|
```
|
|
|
|
Now let's tell our InputEngine to use it, and why don't we go ahead and make the Up key move the paddle upward too.
|
|
|
|
```cs
|
|
...
|
|
|
|
foreach (ref readonly var playerInputEntity in ReadEntities<PlayerInputComponent>())
|
|
{
|
|
ref readonly var playerInputComponent = ref GetComponent<PlayerInputComponent>(playerInputEntity);
|
|
|
|
if (HasComponent<PaddleMoveSpeedComponent>(playerInputEntity))
|
|
{
|
|
ref readonly var paddleMoveSpeedComponent = ref GetComponent<PaddleMoveSpeedComponent>(playerInputEntity);
|
|
var paddleSpeed = paddleMoveSpeedComponent.Speed;
|
|
|
|
if (playerInputComponent.PlayerIndex == PlayerIndex.One)
|
|
{
|
|
if (keyboardState.IsKeyDown(Keys.Down))
|
|
{
|
|
SendMessage(
|
|
new MotionMessage(
|
|
playerInputEntity,
|
|
new System.Numerics.Vector2(0, paddleSpeed * (float)dt)
|
|
)
|
|
);
|
|
}
|
|
else if (keyboardState.IsKeyDown(Keys.Up))
|
|
{
|
|
SendMessage(
|
|
new MotionMessage(
|
|
playerInputEntity,
|
|
new System.Numerics.Vector2(0, -paddleSpeed * (float)dt)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
...
|
|
```
|
|
|
|
I'm starting to get get a bad feeling about this. Let me explain.
|