saboteur Posted March 22, 2017 Author Share Posted March 22, 2017 Ran into an issue last night regarding player movement and animation. The player can move left and right no problem but I utilise a 16*16 bmp with 8 frames ( 4 for left and for 4 right ) and using a global frame counter I can cycle through the frames as required.... but it's way to fast. Anyway to slow this down ? SUB Player_Update_Position LOCAL LVAR_x%, LVAR_pad% LVAR_x=rgetobj(ID_player,R_sprite_x) ' get player's current X position LVAR_pad=getpad(1) ' get PAD1 status (from U235) rlocate 100,80 print "PLAYER DIRECTION ", player_direction, rlocate 100,100 print "FRAME ", GVAR_player_frame IF LVAR_pad=PAD_LEFT THEN ' was LEFT pressed? IF player_direction = 1 THEN IF GVAR_player_frame < 7 THEN GVAR_player_frame = GVAR_player_frame + 1 ELSEIF GVAR_player_frame = 7 THEN GVAR_player_frame = 4 ENDIF ELSEIF player_direction = 2 THEN GVAR_player_frame = 0 ENDIF player_direction = 1 IF LVAR_x<>(37<<16) THEN ' already at far-left position? LVAR_x=LVAR_x-(1<<16) ' subtract 1 from X-position endif ELSEIF LVAR_pad=PAD_RIGHT THEN ' was RIGHT pressed? IF player_direction = 2 THEN IF GVAR_player_frame < 3 THEN GVAR_player_frame = GVAR_player_frame + 1 ELSEIF GVAR_player_frame = 3 THEN GVAR_player_frame = 0 ENDIF ELSEIF player_direction = 1 THEN GVAR_player_frame = 4 ENDIF player_direction = 2 IF LVAR_x<>(300<<16) THEN ' already at far-right position? LVAR_x=LVAR_x+(1<<16) ' add 1 to X-position ENDIF ELSEIF LVAR_pad=PAD_A THEN ' was JUMP pressed? rlocate 100,120 print "JUMP PRESSED" GVAR_player_is_jump = 1 GVAR_player_x = rgetobj(ID_player, R_sprite_x) GVAR_player_y = rgetobj(ID_player, R_sprite_y) ENDIF 'rsetobj(ID_player,R_sprite_x,LVAR_x) ' store the new x-position RSETOBJ(ID_player, R_sprite_x, LVAR_x) RSETOBJ(ID_player, R_sprite_gfxbase, GVAR_player_gfx_loc + (GVAR_player_gfx_size*GVAR_player_frame)) END SUB ' exit Quote Link to comment Share on other sites More sharing options...
Sporadic Posted March 22, 2017 Share Posted March 22, 2017 Raptor does have built in animation and speed for frames. But if you need to roll your own then what i do is have a separate int and +1 whilst moving. Then only update your frames when that equals 3 (for example). Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 22, 2017 Author Share Posted March 22, 2017 Raptor does have built in animation and speed for frames. But if you need to roll your own then what i do is have a separate int and +1 whilst moving. Then only update your frames when that equals 3 (for example). Great minds Sporadic, just implemented that in the main loop seems to do the trick at the moment. Any recomendation on capturing a video of where i'm at - I tried using VLC but got very mixed results. I want to implement jumping tonight and then i can post an .abs 1 Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted March 22, 2017 Share Posted March 22, 2017 Any recomendation on capturing a video of where i'm at - I tried using VLC but got very mixed results. I'd be happy to make a video for you. 1 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 22, 2017 Author Share Posted March 22, 2017 Thanks for the offer CJ, what do you need ? just .abs and assets or the whole project folder. WARNING : if the it's the whole project then no p*ss taking over the rats nest of code i've created so far Although there's not much to see as i've not got the jumping working yet 1 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 22, 2017 Author Share Posted March 22, 2017 ABS file http://allwheeler.com/images/manic_1.abs 1 Quote Link to comment Share on other sites More sharing options...
ggn Posted March 22, 2017 Share Posted March 22, 2017 FWIW The .abs file will do fine. Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted March 22, 2017 Share Posted March 22, 2017 https://youtu.be/D0lk-Rgl5qc As I suspected - object overload (see the tearing at the top of the screen) I think you are going to have to go with a single bitmap for the entire screen and use the level data as a collision map. However! Very positive start, keep at it! 1 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 22, 2017 Author Share Posted March 22, 2017 Now with added audio POWA - see what i did there http://allwheeler.com/images/manic_abs/manic_1.abs Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 22, 2017 Author Share Posted March 22, 2017 Thanks CJ - that is way slower than when i run it on this here laptop though ? Am I doing something wrong ? or is it the number of frames setting on the capture software. Yeah I agree about overload but I want to make a completable level this way then I can at least point to it and say that's done now let's make it better Quote Link to comment Share on other sites More sharing options...
Sporadic Posted March 22, 2017 Share Posted March 22, 2017 (edited) Thanks CJ - that is way slower than when i run it on this here laptop though ? Am I doing something wrong ? or is it the number of frames setting on the capture software. Yeah I agree about overload but I want to make a completable level this way then I can at least point to it and say that's done now let's make it better The emulator is usually faster than real hardware. A quick win to save the slowdown and tearing would be to reduce the size of the particle layer. This is the transparent layer that the print commands and particles use. By default it is set to 320 by 240 px. You can make this smaller to reduce the amount of overdraw the downside being you can't show a full screen of text. If you look in the rapapp.s file - scroll down a little and look for raptor_particle_buffer_height . Change that to 16. This will give you about 1 lines worth of text area. Remember to change any rlocate statements to 0 on the y axis though. The print command itself isn't particularly fast either, so you could try commenting the frame counter out for now. If all else fails, you are probably best doing as CJ suggested and using 1 large background image, a 2d array for collisions and then just use sprites for special cases like crumbling blocks etc. Using lots of 16px wide sprites with an 8px image inside, when layed out next to each other, you are basically overlapping 50% of all the objects along every scanline. These are the kind of things that can crop up developing on old hardware Keep at it though, it's all part of the jaguar learning experience Edited March 22, 2017 by Sporadic 4 Quote Link to comment Share on other sites More sharing options...
omf Posted March 22, 2017 Share Posted March 22, 2017 (edited) you could use getpixel (which is documented around these forums somewhere) to retrieve the pixel colour of points around your player, if you have specific colours for the walls and floors like it looks like you have this can be used as 'you cant go any further in that direction' i have started to turn this into a platform game engine i have put this on that back burner for some time though unfortunately Edited March 22, 2017 by omf Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 22, 2017 Author Share Posted March 22, 2017 you could use getpixel (which is documented around these forums somewhere) to retrieve the pixel colour of points around your player, if you have specific colours for the walls and floors like it looks like you have this can be used as 'you cant go any further in that direction' i have started to turn this into a platform game engine i have put this on that back burner for some time though unfortunately That is actualy were I think i'm headed, we'll see though. I'm just happy to get something on the screen reacting to commands at the moment Again - thanks for all the help, it's appreciated. 1 Quote Link to comment Share on other sites More sharing options...
ggn Posted March 22, 2017 Share Posted March 22, 2017 (edited) If I've been silent so far it was because I was testing some things. So...First of all, I can see two options to gain performance out of this:a) Use a single big backgrop object and all the movable parts as different objects (such as crumbly walls or animated stuff). This way you get a ton of OP processing time backb) Keep using tiles-as-objects but add branch objectsOption b is a bit more advanced so I wouldn't recommend that at all. So let's go with a. The question of course would be "how to fill such an object"? Here I could just tell you to draw each map as bmp, pack them, import them into the game and unpack them per screen. But that's again a bit advanced and hassle-y. I'd only recommend that if your graphic artist would like to go wild and draw the level as a single thing, not as tiles.The other option is, like you did, store the map as rectangular tiles into values inside an array. Then you can draw the map easily and check for collision and stuff using this. But again the question remains, how to fill the object?That's why I sat down and created a mini project that does exactly this. Let me paste the code over and walk through it: set maps[1000][20] as short {0x0A,0x10,0x47,0x83,0x25,0x0A,0x48,0x83,0x82,0x00,0x83,0x85,0x47,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, ... snip 998 lines... {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x1C,0x1D,0x1E,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01} 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 49 ' Draw map for y=0 to 19 for x=0 to 19 c=maps[map*20+y][x] tilex=(c % 20) tiley=(c/20) for i=0 to 7 lpoke strptr(scrbuf)+y*(160*+x*8+i*160,lpeek(strptr(tiles)+tilex*8+tiley*(160*+i*160) lpoke strptr(scrbuf)+y*(160*+x*8+i*160+4,lpeek(strptr(tiles)+tilex*8+tiley*(160*+i*160+4) next i next x next y 'Bring the map to screen for ph=0 to pi/2 step pi/90/2 rlist[1].x=(352-sin(ph)*336)*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 First of all, the map itself. As you see it's stored inside the array maps, which is 20 columns and 1000 lines. If 1000 seems too big, it's just that I stored 50 levels one after the other. So maps[0][0] to maps[19][19] has the first map, maps[20][20] to maps[20+19][20+19] the second etc. You'll also notice that each line of the map is enclosed in curly braces, that's essential so the compiler can know how the map is dimensioned. Lastly that "0x" business before each value means that the value is in hex. You don't need to do that yourself, plain decimal values are ok. I used hex because the maps were taken off a game and they came in binary format (hex looks much more tidy). FWIW the maps and tileset I used were taken from a PD ST game called Lost world (which, incidentally, is a manic miner clone ).The most crucial part is that of map drawing. But to explain this I have to lay down some parameters first. The screen object is a 320x200 buffer in 4bpp mode The tiles are stored in a completely similar object The tiles are 16x8 pixels each So if you do some number crunching then you'll see that each tile is 8 bytes in width (16 pixels * 4 bits per pixel / 8 bits per byte. So we need to copy 8 bytes horizontally times 8 times vertically per tile. For this I used lpoke which copies 4 bytes in 1 go. Which means we'll need 2 lpokes for copying 8 bytes per tile's line. The innermost loop (for i ... next i) copies a tile from the tile map at coordinates (tilex,tiley) to screen coordinates (x,y). tilex,tiley coordinates come from the map's current tile value, and converted to position inside the map. i loops for as many vertical lines per tile. The x and y loops simply iterate through the whole map.Then the rest is just bringing the map object to screen, pausing, and then sending it away. I decided to do this in order not to show the map redraws which could be ugly (plus, this is the 64 bit powerhouse, let's show some big object movement there!). But if you notice I don't pause when the object is off screen but it seems that the map is filled up pretty quick (at least on vj ).So anyway that's mostly it. It shouldn't be too hard to convert to 8x8 tiles, just one lpoke per line would be needed and the offset calculation will need some adjusting but I trust people will get the idea! Full project will be pushed to the repositories right after I hit "submit" here . drawmap.abs Edited March 23, 2017 by ggn 6 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 23, 2017 Author Share Posted March 23, 2017 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 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 0,0 ; sprite_x ; 16.16 x value to position at dc.w 0,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 320 ; sprite_width ; width of sprite (in pixels) dc.l 240 ; 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 320/2 ; sprite_hbox ; width of collision box dc.l 240/2 ; sprite_vbox ; height of collision box dc.l BMP_BACKDROP ; 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 320*240*2 ; sprite_framesz ; size per frame in bytes of sprite data dc.l 320*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_wrap ; 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 no_CLUT ; sprite_CLUT ; no_CLUT (8/16/24 bit) or CLUT (1/2/4 bit) dc.l cant_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 0 ; sprite_damage ; Hitpoints deducted from target dc.l 320/2 ; sprite_gwidth ; GFX width (of data) Any idea why that is incorrect ? Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted March 23, 2017 Share Posted March 23, 2017 Bit depth is 4, so your *2 need to be /2 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 23, 2017 Author Share Posted March 23, 2017 DOH! Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 23, 2017 Author Share Posted March 23, 2017 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 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 23, 2017 Author Share Posted March 23, 2017 Bit depth is 4, so your *2 need to be /2 No - still not right Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted March 23, 2017 Share Posted March 23, 2017 That looks fine - 0,0 is the very top left of the screen - you need to use a relative offset. This is what I use for the ST ports: dc.w 17,0 ; sprite_x ; 16.16 x value to position at dc.w 33,0 ; sprite_y ; 16.16 y value to position at 1 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 23, 2017 Author Share Posted March 23, 2017 when i set the x and y origin to 0 it's as above but if i set them to 20 as below the backdrop is displayed correctly. dc.w 20,0 ; sprite_x ; 16.16 x value to position at dc.w 20,0 ; sprite_y ; 16.16 y value to position at I'm sorry to ask what is probably a stupid question(s) but why is 0,0 not the top left of the screen ? Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted March 23, 2017 Share Posted March 23, 2017 when i set the x and y origin to 0 it's as above but if i set them to 20 as below the backdrop is displayed correctly. dc.w 20,0 ; sprite_x ; 16.16 x value to position at dc.w 20,0 ; sprite_y ; 16.16 y value to position at I'm sorry to ask what is probably a stupid question(s) but why is 0,0 not the top left of the screen ? It's not a stupid question 0,0 is the top left. The screen isn't 320x200 Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 23, 2017 Author Share Posted March 23, 2017 It's not a stupid question 0,0 is the top left. The screen isn't 320x200 Right'o - what is the native resolution then or is that dependant on PAL or NTSC t.v's ? I'm trying to get my head around it and failing at the moment. Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted March 23, 2017 Share Posted March 23, 2017 The width can be set in software, the height is how many scanlines there are The default mode for RAPTOR applications is ~ 352*248 (maximum) but quite a lot will be in overscan areas. Quote Link to comment Share on other sites More sharing options...
saboteur Posted March 23, 2017 Author Share Posted March 23, 2017 That makes sense so pick a resolution and stick to it Thanks for all the help guys - it's starting to sink in, honest. 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.