Mit Minetest den Retroklassiker Snake programmieren

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

Der Adventskalender 2020: Weihnachtsbräuche und noch etwas Mese dazu

von Norbert Thien, www.multimediamobile.de

1. Die Ausgangssituation

Das wichtigste an einem Adventskalender sind 24 Möglichkeiten, kleine Überraschungen zu verstecken. So entstand die Idee eines Labyrinths. Es enthält 24 Bücher, die jeden Tag die Weihnachtsbräuche in einem bestimmten Land erklären:

Natürlich sollten die Bücher nicht alle sofort zu sehen sein, sondern nur am jeweils passenden Tag. Hier kommt MESE – das Redstone in Minetest – ins Spiel. Aber MESE bedeutet auch immer, dass man viele Leitungen legen muss, die je nach Vorhaben den Gesamteindruck des Bauwerks schmälern. Also wurde dem Labyrinth ein Untergeschoss verpasst, das die gesamte Technik aufnimmt:

(mehr …)

Tür 1 im digitalen Adventskalender 2019

Schöner kann das Datum nicht fallen: Am 1. Dezember ist der 1. Advent. In Genau 24 Tagen ist Weihnachten und der schönste Countdown des Jahres beginnt. Wir starten hiermit den digitalen Adventskalender. Das erste Türchen führt über einen Warpstein, den man anklicken muss zu dieser wunderschönen Kirche. Glaube, Liebe und Hoffnung stehen im Zentrum. Auf dem Altar liegt eine Bibel. Wenn man sie (mit links) anklickt, kann man den Predigttext des 1. Advents-Sonntags lesen.

Dazu passt wunderbar das schöne Lied “Die Nacht ist vorgedrungen” von Jochen Klepper, das man z. B. hier hören kann: https://www.liederprojekt.org/lied31689-Die_Nacht_ist_vorgedrungen.html. Mehr Informationen zu diesem Lied findet man hier: https://de.wikipedia.org/wiki/Die_Nacht_ist_vorgedrungen

Eine Adventspredigt von Pfr. Thomas Ebinger zum 1. Advent (siehe https://www.kirchenjahr-evangelisch.de/article.php#836) kann man (in Kürze) hier herunterladen: https://www.kemnat-evangelisch.de/15-02-2019-downloads/23-04-2019-predigten/

Es lohnt sich auch, in der Kirche die Stockwerke nach oben zu steigen. Dort kann man den Schalter betätigen und ein wunderschönes Kreuz als Lichtinstallation sehen.

Reinkommen und mitmachen

Alle Informationen dazu in diesem Post: Der Minetest-Adventskalender 2019 ist online!

Tür 22 im digitalen Adventskalender 2018

Technik sorgt bei uns dafür, dass es gemütlich wird. Heute gibt es kurz vor dem großen Finale einen Blick hinter die Kulissen der Adventskalendermechanik. Bei einer gemütlichen Rundfahrt mit einem Minecart kann man das Wunderwerk bestaunen, das mmmsued erschaffen und hier ausführlich dokumentiert hat.  Wer es ihm nachtun will: Man braucht keine besonderen Rechte dafür, alle Materialien und Programmiermöglichkeiten stehen für alle Spieler zur Verfügung.

(mehr …)

Die Mese-Mechanik des Minetest-Adventskalenders – eine Dokumentation

Von Norbert Thien, multimediamobil – Region Süd, www.multimediamobile.de/sued.html

Am Anfang stand die Frage, wie ein Adventskalender in Minetest aussehen könnte. Baut man einfach eine große Wand mit 24 Zugängen? Und wie schafft man es, dass sich die Türen immer nur am richtigen Tag öffnen?

Schnell war klar, dass viel MESE, das Redstone in Minetest, zum Einsatz kommen würde. Aber viele MESE-Leitungen bedeuten oft auch, dass man eine Menge Technik verbauen muss. Und wie bei richtigen Gebäuden will man natürlich die Installation möglichst vor den Augen der Besucher verbergen. So entstanden am Ende 24 kleine Häuser, vier Blöcke breit, fünf Blöcke hoch und tief, mit einem kleinen Spitzdach:

Die Technik

Zum Einsatz kommen Stahltüren (STEEL DOOR), denn diese sind individualisiert, können also mit Rechtsklick nur von der Person geöffnet werden, die sie angelegt hat. Oder aber über MESE-Objekte, zum Beispiel mit einer Druckplatte (STONE PRESSURE PLATE). Hierfür – und für die weiteren Bauten – müssen die beiden Mods MESECONS und DIGILINES  installiert sein. Der vereinfachte Aufbau sieht am Ende so aus: (mehr …)