Web client.
This commit is contained in:
parent
2af1ed0197
commit
45f02be68e
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,393 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>Vlak ve 4:20</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
* {
|
||||
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
|
||||
-moz-box-sizing: border-box; /* Firefox, other Gecko */
|
||||
box-sizing: border-box; /* Opera/IE 8+ */
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: darkgrey;
|
||||
font-family: "Lucida console", monospaced;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#all {
|
||||
width: 642px;
|
||||
height: 480px;
|
||||
margin: auto;
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
#all:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#texty {
|
||||
float: left;
|
||||
width: 400px;
|
||||
padding: 5px;
|
||||
border: 1px solid black;
|
||||
overflow: auto;
|
||||
height: 480px;
|
||||
}
|
||||
|
||||
#menu {
|
||||
float: left;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
#menu a {
|
||||
display: block;
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
padding: 5px;
|
||||
}
|
||||
</style>
|
||||
<script src="fengari-web.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="all">
|
||||
<div id="texty">
|
||||
<p>Demo hry vlak ve 4:20</p>
|
||||
<p>Pokud se hra nespustí, dejte vědět Severákovi a napište mu, jaký prohlížeč používáte.</p>
|
||||
</div>
|
||||
<div id="menu">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var el_texty = document.getElementById("texty");
|
||||
var el_menu = document.getElementById("menu");
|
||||
|
||||
function ui_p(txt)
|
||||
{
|
||||
|
||||
el_texty.innerHTML += ("<p>" + txt + "</p>");
|
||||
el_texty.scrollTop = el_texty.scrollHeight;
|
||||
}
|
||||
|
||||
function ui_cls(txt)
|
||||
{
|
||||
|
||||
el_texty.innerHTML = "";
|
||||
}
|
||||
|
||||
function ui_add_menu(code, txt)
|
||||
{
|
||||
|
||||
el_menu.innerHTML += ("<a href=\"#\" data-code=\""+code+"\">" + txt + "</p>");
|
||||
}
|
||||
|
||||
function ui_cls_menu()
|
||||
{
|
||||
|
||||
el_menu.innerHTML = "";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script type="application/lua">
|
||||
local js = require "js"
|
||||
local window = js.global
|
||||
|
||||
gamefile = "vlak420.lua"
|
||||
|
||||
-- Hagen game engine
|
||||
-- (c) Severák 2019-2021
|
||||
|
||||
-- kód nedoporučuju nikomu číst, protože zárodek vzniknul během jednoho odpoledne
|
||||
|
||||
-- inspirace
|
||||
-- - hra Gateway od Legend entrertaiment
|
||||
-- - textovky od Petra Kaina
|
||||
-- - textovkový engine INSTEAD
|
||||
|
||||
-- globals
|
||||
|
||||
paramsNo = 0
|
||||
params = {}
|
||||
currVerb = nil
|
||||
|
||||
verb_ord = {}
|
||||
room_ord = {}
|
||||
item_ord = {}
|
||||
|
||||
menu2codes = {}
|
||||
|
||||
issued_command = {}
|
||||
|
||||
-- API
|
||||
|
||||
function verb(def)
|
||||
def.is_verb = true
|
||||
def.params = def.params or {}
|
||||
verb_ord[#verb_ord+1] = def
|
||||
return def
|
||||
end
|
||||
|
||||
function room(def)
|
||||
def.is_room = true
|
||||
room_ord[#room_ord+1] = def
|
||||
return def
|
||||
end
|
||||
|
||||
function item(def)
|
||||
def.is_item = true
|
||||
item_ord[#item_ord+1] = def
|
||||
return def
|
||||
end
|
||||
|
||||
function cls()
|
||||
window:ui_cls()
|
||||
end
|
||||
|
||||
local function split_lines(str)
|
||||
local result = {}
|
||||
for line in str:gmatch '[^\n]+' do
|
||||
table.insert(result, line)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function p(par)
|
||||
par = par or ""
|
||||
for line in par:gmatch '[^\n]+' do
|
||||
window:ui_p(line)
|
||||
end
|
||||
end
|
||||
|
||||
function here()
|
||||
return game[game.me.w]
|
||||
end
|
||||
|
||||
function move(what, where)
|
||||
game[what].w = where
|
||||
end
|
||||
|
||||
function walk(where, nocls)
|
||||
assert(game[where], "room " .. where .. " does not exist")
|
||||
move("me", where)
|
||||
if not nocls then
|
||||
cls()
|
||||
end
|
||||
p(game[where].n)
|
||||
p(game[where].d)
|
||||
for i,item in ipairs(item_ord) do
|
||||
if item.d and item.w==here().ref then
|
||||
p(item.d)
|
||||
end
|
||||
end
|
||||
show_verbs()
|
||||
end
|
||||
|
||||
function has(what)
|
||||
return game[what].w=="me"
|
||||
end
|
||||
|
||||
function location_of(what)
|
||||
return game[what].w
|
||||
end
|
||||
|
||||
function is_here(what)
|
||||
return game[what].w==game.me.w
|
||||
end
|
||||
|
||||
|
||||
-- end of API
|
||||
|
||||
-- TODO - checkovat všechny parametry
|
||||
function _has_subj_of(verb)
|
||||
local parCode = verb.params[#params+1]
|
||||
for i,item in ipairs(item_ord) do
|
||||
if item[parCode] and (verb.global_reach or item.w==here().ref or item.w=="me") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function show_verbs()
|
||||
paramsNo = 0
|
||||
currVerb = ""
|
||||
params = {}
|
||||
local here = game[game.me.w]
|
||||
window:ui_cls_menu();
|
||||
menu2codes={}
|
||||
for i,verb in ipairs(verb_ord) do
|
||||
if verb.always or here[verb.ref] or _has_subj_of(verb) then
|
||||
local idx=#menu2codes+1
|
||||
window:ui_add_menu(idx, verb.n);
|
||||
menu2codes[idx] = verb.ref
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function show_items()
|
||||
local verb = game[currVerb]
|
||||
local parCode = verb.params[#params+1]
|
||||
-- print("parCode="..parCode)
|
||||
window:ui_cls_menu();
|
||||
menu2codes={}
|
||||
for i,item in ipairs(item_ord) do
|
||||
if item[parCode] and (verb.global_reach or item.w==here().ref or item.w=="me") then
|
||||
local idx=#menu2codes+1
|
||||
window:ui_add_menu(idx, item.n);
|
||||
menu2codes[idx] = item.ref
|
||||
end
|
||||
end
|
||||
if #menu2codes=="0" then
|
||||
show_verbs() -- situace kdy není možné zobrazit další krok v menu
|
||||
-- TODO - vyřešit nějak líp
|
||||
end
|
||||
end
|
||||
|
||||
function process_param(param)
|
||||
if paramsNo == 0 then
|
||||
currVerb = param
|
||||
paramsNo = #game[currVerb].params
|
||||
else
|
||||
params[#params+1]=param
|
||||
end
|
||||
|
||||
-- debug:
|
||||
|
||||
--[[
|
||||
print("param="..param)
|
||||
print("params="..table.concat(params," "))
|
||||
print("currVerb="..currVerb)
|
||||
print("paramsNo="..paramsNo)
|
||||
print("#params="..#params)
|
||||
print "---"
|
||||
]]
|
||||
|
||||
if #params==paramsNo then
|
||||
p ""
|
||||
p("> " .. table.concat(issued_command, " "))
|
||||
issued_command = {}
|
||||
game[currVerb].act(table.unpack(params))
|
||||
if game.round then
|
||||
game.round()
|
||||
end
|
||||
show_verbs()
|
||||
else
|
||||
show_items()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- game defaults
|
||||
|
||||
game = {
|
||||
title = "Emty game",
|
||||
me = item{
|
||||
w="intro"
|
||||
},
|
||||
intro = room{
|
||||
n="void",
|
||||
d="YOU ARE IN A MAZE OF TWISTY LITTLE PASSAGES, ALL ALIKE.",
|
||||
ref = "intro"
|
||||
},
|
||||
void = room{
|
||||
n="void",
|
||||
d="YOU ARE IN A MAZE OF TWISTY LITTLE PASSAGES, ALL ALIKE.",
|
||||
ref = "void"
|
||||
},
|
||||
vars = {}
|
||||
}
|
||||
|
||||
-- utils
|
||||
|
||||
function read_config(filename)
|
||||
filename = filename or ''
|
||||
assert(type(filename) == 'string')
|
||||
local ans,u,k,v,temp = {}, '_'
|
||||
local f = io.open(filename)
|
||||
if f then
|
||||
f:close()
|
||||
for line in io.lines(filename) do
|
||||
temp = line:match('^%[(.+)%]$')
|
||||
if temp ~= nil and u ~= temp then u = temp end
|
||||
k,v = line:match('^([^=]+)=(.+)$')
|
||||
if u ~= nil then
|
||||
ans[u] = ans[u] or {}
|
||||
if k ~= nil then
|
||||
ans[u][k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
return ans
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
-- GUI
|
||||
|
||||
-- loads game
|
||||
load_game, err = loadfile(gamefile, "t", setmetatable(game, {__index=_G}))
|
||||
|
||||
if err then
|
||||
print(err)
|
||||
-- os.exit(1)
|
||||
end
|
||||
|
||||
load_game()
|
||||
|
||||
local refcnt = 0
|
||||
-- add refs
|
||||
for ref,obj in pairs(game) do
|
||||
if type(obj)=='table' and (obj.is_verb or obj.is_room or obj.is_item) then
|
||||
obj.ref = ref
|
||||
refcnt = refcnt + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- stupid cyber arm glitching again!
|
||||
for i,obj in ipairs(verb_ord) do
|
||||
print("verb " .. obj.ref)
|
||||
end
|
||||
for i,obj in ipairs(room_ord) do
|
||||
print("room " .. obj.ref)
|
||||
end
|
||||
for i,obj in ipairs(item_ord) do
|
||||
print("item " .. obj.ref)
|
||||
end
|
||||
|
||||
print("refcnt = " .. refcnt)
|
||||
print("#verb_ord = " .. #verb_ord)
|
||||
print("#room_ord = " .. #room_ord)
|
||||
print("#item_ord = " .. #item_ord)
|
||||
print("#sum_ord = " .. #verb_ord + #room_ord + #item_ord)
|
||||
|
||||
walk("intro")
|
||||
|
||||
window.document:getElementById("menu"):addEventListener("click", function(eL, ev)
|
||||
local target = ev.target;
|
||||
local code = target:getAttribute("data-code")
|
||||
|
||||
local text = target.innerText
|
||||
local i = tonumber(code)
|
||||
|
||||
issued_command[#issued_command+1] = text
|
||||
process_param(menu2codes[i])
|
||||
|
||||
ev:stopPropagation();
|
||||
ev:preventDefault();
|
||||
end)
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue