Re: Showroom - Aktuelle Arbeiten und Projekte
Verfasst: 25.11.2020, 20:29
Die Menüs sind super!
Die deutsche Spieleentwickler-Community (seit 1999).
https://zfx.info/
Danke! Solche Details in Menüs wie die Transitions und kleinen Animationen sind wichtig und im aktuellen Stand der Entwicklung "nicht notwendig", aber ein guter Benchmark, um die Software-Architektur zu testen. Zudem ist der erste Eindruck halt auch 100 mal besser mit schön animierten Menüs statt einfach nur grauen Buttons und macht beim Entwickeln auch gute Laune.
Hm, das klingt erstmal ein wenig frustrierend. Ist es denn immer langsamer? Skaliert es irgendwie anders als die unparallele Version? Vielleicht laufen jetzt ja zumindest sehr große Szenen flüssiger?Schrompf hat geschrieben: ↑07.12.2020, 22:30 Sieht aus wie immer, hm? Ist ein klein bisschen langsamer als der ursprüngliche Point Cloud Renderer, den ich im Jahr 2018 für ne ZfxAction gebastelt hatte. Aber dafür ist er jetzt auf 12+12 Hardwarethreads parallelisiert :-( Hat sich echt gelohnt, die Arbeit.
Ich spekuliere hier bloß, aber:
Die 3D-Grafik ist durchaus angemessen, die Frage ist nur, wie viel Budget man hatte. Wenn man richtig viel Kohle hatte, konnte man sich durchaus auch ein grafisches Terminal von Tektronix kaufen, mit gigantischen 4096x3078 Bildpunkten:
:D Ich konnte wieder meine Klappe nicht halten. Sieht aber sweeeeeeeet aus. Ich könnte dran arbeiten!
Puh, 2017, schon so lange her mein erstes Sequenzer-Projekt (eigentlich nur eine Gamejingle-Komponierhilfe) :D Aber das damals angesprochene "irgendwann" ist genau jetzt. Das Prinzip Harmonielehre als Schablone habe ich kürzlich für Midi ausgebaut. Diesmal ein In-Code-Sequencer, der Midi-Commands im richtigen Timing ausspuckt. Code sieht inzwischen anders aus, aber so ähnlich:
Code: Alles auswählen
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>retro 3D maze game</title>
</head>
<body style="background-color:#000800;">
<div align="center"><canvas id="img" width="1024" height="768"></canvas></div>
<script>
//simple retro 3D maze game, joeydee 2020
var c=document.getElementById("img");
var inf=document.getElementById("info");
var ctx=c.getContext("2d");
var cx=c.width*0.5;
var cy=c.height*0.5;
var scale=Math.min(cx,cy);
var maze="";
var width=0;
var px=0;
var py=0;
var dir=0;
var dlt=[-1,0,0,-1,1,0,0,1];
var dfd=[0,-1,1,0,0,1,-1,0];
var drt=[1,0,0,1,-1,0,0,-1];
var dirs=["north","east","south","west"];
var numCoins=0;
var coins=0;
var findExit=false;
var newMaze=true;
var dungeonNr=0;
var initialSeed=1;
var seed=1;
var name="";
var myAlert="";
var names={};
names["$0"] = ["$2$2, the $1 $3 of $4", "the $1 $3 of $2$2$2\n($6 $5)", "$2$2$9$2$7, $3 of $2$2", "$1 $8 $2$2-$2 $3", "$2$2$2 $3\n(home of these $1 $5)"];
names["$1"] = "old,spooky,mindgrabbing,dark,wandering,neverending,crying,hollow,wet,scary,pink,hairy,crusty,dangerous,deadly,egypt,forgotten,derelict,buried,lost,undead,endless,slimy".split(",");
names["$2"] = "o',$2ke,ta,ro,ba,ko,no,pan,hel,bar,kof,dil,men,sor,fat$2,gol,gos,wee,had,mor,fur,kos,lor,fee,ton,dra,mork,nask,prom".split(",");
names["$3"] = "dungeon,maze,tunnels,rooms,caves,graves,tombs,catacombs,basement,mines,nexus,nemesis,ruins".split(",");
names["$4"] = "darkness,sorrow,howling,doom,apocalypse,horror,perdition,infinity,fear".split(",");
names["$5"] = "harmless ghosts,werewolf drawings,hallucinations,grapping hands,old indian spirits,restless spiders,speaking walls,irrational deep traps,masked mummies,black cats,chinese ghosts,headless warriors,tame scorpions,insane souls".split(",");
names["$6"] = "don't be scared of,beware of,avoid,run away from,hide in case of,good luck with,there might be".split(",");
names["$7"] = "berg,bach, valley,burgen, castle, creek".split(",");
names["$8"] = "upper,lower,st.,great,ol'".split(",");
names["$9"] = "-$2,".split(",");
document.addEventListener("keydown",kdown);
var fontSize=16;
ctx.font=fontSize+"px Courier";
randomMaze();
redraw();
function rnd(id){
id = (id * id * id * 9301 + 49297) % 233280;
return Math.abs(id / 233280);
}
function randomMaze(){
dungeonNr++;
seed=rnd(dungeonNr*4564689+129)*463278+623;
initialSeed=rnd(seed*452356+23452)*5349+124;
if(dungeonNr==18||dungeonNr==25)seed+=5223;
maze="";
width=6;
numCoins=coins=0;
for(var y=0;y<6;y++){
var a="";
var b="";
for(var x=0;x<width/2;x++){
var r=rnd(seed++);
if(r<0.2){
a+="# ";
b+="# ";
}
else if(r<0.4){
a+="##";
b+=" ";
}
else if(r<0.8){
a+="# ";
b+=" ";
}
else {
a+="#C";
b+=" ";
numCoins++;
}
}
maze+=a+b;
}
maze+="#X";
px=width;
py=1;
dir=3;
findExit=false;
newMaze=false;
name=mazeName("$0",initialSeed);
myAlert=name+"\n\n"+"you are trapped in this dark dungeon!\nfind all magic coins and then the exit (X)\n\nuse cursor keys to navigate\npress any key to start";
}
function mazeName(txt, mazeSeed){
var res=txt;
for(var s in names){
var s2=s;
var arr=res.split(s2);
res=arr[0];
for(var i=1;i<arr.length;i++){
mazeSeed=rnd(mazeSeed*123456);
var id=Math.floor(mazeSeed*names[s2].length);
res+=mazeName(names[s2][id]+arr[i],mazeSeed++);
}
}
return res;
}
function kdown(event){
if(event.key=="x")newMaze=true;
if(newMaze){
randomMaze();
redraw();
return;
}
if(event.key=="ArrowUp") goto(px+dfd[dir*2], py+dfd[dir*2+1]);
if(event.key=="ArrowDown") goto(px-dfd[dir*2], py-dfd[dir*2+1]);
if(event.key=="ArrowRight")dir+=1;
if(event.key=="ArrowLeft")dir+=3;
dir%=4;
redraw();
}
function goto(nx,ny){
var t=getTile(nx,ny);
if(t!="#"){
px=nx;
py=ny;
if(t=="C"){
setTile(px,py,".");
coins++;
myAlert="you found a magic coin!";
}
if(t=="X"){
if(findExit){
myAlert="congrats!\nyou escaped "+name.split("\n")[0]+".\npress any key to fall into another dungeon.";
newMaze=true;
}
else myAlert="find all magic coins first.\n"+(numCoins-coins)+" magic coin(s) remaining.";
}
}
}
function getTile(tx,ty){
if(tx<0 || tx>=width)return "#";
var id=ty*width+tx;
if(ty<0 || id>=maze.length)return "#";
return maze.substr(id,1);
}
function setTile(tx,ty,char){
if(tx<0 || tx>=width)return;
var id=ty*width+tx;
if(ty<0 || id>maze.length)return;
maze=maze.substr(0,id)+char+maze.substr(id+1);
}
function draw(x,y,zoom){
lt=getTile(x+dlt[dir*2],y+dlt[dir*2+1]);
fd=getTile(x+dfd[dir*2],y+dfd[dir*2+1]);
rt=getTile(x+drt[dir*2],y+drt[dir*2+1]);
drawLayer(zoom,lt!="#",rt!="#");
if(fd=="C")drawCircle(0,zoom*scale/3,zoom*0.1);
if(fd=="X"){
var a=zoom*scale*0.5;
drawLine(-a,a,a*0.5,a*0.5);
drawLine(a,a,-a*0.5,a*0.5);
}
if(fd!="#" && zoom>0.01)draw(x+dfd[dir*2],y+dfd[dir*2+1],zoom*0.5);
ctx.fillText("dungeon #"+dungeonNr+" - "+name,10,1*fontSize*1.2);
var cns="magic coins: "+coins+"/"+numCoins+(coins==numCoins?" find exit (X)!":"");
ctx.fillText(cns+" - "+"compass: "+dirs[dir],10,2*fontSize*1.2);
if(coins==numCoins && !findExit){
myAlert="you found all magic coins!\nnow find the exit (X)";
findExit=true;
}
}
function redraw(){
ctx.clearRect(0,0,cx*2,cy*2);
ctx.fillStyle="#000000";
ctx.fillRect(0,0,cx*2,cy*2);
ctx.strokeStyle="#00AA00";
ctx.fillStyle="#00FF00";
draw(px,py,1.7);
if(myAlert!=""){
var arr=myAlert.split("\n");
ctx.fillStyle="#003000A0";
var w=scale*1.4;
var h=scale*0.5;
ctx.fillRect(cx-w*0.5,cy-h*0.5,w,h);
ctx.fillStyle="#00FF00";
for(var i=0;i<arr.length;i++){
ctx.fillText(arr[i],cx-w*0.5+10,cy-h*0.5+fontSize*(i+1)*1.2);
}
}
myAlert="";
}
function drawLayer(zoom, leftWay, rightWay) {
col = Math.min(255, Math.floor(zoom * 100+10)).toString(16);
ctx.strokeStyle = "#00"+col+"00";
var a=zoom*scale;
var b=a*0.5;
drawLine(-a,-a,-b,-b);
drawLine( a,-a, b,-b);
drawLine( a, a, b, b);
drawLine(-a, a,-b, b);
if(leftWay){
drawLine(-a,-b,-b,-b);
drawLine(-a,b,-b,b);
}
if(rightWay){
drawLine( a,-b,b,-b);
drawLine( a,b,b,b);
}
ctx.beginPath();
ctx.rect(-b+cx,-b+cy,a,a);
ctx.stroke();
}
function drawLine(ax,ay,ex,ey){
ctx.beginPath();
ctx.moveTo(ax+cx,ay+cy);
ctx.lineTo(ex+cx,ey+cy);
ctx.stroke();
}
function drawCircle(x,y,r){
ctx.beginPath();
ctx.arc(x+cx,y+cy,r*scale,0,2*Math.PI);
ctx.stroke();
}
</script>
</body>
</html>
Bin einmal mehr sehr beeindruckt! Wie hast du die Kollision realisiert? Ist das ein Eigenbau? (-: