Retrogamecoding(.org) > Examples

Simple turtle library for EGSL

(1/4) > >>

Tomaaz:
I've ported my simple turtle library for Yabasic to EGSL. Not really meant for games, but who knows. ;)

forward(x) - moves the turtle x pixels forward and draws the line when pen is down
backward(x) - moves the turtle x pixels backward and draws the line when pen is down
turnright(x) - turns the turtle x degrees to the right
turnleft(x) - turns the turtle x degrees to the left
pendown() - puts the pen down
penup() - lifts the pen up
goxy(x, y) - moves the turtle to (x, y) position
gox(x) - moves the turtle vertically by x pixels
goy(x) - moves the turtle horizontally by x pixels
resetangle() - set the angle to 0

No matter if the pen is down or up, goxy, gox and goy don't draw anything on the canvas. Value of angle (in degrees) is stored in katzolwia global variable. Position of the turtle is stored in pozycjax and pozycjay global variables.

The source, two examples and updated configuration file for Geany (syntax highlighting) are attached.

Library:

--- Code: ---pi = 3.14159
katzolwia = 0
pozycjax = 300
pozycjay = 300
rysowanie = 1

function forward(dlugosc)
local a, b, x, y
a = (math.sin(katzolwia * pi / 180) * dlugosc)
b = (math.cos(katzolwia * pi / 180) * dlugosc)
x = pozycjax + a
y = pozycjay - b
if rysowanie == 1 then
line (pozycjax, pozycjay, x, y)
end
pozycjax = x
pozycjay = y
redraw()
end

function backward(dlugosc)
local a, b, x, y
a = (math.sin(katzolwia * pi / 180) * dlugosc)
b = (math.cos(katzolwia * pi / 180) * dlugosc)
x = pozycjax - a
y = pozycjay + b
if rysowanie == 1 then
line (pozycjax, pozycjay, x, y)
end
pozycjax = x
pozycjay = y
redraw ()
end

function turnright(zmiana)
katzolwia = katzolwia + zmiana
if katzolwia > 360 then
katzolwia = katzolwia - 360
end
if katzolwia < 0 then
katzolwia = katzolwia + 360
end
end

function turnleft (zmiana)
katzolwia = katzolwia - zmiana
if katzolwia > 360 then
katzolwia = katzolwia - 360
end
if katzolwia < 0 then
katzolwia = katzolwia + 360
end
end

function penup()
rysowanie = 0
end

function pendown()
rysowanie = 1
end

function goxy(zmianax, zmianay)
pozycjax = zmianax
pozycjay = zmianay
end

function gox(zmianax)
pozycjax = pozycjax + zmianax
end

function goy(zmianay)
pozycjay = pozycjay + zmianay
end

function resetangle()
katzolwia = 0
end

--- End code ---

Koch Curve:

--- Code: ---require "turtle"
openwindow (640, 480, 32, "Test")
goxy (10, 300)
turnright(90)
function koch(x, t)
if t > 0 then
t = t - 1
x = x / 3
koch(x, t)
turnleft(60)
koch(x, t)
turnright(120)
koch(x, t)
turnleft(60)
koch(x, t)
else
forward(3 * x)
end
end

koch(200, 6)
inkey()

--- End code ---

Example 2:

--- Code: ---require "turtle"
openwindow(900, 650, 32, "Test")
resetangle()
goxy(110, 300)

for x = 1, 20 do
colour(255, 255 - x * 10, x * 5)
forward(250)
turnleft(198)
end

resetangle()
goxy(230, 440)
for k = 1, 20   do
colour(0, 0, 256 - k * 10)
gox(2)
goy(2)
for x = 1, 36 do
if x % 2 == 0 then
penup()
end
backward(20)
pendown()
turnright(10)
end
end

resetangle()
goxy(350, 550)
k = 2
while (k < 496) do
colour (k / 2, k / 2, k / 2)
forward(500 - k)
turnright(91)
k = k + 2
end

inkey()

--- End code ---

cvirus:
Very nice, thanks.  8)

Tomaaz:
There is no need to use a special pi variable as Lua has build in math.sin() function. For some reason I was trying to call sin() instead of math.sin(). Of course it didn't work, so I added the pi variable.

I've also made another improvement. By default the library call EGSL redraw() function after any drawing takes place. Now it's possible to disable it by using a new setredraw(0) function and call redraw() manually when needed. It makes execution significantly faster. Just compare old Koch Curve example with this one:

--- Code: ---require "turtle"
openwindow (640, 480, 32, "Test")
goxy (10, 300)
turnright(90)
setredraw(0)
function koch(x, t)
if t > 0 then
t=t-1
x=x/3
koch(x, t)
turnleft(60)
koch(x, t)
turnright(120)
koch(x, t)
turnleft(60)
koch(x, t)
else
forward(3*x)
end
end

koch(200, 6)
redraw()
inkey()

--- End code ---

To enable automatic redrawing just use setredraw(1).

New version of the library and an updated file for Geany are attached.

Bereb:
Here's a very very minimal "turtle", which could be written as a library too :

--- Code: ---#!/usr/bin/egsl
--================================================--
-- Turtle Graphics  (EGSL) - RECURSIVE TREE (3)
--
-- EGSL 1.5.3 -  Bertrand Carette - nov. 2012
--================================================--

openwindow(400, 400, 0, "EGSL Turtle Graphics")
backcolor(255,255,255)
color(0,0,0)
clearscreen()

-------------------------------------------------
-- constants & variables
-------------------------------------------------
center = {x = screenwidth()/2, y =  screenheight()/2}
coor= {x = 0, y = 0} -- coordinates of the turtle
heading = 0 -- orientation of the turtle
pendown = true -- pen is down
pensize = 0 -- drawing width

-------------------------------------------------
-- basic procedures for polar/turtle graphics
-------------------------------------------------
local sin, cos, rad = math.sin, math.cos, math.rad -- (faster if declared as local)

function setpos(px, py)
-- draw if pen is down
if pendown then
for i = 0, pensize/2, 0.25 do
aaline(center.x+(coor.x+i), center.y-(coor.y+i),center.x+(px+i), center.y-(py+i))
end
end
-- set new position
coor.x, coor.y = px, py
end

function home()
-- move to screen center without drawing or clearing
pen 'up'   -- pendown = false
setpos(0,0)
pen 'down' -- pendown = true
end

function turn(degree)
-- set orientation in degree : right = +degree / left = -degree
heading = heading + degree % 360
end

function go(distance)
-- move : forward = +distance / backward = -distance
setpos(coor.x+(distance*sin(direction)), coor.y+(distance*cos(direction)))
end

function pen(p)
local p = p or 'down'
if p == 'down' then
pendown = true
elseif p == 'up' then
pendown = false
else
pendown = false
end
end

--------------------------------------------------
-- MAIN PROGRAM : recursive tree (3)
--------------------------------------------------
setcaption("Recursive tree (3)")

red   = {255,0,0}
green = {0,255,0}
blue  = {0,0,255}
col   = {red, green, blue}

function tree(size)
pensize = size/8
pencolor = col[math.random(1,3)]
colour(pencolor[1], pencolor[2], pencolor[3])
go(size)
if size > 5 then
turn(30)
tree(size/2)
turn(30)
tree(size/2)
turn(-90)
tree(size/2)
turn(-30)
tree(size/2)
turn(60)
end
pen 'up'
go(-size)
pen 'down'
pensize = 0
end

pen 'up'
go(-150)
pen 'down'
tree(150)
redraw()

inkey()
closewindow()

-- fin du programme

--- End code ---

Tomaaz:
Nice. :) But I needed to fix line 25 to make it work: local sin, cos, rad = math.sin, math.cos, math.rad --(faster if declared as local)

Regards. :)