Was mit Minetest alles machbar ist, beweist schön das von SGVsbG8K programmierte Snake-Spiel, bei dem es darum geht, eine Schlange den nächsten Stein fressen zu lassen, wodurch sie immer länger wird. Mit seiner Genehmigung dokumentieren wir hier den Code und ermutigen zum Nachmachen .
Man erreicht es über den POI „Snakespiel“ im Inventar (P anklicken).
Programmierung
Code für die Leuchtsteine auf der Anzeigetafel, unterster Controller:
if event.type=="program" then mem.pos={0,7} end local function is_this(pos) return (pos[1]==mem.pos[1] and pos[2]==mem.pos[2]) or pos=="all" end if event.type=="digiline" and event.channel=="screen" and is_this(event.msg[1]) then port.c=event.msg[2] end
Code des Spiels:
local function reset() mem.cursor={0,0} digiline_send("screen", {"all",false}) digiline_send("screen", {mem.cursor,true}) mem.length=0 mem.tail={{0,0}} mem.dir={1,0} mem.dirname="left" mem.food={math.random(0,mem.w-1), math.random(0,mem.h-1)} digiline_send("screen", {mem.food,true}) if not mem.running then interrupt(1);mem.running=true end end if event.type=="program" then mem.name="anonym" mem.w=8 mem.h=8 mem.dirs={["up"]={0,1}, ["down"]={0,-1}, ["left"]={1,0}, ["right"]={-1,0},} reset() end local function random_pos() return {math.random(0,mem.w-1), math.random(0,mem.h-1)} end local function touching_tail(pos) for i,j in ipairs(mem.tail) do if j[1]..","..j[2] ==pos[1]..","..pos[2] then return true end end return false end local function get_vh(dir) test={["right"]="h", ["left"]="h", ["up"]="v", ["down"]="v"} return test[dir] end local function is_valid(dir) return not (get_vh(dir) == get_vh(mem.dirname)) end if event.type=="digiline" and event.channel=="name" then name=event.msg mem.name=name end if event.type=="digiline" and event.channel=="buttons" then dir=mem.dirs[event.msg] if not dir then if event.msg=="middle" then --[[mem.cursor={0,0} digiline_send("screen", {"all",false}) digiline_send("screen", {mem.cursor,true}) mem.length=0 mem.dir={1,0} mem.tail={{0,0}} mem.dirname="left" mem.food={math.random(0,mem.w-1), math.random(0,mem.h-1)} digiline_send("screen", {mem.food,true})]] reset() end return end if is_valid(event.msg) then mem.dir=dir mem.dirname=event.msg end end local function equal_pos(p1,p2) return (p1[1]..","..p1[2] == p2[1]..","..p2[2]) end local function select_new_food_pos() pos=random_pos() if touching_tail(pos) then while touching_tail(pos) do pos=random_pos() end end mem.food=pos digiline_send("screen", {mem.food,true}) end local function die() mem.running=false digiline_send("image_manager", "dead")--die digiline_send("highscore", {mem.name,mem.length}) end --main loop if event.type=="interrupt" then if (mem.cursor[1]+mem.dir[1]<0 or mem.cursor[1]+mem.dir[1]>mem.w-1) or (mem.cursor[2]+mem.dir[2]<0 or mem.cursor[2]+mem.dir[2]>mem.h-1) then die() return end --digiline_send("screen", {mem.cursor,false}) if #mem.tail-1>mem.length then digiline_send("screen", {mem.tail[1],false}) table.remove(mem.tail,1) end mem.cursor={mem.cursor[1]+mem.dir[1],mem.cursor[2]+mem.dir[2]} if touching_tail(mem.cursor) then mem.running=false die() return end if equal_pos(mem.cursor, mem.food) then mem.length=mem.length+1 select_new_food_pos() end digiline_send("screen", {mem.cursor,true}) --[[for i,j in ipairs(mem.tail) do digiline_send("screen", {j,true}) end]] digiline_send("screen", {mem.food,true}) table.insert(mem.tail, mem.cursor) interrupt(1) end --[[test-program if event.type=="program" then mem.w=6 mem.h=6 mem.cursor={0,0} digiline_send("screen", {"all",false}) digiline_send("screen", {mem.cursor,true}) mem.dirs={["up"]={0,1}, ["down"]={0,-1}, ["left"]={1,0}, ["right"]={-1,0},} end if event.type=="digiline" and event.channel=="buttons" then dir=mem.dirs[event.msg] if not dir then if event.msg=="middle" then digiline_send("screen", {mem.cursor,false}) mem.cursor={0,0} digiline_send("screen", {mem.cursor,true}) end return end if (mem.cursor[1]+dir[1]<0 or mem.cursor[1]+dir[1]>mem.w-1) or (mem.cursor[2]+dir[2]<0 or mem.cursor[2]+dir[2]>mem.h-1) then return end digiline_send("screen", {mem.cursor,false}) mem.cursor={mem.cursor[1]+dir[1],mem.cursor[2]+dir[2]} digiline_send("screen", {mem.cursor,true}) end--]]
Mittlerer Controller:
if event.type=="program" then mem.images={["404"]={}, ["dead"]={{2,2}, {5,2}, {3,3}, {4,3}, {2,5}, {5,5}}, ["clear"]={}} end if event.type == "digiline" and event.channel=="image_manager" then digiline_send("screen", {"all",false}) image=mem.images[event.msg] or mem.images["404"] for i,j in ipairs(image) do digiline_send("screen",{j,true}) end end
Oberer Controller:
if event.type=="program" then mem.list={} end local function update() digiline_send("display", "\n\n\n\n\n\n") for i,j in pairs(mem.list) do digiline_send("display", j[1]..": "..j[2]) end end if event.type=="digiline" and event.channel=="highscore" then name=event.msg[1] points=event.msg[2] if #mem.list==0 then table.insert(mem.list,{name,points}) elseif mem.list[#mem.list][2]<=points then for i,j in ipairs(mem.list) do if j[2]<=points then table.insert(mem.list,i,{name,points}) break end end if #mem.list > 6 then table.remove(mem.list,#mem.list) end elseif #mem.list<7 then table.insert(mem.list,{name,points}) end update() end
Schalter für neues Spiel:
if event.type=="program" then mem.list={} end local function update() digiline_send("display", "\n\n\n\n\n\n") for i,j in pairs(mem.list) do digiline_send("display", j[1]..": "..j[2]) end end if event.type=="digiline" and event.channel=="highscore" then name=event.msg[1] points=event.msg[2] if #mem.list==0 then table.insert(mem.list,{name,points}) elseif mem.list[#mem.list][2]<=points then for i,j in ipairs(mem.list) do if j[2]<=points then table.insert(mem.list,i,{name,points}) break end end if #mem.list > 6 then table.remove(mem.list,#mem.list) end elseif #mem.list<7 then table.insert(mem.list,{name,points}) end update() end
Schalter „nach links“:
if event.type=="on" and pin.c then digiline_send("buttons", "left") end