0
\$\begingroup\$

I am programming a side-view tennis game, inspired by an old arcade game, using Javscript and HTML5 canvas elements. The player can move left and right and holds a racket at arms length which can be rotated 360 degrees around the shoulder joint.

I am quite happy with the collision detection and resulting deflection angle between the racket and the ball in the case where the player stands still and the racket does not move. I use a ray-casting approach for this collision detection between the vector that represents the racket and the trajectory vector for the ball as proposed here.

However, I am having trouble implementing the collision detection between the rotating racket and the ball. When the racket is swung, the area in which a collision would apply has a shape similar to a circular segment , but the racket rotates rotates to fast and the collision detection does not pick it up in most cases. The image bellow illustrates the problem, the red arrow indicates the direction of the swinging racket.

enter image description here

The following code snippet from the player entity's update function shows how the racket is updated. arcmx and armcy is the location of the shoulder joint, rstart_ and rend_ are the beginning and end of the racket.

  if(KEY_STATUS.rleft || KEY_STATUS.rright) {
    if(KEY_STATUS.rright) {
      this.rangle += this.rspeed;
    } else if (KEY_STATUS.rleft) {
      this.rangle -= this.rspeed;
    }
  } 

  this.armcx = this.x + this.width/2;
  this.armcy = this.y + 46;
  this.rstartx = this.armcx + Math.cos(this.rangle)*40;
  this.rstarty = this.armcy + Math.sin(this.rangle)*40;

  this.rendx = this.armcx + Math.cos(this.rangle)*71;
  this.rendy = this.armcy + Math.sin(this.rangle)*71;

I am pretty lost on this problem and appreciate any hints on how to approach it.

\$\endgroup\$
1
\$\begingroup\$

Multisampling, as the people over at Metanet call it.

Basically, you do a racket/ball collision test at frequent enough time intervals between frames such that the ball can't be passed by the racket without a collision being detected. This gives a rough estimate as to when the collision occurred, after which you can start subdividing your time step to find the exact moment of contact (the more accurate you want it, the more you subdivide). This should ensure collisions are correctly detected, and consistent.

Or perform a sweep test (arguably harder to implement).

\$\endgroup\$
0
\$\begingroup\$

What you could do is give the racket a defined constant "range" that is +- half the distance the ball moves every update. This way the ball would never pass through the racket. This will of course result in minor inconsistencies with the ball's rebound trajectory, but you'd have to test this out to determine their actual effects.

Yes the logical size of the racket would then change dynamically, but that is the best way that I can think of to correctly determine when the ball would hit the racket, without impeding onto the performance too badly.

Although you could move the ball and racket minute distances multiple times per update and then check after each movement. This seems a little tedious and could possibly be a little tough on the hardware depending the system running the game, but it would probably be most accurate.

I have done this for a game of my own where I had to check whether a balloon touched the top of the spike, rather than the sides, so this is a valid method, although it could possibly be fine-tuned a bit to fit your game.

\$\endgroup\$
  • \$\begingroup\$ Do you mean making the racket 'thicker' ? The ball's speed varies dramatically, so I think the racket would have to be very thick to account for all circumstances, increasing the false positives. \$\endgroup\$ – feob Jul 7 '14 at 21:32
  • \$\begingroup\$ @feob I added to my answer. \$\endgroup\$ – StrongJoshua Jul 7 '14 at 21:38
  • \$\begingroup\$ A simpler solution might be to "pad" the vector of the moving ball (like having a trail), so that an intersection is detected. \$\endgroup\$ – Sergio Jul 15 '14 at 9:14
  • \$\begingroup\$ @Sergio That would have the same effect, just that hear you're padding the ball whereas by my solution you're padding the paddle. \$\endgroup\$ – StrongJoshua Jul 15 '14 at 13:53
  • \$\begingroup\$ @StrongJoshua Agreed. I just thought that padding the ball would be cheaper to run (no need for multiple updates) and wouldn't require new code (as in the case of the thick racket). \$\endgroup\$ – Sergio Jul 15 '14 at 16:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.