Jump to content
IGNORED

Overestimating Collision Detection?


slx

Recommended Posts

For a possible entry into the 10-lines-contest I have set up the following in BASIC XL:

 

  • a Graphics 12 playfield with some characters on it as well as
  • a Player (0).

 

Now I try to move the player around with the following routine:

50 POKE 53278,0:S=HSTICK(0):T=VSTICK(0):H=H+S:PMMOVE 0,H;T:C=PEEK(53252)>0:H=H+C*-S:PMMOVE 0,P+C*-H;C*-T:GOTO 50

This is supposed to move the player by one unit for every iteration while the stick is pushed. This works fine.

 

When a collision between the player and the playfield is detected, it should retrace the last movement by repeating it with a reversed sign.

What actually happens is that the player is "slowed down" and starts moving jerkily. While some moves seem to be caught and reversed by the collision detection, the general movement ist still in the direction the stick is pushed.

 

Am I overestimating the "power" of collision detection? Am I clearing HITCLR to often? (If I don't clear it, the player indeed "stops" on first contact with playfield graphics but then remains "stuck.

 

Thanks for hints!

 

Link to comment
Share on other sites

P/M collisions are only detected when GTIA actually draws that portion of the screen. What's probably happening is that your check is failing because GTIA hasn't actually tested the collision between the time that you strobe HITCLR, move the object, and check for a collision. You need to frame lock your game loop for this to be reliable.

Link to comment
Share on other sites

In Basic it's somewhat hard to implement that system because you can't really framelock things. Ideally you'd have check/clear collision in VBlank followed shortly by movement.

Real world, it sometimes takes even TurboBasic an entire frame or more just to execute one statement and sometimes you'll get multiple executions.

 

Plenty of games out there use that method. Maybe an alternative could be:

Perform the movement, remember the joystick direction.

If collision occurs, restore player to "old" position and don't accept movement in the joystick direction previously used until another direction aside from neutral is tried.

 

Ideally you'd need to ensure that a frame draw occurs between movement and collision checking. In Basic the easiest way would probably be to do the collision check immediately before the move operation.

Link to comment
Share on other sites

I had a similar problem with a demo I was doing of a person (player) walking on randomly created land (playfield). The player was doing a horrible amount of jittering up and down. Eventually I figured out that BASIC XL as so fast that the time between HITCLR and checking the collision was so short that no collision had been flagged yet. (So, no collision flagged caused the person to "sink" down another scan line into the ground even though it had already been moved down into the ground.)

 

Moving the HITCLR as far as possible from checking the collision smoothed out the motion. In BASIC XL that might mean slowing down the code. The perfect solution is locking to the frame rate which isn't really practical in BASIC. This might come close:

.

Poke 20,0: While Peek(20)<2: Endwhile

.

That guarantees at least one full frame has passed. If you can reorganize the code to separate the clock clearing from the clock checking delay, it may not even degrade performance (much). You want the player to sit in its current position for a full frame before evaluating the collision and moving the player again:

.

While MoreElectricity
  Poke HITCLR,0:Poke 20,0
  Do stuff here which takes up time
  While Peek(20)<2:Endwhile
  Evaluate Collision here
  Move player to new position
Endwhile

.

 

If you use Peek(20)<1 it may not be a full frame -- BASIC sets the jiffy clock to 0 at the bottom of a frame, VBI increments it, and BASIC checks it again at the top of the frame before most of the display has been drawn, so then collisions are not set.

Link to comment
Share on other sites

Hi,

 

In Basic it's somewhat hard to implement that system because you can't really framelock things. Ideally you'd have check/clear collision in VBlank followed shortly by movement.

Real world, it sometimes takes even TurboBasic an entire frame or more just to execute one statement and sometimes you'll get multiple executions.

 

Plenty of games out there use that method. Maybe an alternative could be:

Perform the movement, remember the joystick direction.

If collision occurs, restore player to "old" position and don't accept movement in the joystick direction previously used until another direction aside from neutral is tried.

 

Ideally you'd need to ensure that a frame draw occurs between movement and collision checking. In Basic the easiest way would probably be to do the collision check immediately before the move operation.

 

Note that at least in TurboBasic XL you can do a "PAUSE 0" to sync to the vertical blank, and check the collision registers afterwards.

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...