encompass-cs-docs/content/pong/move_paddle/magic_values.md

108 lines
3.4 KiB
Markdown
Raw Normal View History

2019-05-24 00:45:22 +00:00
---
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))
);
}
...
2019-05-24 00:45:22 +00:00
```
*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?
2019-05-24 00:45:22 +00:00
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?
2019-05-24 00:45:22 +00:00
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**
2019-05-24 00:45:22 +00:00
```cs
using Encompass;
2019-05-24 00:45:22 +00:00
namespace PongFE.Components
{
public struct PaddleMoveSpeedComponent : IComponent
{
public float Speed { get; }
public PaddleMoveSpeedComponent(float speed)
{
Speed = speed;
}
}
2019-05-24 00:45:22 +00:00
}
```
And let's add it to our paddle Entity.
In **PongFEGame.ts**
2019-05-24 00:45:22 +00:00
```cs
...
2019-05-24 00:45:22 +00:00
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)));
2019-05-24 00:45:22 +00:00
...
```
2019-05-24 00:45:22 +00:00
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)
)
);
}
}
}
2019-05-24 00:45:22 +00:00
}
...
2019-05-24 00:45:22 +00:00
```
I'm starting to get get a bad feeling about this. Let me explain.