Skip to content

Instantly share code, notes, and snippets.

@xriss
Last active Sep 16, 2016
Embed
What would you like to do?
Bouncing Ball// source http://jsbin.com/lagahi
<html>
<head>
<title>Bouncing Ball</title>
<script data-pace-options='{ "eventLag": false }' src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.min.js"></script>
<style>
.pace .pace-progress { height:4px; background:#88f; position:fixed; z-index:9999; top:0; right:100%; width:100%; }
.pace-inactive { display:none; }
.pace { -webkit-pointer-events:none; pointer-events:none; -webkit-user-select:none; -moz-user-select:none; user-select:none; }
</style>
</head>
<body style=" margin:0; padding:0; border:0; overflow:hidden; background:#000;">
<script id="gamecake_init_lua" type="text/lua" >--<![CDATA[
-- grab some libs
local pack=require("wetgenes.pack") -- raw memory packing
local wstr=require("wetgenes.string") -- string helpers
local tardis=require("wetgenes.tardis") -- matrix/vector math
-- a window/screen handler this works in windows/linux/nacl/android/raspi
local win=require("wetgenes.win").create({})
-- wrap some extra shader compiler functions around a basic gles2 library
local gl=require("glescode").create( assert(require("gles").gles2) )
-- source code for a simple a shader, the name= are just for debuging
local prog_color=
{
name="prog_color",
vshaders=
{{
name="vtx_color",
source=[[
{shaderprefix}
uniform mat4 modelview;
uniform mat4 projection;
attribute vec3 vertex;
uniform vec4 color;
varying vec4 v_color;
void main()
{
gl_Position = projection * modelview * vec4(vertex, 1.0);
v_color=color;
}
]]
}},
fshaders=
{{
name="frg_color",
source=[[
{shaderprefix}
varying vec4 v_color;
void main(void)
{
gl_FragColor=v_color ;
}
]]
}},
}
-- an amiga ball
local function ball_create()
local ball={}
local p={} -- tempory table to build points into
function pp(...) for i,v in ipairs{...} do p[#p+1]=v end end -- and data push function
function xy(x,y) return p[((x+(y*17))*3)+1],p[((x+(y*17))*3)+2],p[((x+(y*17))*3)+3] end
for y=0,8 do
for x=0,16 do
local s=math.cos(math.pi*(y-4)/8)
pp( math.sin(2*math.pi*x/16)*s , math.sin(math.pi*(y-4)/8) , math.cos(2*math.pi*x/16)*s )
end
end
local t={} -- tempory table to build tris into
function tp(...) for i,v in ipairs{...} do t[#t+1]=v end end -- and data push function
for check=0,1 do -- make chequered pattern order
for y=0,7 do
for x=0,15 do
if ((x+y)%2)==check then
tp( xy(x+0,y+0) )
tp( xy(x+1,y+0) )
tp( xy(x+0,y+1) )
tp( xy(x+1,y+0) )
tp( xy(x+1,y+1) )
tp( xy(x+0,y+1) )
end
end
end
end
ball.vdat=pack.alloc( #t*4 )
pack.save_array(t,"f32",0,#t,ball.vdat) -- pack data as 32bit floats
ball.vbuf=gl.GenBuffer()
gl.BindBuffer(gl.ARRAY_BUFFER,ball.vbuf)
gl.BufferData(gl.ARRAY_BUFFER,#t*4,ball.vdat,gl.STATIC_DRAW)
function ball.draw(siz,color,part)
local p=gl.program(prog_color)
gl.UseProgram( p[0] )
gl.PushMatrix()
gl.Scale(siz,siz,siz)
gl.BindBuffer(gl.ARRAY_BUFFER,ball.vbuf)
gl.VertexAttribPointer(p:attrib("vertex"), 3 , gl.FLOAT , gl.FALSE , 3*4 , 0*4)
gl.EnableVertexAttribArray(p:attrib("vertex"))
gl.UniformMatrix4f(p:uniform("modelview"), gl.matrix(gl.MODELVIEW) )
gl.UniformMatrix4f(p:uniform("projection"), gl.matrix(gl.PROJECTION) )
gl.Uniform4f(p:uniform("color"), color[1],color[2],color[3],color[4] )
-- draw odd squares or even squares or both. so we can choose what color ball to draw very simply
if part==0 then
gl.DrawArrays(gl.TRIANGLES,0,(#t/3)/2)
elseif part==1 then
gl.DrawArrays(gl.TRIANGLES,(#t/3)/2,(#t/3)/2)
elseif part==2 then
gl.DrawArrays(gl.TRIANGLES,0,(#t/3))
end
gl.PopMatrix()
end
return ball
end
-- select a standard gles context
win:context({})
--local frame_rate=1/60
local frame_time=0
local ball=ball_create()
-- lets bounce
local siz=256
local pos={0,0,0}
local vec={4,4,0}
local rot={0,0,0}
local vrt={1,1,1/2}
local function pulse()
-- frame limit
if frame_rate then
if frame_time<win:time() then frame_time=win:time() end -- prevent race condition
if frame_time>win:time() then return end -- simple frame limit
frame_time=frame_time+frame_rate -- step frame forward
end
repeat -- handle msg queue (so we know the window size on windows)
local m=win:msg()
until not (m and m[1])
-- velocity
rot[1]=rot[1]+vrt[1]
rot[2]=rot[2]+vrt[2]
rot[3]=rot[3]+vrt[3]
pos[1]=pos[1]+vec[1]
pos[2]=pos[2]+vec[2]
-- gravity
vec[2]=vec[2] + (1/8)
-- simple collision against sides ofscreen
siz=win.height/4
if pos[1] > -siz+win.width/2 then pos[1]=-siz+win.width/2 vec[1]=vec[1]*-1 vrt[1]=vrt[1]*-1 end
if pos[1] < siz-win.width/2 then pos[1]= siz-win.width/2 vec[1]=vec[1]*-1 vrt[1]=vrt[1]*-1 end
if pos[2] > -siz+win.height/2 then pos[2]=-siz+win.height/2 vec[2]=vec[2]*-1 vrt[2]=vrt[2]*-1 end
if pos[2] < siz-win.height/2 then pos[2]= siz-win.height/2 vec[2]=0 vrt[2]=vrt[2]*-1 end
-- fake friction at top, prevents runaway fizix
-- prepare to draw a frame
gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) -- default of premultiplied alpha blending mode
gl.Enable(gl.BLEND)
gl.Enable(gl.DEPTH_TEST)
win:info() -- updates the current width and height
gl.Viewport(0,0,win.width,win.height)
gl.ClearColor(0,0,1/4,1/4)
gl.Clear(gl.COLOR_BUFFER_BIT+gl.DEPTH_BUFFER_BIT)
gl.MatrixMode(gl.PROJECTION)
gl.LoadMatrix( tardis.m4_project23d(win.width,win.height,win.width,win.height,0.25,win.height*4) )
gl.MatrixMode(gl.MODELVIEW)
gl.LoadIdentity()
gl.PushMatrix()
-- draw the ball
gl.Translate(0,0,-win.height*2)
gl.Translate(pos[1],pos[2],pos[3])
gl.Rotate(rot[2],1,0,0)
gl.Rotate(rot[1],0,0,1)
ball.draw(siz,{1,1,1,1},0) -- draw white parts
ball.draw(siz,{1,0,0,1},1) -- draw red parts
--calling this can stall the pipeline but is good for catching errors
--print(gl.GetError())
gl.PopMatrix()
win:swap()
end
-- set a global function that will get called from javascript and keep all the above locals alive
gamecake_pulse=pulse
--]]></script>
<div id="gamecake_container" style=" width:100%; height:100%; position:absolute; ">
<canvas id="gamecake_canvas" style=" width:100%; height:100%; position:absolute; " oncontextmenu="event.preventDefault()"></canvas>
<script type="text/javascript">
var gamecake_start=function() {
//define a callmelater function
/* var requestAnimationFrame = (function(){
return function(callback,element){
window.setTimeout(callback, 1000 / 60);
};
})();
*/
//initialise lua
gamecake_post('cmd=lua\n',document.getElementById("gamecake_init_lua").innerHTML);
//gamecake_post('cmd=lua\n','require("wetgenes.win").emcc_start({})');
// create a pulse function and call it every frame
var pulse;
pulse=function() {
requestAnimationFrame(pulse); // we need to always ask to be called again
gamecake_post('cmd=lua\n','return gamecake_pulse()');
};
requestAnimationFrame(pulse); // start the updates
}
var show_progress=function(n)
{
window.show_progress_max=window.show_progress_max || 0;
if(window.show_progress_max<n) { window.show_progress_max=n; }
var pct=Math.floor(100*(1-(n/window.show_progress_max)));
console.log("GameCake Loading "+pct+"%");
};
var resize=function(){
var e=document.getElementById("gamecake_container");
var w=parseFloat(window.getComputedStyle(e).width);
var h=parseFloat(window.getComputedStyle(e).height);
Module.setCanvasSize(w,h);
if(gamecake_post)
{
gamecake_post('cmd=lua\n','require("wetgenes.win").hardcore.resize(nil,'+w+','+h+')');
}
};
window.addEventListener("resize",resize);
Module={};
Module.canvas=document.getElementById("gamecake_canvas");
Module.canvas_resize=resize;
Module.memoryInitializerPrefixURL="http://play.4lfa.com/gamecake/";
Module['_main'] = function() {
gamecake_post = Module.cwrap('main_post', 'int', ['string','string']);
gamecake_start();
resize();
};
Module["preInit"] = function() {
// FS.createPreloadedFile('/', "gamecake.zip", "/swankypaint.zip", true, false);
};
Module["monitorRunDependencies"]=show_progress;
</script>
<script type="text/javascript" src="http://play.4lfa.com/gamecake/gamecake.js"></script>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment