Spritely Beta

@Mark I was thinking about this some more and just wondered: why not just draw a big version of the actual image to draw the image. It seems like that would be efficient. There would be no need to loop through the grid cells, or the hassle of setting up a mesh.

Just set noSmooth(), a clipping rectangle and draw the image itself. Then you can draw gridlines over it the way described above.

Yeah, that blinding moment of obvious finally hit me last night – but only after I tangled myself into knots with the mesh. I’m this close to stripping draw() down to nothing, getting rid of the grid[x][y] element, and making all the string functions run straight from the image.

Also made yet more cosmetic changes that I think look pretty nice. I have to run into a meeting for the next few hours, but when I get out I hope to tidy up. This actually simplifies quite a few things, not just draw.

Just one problem standing between me and the faster, simpler revision–but it’s a weird one.

Flood fill works in a simple, but recursive manner by identifying candidate pixles above, below, left and right of a target pixel that could be changed, changing the pixels, then looking around changed pixels for other potential candidates. It’s not fancy, but it’s effective. Only now it’s locking up tighter than a drum.

Here’s the weird part: if I put in a displayMode(STANDARD) so I can watch values… it works fine. In fact, I don’t even have to throw in a watch, or a print. Putting it in standard mode fixes the problem, while commenting out just the change in displaymode, causes the routine to lock up. It’s like it only behaves when it knows I’m watching.

Hmm the only thing that displayMode(STANDARD) should change in your code is the following:

  • The return value of displayMode() – called without arguments
  • The values of WIDTH and HEIGHT

Feel free to email me the project if you need help with this bug (simeon@twolivesleft.com)

Here’s take 4 with the editgrid gutted and everything done directly on the image without an intermediate grid. A heaping pile of code went bye-bye.

http://devilstower.posterous.com/spritely-beta-take-4

A couple of things where I’d definitely appreciate a second set of eyeballs:

In the EditGrid class, the floodFill and textPix functions which together do area fill, can still generate runaway cascades in which it just keeps sitting there re-nominating spots that should have already been changed. I put a hard stop in the routine at 1024 dots (as much as a 32x32 image can generate) so it shouldn’t generate overruns, but I’d love to understand what I missed in this. I’m sure it’s staring me in the face.

The other thing is on the Main tab the sliderPaneleTouched() function. There’s a simple bit here that resizes the image. This is probably the only place where not having the grid made it harder. When the image is getting smaller, it’s easy enough to copy from one image to another, but when sliding the image larger I ran into messy problems. I solved them with a little get / set loop, but the behavior is less than snazzy and the code is ugly. Surely there’s a better way.

Other than that, everyone now suffers the Spacecute background because it’s the onlymoderately tilable pattern in the sprite library.

One thing I notice in EditGrid:draw is that it actually draws the horizontal lines inside the vertical line loop - this is making Codea draw many more lines than it needs to. Here it is with the two loops side by side instead:

function EditGrid:draw()
    local cw, c, x, y
    cw = (self.frame.x2 - self.frame.x1) / self.img.width
    pushStyle()
    stroke(127, 127, 127, 255)
    strokeWidth(1)
    fill(0, 0, 0, 255)
    self.frame:draw()
    rectMode(CORNER)
    c = color(0, 0, 0, 255)
    sprite(self.img, self.frame:midx(), self.frame:midy(), 
           self.frame:width(), self.frame:height())
    for x = 1, self.img.width do
        line(math.floor(x * cw + self.frame.x1), self.frame.y1, 
        math.floor(x * cw + self.frame.x1), self.frame.y2)
    end
    for y = 1, self.img.height do
        line(self.frame.x1, math.floor(self.frame.y2 - cw * y), 
        self.frame.x2, math.floor(self.frame.y2 - cw * y))
    end
    popStyle()
end

The Space Cute background works brilliantly by the way :slight_smile:

Also it’s looking really polished.

@Mark I’m sure you’ve noticed spritely is now in the current build of 1.3. I’ve noticed that it can be slow when drawing pixels. How are you detecting which squares to paint when using the pencil tool?

Also would you be happy for us to submit with your latest build of Spritely? Are you happy with it?

I’ve got a slightly updated version with just a little nudge here and there. I’ll get it up to poserous shortly. I’m making a last pass through the code to make things a little neater.

Nice to see it in the build.

Great! I’m just finalising 1.3 so I’ll have a beta build once I include your final version.

Take 5

http://devilstower.posterous.com/spritely-beta-take-5

And now I promise to quit niggling things two pixels here, 10% change in alpha there.

Not for 1.3, but for the next version I’m adding a simple form of compression. Since most icons consist of a few colors, it makes sense to scan the image, build a color palette, and then map the actual pix against those colors. In a few test images (in this case, icons that emulate Mario games) this drops the overal size of the info to store the image by >70%. Kind of like a GIF file without the bitmap compression.

Naturally, on images with a lot of colors, this could actually make things larger, and it will need an image decompress function to use, but it still seems worthwhile.