Tutorial game: let’s move around (part 7)

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:


Player movement

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
    • redraw
  • 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=1 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.