Jump to content

Photo

RB+ Manic Miner :)


87 replies to this topic

#51 ggn OFFLINE  

ggn

    Stargunner

  • 1,356 posts
  • Location:Athens, Greece

Posted Thu Mar 23, 2017 3:51 AM



GGN - that's just showing off :) and I honestly can't get my head around it yet, but will download the project and have a butchers hook.

 

I went off on another tack last night and thought about doing as everyone said and using a background image and then having items that require interaction being an separate image.

 

I fell flat on my face at the first hurdle however.

 

I lashed up an image in paint that is 320*240 @ 4bpp but I clearly am still not understanding the rapinit.s format becasue the image does not fit/fill the display.

; Backdrop Object
<snip snip>

Any idea why that is incorrect ?

 

Showing off? Naaah I didn't mean to :). Also, if in doubt then have a look at how I defined the object for my map.

 



So If i understand GGN's code correctly then the maps data is the start position of each graphic in the tiles bitmap.

 

And then he's grabing each byte from that start position and pokeing it onto the blank screen placeholder ?

 

And i would gues you could do build a collison map at the same time which would be used for checking current player position against ?

 

My head hurts :)

 

One thing at a time! So yes, each tile is stored as a byte in an array. This can be your master reference for everything - which tiles to draw on screen, where your sprite is inside the map, collisions (you probably don't need pixel perfect stuff so you can check the map as well). 



#52 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,818 posts
  • Busy bee!
  • Location:England

Posted Thu Mar 23, 2017 3:59 AM

Off to a good start!
 

... collisions (you probably don't need pixel perfect stuff so you can check the map as well).


I'm pretty sure that the original Spectrum Manic Miner is pixel perfect when it comes to collisions with keys, plants/weeds and the enemies.



#53 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Thu Mar 23, 2017 10:01 AM

Had some time to play with GGN's code, I think i'm understanding most parts ( although took m a while to figure out that bit with the screen wipe in and out ).

 

I tried converting to 8*8 ( cos MM screen platform graphics are all 8*8 ) but i've not understood it correctly.

 

So the screen is 320*240 and my map is 40 columns by 30 rows. ( 320/8 = 40 and 240/8 = 30)

 

This is what i changed it to

' Draw map
    for y=0 to 29
        for x=0 to 39
            c=maps[map*30+y][x]
            tilex=(c % 40)
            tiley=(c/30)
            for i=0 to 7
                lpoke strptr(scrbuf)+y*(80*8)+x*8+i*80,lpeek(strptr(tiles)+tilex*8+tiley*(80*8)+i*80)
            next i
        next x
    next y

But everything is out by  what looks like an extra 8 pixels - but I didn't get where the original 160 come from anyway.

 

Cheers



#54 ggn OFFLINE  

ggn

    Stargunner

  • 1,356 posts
  • Location:Athens, Greece

Posted Thu Mar 23, 2017 1:01 PM

I thought I'd leave you a couple of hours to think this over until I answered, see if you could sort it out yourself. Well - time's up!

So let me try to re-write that semi-cryptic poke (doing this at blind, so there's a chance it's wrong!):
 

lpoke strptr(scrbuf)+y*(dest_screen_width_in_bytes*tile_height)+x*tile_width_in_bytes+i*dest_screen_width_in_bytes,lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes)

Makes better sense now? :)

Basically this tries to copy a rectangle of graphics from a source (src) screen to a destination (dst) screen.

  • First you have to figure out how wide both screens are in bytes. For my case they are both 160 since the width is 320 pixels in 4bpp (so 320*4/8=160 bytes).
  • Then calculate how wide your rectangle is. For me it's 16 pixels in 4bpp, so 16*4/8=8 bytes.
  • tilex and tiley are the coordinates of the block to be copied, but in my code they are expressed in tiles (say we want the 2nd tile horizontally and 4th vertically, so we need the (2,4) tile). They have to be converted to screen offsets. With tilex you just have to multiply it with the width of a tile in bytes, so tilex*tile_width_in_bytes. With tiley we have to skip blocks vertically, and as each block has a certain height, we have to multiply tiley with that height. But since this offset has to skip lines we also have to multiply that with the source screen width, thus tiley*(src_screen_width_in_bytes*tile_height).
  • After that, you can do pretty much the same calculations for destination offsets x and y, so x*tile_width_in_bytes and y*(dest_screen_width_in_bytes*tile_height).
  • Of course you also need to add to that the source and destination screen addresses.
  • Finally, if you do a single lpoke you'll only copy 8 pixels horizontally and that's it. That's why the i iterator is added, so it can copy the whole tile downwards from the initial addresses, so add i*src_screen_width_in_bytes and i*dest_screen_width_in_bytes to the mix.

 

So take the equation, plug your calculated values and you should be fine (unless I screwed up like I said above ;))

 

Let me know what happened!



#55 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Thu Mar 23, 2017 3:20 PM

Thanks for the detailed explanation GGN, i would never have guessed how you came up with the 160.

I've applied it correctly nkw and it works.

I did however do a bit of testing and managed to breakit in a way i don't get.

My array is 30 rows of 20 columns.

But if i set the y loop to anything over 27 then it crashes spectacularly.

I can't think why that would occur so tried increasing the array size and added a second room but still doesn't like it.

As it happens MM doesn't require that many rows, but i'd like to figure it out.

Anyhoo, again ta for all the help and advice.

#56 Sporadic OFFLINE  

Sporadic

    Moonsweeper

  • 490 posts
  • Probably RB+ing
  • Location:UK

Posted Thu Mar 23, 2017 5:42 PM

How tall is your destination sprite? Perhaps it's run out of space and you are poking values outside the bitmap.



#57 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Thu Mar 23, 2017 6:10 PM

Double DOH! With an added facepalm.

Ta for that.

#58 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Tue Mar 28, 2017 2:53 AM

Got stuck over the weekend and never really had a chance to do much.

 

However, I thought I had GGN's map code understood but something is still eluding me.

 

I've created my tiles in an image that ( at the moment ) is 208*24pixels. ( 26 * ( 8 * 8 ) tiles * 3 rows )

 

so my lpoke lpeek line is

lpoke strptr(scrbuf) + y * (160 * 8)+ x * 4 + i * 160, lpeek(strptr(tiles) + tilex * 4 + tiley *(104 * 8) + i * 104)

which i think is correct

 

My array is 34 rows of 40 columns ( 17 rows * 40 columns per screen ) - defining 2 screens

 

so my loops are : map 0 to 1, y 0 to 16 and x 0 to 39

 

what i think i'm getting wrong is the section defining c, tile_x and tile_y

c=maps[map*40+y][x]
tilex=(c % 26)
tiley=(c/26)

Any pointers ? cos i've been over this multiple times with varying results - none of them end up as i'd expect


Edited by saboteur, Tue Mar 28, 2017 2:54 AM.


#59 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Tue Mar 28, 2017 4:07 AM

Heres the full code - for some reason screen 2 is always garbled rubbish.

'
' Your code goes here
' Have fun!
'
rlist=(RAPTOR_LIST *)strptr(RAPTOR_sprite_table)
basic_r_indx=1
basic_r_size=1
RLOCATE 0,202
RPRINT "          RAPTOR BASIC+ - REBOOT        "
basic_r_size=0
basic_r_indx=0
RLOCATE 0,218
RPRINT "        Derived from BCX BASIC v6       "

set maps[34][40] as short

' 01   02   03   04   05   06   07   08   09   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x09,0x05,0x05,0x05,0x05,0x09,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 01
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 02
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 03
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x08,0x05,0x05,0x05,0x05,0x08,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 04
{0x0b,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b},	' screen 1 row 05
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 06
{0x0b,0x0a,0x0a,0x0a,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 07
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b,0x0b,0x0b,0x05,0x08,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 08
{0x0b,0x0a,0x0a,0x0a,0x0a,0x05,0x05,0x05,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 09
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0a,0x0a,0x0a,0x0b},	' screen 1 row 10
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 11
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x08,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b,0x0b,0x0b,0x0b,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b},	' screen 1 row 12
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 13
{0x0b,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x0b},	' screen 1 row 14
{0x0b,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b},	' screen 1 row 15
{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x1c,0x38,0x41,0x47,0x45,0x34,0x3f,0x03,0x03,0x1c,0x34,0x49,0x38,0x45,0x41,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03},	' screen 1 row 16
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02},	' screen 1 row 17
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x09,0x06,0x06,0x06,0x06,0x09,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 01
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 02
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 03
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x08,0x06,0x06,0x06,0x06,0x08,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 04
{0x0b,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0d,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b},	' screen 2 row 05
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0d,0x0d,0x0d,0x0d,0x0d,0x0b,0x06,0x06,0x06,0x0b,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 06
{0x0b,0x0a,0x0a,0x0a,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b,0x06,0x06,0x06,0x0b,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 07
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b,0x0b,0x0b,0x06,0x08,0x06,0x0b,0x06,0x06,0x06,0x0b,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 08
{0x0b,0x0a,0x0a,0x0a,0x0a,0x06,0x06,0x06,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b,0x0a,0x0a,0x0a,0x0b,0x0a,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 09
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b,0x06,0x06,0x06,0x0b,0x06,0x06,0x0a,0x0a,0x0a,0x0b},	' screen 2 row 10
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b,0x06,0x06,0x06,0x0b,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 11
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x08,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b,0x0b,0x0b,0x0a,0x0b,0x0a,0x0a,0x0a,0x0a,0x0a,0x0b},	' screen 2 row 12
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x0a,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 13
{0x0b,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0b},	' screen 2 row 14
{0x0b,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x0b},	' screen 2 row 15
{0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x1c,0x38,0x41,0x47,0x45,0x34,0x3f,0x03,0x03,0x1c,0x34,0x49,0x38,0x45,0x41,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03},	' screen 2 row 16
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}	' screen 2 row 17


end set

loadclut(strptr(tiles_clut),0,16)

dim x as short
dim y as short
dim c as short
dim tilex as short
dim tiley as short
dim map as short
dim i as int
DIM pi!: pi=3.1415926535897932384626433832795
dim ph!

for map=0 to 1
    ' Draw map
    for y=0 to 16
        for x=0 to 39
            c=maps[map*40+y][x]
            tilex=(c % 26)
            tiley=(c/26)
		
			for i=0 to 7
			
				' Formula explanation - kindly supplied by GGN :)
				'LPOKE strptr(scrbuf) + y * (destination_screen_width_in_bytes * tile_height) + x * tile_width_in_bytes + i * destination_screen_width_in_bytes
				'LPEEK strptr(tiles) + tilex * tile_width_in_bytes + tiley * (source_screen_width_in_bytes * tile_height) + i * source_screen_width_in_bytes
				'lpoke strptr(scrbuf) + y * (dest_screen_width_in_bytes*tile_height) + x * tile_width_in_bytes + i * dest_screen_width_in_bytes, lpeek(strptr(tiles)+tilex*tile_width_in_bytes+tiley*(src_screen_width_in_bytes*tile_height)+i*src_screen_width_in_bytes)
				
				lpoke strptr(scrbuf) + y * (160 * 8)+ x * 4 + i * 160, lpeek(strptr(tiles) + tilex * 4 + tiley *(104 * 8) + i * 104)
				
            next i
        next x
    next y

    ' Bring the map to screen
    for ph=0 to pi/2 step pi/90/2
		basic_r_size=0
		basic_r_indx=0
		rlist[1].x=(330-sin(ph)*314)*65536
		vsync
    next i
	
'    'Pause so the level can be seen
    for i=0 to 255
        vsync
    next i
	 
'    ' Send the object offscreen
    for ph=pi/2 to 0 step -pi/90/2
        rlist[1].x=(352-sin(ph)*336)*65536
        vsync
    next i


next map

'do
'vsync
'loop


#60 ggn OFFLINE  

ggn

    Stargunner

  • 1,356 posts
  • Location:Athens, Greece

Posted Tue Mar 28, 2017 5:41 AM

Got stuck over the weekend and never really had a chance to do much.

 

However, I thought I had GGN's map code understood but something is still eluding me.

 

I've created my tiles in an image that ( at the moment ) is 208*24pixels. ( 26 * ( 8 * 8 ) tiles * 3 rows )

 

so my lpoke lpeek line is

lpoke strptr(scrbuf) + y * (160 * 8)+ x * 4 + i * 160, lpeek(strptr(tiles) + tilex * 4 + tiley *(104 * 8) + i * 104)

which i think is correct

 

My array is 34 rows of 40 columns ( 17 rows * 40 columns per screen ) - defining 2 screens

 

so my loops are : map 0 to 1, y 0 to 16 and x 0 to 39

 

what i think i'm getting wrong is the section defining c, tile_x and tile_y

c=maps[map*40+y][x]
tilex=(c % 26)
tiley=(c/26)

Any pointers ? cos i've been over this multiple times with varying results - none of them end up as i'd expect

 

That "40" is actually the height of a single map. So it's not 40 in your case but 17. Try that and see if it helps.

 

(makes a mental note to parametrise all hardcoded values in the sample project - they're not clear as is [EDIT] Updated the project).


Edited by ggn, Tue Mar 28, 2017 6:02 AM.


#61 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Tue Mar 28, 2017 6:01 AM

Thanks GGN - i'd assumed it was the width of the map - but on reflection i should have noticed the y sitting right next to it. :-o 

 

Anyhoo works just fine now and I can proceed further putting stuff together.

 

Gonna work on a map builder over the next few days as well, doing it by eye and converting is giving me eye strain :)



#62 ggn OFFLINE  

ggn

    Stargunner

  • 1,356 posts
  • Location:Athens, Greece

Posted Tue Mar 28, 2017 6:15 AM

I'd recommend you use a tile editor like Tiled or Mappy and export the map values as hex/decimal values. Tiled can export the map as a csv file which you can copy and paste directly to your rb+ source :).


Edited by ggn, Tue Mar 28, 2017 6:22 AM.


#63 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Tue Mar 28, 2017 6:41 AM

That'll come in handy and will save a large amount of time.

Thanks



#64 ggn OFFLINE  

ggn

    Stargunner

  • 1,356 posts
  • Location:Athens, Greece

Posted Tue Mar 28, 2017 7:04 AM

I'll just leave this here

 

JSWManicMiner.png



#65 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Tue Mar 28, 2017 8:03 AM

Too late - already did a load of screen shots from the speccy version.

 

Thank god for pokes :) though cos i've never manged to complete the game.



#66 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Wed Mar 29, 2017 4:38 AM

Morning all, had a bit more of a play last night and starting working on the jumping mechanism.

 

One question - how do i detect multiple button presses ?

 

E.G DPAD is right and jump button is pressed ?

 

i thought that the following would work, but it doesn't

elseif LVAR_pad=PAD_A and LVAR_pad=PAD_RIGHT then

cheers



#67 ggn OFFLINE  

ggn

    Stargunner

  • 1,356 posts
  • Location:Athens, Greece

Posted Wed Mar 29, 2017 6:33 AM

Your LVAR_pad variable contains the state of all the buttons and D-pad directions. Each button is assigned one bit - take a look at rbasic.h if you're curious. So, to answer your question, if more than one button is pressed at the same time, you need to combine the status of the keys you want to check. Something like:
elseif LVAR_pad=(PAD_A bor LVAR_pad)=PAD_RIGHT then
should do the trick (bor stands for bitwise or, i.e. mash together the bits of two values).

#68 sh3-rg OFFLINE  

sh3-rg

    River Patroller

  • 3,388 posts
  • doge + tie = dothemath
  • Location:BOLTON, England

Posted Wed Mar 29, 2017 6:39 AM

To keep things simple and tidy I use separate BAND statements and stack them up as needed. So looking for button press and right...

 

IF (LVAR_pad BAND PAD_A AND LVAR_pad BAND PAD_RIGHT) THEN 



#69 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Wed Mar 29, 2017 6:48 AM

Thanks guys - now where getting somewhere.

 

Got to read through a few of the sample projects and figure out collision detection next  :)



#70 CyranoJ OFFLINE  

CyranoJ

    Quadrunner

  • 5,317 posts
  • RAPTOR in LOCAL
  • Location:Adelaide, SA

Posted Mon May 1, 2017 1:11 AM

How's this one going? 



#71 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Tue May 2, 2017 4:20 AM

To be honest i've not acheived as much as i would have liked, real life crept up on me ( easter holidays with the family, ISO audit at work and the new expansion pack on BF1 :) ).

 

However, I have been pratting around with collision detection and how to handle it ( MM's a bit awkward in that you can jump though certain floor types but not others ).

 

I've been thinking that MM wasn't the best choice and maybe I should just do my own platformer type thing, but I should have a better idea over the next week as i have more time to play at coding.

 

I'm still not entirely happy with the jumping either, i'm using precalulated values to plot the parabola, which works but seems a bit clunky.

 

Anyhoo, i should get more done this week and hopefully should start posting more progress.



#72 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Tue May 9, 2017 7:17 AM

OK finaly managed to get a bit more done, but have run into something i'm really not sure how to handle.

 

Being as it's manic miner and everything is in nice primary colours adn that MM himself is the only white sprite I thought that handling collision detection for the background map woudl be best handled by comparing sprite and background pixel colours (some kind of XOR i guess).

 

Is this the wrong way to do this ? if it isn't anyone point me to which RB+ commands to use.

 

Cheers


Edited by saboteur, Tue May 9, 2017 7:17 AM.


#73 sh3-rg OFFLINE  

sh3-rg

    River Patroller

  • 3,388 posts
  • doge + tie = dothemath
  • Location:BOLTON, England

Posted Tue May 9, 2017 2:23 PM

rb+ has some really nice routines for object vs object collision detection, using raptor's gpu routines nice and speedy. Obvs you can't use those if you generate your backdrops (platforms) as a single object using map data (guessing that's what you're doing as I can't remember and can't be bothered reading back through :P Ignore the rest of this if not, hah).

 

So you'd maybe want to peek at the backdrop object data at offsets from the current player sprite object coords, maybe just a handful of sensible ones rather than a whole solid block and have different patterns based on the gfx appearance in the frame? You could do it less efficiently and less hardcoded by simply peeking at the backdrop object data at an offset from the player object position for every pixel in the player sprite that is non-zero, iterate through all those every frame, it'd certainly help with edge cases where background gfx have black holes in them.

 

It's definitely simpler making games with rb+ when you make the most of its features and hand-holding, designing a game within the confines of what rb+ makes easy/trivial rather than having to get messy :)


Edited by sh3-rg, Tue May 9, 2017 2:24 PM.


#74 ggn OFFLINE  

ggn

    Stargunner

  • 1,356 posts
  • Location:Athens, Greece

Posted Wed May 10, 2017 1:14 AM

OK finaly managed to get a bit more done, but have run into something i'm really not sure how to handle.
 
Being as it's manic miner and everything is in nice primary colours adn that MM himself is the only white sprite I thought that handling collision detection for the background map woudl be best handled by comparing sprite and background pixel colours (some kind of XOR i guess).
 
Is this the wrong way to do this ? if it isn't anyone point me to which RB+ commands to use.
 
Cheers


That would be correct, mostly. I'm assuming you write "xor" because of the way computers without sprite hardware display sprites on screen. Especially on the spectrum people would simply have the background static and then XOR the sprite in (very convenient as XORing the sprite again would undraw it and restore the background).

But in this platform you don't need to do this, it's automatically done by the hardware. If you re-read my post about the OP a bit you'll see (or remember) that each object is its own layer and the OP just constructs an image from all objects (layers) without you needing to do anything nasty. Which means that you can keep each object clutter free of the other.

Of course that raises the problem you rightfully identified: how to detect a collision between your main sprite and the background?

One solution (which I don't really recommend) would be to use the blitter to draw the sprites, then you get collision detection for "free". Another would be (again as you say) to check the background bitmap compared to the x/y position of your sprite.

You might think "oh man that's too hard!" but it's not! In fact, the code we discussed above to draw the map is the key! The formula I wrote a few posts ago can give you the value of 2 4bit pixels by means of a single PEEK. So this sould do the trick:
peek(strptr(scrbuf)+y*(160*8)+(x band 0xfffe)*8)
(Note that I didn't test it beforehand so it might not work! Let me know what happens!).
(Note 2: the band 0xfffe aligns the coordinate to 2 pixels - this is essential to calculate the offset)
So now let's apply this to our problem: say you know the top-left corner of your sprite and is in x,y. Your sprite is 16 pixels wide and 16 pixels high. Let's keep it simple for now and assume that checking a couple of pixels near the centre directly below the sprite would be enough (and it usually is). So we plug this into the formula above and end up without
peek(strptr(scrbuf)+(y+16)*(160*8)+(((x+8) band 0xfffe)*8)
If we make the assumption that the tiles we can move are completely blank then if the result of that peek is non-zero then we have something there. So if the sprite was falling then we need to make it halt now. (or maybe you can do this test each frame to see if you need your sprite to fall or not - just increase your y if the result is zero).

Hope this helps a bit!

P.S. Sorry for being too verbose or if I sound patronising - I just wanted to help others understanding the problem instead of just giving you a math formula or just code :).
P.S.2 There is also a third idea where you can convert your sprite screen coordinates to map coordinates and check the map for collisions. This of course is not pixel perfect so it might not suit your needs.
P.S.3 I did not want to conver this here but I would suggest that for animated tiles and background stuff that can hurt the player to use different objects and not draw them as background (and actually leave a blank in your map there). That way you can take advantage of raptor animating the tiles and have collision for free.

#75 saboteur ONLINE  

saboteur

    Chopper Commander

  • Topic Starter
  • 109 posts

Posted Wed May 10, 2017 2:16 AM

Cheers GGN - will try this out in a bit and how did you guess I like a bit of ZX Speccy coding :)

I did look through your map code and had come to the conclusion that the LPEEK section was where I needed to concentrate but got a bit hung up this morning on where SCRBUF was coming from.

I guess it's a RAPTOR constant ?

It also hadn't clicked that each item in the OP is a layer in it's own right - and that makes things easier to understand.

Does the size of the graphic in the OP affect the performance or is it just number of items in the OP that causes slow down ?

 

Your P.S.3 suggestion is kind of where i've go to :)

Anyhoo, i'll have a play and probably be back with waaaay more questions.

Cheers





Reply to this topic



  


0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users