Bouncing ball demo

Pulp is meant for tile-based games, and this is what happens if you try to ignore the grid.

The trick here is that all 225 (!) possible displacements of the 8x8 ball are rendered as separate tiles:

Screenshot_20220123_010121

This is similar to this project, except that absolutely every possible displacement is available here. Each tile is named according to its horizontal and vertical displacement relative to the original position; for example, this selected tile is called ball 1 3. Then we store the pixel coordinates of the ball and extract the sub-tile displacements with some modulo operations:

on draw do
	hide
	
	arg0 = ball_x
	arg0 = round arg0
	arg1 = 8
	call "divmod"
	ball_tile_x = ret0
	ball_sub_x = ret1
		
	arg0 = ball_y
	arg0 = round arg0
	arg1 = 8
	call "divmod"
	ball_tile_y = ret0
	ball_sub_y = ret1
	
	draw "ball {ball_sub_x} {ball_sub_y}" at ball_tile_x,ball_tile_y
	if ball_sub_x>0 then
		ball_sub_x -= 8
		ball_tile_x += 1
		draw "ball {ball_sub_x} {ball_sub_y}" at ball_tile_x,ball_tile_y
		if ball_sub_y>0 then
			ball_sub_y -= 8
			ball_tile_y += 1
			draw "ball {ball_sub_x} {ball_sub_y}" at ball_tile_x,ball_tile_y
			ball_sub_x += 8
			ball_tile_x -= 1
			draw "ball {ball_sub_x} {ball_sub_y}" at ball_tile_x,ball_tile_y
		end
	elseif ball_sub_y>0 then
		ball_sub_y -= 8
		ball_tile_y += 1
		draw "ball {ball_sub_x} {ball_sub_y}" at ball_tile_x,ball_tile_y
	end
end

on divmod do
	ret0 = arg0
	ret0 /= arg1
	ret0 = floor ret0
	
	ret1 = ret0
	ret1 *= arg1
	ret1 *= -1
	ret1 += arg0
end

A misaligned ball touches 4 tiles, so we have to draw up to 4 tiles as well. Suppose that ball_sub_x and ball_sub_y are 1 and 3 respectively; then the tile selected above would be drawn, ball -7 3 would be drawn to the right, ball 1 -5 would be drawn below, and finally ball -7 -5 (which consists of a single pixel) would be placed in the corner. The tiles and the frames themselves are generated by manipulating the exported JSON with an external Ruby script; they are marked as player tiles, but any layer will work fine as those tiles will never be used as stand-alone objects.

The most obvious drawback is that transparency around the ball does not work because all tiles are opaque. I tried to draw the ball with the fill function alone, but it seems Pulp doesn’t properly redraw tiles that were covered by those fills and then exposed in subsequent frames, leaving a trail of black strips on the background. Making two such objects overlap results in an unmanageable number of distinct tiles.

On every frame a simple linear acceleration is applied to the ball using the accelerometer position. The collision detection code is a real mess since it has to treat all wall directions uniformly; something like a platform game would probably require fewer hit tests.

JSON: bounce_demo.zip (6.8 KB)

9 Likes

Wow, impressive! Obviously the SDK is much better suited for this type of game, but very cool that you managed to bend Pulp enough to make it happen :slight_smile:

The fill function appears to be implemented incorrectly in the web-based emulator, resulting in anti-aliasing when using floating-point coordinates. I suspect this will get fixed … in the meantime you could either floor / round your fill arguments, or alternatively ( as a quick & dirty fix ) only floor the origin of your “clear” fill and increase the size by 1 pixel. Attached is a simple example ( use accelerometer to control ).

Fix.zip (2.1 KB)

1 Like

The coordinates are already rounded, because otherwise the tile lookup will fail (those ball names expect integers). What I mean is the following:

on draw do
	hide
	
	x = floor ball_cx
	y = floor ball_cy
	
	fill "white" at x,y,8,8
	fill "black" at x,y,8,8
end

Now as the ball moves around parts of it will remain on the map and never get repainted. Using a larger area for the white fill helps, but at the cost of losing even more transparency.

Very cool! It’s really neat that you were able to figure out how to programmatically modify the JSON! Do you have any info you would be willing share on the structure of the JSON?

I think this is now fixed.

This is epic! Can't believe you actually managed to do this.