How-To: Make sprites pushable

Hi everyone,

do you like pushing sprites around? I bet you do. Here's how!

push sprites

This imlementation was the result of trying to get this to work for my own game. I tried to make the tutorial really beginner-friendly, so I'll discuss almost every line of code individually.

Implementation

Let's take a look at the complete code first (We'll break it down afterwards). This is the script of the sprite we want to make pushable. There is no other code needed elsewhere.
on interact do
	// Determine destination coordinated of crate
	DesX = event.x
	DesY = event.y
	
	if event.dy==1 then
		DesY++
	elseif event.dy==-1 then
		DesY--
	elseif event.dx==1 then
		DesX++
	elseif event.dx==-1 then
		DesX--
	end
	
	// Check whether the destination is solid/blocked
	isSolid = solid DesX,DesY
	
	// If the destination isn't solid, then the crate can be moved there
	if isSolid==0 then
		tell DesX,DesY to
			swap "Crate" // Swap with crate
		end
		swap "white" // Swap in empty tile where the crate was
		goto event.x,event.y
	end
end

You didn't understand everything? That's okay, let's go over the code line-by-line.

First of all, the whole code is packed into an interact event. This event triggers as soon as the player bumps into the sprite, like if he's attempting to push it.


// Determine destination coordinated of crate
	DesX = event.x
	DesY = event.y
	
	if event.dy==1 then
		DesY++
	elseif event.dy==-1 then
		DesY--
	elseif event.dx==1 then
		DesX++
	elseif event.dx==-1 then
		DesX--
	end

In the code block above we determine the coordinates the crate is about to be pushed to. We create two variables DesX and DesY, which are filled with the coordinates of the event. Because the interact event is called on the crate, the x and y coordinates of the event correspond to those of the crate.

DesX and DesY now contain the current position of the crate, but we wanted the destination position. For that we have to know into which direction the crate is being pushed. Therefore a check whether event.dy or event.dx changed is in order. They indicate the direction the player moved into (x is horizontal; y is vertical). If the player moved down for example (event.dy==1), the crate has to move down too. We therefore increase DesY by 1 (DesY++) and have our destination coordinates. Note here, that the top left tile of a room is 0,0 and the bottom right one is 24,14, so a downward movement is an increase in Y.


	// Check whether the destination is solid/blocked
	isSolid = solid DesX,DesY

	// If the destination isn't solid, then the crate can be moved there
	if isSolid==0 then

Can we push the crate through a wall? Well, if you're strong enough and have a really sturdy crate, but otherwise, no. Thus we'll check if there is a wall ahead or not. As DesX and DesY already point towards the destination of the crate, we'll check those coordinated with a solid function and store the result in the variable isSolid. If the tile at DesX, DesY is solid, isSolid will be 1. Otherwise, if isSolid is 0, there is nothing blocking our way and we can move ahead. We pour this check into code with if isSolid==0 then. The following code will only be executed if the path ahead is free.


		tell DesX,DesY to
			swap "Crate" // Swap with crate
		end
		swap "white" // Swap in empty tile where the crate was

Where do we want the crate? Right, at DesX, DesY! We therefore tell DesX, DesY to swap in our crate. Note, that the crate tile has to be named "Crate". We close the tell with an end, so Pulp knows we don't want to "talk" to the destination tile anymore.

Now, and you will never see this if you play, but there are actually two crates now: in the original position and in the destination position. To get rid of the original crate we swap in a "white" tile. You can change this tile to any world tile that makes up your background, in this case a white background. Note, that the tile swapped in will always be the same, so the area where the crate is moveable should have the same tile as world tile everywhere (I'll show you a way around this limitation a bit further down).


		goto event.x,event.y
	end
end

Congrats, you've moved the crate. But wait, the player is still where he was. If thats fine with you, feel free to skip the next line shown above (Don't skip the two end!!). If you want the player to follow the crate though, you'll have to tell him to do so. Tell him to goto event.x, event.y, the original position of the crate.

Congratulations, you did it! Push your crate around a little and be proud. If you're done, let's move on to two small addition.


Remember world tile below sprite

To achieve this we basically add two lines of code (marked as NEW below). With the first one the tile onto which the crate is pushed is being recorded in newUnder. Then, with the second new line, underCrate is updated to contain the tile we just safe. The next time the crate is pushed and swap underCrate is triggered, it will swap in the tile the box was standing on.

if isSolid==0 then
		tell DesX,DesY to
			newUnder = event.tile // NEW
			swap "Crate" 
		end
		swap underCrate
		underCrate = newUnder // NEW
		goto DesX,DesY
	end	
end

Do something when being pushed into a solid tile

This one is pretty easy. Just add the following new lines either right before if isSolid==0 then or after you closed that if-statement with the second to last end and then add your code. Fun idea: With solidTile = name DesX, DesY you can store the name of the solid tile beyond the crate in solidTile. With some if-statements you could do different things depending on what the tile is.

if isSolid==1 then

end

Closing remarks

Hey, you made it through! Thank you so much for reading! I hope you found this quick how-to useful and could learn something from it. I also hope the style, grammar and spelling of this quick tutorial weren't too bad. English isn't my first language. Thanks again for reading. Now go make something awesome in Pulp (that maybe involves pushing stuff around)!
23 Likes

I just wanted to say thanks. I copy/pasted this into my game and it works great!

I've made some slight improvements to code

  1. store name of the pushable sprite that way any other sprite can mimic it without it turning into a crate

  2. remember the last tile it was on so that tiles/items don't get turned into white

on interact do
	if str==0 then
		say "this is too heavy to push"
	else
		// Determine destination coordinated of crate
		DesX = event.x
		DesY = event.y
		
		// name of the sprite so that other sprites can mimick it
		tilename = name DesX,DesY
		
		DesX += event.dx
		DesY += event.dy
		
		// Check whether the destination is solid/blocked
		isSolid = solid DesX,DesY
		tilenew = name DesX,DesY
		
		// code to stop box passing through certain tiles
		if tilenew=="ladder" then
			isSolid = 1
		end
		if tilenew=="boxstopper" then
			isSolid = 1
		end
		
		
		// If the destination isn't solid, then the crate can be moved there
		if isSolid==0 then
			
			tell DesX,DesY to
				swap tilename // Swap with crate
			end
			
			// remebers last tile and swaps it
			swap tileold
			tileold = tilenew
			goto event.x,event.y
		end
	end
end