You can do it without behaviors. Just give the object an x and y velocity and do the bouncing by checking if walls are going to be hit horizontally or vertically. If they are, then reverse the velocity.
> Globals:
G=100
Instance variables:
Vx=0
Vy=0
Every tick
— sprite: add g*dt to vy
Sprite: overlaps wall at offset (self.vx*dt, 0)
— sprite: set vx to -self.vx
Sprite: overlaps wall at offset (0, self.vy*dt)
— sprite: set vy to -self.vy
Every tick
— sprite: set x to self.x+self.vx*dt
— sprite: set y to self.y+self.vy*dt
Just set vx and vy when the player throws it. You can adjust g to taste.
Should be pretty close. At the very least you’ll get the perfect bounces. There are improvements that could be had. Here are a few of them that may be of interest:
Possible improvements:
The sprite needs to be outside of walls when it starts and throughout the motion. If it’s in a tight area, or it’s started inside a wall, then you need to move it out of the wall first.
Usually not an issue if created inside the players collision area, and it’s given enough room to move around.
There can be energy loss with vertical bouncing at times. The sprite will bounce lower after a few bounces.
One reason for this is variable dt. You can help correct this by replacing self.vy*dt in all expressions with self.vy*dt+0.5*g*dt*dt.
Bouncing is done by checking where the ball will be a frame later. You can get more precise bounces by calculating when the wall is hit exactly before bouncing then moving again with the remaining time. Not really necessary but has advantages for very fast sprites.
A final idea is to only use integers for position and speed, and always use a fixed dt. This complicates it a bit but it removes energy loss from rounding caused by floating point numbers.
Thanks so much R0J0hound I really appreciate it, looks awesome! So G is speed, and setting Vx and Vy at spawn time sort of controls how high and far they are thrown?
Bouncing is done by checking where the ball will be a frame later. You can get more precise bounces by calculating when the wall is hit exactly before bouncing then moving again with the remaining time. Not really necessary but has advantages for very fast sprites.
I'm not exactly sure how this could be done, although Jill's blade moves fairly slowly, I'm interested in what method could be used.
A final idea is to only use integers for position and speed, and always use a fixed dt. This complicates it a bit but it removes energy loss from rounding caused by floating point numbers.
Should I encapsulate all variables in int() to achieve this? And how is dt made to be fixed (presumably so it's not machine independent?