 # 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: 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 `fill`s 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 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.