Jump to content
IGNORED

RB+ Manic Miner :)


Recommended Posts

Right, i've started having a bash at RB+ and decided to prat about getting a lash of Mathew Smith's classic Manic Miner.

 

I've managed to rip the original graphics from the ZX Spectrum version and have started to throw together a few experiments and will post my progress and questions in this thread.

 

So my first question(s) :

 

I have my Miner Willy :-o and a guardian moving around and animated but how do I flip them when they change direction/ reach an edge of a patrol route? Do I have to have sperate left and right images or is there a flip command ?

 

Is there a list of RB+ commands ??

 

Any help appreciated.

Link to comment
Share on other sites

Awesome. Can't wait to see your progress.

 

Each object has a flip flag.

 

So for example you can do

 

rlist[objectnumber]. flip = R_is_flipped

Or

rlist[objectnumber]. flip = R_is_normal

 

Where objectnumber is the number of the object from the object list that you want to flip. Also, this is a horizontal flip, there is no vertical.

 

I think you can update almost all an objects properties this way.

 

Hope that helps a bit. Typed on my phone so there could be errors.

 

Also, in the RB+ folder there is a docs folder with a quick reference.txt and also a bcxbasic help file.

Edited by Sporadic
Link to comment
Share on other sites

Nice one Sporadic.

 

Hope to have the first cavern layout done tonight - need to do a bit of thinking about storing layouts - but by doing 1 cavern I should come up with a plan.

 

Also ss it possible to change the colour of a sprite - I noticed a blitter example but not sure if that will be relevant or overkill ( all of the keys on each level colour cycle )

 

cheers

  • Like 1
Link to comment
Share on other sites

 

Nice one Sporadic.

 

Hope to have the first cavern layout done tonight - need to do a bit of thinking about storing layouts - but by doing 1 cavern I should come up with a plan.

 

Also ss it possible to change the colour of a sprite - I noticed a blitter example but not sure if that will be relevant or overkill ( all of the keys on each level colour cycle )

 

cheers

 

Never mind - I just animated the keys by having 8 frames but changing the coliur each time :)

Edited by saboteur
  • Like 1
Link to comment
Share on other sites

That's a good solution :). I can also think a couple more, provided you use up to 8bpp mode for your sprite.:

 

a) Have multiple palettes and use the sprite_CLUT attribute from raptor to change the sprite's palette. Have a look at the raptor manual for this.

b) Poke the palette value with the value of the col you want to set. The basic formula is something like


DPOKE CLUT+col_index*2,(red<<11)|(blue<<6)|(green)
where col_index is a value from 0 to 255 that corresponds to the index you want to change, red and green are values from 0 to 31 and blue a value from 0 to 63.

 

You can calculate col_index if you know which col index your sprite uses and which clut are you setting.

 

(Also typed my memory so this could be off.)

 

 

Lastly, big up for getting started!

Edited by ggn
  • Like 2
Link to comment
Share on other sites

A couple of times I think I imported a 16bit asset and used it as a colour palette, peek at it and poke into colour register, to save xunting around with RBG values and shifting around, just draw your palette in PSP or whatever.

  • Like 1
Link to comment
Share on other sites

Right i'm clearly not understanding rapinit.s properly.

 

below are two definitions, one of a 16*16 bmp, the other of an 8*8 bmp.

 

The 16*16 all works fine but the 8*8 is all f****d up so i'm clearly getting it wrong somewhere.

 

Any pointers ??

 

cheers

 

; Player Lives Object
dc.l 3 ; (REPEAT COUNTER) ; Create this many objects of this type (or 1 for a single object)
dc.l is_active ; sprite_active ; sprite active flag
dc.w 20,0 ; sprite_x ; 16.16 x value to position at
dc.w 220,0 ; sprite_y ; 16.16 y value to position at
dc.w 0,0 ; sprite_xadd ; 16.16 x addition for sprite movement
dc.w 0,0 ; sprite_yadd ; 16.16 y addition for sprite movement
dc.l 16 ; sprite_width ; width of sprite (in pixels)
dc.l 16 ; sprite_height ; height of sprite (in pixels)
dc.l is_normal ; sprite_flip ; flag for mirroring data left<>right
dc.l 0 ; sprite_coffx ; x offset from center for collision box center
dc.l 0 ; sprite_coffy ; y offset from center for collision box center
dc.l 16/2 ; sprite_hbox ; width of collision box
dc.l 16/2 ; sprite_vbox ; height of collision box
dc.l BMP_LIVES ; sprite_gfxbase ; start of bitmap data
dc.l 4 ; (BIT DEPTH) ; bitmap depth (1/2/4/8/16/24)
dc.l is_RGB ; (CRY/RGB) ; bitmap GFX type
dc.l is_trans ; (TRANSPARENCY) ; bitmap TRANS flag
dc.l 16*16/2 ; sprite_framesz ; size per frame in bytes of sprite data
dc.l 16/2 ; sprite_bytewid ; width in bytes of one line of sprite data
dc.l 0 ; sprite_animspd ; frame delay between animation changes
dc.l 0 ; sprite_maxframe ; number of frames in animation chain
dc.l ani_rept ; sprite_animloop ; repeat or play once
dc.l edge_ignore ; sprite_wrap ; wrap on screen exit, or remove
dc.l spr_inf ; sprite_timer ; frames sprite is active for (or spr_inf)
dc.l spr_linear ; sprite_track ; use 16.16 xadd/yadd or point to 16.16 x/y table
dc.l 0 ; sprite_tracktop ; pointer to loop point in track table (if used)
dc.l spr_unscale ; sprite_scaled ; flag for scaleable object
dc.l %00100000 ; sprite_scale_x ; x scale factor (if scaled)
dc.l %00100000 ; sprite_scale_y ; y scale factor (if scaled)
dc.l -1 ; sprite_was_hit ; initially flagged as not hit
dc.l 0 ; sprite_CLUT ; no_CLUT (8/16/24 bit) or CLUT (1/2/4 bit)
dc.l can_hit ; sprite_colchk ; if sprite can collide with another
dc.l cd_keep ; sprite_remhit ; flag to remove (or keep) on collision
dc.l single ; sprite_bboxlink ; single for normal bounding box, else pointer to table
dc.l 1 ; sprite_hitpoint ; Hitpoints before death
dc.l 2 ; sprite_damage ; Hitpoints deducted from target
dc.l 16/2 ; sprite_gwidth ; GFX width (of data)

; Objects Object
dc.l 1 ; (REPEAT COUNTER) ; Create this many objects of this type (or 1 for a single object)
dc.l is_active ; sprite_active ; sprite active flag
dc.w 100,0 ; sprite_x ; 16.16 x value to position at
dc.w 100,0 ; sprite_y ; 16.16 y value to position at
dc.w 0,0 ; sprite_xadd ; 16.16 x addition for sprite movement
dc.w 0,0 ; sprite_yadd ; 16.16 y addition for sprite movement
dc.l 8 ; sprite_width ; width of sprite (in pixels)
dc.l 8 ; sprite_height ; height of sprite (in pixels)
dc.l is_normal ; sprite_flip ; flag for mirroring data left<>right
dc.l 0 ; sprite_coffx ; x offset from center for collision box center
dc.l 0 ; sprite_coffy ; y offset from center for collision box center
dc.l 8/2 ; sprite_hbox ; width of collision box
dc.l 8/2 ; sprite_vbox ; height of collision box
dc.l BMP_OBJECT ; sprite_gfxbase ; start of bitmap data
dc.l 4 ; (BIT DEPTH) ; bitmap depth (1/2/4/8/16/24)
dc.l is_RGB ; (CRY/RGB) ; bitmap GFX type
dc.l is_trans ; (TRANSPARENCY) ; bitmap TRANS flag
dc.l 8*8/2 ; sprite_framesz ; size per frame in bytes of sprite data
dc.l 8/2 ; sprite_bytewid ; width in bytes of one line of sprite data
dc.l 0 ; sprite_animspd ; frame delay between animation changes
dc.l 0 ; sprite_maxframe ; number of frames in animation chain
dc.l ani_rept ; sprite_animloop ; repeat or play once
dc.l edge_ignore ; sprite_wrap ; wrap on screen exit, or remove
dc.l spr_inf ; sprite_timer ; frames sprite is active for (or spr_inf)
dc.l spr_linear ; sprite_track ; use 16.16 xadd/yadd or point to 16.16 x/y table
dc.l 0 ; sprite_tracktop ; pointer to loop point in track table (if used)
dc.l spr_unscale ; sprite_scaled ; flag for scaleable object
dc.l %00100000 ; sprite_scale_x ; x scale factor (if scaled)
dc.l %00100000 ; sprite_scale_y ; y scale factor (if scaled)
dc.l -1 ; sprite_was_hit ; initially flagged as not hit
dc.l 0 ; sprite_CLUT ; no_CLUT (8/16/24 bit) or CLUT (1/2/4 bit)
dc.l can_hit ; sprite_colchk ; if sprite can collide with another
dc.l cd_keep ; sprite_remhit ; flag to remove (or keep) on collision
dc.l single ; sprite_bboxlink ; single for normal bounding box, else pointer to table
dc.l 1 ; sprite_hitpoint ; Hitpoints before death
dc.l 2 ; sprite_damage ; Hitpoints deducted from target
dc.l 8/2 ; sprite_gwidth ; GFX width (of data)

Link to comment
Share on other sites

Sorry for the late reply.

 

Thanks for that - kinda makes sense :)

 

So I changed my 8*8 image to 16*16 and altered the bounding box to 8*8 and all is fine.

 

Did some more pratting around last night - got hung up on a few things so didn't acheive as much as I wanted but i'm getting there.

 

Hope to post a vid a little later.

 

One thing that's been running around my head is how to store room info, I thought about storing everything in data statements ( e.g x, y, block type ) and iterating through - does this make sense ??

 

Another thing is all of MM's platforms are made up of multiple character blocks, but in RB+ do I have to over allocate each individual block in the rapinit.s, say 100, even though I may not use them on all levels ?

 

Anyhoo, keep on keeping on.

Link to comment
Share on other sites

One thing that's been running around my head is how to store room info, I thought about storing everything in data statements ( e.g x, y, block type ) and iterating through - does this make sense ??

 

Another thing is all of MM's platforms are made up of multiple character blocks, but in RB+ do I have to over allocate each individual block in the rapinit.s, say 100, even though I may not use them on all levels ?

 

Anyhoo, keep on keeping on.

 

I wouldn't load each tile up as a separate object, you will eat all the bandwidth with the ObjectProcessor processing the list.

 

The best way would be a single image (object) that you use as the screen, and draw into it. - Or even better just have a character map in ram that you check against, but use a full 16 bit image for the entire screen, eg, store each screen as a static bitmap 320x200 and work out where you are in your character table (which isn't draw)

  • Like 1
Link to comment
Share on other sites

 

I wouldn't load each tile up as a separate object, you will eat all the bandwidth with the ObjectProcessor processing the list.

 

The best way would be a single image (object) that you use as the screen, and draw into it. - Or even better just have a character map in ram that you check against, but use a full 16 bit image for the entire screen, eg, store each screen as a static bitmap 320x200 and work out where you are in your character table (which isn't draw)

OK - so if i understand correctly, draw the whole cavern as an image and then calculate where the player sprite is against the x and y's of the platform on the image ??

 

I can see that working but how would I handle interactive platforms - E.G the ones where they crumble away ? would these be laid over the top ?

 

As an aside to this though this is what I came up with earlier but doesn't do as expected - just dumps all the blocks in the bottom left hand corner of the screen

sub display_cavern

    local LVAR_brick_id%, LVAR_platform_id%, LVAR_y%, LVAR_x%
    dim x as short
	
	LVAR_brick_id = ID_bricks
	LVAR_platform_id = ID_platform
	LVAR_x = 20
	LVAR_y = 20
	
	for x = 0 to 199
		if DATA$[x] = "1" THEN
			rsetobj(LVAR_brick_id, R_sprite_x, (LVAR_x<<16)) 				' set x-position'
			rsetobj(LVAR_brick_id, R_sprite_y, (LVAR_y<<16)) 				' set y-position'
			LVAR_x = LVAR_x + 16
			LVAR_brick_id = LVAR_brick_id + 1
		elseif DATA[x] = "2" THEN
			rsetobj(LVAR_platform_id, R_sprite_x, (LVAR_x<<16))				' set x-position'
			rsetobj(LVAR_platform_id, R_sprite_y, (LVAR_y<<16))				' set y-position'
			LVAR_x = LVAR_x + 16
			LVAR_platform_id = LVAR_platform_id + 1
		elseif DATA[x] = "x" THEN                                                               ' its the end of the line so advance y and reset x'
			LVAR_y = LVAR_y + 16
			LVAR_x = 20
                elseif DATA[x] = "0" THEN                                                               ' its a blank block so advance the x position'
                       LVAR_x = LVAR_x + 16
		endif
	loop
	
	    '1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0'
	data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,x	'1'
	data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,x	'2'
	data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,x	'3'
	data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,x	'4'
	data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,x	'5'
	data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,x	'6'
	data 1,0,0,0,0,0,0,0,0,0,1,1,1,2,2,2,2,2,1,x	'7'
	data 1,0,0,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,1,x	'8'
	data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,x	'9'
	data 1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,x	'0'
	
end sub

Cheers for all the help and advice.

Edited by saboteur
Link to comment
Share on other sites

After some jiggery pokery i've concluded that DATA[x] doesn't read anything at all which is a bit of a head scratcher.

 

Gonna have to try something else then :(

Instead of data, you could use

 

Set varname[] As integer

0,0,0,0,0,0,0,0. Blah blah

End set

  • Like 2
Link to comment
Share on other sites

Instead of data, you could use

 

Set varname[] As integer

0,0,0,0,0,0,0,0. Blah blah

End set

 

or

 

dim map[2,20]={{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20},{21,22,23,24,25,26,27}}  as short

 

Note: dim expects you to define number of lines first and then columns.

Edited by ggn
  • Like 1
Link to comment
Share on other sites

Also, something of lower priority for now, but this

 

 

rsetobj(LVAR_brick_id, R_sprite_x, (LVAR_x<<16)

 

can also be written as

 

rlist[LVAR_brick_id].x=LVAR_x<<16

 

which will produce much faster code in general. Also:

 

rlist[LVAR_brick_id].x_=LVAR_x<<16
can be used if the fraction part of x (i.e. the low 16 bits) is 0.
Link to comment
Share on other sites

 

Also, something of lower priority for now, but this

rsetobj(LVAR_brick_id, R_sprite_x, (LVAR_x<<16)

can also be written as

rlist[LVAR_brick_id].x=LVAR_x<<16

which will produce much faster code in general. Also:

rlist[LVAR_brick_id].x_=LVAR_x<<16
can be used if the fraction part of x (i.e. the low 16 bits) is 0.

 

 

Again, thanks for the info.

Link to comment
Share on other sites

 

rlist[LVAR_brick_id].x_=LVAR_x<<16

can be used if the fraction part of x (i.e. the low 16 bits) is 0.

 

Correction: this should be

rlist[LVAR_brick_id].x_=LVAR_x
(thanks to Sporadic for mentioning this!) Edited by ggn
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...