### Author Topic: Waiting for Pulsar !... EGSL is not yet dead  (Read 612 times)

#### Bereb

• Newcomer
• Posts: 47
##### Waiting for Pulsar !... EGSL is not yet dead
« on: 13. May 2015, 13:23:12 »
Just a little OOP with EGSL  (I didn't use knowingly the collision functions of EGSL, so as to explore OOP possibilities of Lua)

Code: [Select]
#!/usr/local/bin/egsl
------------------------------------------------------------------------
-- Balls (Bouncy Bubbles)
-- EGSL 1.6.0 on Lunbuntu 14.04
-- by Bereb - october 2012 (revised may 2015)
------------------------------------------------------------------------

local random = math.random -- sorry, I prefer Lua's random() to EGSL rnd()
local sqrt, atan2, cos, sin =  math.sqrt, math.atan2, math.cos, math.sin

local width, height = 640, 360
local br, bg ,bb = 50, 100, 100    -- for background color

local numBalls = 10
local spring = 0.05
local gravity = 0.03
local friction = -0.9
local balls = {}

local key

--> Class 'Ball' <------------------------------------------------------
local Ball = {}

function Ball:new(arg)
-- arg = {x, y, diameter, color, vx, vy, id, others}
local obj = {
x = arg.x or 10,
y = arg.y or 10,
diameter = arg.diameter or 30,
color = arg.color or random(255),
vx = arg.vx or 0,
vy = arg.vy or 0,
id = arg.id or 1,
others = arg.others or {}
}
setmetatable(obj, self)
self.__index = self
return obj
end

function Ball:collide()
local dx, dy, distance, minDist, angle, targetX, targetY, ax, ay
for i = self.id + 1, numBalls do
dx = self.others[i].x - self.x
dy = self.others[i].y - self.y
distance = sqrt(dx*dx + dy*dy)
minDist = self.others[i].diameter + self.diameter
if distance < minDist then
angle = atan2(dy,dx)
targetX = self.x + cos(angle) * minDist
targetY = self.y + sin(angle) * minDist
ax = (targetX - self.others[i].x) * spring
ay = (targetY - self.others[i].y) * spring
self.vx = self.vx - ax
self.vy = self.vy - ay
self.others[i].vx = self.others[i].vx + ax
self.others[i].vy = self.others[i].vy + ay
end
end
end

function Ball:move()
self.vy = self.vy + gravity
self.x, self.y = self.x + self.vx, self.y + self.vy
if self.x + self.diameter/2 > width then
self.x = width - self.diameter/2
self.vx = self.vx * friction
elseif self.x - self.diameter/2 < 0 then
self.x = self.diameter/2
self.vx = self.vx * friction
end
if self.y + self.diameter/2 > height then
self.y = height - self.diameter/2
self.vy = self.vy * friction
elseif self.y - self.diameter/2 < 0 then
self.y = self.diameter/2
self.vy = self.vy * friction
end
end

function Ball:display()
alphachannel(200)
color(self.color,self.color, self.color)
fillcircle(self.x, self.y, self.diameter)
end

function Ball:erase()
alphachannel(255)
color(br,bg,bb) -- same as background color
fillcircle(self.x, self.y, self.diameter)
end
--> End class 'Ball' <--------------------------------------------------

openwindow(640, 360, 32, "Bouncy Balls (EGSL and OOP)")
backcolor(br,bg,bb)
clearscreen()

-- creating objects 'balls'
for i = 1, numBalls do
balls[i] = Ball:new {
x = random(width),
y = random(height),
diameter = random(20,40),
id = i,
others = balls
}
end

-- main loop
repeat
key = getkey()
for i = 1, numBalls do
balls[i]:erase()
balls[i]:collide()
balls[i]:move()
balls[i]:display()
end
redraw()
until key == 27 -- <Esc>

closewindow()

« Last Edit: 13. May 2015, 13:28:22 by Bereb »
Regards, Bertrand
** Lubuntu 14.04 (Intel Celeron CPU 2.66GHz - 1280MiB) **