Created
October 26, 2008 23:42
-
-
Save DanielVF/19971 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Learning both Lua, and OpenGL. Probably NOT GOOD CODE. | |
-- But it's pretty in action. | |
-- Click to add squares. | |
require 'luagl' | |
require 'luaglut' | |
local fps = 60 | |
local msec = 1000 / fps | |
quit = false | |
local remap_timer = 10 | |
local map_size = {x=640,y=480} | |
local screen_padding = -10 | |
local soldiers = {} | |
WorldGrid = {} | |
function WorldGrid:init(resolution,world_size_x,world_size_y) | |
self.grid = {} | |
self.resolution = resolution | |
self.world_size_x = world_size_x | |
self.world_size_y = world_size_y | |
self.scale_x = world_size_x/resolution | |
self.scale_y = world_size_y/resolution | |
self.objectcell = {} | |
for x=0,resolution-1 do | |
self.grid[x]={} | |
for y=0,resolution-1 do | |
local cell = {} | |
cell.objects={} | |
cell.x=x | |
cell.y=y | |
self.grid[x][y] = cell | |
end | |
end | |
end | |
function WorldGrid:new(resolution,world_size_x,world_size_y) | |
o = setmetatable({},{__index=WorldGrid}) | |
WorldGrid.init(o,resolution,world_size_x,world_size_y) | |
return o | |
end | |
function WorldGrid:set(object,v) | |
local x = math.floor(v.x / self.scale_x) | |
local y = math.floor(v.y / self.scale_y) | |
local new_cell = self.grid[x][y] | |
if new_cell == nil then return end | |
-- new object? | |
if self.objectcell[object] == nil then | |
self.objectcell[object]=new_cell | |
new_cell.objects[object]=true | |
-- moved? | |
elseif not (self.objectcell[object] == new_cell) then | |
self.objectcell[object].objects[object] = nil | |
self.objectcell[object] = new_cell | |
new_cell.objects[object] = true | |
end | |
end | |
function WorldGrid:neighbors(object,v) | |
local cell = self.objectcell[object] | |
local out = {} | |
local near_cell = nil | |
for x=cell.x-1, cell.x+1 do | |
if self.grid[x] then | |
for y=cell.y-1, cell.y+1 do | |
near_cell = self.grid[x][y] | |
if near_cell then | |
for k,v in pairs(near_cell.objects) do | |
if not (k==object) then | |
table.insert(out,k) | |
end | |
end | |
end | |
end | |
end | |
end | |
return out | |
end | |
function WorldGrid:dump() | |
print("WORLD GRID DUMP") | |
for x=0,self.resolution-1 do | |
for y=0,self.resolution-1 do | |
local cell = self.grid[x][y] | |
for k,v in pairs(cell.objects) do | |
print("item",x,y) | |
end | |
end | |
end | |
end | |
local world_grid = WorldGrid:new(10,map_size.x,map_size.y); | |
local function make_soldiers(x,y,x2,y2) | |
for i=1, 4 do | |
local soldier = {x=math.random(x,x2),y=math.random(y,y2)} | |
soldier.velocity = {x=math.random()*2-1,y=math.random()*2-1} | |
table.insert(soldiers,soldier) | |
world_grid:set(soldier,{x=soldier.x,y=soldier.y}) | |
end | |
end | |
function scatter_soildiers() | |
for i,soldier in ipairs(soldiers) do | |
soldier.x = soldier.x + math.random(-20,20) | |
soldier.y = soldier.y + math.random(-20,20) | |
end | |
end | |
make_soldiers(40,40,map_size.x,40) | |
Vect = {} | |
function Vect.normalize(a) | |
local dist = math.sqrt( (a.x^2) + (a.y^2) ) | |
if dist == 0 then return {x=0,y=1} end | |
return { x = a.x / dist, y = a.y / dist } | |
end | |
function Vect.multiplys(a,v) | |
return { x = a.x * v, y = a.y * v } | |
end | |
function Vect.plus(a,b) | |
return { x = a.x + b.x, y = a.y + b.y } | |
end | |
function Vect.minus(a,b) | |
return { x = a.x - b.x, y = a.y - b.y } | |
end | |
function draw_soldier(soldier) | |
if soldier.velocity.y > 0 then | |
glColor3d(1,0,0) | |
else | |
glColor3d(0.2,0,0) | |
end | |
glRectd(soldier.x-5,soldier.y-4,soldier.x+5,soldier.y+4) | |
end | |
function is_too_close(soldier) | |
local distance = 0 | |
for i,other_guy in ipairs(world_grid:neighbors(soldier)) do | |
if not (other_guy == soldier) then | |
distance = math.sqrt((soldier.x - other_guy.x)^2 + (soldier.y - other_guy.y)^2) | |
if distance < 30 then | |
local diff = Vect.minus(soldier,other_guy) | |
diff = Vect.multiplys(Vect.normalize(diff),0.2) | |
soldier.velocity = Vect.normalize(Vect.plus(soldier.velocity,diff)) | |
end | |
end | |
end | |
end | |
local function display_func() | |
glClear(GL_COLOR_BUFFER_BIT) | |
glMatrixMode(GL_PROJECTION) | |
for i,soldier in ipairs(soldiers) do | |
is_too_close(soldier) | |
if soldier.y > map_size.y + screen_padding then | |
soldier.velocity.y = -1 | |
end | |
if soldier.y < 0 - screen_padding then | |
soldier.velocity.y = 1 | |
end | |
if soldier.x > map_size.x + screen_padding then | |
soldier.velocity.x = - 1 | |
end | |
if soldier.x < 0 - screen_padding then | |
soldier.velocity.x = 1 | |
end | |
soldier.x = soldier.x + soldier.velocity.x | |
soldier.y = soldier.y + soldier.velocity.y | |
draw_soldier(soldier) | |
end | |
if remap_timer < 1 then | |
for i,soldier in ipairs(soldiers) do | |
world_grid:set(soldier,{x=soldier.x,y=soldier.y}) | |
end | |
remap_timer = 10 | |
end | |
remap_timer = remap_timer - 1 | |
-- world_grid:dump() | |
glutSwapBuffers() | |
end | |
local function keyboard_func(key) | |
print(key) | |
if key == 27 then | |
quit = true | |
glutDestroyWindow(window) | |
os.exit(0) | |
end | |
end | |
function resize_func(w, h) | |
local ratio = w / h | |
glMatrixMode(GL_PROJECTION) | |
glLoadIdentity() | |
glViewport(0,0,w,h) | |
glMatrixMode(GL_MODELVIEW) | |
glLoadIdentity() | |
glOrtho(0, map_size.x, 0, map_size.y, 0, 1); | |
glEnable(GL_LEQUAL) | |
glEnable(GL_NORMALIZE) | |
end | |
function timer_func() | |
if quit then return end | |
glutSetWindow(window) | |
glutTimerFunc(msec, timer_func, 0) | |
glutPostRedisplay() | |
end | |
function mouse_func(button,state,x,y) | |
if state == GLUT_UP then | |
y = map_size.y- y | |
make_soldiers(x-5,y-5,x+5,y+5) | |
else return end | |
end | |
glutInit() | |
glutInitDisplayMode(GLUT_RGB + GLUT_DOUBLE) | |
glutInitWindowSize(map_size.x,map_size.y) | |
window = glutCreateWindow("BOB") | |
glutDisplayFunc(display_func) | |
glutKeyboardFunc(keyboard_func) | |
glutMouseFunc(mouse_func) | |
glutReshapeFunc(resize_func) | |
glutTimerFunc(msec, timer_func, 0) | |
start_time = glutGet(GLUT_ELAPSED_TIME) | |
glutMainLoop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment