Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 13:08:16 GMT -5
So, I was planning on using ReadTiles to see if a sprite hit a physical object. Trouble is, sprites use a pixel by pixel coordinate system while ReadTiles uses a 8x8 tile coordinate method. How to I determine which tile to read based of the pixel coordinates of a sprite? Usually I'd think about dividing the sprite coordinate by 8 but I don't see a round() function if ReadTile(round(playerx/8), round(playery/8)+1) = #solid then playerx = xprevious : playery = yprevious
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 13:14:28 GMT -5
tilecoord * 8 Read tile isn't the best method for collision. I used X,Y coords of the sprite and check to see if a tile is in a certain range to determine if you can walk there or not.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 13:23:11 GMT -5
tilecoord * 8 Read tile isn't the best method for collision. I used X,Y coords of the sprite and check to see if a tile is in a certain range to determine if you can walk there or not. Hmmn.. with the tilecoord * method.. er, I guess I don't understand at all Do you mean match the tile coordinate (times 8) just below Mario's y coordinate to see if it's a brick tile? How would I know which tile to compare? Seems backwards to me (because I don't understand ) Wouldn't you want to figure out which tile is below Mario and see if it is a brick? Would you have to check every tile in range to see if it's hitting the Mario character? English isn't working very well for me today Do you have a code example? Or, am I on the right track but not thinking right about rounding? Does a divide on an integer like the sprites x or y coordinate give a remainder or just automatically rounds up/down? if ReadTile((playerx/8),(playery/8)+1) = #solid then goto solid_stop P.S. @elusive: Reading your other topic on tile collision you had another quandry with clearing the tile buffer. Did you find a neat way to do that? If not I have an idea.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 13:39:17 GMT -5
Use ..
tile_x = sprite_x >> 3 tile_y = sprite_y >> 3 And as elusive mentioned, don't use readtiles .. grab the data from the ROM ( or RAM when dynamic ).
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 13:57:51 GMT -5
Use .. tile_x = sprite_x >> 3 tile_y = sprite_y >> 3 And as elusive mentioned, don't use readtiles .. grab the data from the ROM ( or RAM when dynamic ). Thanks for the clues moon! Er, does "sprite_x >> 3" round sprite_x down or up (or not at all?) UPDATE: Looks like sprite_x >> 3 rounds down so if sprite_x = 25 the answer is 3. And you mean I should either: Have a collision map in DATA statements? Would this still be in pixels or can I still round up/down to 8x8 tile chunks? if collision_map((playerx/8) >> 3),((playery/8) >> 3)+1)) = #solid then goto stop_player
collision_map: DATA 1, 0, 0, 0, .. or should be treating the tile buffer as an array instead of readtile commands? Somehow re-DIM'ing the tile buffer RAM to look like a normal array(x,y) to check against the sprite position?
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 14:06:03 GMT -5
There is no rounding with integers .. besides, the snippet I posted uses bit-shifting. Talking about rounding in that context doesn't make any sense ( but to answer your question, integers usually round down ). Read this -> en.wikipedia.org/wiki/Bitwise_operation#Bit_shiftsAnd you're probably going to have your map data in your ROM / as DATA statement. In most cases you can use that for collision as well ( just be smart about it ).
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 14:21:01 GMT -5
That sprite_x >> 3 bit shiift operation looks PERFECT! Thank you moon! I keep thinking in QuickBASIC terms with variables. I guess 4GLs like FoxPro spoiled me My scrolling engine uses map data in 21x21 tile chunks. Making a collision map would be awkward at best. I'll try your bit-shift operation in combination with readtile and see why readtile gets a bad rap. I haven't found a description of why it sucks yet.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 14:23:25 GMT -5
|
|
|
Post by jlf65 on Jun 22, 2011 16:04:57 GMT -5
x >> y is the same thing as x / (2**y) where ** is the power function. So x >> 1 == x / 2, x >> 2 == x / 4, etc. The >> notation derives for C, but is pretty common in a lot of languages now.
Similarly, x << y is the same thing as x * (2**y). >> shifts right while << shifts left.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 17:13:04 GMT -5
jlf65 is right, with the important exception of .. y = 8 x = y / 2 print x ' Output = 8 (Incorrect) x = y >> 1 print x ' Output = 4 (Correct) .. which is a bug in BEX that has been reported long ago
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 18:50:05 GMT -5
Never knew about that bug (or the work around). Awesome stuff to know All integers round down. I've never seen an integer round up before (at least by default) in any language (C/C++, PHP, qbasic, VBasic, etc). @theloon: The way I did my collision was I set the sprite in the center of the screen (288,240), and without the planes scrolled at all, his X and Y coords were something like X = 10 and Y = 7 (I believe). This set his X & Y coords for the map. I move my sprite at a 16 pixel chunk per step, so it's a little easier for me, and I'm assuming you're moving your sprite by 1 pixel at a time, so you would do something like this: dim steps as integer if joypad = left then steps-- elseif joypad = right then steps++ end if if steps = 16 then X++ end if if maparray(X+,Y) = TileNumberThatIsBrick then DoNotMove else GoAheadAndMove end if No, this code probably won't work, but it should give you an idea on how to do collisions. If you have other sprites that you need to do collisions on, you just check their X & Y coords and see if each other enter their space, example: if spritexpos(sprite1) > spritexpos(sprite2) and spritexpos(sprite1) < spritexpos(sprite2) + sprite2Width then CollisionHappend You will need to check the Y coords as well. Hope this helped
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 22, 2011 22:29:15 GMT -5
Wow! This is alot of info! I shall not waste an ounce! Especially since this topic reminded us of a known bug that's easy to stumble on.
Elusives techniques will definitely prove useful - especially if readtiles or some use of vdpramread doesn't work (too slow).
Just so this thread comes in handy for other beginners I've started a Bit-Shifting section in the BasiEgaXorz Command Reference:
Bit-Shifting Operations Bit shifting can be an easy and fast way to divide integers (x >> y) or multipy them (x << y). As a side-effect you can also count on the results being rounded down.
According to jlf65:
UNDER CONTRSTRUCTION: Moon reports that a known bug exists to where division might not work:
y = 8 x = y / 2 print x ' Output = 8 ' (Incorrect) x = y >> 1 print x ' Output = 4 ' (Correct)
|
|
|
Post by jlf65 on Jun 23, 2011 4:01:03 GMT -5
My, that's a pretty BIG bug. Well, when one is dividing by a power of two, one should probably get in the habit of using shifts instead. Modern C/C++ classes actually teach the opposite these days, telling students to rely on the compiler to change a divide/multiply by a power of two into a shift. The problem there is that you are then relying on undefined operations in a particular compiler. If you mean for a power of two to be converted to a shift, do it yourself and changes in the compilers won't be a factor.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Jun 23, 2011 6:05:11 GMT -5
Bit shifting can be an easy and fast way to divide integers (x >> y) or multipy them (x << y). Don't refer to bit-shifting as division / multiplication. Just because you can create the same results ( in a couple of circumstances ) doesn't mean they are the same thing. Fun fact; BEX automatically detects when a multiplication / division can be solved with a bit-shift, and uses LSL / LSR instead of MULU / DIVU. Just like modern compilers
|
|