Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!-- Test Emscripten Lua GameCake build -->
<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>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
xrisspro
0viewers