I think you are on the right track. You want the Player object to allow autonomous movement, but without putting too much knowledge about the "outer game mechanics" into it. A "grabbed" state inside the player does not fit to this design, and you are perfectly right: introducing such extra attributes will make the class less reusable and flexible.
One can solve this by developing a clear idea what fits well into a certain abstraction, and what not. That's what we call the responsibility of a class. In this case, you want the Player to be an abstraction for a physical game item - hence it makes sense let the player know only it's own physical properties (like velocity and position).
Since the game will allow changing velocity and position of a player "from outside", you need to give it getters and setters for both. Making a boss "grab" a player just sets the player's velocity to zero - no need to introduce an extra state attribute for this.
Still you can implement all methods inside the Player class which can be implemented reasonably by making use of player attributes, like an update method (however, I would consider a more expressive name for it, like moveAutomatically). Such a method fits perfectly into your player abstraction of a "physical item", and placing it there helps to keep your program well organized.
When your program grows, and you add more and more use cases to it, you will several times have to make a decision whether the Playerclass should be extended, or whether a certain functionality should kept out. When you stick to the responsibility you envisioned, this usually leads to some "convergence" - for the first use cases you implement, the class has to be extended, but at some time in the future, the class becomes "feature complete", and new uses cases can be implemented by simply reusing Player methods which are already there.