There are a couple ways you can go about solving this. They vary in complication and difficulty.
What I suggest starting with is testing your move before you actually move the rectangle, or move the rectangle back if there's a collision. Basically, your problem is that the rectangle moves to a position where it is colliding with something:
-------- --------
| | | |
-------- | | -----|-- |
| | -------- --> | --|-----
| | | |
-------- --------
(1) (2)
And then it stays there, unresponsive to the collision. When you run move under condition (2), the rectangles are still considered to be colliding and no move will be carried out, even if that move resolves the collision.
If you prevent it moving there in the first place, then it's free to continue moving in other directions. Code would look something like the following:
public void move(int xa, int ya, Player opponent) {
this.x += xa;
this.y += ya;
if (collision(opponent)) {
this.x -= xa;
this.y -= ya;
}
}
This method can lead to odd collisions though, depending on the velocity at which your rectangle moves. If it attempts to move 10 units but a collision occurs in 9, then it's prevented from moving in a direction even though it isn't flush against the colliding object.
The solution toTo solve that becomes, things get a little more complicated. To give an overview, and explanationsyou determine the magnitude of penetration along the direction one rectangle was traveling, and resources are available in other questions/answers on this site. I'll try to dig a fewback it up for youalong that direction to the point where it's no longer colliding. For now If the rectangle can bounce, start withan even more detailed implementation will determine where the simple stuffrectangle should be considering that it collided mid-timestep. If you're interested on how to get started on those options, I recommend reading through Metanet Software's collision detection tutorials.