OOP is a way of thinking about things. It helps you break down a complex problem in smaller, more easily digestible chunks. More interestingly, OOP uses a model that humans tend to already innately think in: individual objects, each with their own qualities (properties/fields) and abilities (methods).
Before we know what code to write, we first have to analyze what it is that we want. In your design phase; you've glossed over an important part of what you need your game to be able to do, because I can tell you've not designed your code to account for it.
Forget about the code for now. Let's talk about your game and how you like it to work.
Now let's suppose that I have a "boss" that can grab the player.
This immediately suggests that the player is not the sole arbiter of their movement. Outside forces are able to interrupt a player's abilities to move or jump around.
I think it's strange to have to update the Player class to support doing something else with the player.
If you think about it, that is precisely what you want the boss (or their hand) to be able to do: change the player's state.
Does this means that I have to modify the Player class to add a GRABBED state in which case the update method doesn't update the position?
That is one way to do it. However, I would expect that your game would have more than one way to override the player's behavior. "Grabbed" is a very specific term that refers to the current scenario, but you might have other reasons to implement the same kind of overriding behavior for which "grabbed" is not the right name, so you'll likely want a more generic sounding name for this.
This is not a given. You could use specific states such as "grabbed", "pushed", ... but then you have to really analyze what these states mean and how they affect your player. In the interest of simplicity, I'm going to keep this answer a bit more generic than that.
The "boss grab hand" feature leads us to specific requirements:
- An outside actor should be able to inhibit the player's own free movement
- An outside actor should be able to move the player around
This leads us to design our class to account for these things. I'm skipping the specific movement logic here because the answer applies regardless of how you implement the movement logic.
I'm a C# dev and, but the syntax should be clear enough for your case. I'm not 100% which language you're using.
public class Player
{
private bool canMove = true; // By default, player can move
public Position Position { get; private set; }
// Outside actors can tell the player that they're (not) able to move
public void CanMove(bool value)
{
this.canMove = value;
}
// Logic involving the player's own voluntary movement
public void Move()
{
if(this.canMove)
{
// Movement logic which updates the Position property
}
}
// Outside actors can move the player around.
public void SetPosition(Position p)
{
this.Position = p;
}
}
This is a basic implementation of the requirements that followed from the "boss grab hand" feature you need. If you want, this could be developed further:
SetPosition
could require the outside actor (boss object) as a parameter, and only allow its position to be set if the actor has the required Strength state to do so (e.g. actor.Strength == this.Strength || this.State == PlayerState.Asleep
, as a crude example)
- A similar check could be implemented for
CanMove(bool)
, whereby an attempt to render the player unable to move is not guaranteed.
- You could implement some sort of skill check whereby the player rolls a die to try and wriggle free and actually still manage to move even though they were set to
canMove = false
.
These are just examples of how you can further flesh out this logic; but it requires specific design decisions on how you want your game to function, and this is beyond the current question.
Another idea I've seen is the component pattern (https://gameprogrammingpatterns.com/component.html), where we would have some "component" defining a behavior that we can change at runtime (like the Strategy pattern).
These are all valid ideas, but they are more complex to implement. A lot of this hinges on your specific requirements and how you intend your overall game to work.
For a sufficiently complex game; things like ECS are really helpful to separate individual gameplay features and keep them dynamically adjustable. However, for a fairly trivial game, this would be overkill.
But all of this seem cumbersome and I don't understand what the benefits are compared to keeping the Player class to a minimum and letting the outside code do whatever they want
There's certainly a style of game where letting the outside code do whatever they want is a valid implementation. I'm not sure if you have experience with Dungeons and Dragons; but in this game the GM (a person) is the sole arbiter of what happens.
The GM is honorably bound by gameplay rules that the players expect the GM to follow, but the GM effectively has the sole authority to tell a player where they move to, or whether their action did(n't) succeed, or how much damage they took, or ... If the GM says it happens, it happens. They are, for all intents and purpose, the god of their game's state.
In a DnD-style game, all your game objects would essentially boil down to state containers, and the GM would be free to set any property/field to whatever value they desired. You wouldn't even need to validate any of these actions, assuming that the GM is a trusted source who is certain that they only perform the correct actions.
However, at the opposite end of the spectrum, consider a multiplayer game. If all game objects can let outsiders do with them as they want, it would be trivial for a player to cheat by messing with their opponent or changing their own stats to gain an unfair advantage.
This is a matter of how you structure your game logic, and this is a discussion much bigger than the question you asked here.