Note: The source code for this tutorial is available in the tutorials/TutorialGame_Introduction/part7.ras (in the TRSE framework), together with all resources mentioned in these texts.
Congrats on getting this far in the tutorials!
We now assume that you have a working level renderer, similar to the one we completed in the previous part. In this tutorial, we’ll combine part 6 (level renderer) with part 3 (sprites).
We’ll start off by merging part 3 with part 6. Start by copying the source code from part 6 to a new file (like, part 7), and remove the joystick-level-browsing in the Raster IRQ routine.
First, add player sprite position variables in the var section:
var ... player_x: integer; player_y: byte; @define playerSprite 0
Note that player_x needs to be an integer, since values will exceed 256 (up to 320). In addition, we define sprite “0” to be our player sprite throughout the code by using a preprocessor define “@playerSprite“.
Now add a sprite initializer routine, similar like the one from part 3:
procedure InitMainSprite(); begin setspriteloc(@playerSprite,$C8,0); player_x:=80; player_y:=120; spritepos(player_x,player_y,@playerSprite); SPRITE_BITMASK:=%00000001; SPRITE_MULTICOLOR:=$FF; SPRITE_MULTICOLOR_REG1:=LIGHT_GREEN; SPRITE_MULTICOLOR_REG2:=GREY; SPRITE_COLOR[@playerSprite]:=RED; end;
Be sure to call this sprite initialization procedure in the main block:
begin Initialize(); InitMainSprite(); levelpointer:=@levelPosition; RenderCharsetColorLevel(curLevel_x,curLevel_y,$04); ...
You should now have your little sprite rendered on top of the levels:
Next up, we’ll be adding joystick support. Joystick programming is acutely easy to implement in Turbo Rascal SE:
procedure MovePlayerSprite(); begin joystick(); player_x:=player_x+joystickright-joystickleft; player_y:=player_y+joystickdown-joystickup; spritepos(player_x,player_y,@playerSprite); end;
Here, the “joystick()” method reads input from the joystick port 2 and populates the joystickvariables “joystickup”,”joystickdown”,”joystickleft”, “joystickright” and “joystickbutton”. If there is no movement in the given direction, the variable is 0. If there is a performed acton, 1. The easiest way to move the player x/y positions in then by just adding/subtracting the joystick values.
Now all you need to do is call the MovePlayerSprite() procedure in the main raster funcion:
interrupt RasterRenderLevels(); begin StartIRQ(@useKernal); MovePlayerSprite(); CloseIRQ(); end;
You should now be able to freely move your sprite around.
Traversing the levels
In this final section, we add support for traversing the levels. When your player sprite enters the border regions, we should move the sprite to the opposite part of the screen and render a new screen in that direction. Here’s the idea flowchart:
- Check whether the player variable hits close to any of the four borders
- If it does, and the corresponding direction contains a level (0 or larger, less than level size x/y), then
- Move the player coordinate to the opposite screen
- change current level x/y to the corresponding direction
- if not, constrain sprite movement (so it won’t move outside the screen
- Repeat for all 4 directions
Here’s a method that does exactly this:
@define miny 66 @define maxy 210 @define minx 16 @define maxx 320 procedure TraverseLevels(); var redraw:byte=0; begin redraw:=0; if (player_x<@minx) then begin if (curLevel_x<>0) then begin dec(curLevel_x); player_x:=@maxx-1; redraw:=1; end else player_x:=@minx+1; end; if (player_x>@maxx) then begin if (curLevel_x+1<>m_rl_width) then begin inc(curLevel_x); player_x:=@minx+1; redraw:=1; end else player_x:=@maxx-1; end; if (player_y<@miny) then begin if (curLevel_y<<>0) then begin dec(curLevel_y); player_y:=@maxy-1; redraw:=1; end else player_y:=@miny+1; end; if (player_y>@maxy) then begin if (curLevel_y+1<>m_rl_height) then begin inc(curLevel_y); player_y:=@miny; redraw:=1; end else player_y:=@maxy-1; end; if redraw then begin levelpointer:=@levelPosition; RenderCharsetColorLevel(curLevel_x,curLevel_y,$04); end; end;
And that’s it for this tutorial! In the next part we’ll be will add background collision support.