Kiwi Posted September 21, 2016 Share Posted September 21, 2016 I trying to wrap my head around trimming the card information down to the GRAM card number. So I can use the card number as software collision detection data. I want to peel off the color information, GRAM bit off the card that been retrieved from the BACKTAB. For right now, I have charx=vmX/8chary=vmY/8print at 12 color 7,<3> charxprint at 32 color 7,<3> chary#Mcard=peek($200+charx+chary*20) I want to get the card # to simplify the comparsion statement. For example, I want card 8-18 to be solid. I want to use if #Mcard>8 AND #Mcard<18 then..... Instead of having big numbers, slowing the processor down. The character moves in 16 different directions in a top down dungeon crawler type of game. It does make hard collision detection hard to figure out, which I tried. Quote Link to comment Share on other sites More sharing options...
carlsson Posted September 21, 2016 Share Posted September 21, 2016 (edited) I am not sure this is the best way to do it, but this the formula I'm using: #val=(PEEK(512+cx+cy*20) AND $09F8)/8 The /8 is essentially to mask away the lower three bits in FG/BG mode. If you're using color stack mode, adjust as required. Edit: If you have no GROM cards, you can AND $01F8 and get a number 0-63 instead of 0-319 of which values 64-255 anyway won't occur. Edited September 21, 2016 by carlsson Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted September 21, 2016 Share Posted September 21, 2016 Instead of having big numbers, slowing the processor down. The CPU does not have an 8 bit compare instruction. All comparisons are 16 bits, so there is no need to have the extra overhead of dividing by 8 in my opinion, just mask out the card number and be done. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted September 21, 2016 Share Posted September 21, 2016 Remember that the card number includes the GRAM flag (bit #11), so the mask should be $0FF8 for Color Stack Mode and $09F8 for FG/BG Mode. -dZ. Quote Link to comment Share on other sites More sharing options...
carlsson Posted September 21, 2016 Share Posted September 21, 2016 If you don't divide by 8, won't you have to compare with GROM/GRAM cards 8, 16, 24, 32, 40 etc all the way to card 2560, or is there another way of thinking? Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted September 21, 2016 Share Posted September 21, 2016 If you don't divide by 8, won't you have to compare with GROM/GRAM cards 8, 16, 24, 32, 40 etc all the way to card 2560, or is there another way of thinking? Correct! Personally, I would just use constants instead of the magic numbers (after applying a suitable bitwise AND mask) and then leave it at that. That way, when you come back to the game source code after a while, you don't have to remember that GRAM card 13(x8) is a wall etc. Quote Link to comment Share on other sites More sharing options...
intvnut Posted September 21, 2016 Share Posted September 21, 2016 If you don't divide by 8, won't you have to compare with GROM/GRAM cards 8, 16, 24, 32, 40 etc all the way to card 2560, or is there another way of thinking? Yes, indeed. But if you're just doing a range compare, then the comparison isn't any more costly. It actually saves you the cost of the divide step. For example, if card #s 8 through 18 are solid walls, then you want to compare the masked value against the range 8*8 = 64 through 18*8 = 144. . #Mcard = peek($200 + charx + 20*chary) AND $FF8 If #Mcard >= 8*8 AND #Mcard <= 18*8 Then .... . And as GroovyBee suggested, replace 8 and 18 with constants, so if your range of 'solid wall' cards ever changes, you can just change the constants. Quote Link to comment Share on other sites More sharing options...
Kiwi Posted September 21, 2016 Author Share Posted September 21, 2016 I winded up doing,Mcard=PEEK($200+charx+chary*20)/8 Mcard being an 8-bit variable it'll shave off the last 8 bits. And dividing by 8, shifts the bit over by 3 to get card number ranging 0-31. I planned to have the background tiles to take GRAM slot 0-31, and MOBs to take slot 32-63. Quote Link to comment Share on other sites More sharing options...
intvnut Posted September 22, 2016 Share Posted September 22, 2016 I winded up doing, Mcard=PEEK($200+charx+chary*20)/8 Mcard being an 8-bit variable it'll shave off the last 8 bits. And dividing by 8, shifts the bit over by 3 to get card number ranging 0-31. I planned to have the background tiles to take GRAM slot 0-31, and MOBs to take slot 32-63. Hmm... Saving that in an 8-bit variable /sorta/ works. You'll end up treating GROM and GRAM tiles identically, though. So, numbers, letters, punctuation, etc... will look similar to GRAM tiles. That is, a space character is GROM #0, and you won't be able to tell that from GRAM #0, for example. Quote Link to comment Share on other sites More sharing options...
carlsson Posted September 22, 2016 Share Posted September 22, 2016 I suppose there is no space in the dungeon? Furthermore, does the collission detection signal anything as long as a MOB moves on GROM #0, or does it have to be GROM #1 or a GRAM for it to flag something may have happened? Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted September 22, 2016 Share Posted September 22, 2016 I suppose there is no space in the dungeon? Furthermore, does the collission detection signal anything as long as a MOB moves on GROM #0, or does it have to be GROM #1 or a GRAM for it to flag something may have happened? The hardware collision only detects when non-zero pixels touch each other. That is when a non-transparent part of a MOB collides with a non-transparent part of a background card or another MOB. Obviously, if the background card is completely transparent (GROM #0), then no collisions can register. P.S. The visibility of a MOB does not affect collisions. A "hidden" MOB (one with the "Visible" flag in the X register turned off) can still trigger a collision. The only factor is the actual pixels. Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted September 22, 2016 Share Posted September 22, 2016 (edited) Another factor to consider with hardware collisions, which may or may not affect your game design, is that while collisions occur on the frame when objects move, they are registered during the next frame. Moreover, if you need to react by moving the sprite or changing its card or altering any feature of the STIC, it will not be reflected until the next frame is drawn. In other words, if you move a sprite on Frame #N and this caused a collision with the background, you won't know this until Frame #N+1; and if you moved or changed the colour of the sprite or altered the GRAM card of the background as a reaction to the event, it won't show up until Frame #N+2. For this reason, sometimes it is better to handle collisions in software, so that you can have full control of their timing. With software collisions, you can move objects on Frame #N, detect collisions right away, and react before the end of the frame. However, software collisions are much more expensive in code and processing time than hardware collisions, which come almost for free. It's just another trade-off of game design. -dZ. Edited September 22, 2016 by DZ-Jay 1 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted September 22, 2016 Share Posted September 22, 2016 (edited) I winded up doing, Mcard=PEEK($200+charx+chary*20)/8 Mcard being an 8-bit variable it'll shave off the last 8 bits. And dividing by 8, shifts the bit over by 3 to get card number ranging 0-31. I planned to have the background tiles to take GRAM slot 0-31, and MOBs to take slot 32-63. If they are all in GRAM, you'll be fine. However, consider what Joe said, if you use GROM for anything, you won't be able to tell them apart. That is because the "GRAM flag" that distinguishes between both is bit #8 (actually, it's bit #11 in the BACKTAB word, which falls on #8 when you divide by eight), which falls outside the range of 0-255, and won't be persisted in 8-bit RAM. -dZ. Edited September 22, 2016 by DZ-Jay Quote Link to comment Share on other sites More sharing options...
intvnut Posted September 22, 2016 Share Posted September 22, 2016 Yeah, hardware collisions actually kinda suck for things like "keeping player in a maze." You want to know before you move a player whether you're moving them into a wall, rather than after. Hardware collision requires the two objects to have actually overlapped already in the past, which for something like maze movement, requires your player to have overlapped the wall already by at least 1px. I mainly save hardware collisions for after-the-fact collision detection for items that are allowed to penetrate each other, and even then I prefer software collision detection. As dZ mentioned upthread, with hardware collision detection, there's effectively a 2 frame delay between when you cause the collision and when you can react to the collision, because you need a displayed frame between the two events. We beat a lot of this to death in a thread a couple years ago: http://atariage.com/forums/topic/231734-the-intv-intybasic-and-collision-detection/ Here is a different idea that may save you a LOT of headache for your current maze navigation: Bits 14 and 15 in each BACKTAB word are not used by the STIC. You can use these for flags in your game. If you're not using them for something else already, you could use them to mark which squares are passable and ones aren't. For example, dedicate bit 15 to indicate whether a given square is passable by the player or not. Then you don't even have to look at the card # to know if it's a wall. You can either "AND $8000" and see if it's zero or non-zero, or you can compare ">= 0" vs. "< 0" without even masking. That allows you to do other tricks, like having a wall you can walk through (hidden passage? easter egg?), among other things. Bit 14 could be used as a flag for, say, "special squares"—squares that trigger an action when you walk onto them. 2 Quote Link to comment Share on other sites More sharing options...
+DZ-Jay Posted September 22, 2016 Share Posted September 22, 2016 I do precisely that in Christmas Carol: there are four bits left unused in the BACKTAB word that I use as the "items bitmap." That way, detecting a collision with, say a Snowflake or a piece of Candy is as simple as testing the four bits on the BACKTAB cell over which the sprite is at the moment to see which one is set. Not only that, but on the edge cards around the maze (where no sprite can actually traverse), I set bit #15 of the cards as a "no paint" marker. When the maze is flashed at the end if the level, only those cards with bit #15 clear change colours. This lets the HUD (score, lives indicator, etc.) remain static. dZ. 2 Quote Link to comment Share on other sites More sharing options...
Kiwi Posted September 23, 2016 Author Share Posted September 23, 2016 I ended up doing: CheckWall:procedure 'store your char coor into lx & ly(stands for last position) lx=vmX ly=vmY 'subpixel routines for finer movement while vmsY>=200:vmY=vmY-1:vmsY=vmsY+8:wend while vmsY>=8:vmY=vmY+1:vmsY=vmsY-8:wend while vmsX>=200:vmX=vmX-1:vmsX=vmsX+8:wend while vmsX>=8:vmX=vmX+1:vmsX=vmsX-8:wend 'divide by 8 with offset of -4 charx=(vmX-4)/8 chary=(vmY-4)/8 'debug info on where your char on screen print at 12 color 7,<3> charx print at 32 color 7,<3> chary 'get card number from BACKTAB 'storing to a byte to trim the last 8 bits from the card 'dividing by 8 will do a shift operation to trim the first 3 bit off the 'Mcard. Mcard is short for Magic Card. Mcard=PEEK($200+charx+chary*20)/8 'debug info on what card # it got from the screen print at 233 color 7,<2> Mcard 'if the card ID number higher than 8, then restore last position. if Mcard>8 then vmY=ly:vmX=lx 'return and end to go back to the main gameloop. return end I usually can make very detail floors so hardware collision wouldn't work since it wall detect set bits. If I want to make a detail water tile that allow projectile to pass through and keep your player from going through, then software collusion is recommend. And I work in BG/FG mode. Intycolor pick up blank tile as part of the GROM, and blank tile is a 0 so it pass through. For Rockcutter for Colecovision, I did have invisible wall so I loaded the wall graphic to the pass through portion of the charset and the solid portion of the tileset. I may do the same for this game. 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.