Drawing Multiple Sprites Of A Water Tank
Recently, I was pointed to a beautiful historical game for teaching simulation. It's
a pipeline puzzle
that also offers a way to evaluate the pressure in the pipeline depending on how the pipeline is connected.
Originally built in Smalltalk, it was recently
ported to JavaScript
. It works, but it stil had an issue: the tank icon always showed it was empty. That's because there were no sprites showing it filled in different stages.
We decided to remedy the situation using
Glamorous Toolkit
.
The challenge is to take this picture and draw multiple sprites with the tank with water inside. We start by loading the picture.
array := ZnClient new
url: 'http://plumbin.ward.wiki.org/assets/pages/plumbin-in-wiki/tiles/tank.png'; get.
form := array readStreamDo: [:s | Form fromBinaryStream: s].
The first thing we need to do is to figure out where we should draw the blue square. So, we create a little tool based on
BlDevCrossover
to help us investigate. This is a decorator that can be added to any element and shows the position of the mouse within the bounds of the element:
element := form asElement.
BlDevCrossover on: element.
element asScalableElement
Once we know the coordinates, we an now try it. Ah, but how do we draw on a form? We first need a canvas. We know that the canvas can be instantiated by querying Bloc preferableSpartaCanvas
. To learn how we draw on it, we can just search in the environment:
Ok, so we can use fill
. Let's try it quickly:
canvas := Bloc preferableSpartaCanvas extent: 40@40.
form asElement drawMeWithEffectsOnCanvas: canvas.
canvas fill
paint: Color blue;
path: (7@6 corner: 33@32);
draw.
canvas
Looks good. Now we can produce multiple canvases:
canvases := (6 to: 32) collect: [ :y |
canvas := Bloc preferableSpartaCanvas extent: 40 @ 40.
form asElement drawMeWithEffectsOnCanvas: canvas.
canvas fill
paint: Color blue;
path: (7 @ y corner: 33 @ 32);
draw.
canvas ]
And now we can export them as PNGs:
canvases doWithIndex: [ :each :i |
PNGReadWriter
putForm: each asForm
onFileNamed: 'tank' , i asString , '.png' ].
'.' asFileReference
That's it. We started from a problem and we worked our way through it in the same uniform environment. Along the way, we constructed a custom tool to answer a question. We searched for similar examples. We prototyped and explored the results. All integrated.
This article is based on
a Twitter thread
I wrote recently.