This inspired me to practice some Lua, so I gave it a try, and did the following example program. Hopefully it gives an idea of how relatively easy it's to get up and running with the code. I have some feedback about the beta editor which I'll try posting on that website forum if I see the server come back online.
Complete program code for controlling a sprite that can push another sprite with collision detection, on a floor of sprites:
--simple program for controlling one object,
--and pushing another object around
--window dimensions:
screen_width=500
screen_height=500
window_offsetx=0
window_offsety=32 --border size, this may vary with different Windows settings
--initial coordinates for objects:
obj1_x=200.0
obj1_y=250.0
obj2_x=400.0
obj2_y=250.0
--velocity constants:
gravvel_y = 6.0
movespeed_x = 6.0
flyvel_y = -12.0 --"eliminate" gravity, then add fly velocity
--function: bleumoon setup callback
function setup()
--screen
fps=30
setscreen(500,500)
--objects
obj1=createobject("Obj1_48x48.bmp")
obj2=createobject("Obj2_48x48.bmp")
positionobject(obj1,obj1_x,obj1_y)
positionobject(obj2,obj2_x,obj2_y)
--create tile row, on bottom of screen
for x=24, screen_width+24, 48 do
local tile=createobject("Tile48x48.bmp")
positionobject(tile, x+window_offsetx, screen_height-window_offsety-24)
end
--create text for debugging
debugger=createtext("Debugging")
positiontext(0,0)
end
--function: bluemoon main loop callback
function mainloop()
settext(debugger, "Press Space to reset")
if (keypressed.space == 1) then
positionobject(obj1,obj1_x,obj1_y)
positionobject(obj2,obj2_x,obj2_y)
end
--1. add pseudo-gravity to object
--2. (control object with input)
--3. ensure object is within boundaries/screen
--(repeat for each object)
moveobject(obj2,0,gravvel_y)
boundobject(obj2, 0,screen_width, 0,screen_height-window_offsety-48)
moveobject(obj1,0,gravvel_y)
controlobject(obj1)
pushobject(obj1,obj2)
boundobject(obj1, 0,screen_width, 0,screen_height-window_offsety-48)
end
--function: tests if an object is within boundaries
--input: obj - object to test
-- x1 - min-x boundary
-- x2 - max-x boundary
-- y1 - min-y boundary
-- y2 - max-y boundary
--return: true if object is already within boundaries, false if it had to be moved into boundaries
function boundobject(obj, x1,x2, y1,y2)
local obj_x = objectx(obj)
local obj_y = objecty(obj)
--local obj_ex = objectxsize(obj) / 2 --not implemented?
--local obj_ey = objectysize(obj) / 2 --not implemented?
local obj_ex = 24
local obj_ey = 24
local bound = true
if (obj_x-obj_ex < x1) then
obj_x = x1+obj_ex
bound = false
end
if (obj_x+obj_ex > x2) then
obj_x = x2-obj_ex
bound = false
end
if (obj_y-obj_ey < y1) then
obj_y = y1+obj_ey
bound = false
end
if (obj_y+obj_ey > y2) then
obj_y = y2-obj_ey
bound = false
end
positionobject(obj,obj_x,obj_y)
return bound
end
--function: applies movement to object, in response to control
function controlobject(obj)
if (keypressed.right == 1) then
moveobject(obj,movespeed_x,0)
end
if (keypressed.left == 1) then
moveobject(obj,-movespeed_x,0)
end
if (keypressed.up == 1) then
moveobject(obj,0,flyvel_y)
end
end
--function: lets an object push another on its sides, or lets it stay on top of it
--input: obj1 - "pusher"
-- obj2 - to be pushed
function pushobject(obj1,obj2)
local obj1_x = objectx(obj1)
local obj1_y = objecty(obj1)
local obj1_ex = 24 --objectxsize(obj1) / 2
local obj1_ey = 24 --objectysize(obj1) / 2
local obj2_x = objectx(obj2)
local obj2_y = objecty(obj2)
local obj2_ex = 24 --objectxsize(obj2) / 2
local obj2_ey = 24 --objectysize(obj2) / 2
--check if objects overlap vertically
if (obj1_y+obj1_ey >= obj2_y-obj2_ey) and (obj1_y-obj1_ey < obj2_y+obj2_ey) then
--check if obj1 is just on top of obj2,
--if so stay on top (don't push)
if (obj1_y+obj1_ey <= obj2_y-obj2_ey+gravvel_y)
and (obj1_x+obj1_ex > obj2_x-obj2_ex) and (obj1_x-obj1_ex < obj2_x+obj2_ex) then
positionobject(obj1, obj1_x, obj2_y-obj2_ey-obj1_ey)
settext(debugger, "On top")
return
end
--check if obj1 "right" is inside obj2
--if so, try pushing obj2 to right
if (obj1_x+obj1_ex >= obj2_x-obj2_ex) and (obj1_x+obj1_ex < obj2_x+obj2_ex) then
local dx = obj1_x+obj1_ex - (obj2_x-obj2_ex)
if (can_moveobject(obj2, dx,0) == true) then
positionobject(obj2, obj2_x+dx, obj2_y)
settext(debugger, "Pushing")
else
positionobject(obj1, obj1_x-dx, obj1_y) --stopped by wall, move back
settext(debugger, "Stopped by wall")
end
return
end
--check if obj1 "left" is inside obj2
--if so, try pushing obj2 to left
if (obj1_x-obj1_ex > obj2_x-obj2_ex) and (obj1_x-obj1_ex <= obj2_x+obj2_ex) then
local dx = obj2_x+obj2_ex - (obj1_x-obj1_ex)
if (can_moveobject(obj2, -dx,0) == true) then
positionobject(obj2, obj2_x-dx, obj2_y)
settext(debugger, "Pushing")
else
positionobject(obj1, obj1_x+dx, obj1_y) --stopped by wall, move back
settext(debugger, "Stopped by wall")
end
return
end
end
return false
end
--function: tests if object can be moved without exceeding boundaries
--input: obj - object to test if it can be moved
-- dx - movement along x-axis (relative)
-- dy - movement along y-axis (relative)
--return: true if object can be moved by (dx,dy)
function can_moveobject(obj, dx,dy)
--store current coordinates, then test-move object
local obj_x = objectx(obj)
local obj_y = objecty(obj)
--1. move forward
--2. test against boundaries
--3. move back again
positionobject(obj, obj_x+dx, obj_y+dy)
can_moveobject_ret = boundobject(obj, 0,screen_width, 0,screen_height-window_offsety-48)
positionobject(obj, obj_x,obj_y)
return can_moveobject_ret
end