jlew715 Posted December 12, 2018 Share Posted December 12, 2018 Hey all, Working on an IntyBasic game and I'd like to implement software-based collision detection rather than relying on the built-in Intellivision collision registers (mainly so I don't have to wait for the player-sprite to already be ~1px inside the wall before the collision is reported). This is simple enough for MOB-on-MOB collisions, but I'm not sure how to implement this for collisions with background elements like walls. I'm envisioning the flow will be something like: Draw player sprite Determine target coordinates for next player move (based on Controller input or whatever). Get info about what type of card is currently shown on the target coordinates. If it's open, set player coordinates = target coordinates. If it's a wall, set player coordinates = last known good coordinates. GOTO 1. Where I'm stuck is step 3. I'm guessing there is a way to convert the target coordinates into a "card number" (BACKTAB?), then load information about what is on that card (is it a wall? is it blank?). But I'm not sure how to A). translate the X/Y coords into a card, and B). how to tell what is displayed on a particular card (is it a wall?). Additionally, I'm guessing that the "origin" for sprites is the upper-left corner. so drawing an 8x8 sprite at coordinates 10,10 would occupy the area from 10,10 to 18,18. Please correct me if I'm wrong. Thanks! Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted December 12, 2018 Share Posted December 12, 2018 Hey all, Working on an IntyBasic game and I'd like to implement software-based collision detection rather than relying on the built-in Intellivision collision registers (mainly so I don't have to wait for the player-sprite to already be ~1px inside the wall before the collision is reported). This is simple enough for MOB-on-MOB collisions, but I'm not sure how to implement this for collisions with background elements like walls. I'm envisioning the flow will be something like: Draw player sprite Determine target coordinates for next player move (based on Controller input or whatever). Get info about what type of card is currently shown on the target coordinates. If it's open, set player coordinates = target coordinates. If it's a wall, set player coordinates = last known good coordinates. GOTO 1. Where I'm stuck is step 3. I'm guessing there is a way to convert the target coordinates into a "card number" (BACKTAB?), then load information about what is on that card (is it a wall? is it blank?). But I'm not sure how to A). translate the X/Y coords into a card, and B). how to tell what is displayed on a particular card (is it a wall?). Additionally, I'm guessing that the "origin" for sprites is the upper-left corner. so drawing an 8x8 sprite at coordinates 10,10 would occupy the area from 10,10 to 18,18. Please correct me if I'm wrong. Thanks! For MOB-to-Background collisions, you could do this: Convert MOB screen coordinates into BACKTAB address: address = $200 + (((x + 4) / 8 ) + (((y + 4) / 8 ) * 20)) This will give you the card in BACKTAB over which the center of the sprite resides. If your collision is against full cards, then just read the type of card by getting the card value from the BACKTAB word using a mask: card = (PEEK(address) AND $7F8) / 8 This will give you the card number, which you can either look up on a table or do something else with it. If your cards have multiple facets (i.e., a card may contain multiple elements drawn inside), then you can get the Modulo 4 of the X and Y coordinates to determine an offset within the card as well. On your last point, the origin of the sprites is indeed the upper-left corner, so you may want to offset your coordinates by 4 (or 3) before translation. -dZ. 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted December 12, 2018 Share Posted December 12, 2018 One other thing you can do: BACKTAB cards are 16-bit long, but the STIC only uses the lower 14 bits. That means that the 2 MSB are not touched and free for your own use. Two bits gives you capacity to store a value from 0 to 3, so if you have at most four kinds of walls, you could "mark" them by adding a value in those bits when you draw the screen. Then, it's a matter of masking them and shifting them in order to use them as an index into a table. Ask for further details if anything here is not clear. -dZ. Quote Link to comment Share on other sites More sharing options...
jlew715 Posted December 12, 2018 Author Share Posted December 12, 2018 (edited) I like the idea of encoding the card type (wall 1, wall 2, etc.) into the 2 unused bits of the each card. How do I got about setting these when Im PRINTing my walls earlier? Say Im printing a wall along the top of the screen: FOR I=0 TO 19 PRINT AT (SCREENPOS(I,0)), BG00 NEXT I Say I wanted to set the MSB of those 20 cards to identify that they are walls - how can I do that? Something with POKE? Edited December 12, 2018 by jlew715 Quote Link to comment Share on other sites More sharing options...
+nanochess Posted December 12, 2018 Share Posted December 12, 2018 I like the idea of encoding the card type (wall 1, wall 2, etc.) into the 2 unused bits of the each card. How do I got about setting these when Im PRINTing my walls earlier? Say Im printing a wall along the top of the screen: FOR I=0 TO 19 PRINT AT (SCREENPOS(I,0)), BG00 NEXT I Say I wanted to set the MSB of those 20 cards to identify that they are walls - how can I do that? Something with POKE? Use the addition operator, for example BG00 + $8000 or BG00 + $4000. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted December 12, 2018 Share Posted December 12, 2018 Use the addition operator, for example BG00 + $8000 or BG00 + $4000. Or, to make it nicer to look at and understand in your program, you can just take the index value (0 to 3) and multiply it by 2^14 or $4000. Like this: #var = BG00 + (0 * $4000) ' Card 0 #var = BG00 + (1 * $4000) ' Card 1 #var = BG00 + (2 * $4000) ' Card 2 #var = BG00 + (3 * $4000) ' Card 3 Essentially, we add the magic values for the bits like nanochess said, but instead of treating the bits as individual flags, we treat them as a field that allows us to store a 2-bit value, or a value from 0 to 3. We then take that 2-bit value and "shift" it to the left into position by multiplying it by 2^14. To read it back, you first mask it, and compare to similar constants, for instance: #card = #var AND $C000 ' Mask the upper 2 bits IF (#card = (2 * $4000)) THEN ' Card is #2 END IF Or IF ((#var AND $C000) = (2 * $4000) THEN) ' Same thing END IF If you plan on using it as an index to a table, you'll have to shift the bits back, which you can do via division, but it may get expensive. Let us know how you plan on using it, and we can help. All that is if you need to keep track of a value within 0 and 3. If all you have is a single flag telling you whether it's a wall or not, then adding a single bit like nanochess suggested would be more straightforward. -dZ. 1 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.