RetroBASIC
Retrogamecoding(.org) => Examples => Topic started by: Tomaaz on November 11, 2012, 08:45:05 PM
-
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:
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
Koch Curve:
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()
Example 2:
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()
-
Very nice, thanks. 8)
-
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:
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()
To enable automatic redrawing just use setredraw(1).
New version of the library and an updated file for Geany are attached.
-
Here's a very very minimal "turtle", which could be written as a library too :
#!/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)
heading = 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
local direction = rad(heading)
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
-
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. :)
-
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)
Oh, sorry :-[
This comment was not in the original script. I added it afterwards to point the trick : when variables are declared as 'local', programs run faster. It's obvious especially with fractals (I've got some samples and have tested them with other prog. languages, see there (http://retrogamecoding.org/board/index.php?topic=17.0)). Thus these sorts of program run up to 5 or 6 times faster and then EGSL (and consequently Lua) has no cause to be envious of some other compiled programing languages ;)
-
Good to know (with that local declaration). Although the EGSL implemented sin, cos etc. are implemented in Pascal and are compiled ... ;)
EDIT: Hm, forget that I was talking rubbish ... The math.sin etc. are implemented in C, right? So Pascal can't be faster.
-
Although the EGSL implemented sin, cos etc. are implemented in Pascal and are compiled ... ;)
Yes. I go on declaring them out of a bad habit, that I'v got before I notice the EGSL helper functions, sorry !
-
Hello All,
can i add this example as part of my EGSL IDE?
http://haikuware.com/directory/view-details/development/ides/egsl-ide (http://haikuware.com/directory/view-details/development/ides/egsl-ide)
-
I'm not sure if you're asking about my simple library or Bereb's work, but if it's my library, feel free to use it and all my examples.
Regards!
-
Sorry, but due to security reasons I removed the links to the images. As Mopz said, maybe you'll find another hoster for images (flickr?)
-
Yes, I need to find something or... maybe you could change the limit of attachments from 2 to 3? :) One archive with all files needed to run an example and two screenshots would be enough. ;)
-
I've added some features to make the library more kids-friendly (after all, I've written it for my son). There are two new functions for colour. They accept 17 colour names (white, black, green, red, blue, yellow, grey, purple, aqua, teal, olive, maroon, navy, magenta, lightblue, lightgrey, darkgrey).
setcolour("[colour name]") - set the colour for drawing to "colour name"
setbgcolour("[colour name]") - clears the screen and set the background colour to"colour name"
For more colours you can still use EGSL functions.
There is also a new fill() function that fills the area with a currently set colour.
Here is a small example (see the screenshot):
require "turtle"
openwindow (640, 550, 0, "Example of turtle graphics")
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
setredraw(0)
setbgcolor("red")
setcolor("yellow")
goxy (100, 150)
turnright(90)
for x = 1, 3 do
koch(150, 5)
turnright(120)
end
goxy (250, 237)
for x = 1, 3 do
koch(50, 4)
turnright(120)
end
setcolor("white")
circle (325, 275, 200)
redraw()
setredraw(1)
goxy (200, 200)
setcolor("purple")
fill()
goxy (320, 275)
setcolor("olive")
fill()
goxy (10, 10)
setcolor("teal")
fill()
inkey()
Source codes and an updated configuration file for Geany are attached.
-
Hi Tomek
I am playing with this Turtle functions in my interpreter and i looking into
your koch curve example ...
how big is variable t
because inside if / end if you have
t=t-1 but i don't see where is t set to value
any help maybe ?
-
t is part of the function call. So if it's
koch(150, 5)
then t=5.
-
Thanks Cyb
i see ,so it is 5....but my main problem is how to avoid recursion calls.
is that possible ::)
-
I don't know. It is actually a recursive function so it will become hard to do it in another way.
-
i see ,so it is 5....but my main problem is how to avoid recursion calls.
is that possible ::)
That's an interesting question. I think you could draw Koch Curve using nested loops, but you would have to manually change the code (the number of loops) to see less/more detailed curve. With recursion all you have to do is to change the value of t (bigger - more details, smaller - less details). Without recursion you would have to manually place t nested loops in your code. But I might be wrong...
The question is - why you don't want to use recursion? Like I said - it might be possible to draw Koch Curve without recursion, but I'm 100% sure the code would be much more complicated.
-
Answer is simple i don't have built-in any shape of subroutines or functions in my
primitive interpreter so i cannot use recursion on that way.
Yes i agree ..recusive calls is the best way to do the job.
I only have currently built in turtle functions TR,TL,MF,MB...
and if you look in bp.org you will see my examples...
-
here is one strange modification
'TURTLE GRAPHICS
defn tx,ty
defn tr
defn tl,level
defn m,s
defn i,t,n
wform 10,100,600,600,#SYS,0,"TURTLE-> StarKoch"
wcolor 0,0,0
'start position
set tx = TURTLEX(300), ty=TURTLEY(240)
set s=12
txcolor 0,220,220
'initial turn to 90 deg LEFT
set tr=TURNR(80),m = moveF(s)
'F LFLF RFLF RFLF RFR F
for n,1,12
'set tr=turnR(120)
For i,1,10
'----------------
set tr=TURNL(60),m = moveF(s), tr = turnL(60),m = moveF(s)
set tr=turnR(120),m = moveF(s),tr = turnL(60),m = moveF(s)
set tr=turnR(120),m = moveF(s),tr = turnL(60),m = moveF(s)
set tr=turnR(120),m = moveF(s),tr=turnL(90),m = moveF(s)
'-------------------------------------
Next i
set tr=turnR(120)
Next n
wtext 40,2,"TURTLE -> StarKoch"