Drawing using Lua (Share yours if you have any!)

Posted by Ashleykitsune on Tue 19 Nov 2013 06:20 PM — 6 posts, 21,423 views.

#0
The other day I was able to finally get back to MUSHClient coding! It's been a while, but now I'm back in the saddle again, and I've already developed some fun code to draw a "Yoshi" head from the Super Mario video games.

The goal is to eventually make it so the user can easily change the colors themselves (and eventually the spike shape, and also add in some hair styles to choose from). This is practice for when I try to eventually develop my own MUD/MUCK. I'm considering having the server record a character code for every character that gets used to translate into an image like this whenever the user looks at another character.

Please take a look and let me know if you have any ideas on simplifying this, considering that it is pretty long. It's currently put into an Alias where it is executed when I type "yoshi"

Also, here's a link to the finished picture:
http://tinyurl.com/pmy4xgw

win = "test_" .. GetPluginID ()
WindowCreate (win, 0, 0, 200, 200, miniwin.pos_top_left, 0, ColourNameToRGB ("white"))  -- create window


-- Grid
  for i = 1, math.max (WindowInfo (win, 3), WindowInfo (win, 4)) / 20 do
    WindowLine (win, i * 20, 0, i * 20, WindowInfo (win, 4), 0xC0C0C0, miniwin.pen_solid, 1)
    WindowLine (win, 0, i * 20, WindowInfo (win, 3), i * 20, 0xC0C0C0, miniwin.pen_solid, 1)
  end -- for


X = 0
Y = 0
color1   = "blue"
color2   = "cyan"
spikecol = "red"
eyecolor = "green"

black   = ColourNameToRGB("black")
spikes  = "70,55,90,50,75,60,90,70,75,75,90,85,60,80"
eyelid1 = {l=X+30, t=Y+0 , r=X+60, b=Y+45}
eyelid2 = {l=X+50, t=Y+10, r=X+80, b=Y+60}
ewhite1 = {l=X+30, t=Y+10, r=X+55, b=Y+55}
ewhite2 = {l=X+50, t=Y+20, r=X+75, b=Y+70}
iris1   = {l=X+30, t=Y+20, r=X+50, b=Y+55}
iris2   = {l=X+50, t=Y+30, r=X+70, b=Y+60}
nose    = {l=X+0 , t=Y+30, r=X+60, b=Y+90}
cheek1  = {l=X+48, t=Y+50, r=X+80, b=Y+80}
cheek2  = {l=X+48, t=Y+57, r=X+77, b=Y+80}
cheekb  = {l=X+55, t=Y+75, r=X+67, b=Y+80}
lip     = {l=X+10, t=Y+30, r=X+70, b=Y+90}


--Spikes
WindowPolygon (win, spikes,
               black,   miniwin.pen_solid, 1,   -- pen (solid, width 3)
               ColourNameToRGB(spikecol), miniwin.brush_solid,    -- brush (solid)
               true,    -- fill
               false)   -- alternate fill


--Lower Lip

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                lip.l, lip.t, cheek2.r, lip.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB("white"), miniwin.brush_solid)  -- brush


--Eyelid 1
WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                eyelid1.l, eyelid1.t, eyelid1.r, eyelid1.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB(color2), miniwin.brush_solid)  -- brush

--Eye White 1

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                ewhite1.l, ewhite1.t, ewhite1.r, ewhite1.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("white"), miniwin.pen_solid, 0, -- pen width 0
                ColourNameToRGB("white"), miniwin.brush_solid)  -- brush

--Iris 1

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                iris1.l, iris1.t, iris1.r, iris1.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB(eyecolor), miniwin.brush_solid) -- brush

--Eyelid 2
WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                eyelid2.l, eyelid2.t, eyelid2.r, eyelid2.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB(color2), miniwin.brush_solid)  -- brush



--Eye White 2

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                ewhite2.l, ewhite2.t, ewhite2.r, ewhite2.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("white"), miniwin.pen_solid, 0, -- pen width 0
                ColourNameToRGB("white"), miniwin.brush_solid)  -- brush



--Iris 2

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                iris2.l, iris2.t, iris2.r, iris2.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB(eyecolor), miniwin.brush_solid)  -- brush


--Nose

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                nose.l, nose.t, nose.r, nose.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB(color2), miniwin.brush_solid)  -- brush

--Cheek 1

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                cheek1.l, cheek1.t, cheek1.r, cheek1.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB(color2), miniwin.brush_solid)  -- brush


--Cheek 2

WindowCircleOp (win, miniwin.circle_ellipse, -- circle
                cheek2.l, cheek2.t, cheek2.r, cheek2.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("black"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB("white"), miniwin.brush_solid)  -- brush

--Cheek square

WindowRectOp (win, miniwin.rect_fill, -- square all white
                cheekb.l, cheekb.t, cheekb.r, cheekb.b, -- Left, Top, Right, Bottom
                ColourNameToRGB("white"), miniwin.pen_solid, 1, -- pen width 1
                ColourNameToRGB("white"), miniwin.brush_solid)  -- brush


WindowShow (win,  true)  -- show it
Australia Forum Administrator #1
Curtis_D said:

Also, here's a link to the finished picture:
http://tinyurl.com/pmy4xgw



500 - Internal Server Error
Australia Forum Administrator #2
Well, that's cute:



You can omit the grid, of course.
Amended on Tue 19 Nov 2013 08:12 PM by Nick Gammon
Australia Forum Administrator #3
Would Bezier curves have simplified it?
#4
Nick Gammon said:

Would Bezier curves have simplified it?


I did consider using a Bezier curve but when I looked into them I didn't think you could fill them in. They probably would have helped out quite a bit if they could!
Australia Forum Administrator #5
You can't, directly, but you could make a Bezier (closed) curve and flood-fill it.


win = "test_" .. GetPluginID ()

WindowCreate (win, 0, 0, 200, 200, miniwin.pos_center_all, 0, 
              ColourNameToRGB("white"))  -- create window

-- draw closed curve
WindowBezier (win, "30, 20, 5, 90, 50, 90, 80, 30, 30, 20, 50, 90, 30, 20", 
              ColourNameToRGB("blue"), 0, 2)

-- flood fill it
WindowRectOp(win, miniwin.rect_flood_fill_border, 50, 50, 0, 0, 
             ColourNameToRGB("blue"), ColourNameToRGB("green"))

-- show window
WindowShow (win,  true)



However, rather amusingly, this doesn't work perfectly because I found a bug in the "flood fill" algorithm, in that it doesn't let you specify a colour. Sure you can specify it (I used green) but it ignores it.

I have fixed that in version 4.92, and the amusing part is that no-one must have ever tried to use it, or I would have got a bug report by now.

In the above example, it fills up to the blue line, and fills everything inside it in green.