+slx Posted March 25, 2015 Share Posted March 25, 2015 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! Quote Link to comment Share on other sites More sharing options...
phaeron Posted March 25, 2015 Share Posted March 25, 2015 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. Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 25, 2015 Share Posted March 25, 2015 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. Quote Link to comment Share on other sites More sharing options...
+slx Posted March 25, 2015 Author Share Posted March 25, 2015 Thanks. So I will reverse collision check and movement. As for the reverse, that'll be quite a challenge in a 10-liner. Quote Link to comment Share on other sites More sharing options...
kenjennings Posted March 25, 2015 Share Posted March 25, 2015 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. Quote Link to comment Share on other sites More sharing options...
dmsc Posted March 25, 2015 Share Posted March 25, 2015 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. 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.