AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi [Andorra 2D] Taschenlampe
Thema durchsuchen
Ansicht
Themen-Optionen

[Andorra 2D] Taschenlampe

Ein Thema von sabbert · begonnen am 25. Aug 2010 · letzter Beitrag vom 26. Aug 2010
Antwort Antwort
sabbert

Registriert seit: 16. Apr 2008
67 Beiträge
 
#1

[Andorra 2D] Taschenlampe

  Alt 25. Aug 2010, 23:25
Nabend zusammen,

ich beschäftige mich schon seit längerem mit Andorra 2D und für mein neues Projekt würde ich gerne eine Taschenlampe "einbauen".

Ich habe mir dazu schon ein paar Gedanken gemacht wie ich da vorgehen könnte...

Undzwar dachte ich erst das ich so eine Art schwarze "Maske" über meine Spiel lege und dann den beleuchteten Bereich freilasse. Also es geht mir um die Darstellung des Beleuchteten Bereiches. Dieser soll recht einfach dargestellt werden. So soll sozusagen nur was angeleuchtet wird vom Spieler gesehen werden habe dazu mal ein sehr einfaches Beispiel angehängt wie ich mir das vorstelle

Aber es soll z.B. nicht durch eine Wand hindurch geleuchtet werden.
Wie kann man sowas berechnen und dann anzeigen lassen?
Gibt es in Andorra eine Option die das Spiel sozusagen komplett auf "dunkel" stellt, als ob es Nacht wäre?

Hoffe ihr habt Ideen

mfg
Miniaturansicht angehängter Grafiken
taschenlampe.jpg   taschenlampe02.jpg  
Christian

Geändert von sabbert (25. Aug 2010 um 23:28 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#2

AW: [Andorra 2D] Taschenlampe

  Alt 26. Aug 2010, 09:20
Ich würde hierzu den Stencil-Buffer verwenden. Erklärungen hierzu finden sich u.a. hier: http://wiki.delphigl.com/index.php/Stencilbuffer und in der entsprechenden Demo.

Du zeichnest zuerst die komplette Umgebung etwas "dunkler" als normal Mittels "Ambient-Color". Dann aktivierst du den Stencil-Buffer und zeichnest eine "Schablone" unter der die Szene normal gezeichnet werden soll. Dann zeichnest du deine Szene nochmals. Der Code (nicht getestet) sollte ungefähr so aussehen:
Delphi-Quellcode:
AdDraw.Options := AdDraw.Options + [aoLights];
AdDraw.Scene.AmbientColor := Ad_ARGB(255, 64, 64, 128);
//Scene einmal zeichnen
AdDraw.Options := AdDraw.Options - [aoLights];

AdDraw.Options := AdDraw.Options + [aoStencil, aoAlphaMask];

//Dieser Aufruf bewirkt, dass jeder gezeichnete Pixel das unten aufgeführte Ereignis auslöst
AdDraw.AdAppl.SetStencilOptions(0, $FFFF, asfAlways);
//Der Wert des Stencil-Puffers wird um eins erhöht
AdDraw.AdAppl.SetStencilEvent(asePass, asoIncrement);

//Eine Maske mit weißer Farbe zeichnen, in der die Scene später mit normaler helligkeit Gezeichnet wird

AdDraw.Options := AdDraw.Options - [aoAlphaMask];

//Nur dort zeichnen, wo vorher die Maske war
//Nur wenn "Null" kleiner als der Stencilbuffer Wert ist (was für alle Pixel der Fall ist, bei denen die Maske gezeichnet wurde), darf ein neuer Pixel an diese Stelle gezeichnet werden.
AdDraw.AdAppl.SetStencilOptions(0, $FFFF, asfLessThan);
//Der Stencil-Buffer soll nicht mehr verändert werden, also beibehalten ("Keep")
AdDraw.AdAppl.SetStencilEvent(asePass, asoKeep);


//Szene zeichnen

//Um das ganze schöner Aussehen zu lassen, eine transparente Version der Maske zeichnen, die an den Ecken zu weniger Transparent ausblendet

AdDraw.Options := AdDraw.Options - [aoStencil];
Lies dich auf jeden Fall mal im oben genannten Link in das Thema ein, sodass du diese "SetStencil*" Aufrufe verstehst.

Andreas

Edit: Das mit "Nicht durch die Wand hindurch Leuchten" ist etwas komplizierter, du musst hier mit Raytraycing oder Shadowmapping - beides fortgeschrittene Techniken - arbeiten. Am einfachsten ist es wohl, wenn du dein Level in Zellen aufteilst und im Vorneherein mittels Raytracing (geht mit einfacher Vektorarithmetik) berechnest, welche Zellen von welcher Zelle aus angeleuchtet werden können, und du die nicht anleuchtbaren Zellen wieder aus dem Stencilbuffer entfernst indem du über diese z.B. ein Weißes Quadrat zeichnest und mit "asoZero" den Stencilbuffer für diese zurücksetzt.
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein

Geändert von igel457 (26. Aug 2010 um 10:50 Uhr)
  Mit Zitat antworten Zitat
sabbert

Registriert seit: 16. Apr 2008
67 Beiträge
 
#3

AW: [Andorra 2D] Taschenlampe

  Alt 26. Aug 2010, 15:03
Ok danke schonmal für die recht ausführliche Antwort

Klingt schon recht anspruchsvoll...
Also habe mir den obigen Link mal durchgelesen und weiß jetzt schon ungefähr wofür der StencilBuffer gut ist.

Es soll also eine Maske gezeichnet werden und so soll z.B. nur ein bestimmter Teil gerendert werden, falls ich das so in etwa richtig verstanden habe...

Jetzt wollte ich den Code mal Testen um das besser zu verstehen, aber an sich passiert da noch nichts.

Wenn ich die letzte Zeile weglasse, dann wird glaube ich eine Arte Maske gezeichnet, da ich keine Objekte mehr sehe, als ob diese unter der Maske liegen würden. Aber eine Farbliche Veränderung findet nicht statt

AdDraw.Options := AdDraw.Options - [aoStencil]; Wo muss ich den genannten Code denn einfügen, damit dieser auch gezeichnet bzw übernommen wird?

Habe den zurzeit zwischen
Delphi-Quellcode:
AdDraw.BeginScene;

//Code...

AdSpriteEngine.Move(AdPerCounter.TimeGap / 1000);
AdSpriteEngine.Draw;
AdSpriteEngine.Dead;

AdDraw.EndScene;
in der "OnIdle procedure" stehen.

Edit:

Ich versteh auch noch nicht so ganz wie ich den Bereich einstellen kann wo die Maske gezeichnet wird?!
Christian

Geändert von sabbert (26. Aug 2010 um 15:51 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#4

AW: [Andorra 2D] Taschenlampe

  Alt 26. Aug 2010, 17:31
Gut...

Mit "Szene zeichnen" meine ich AdSpriteEngine.Draw.

Mit "Maske zeichnen" meine ich den Aufruf irgendeiner Zeichenfunktion (z.B. das Zeichnen eines Transparenten Bitmaps, oder das Zeichnen eines Kreises mittels Canvas).

Der Ganze Code muss zwischen AdSpriteEngine.Move und AdSpriteEngine.Dead
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  Mit Zitat antworten Zitat
sabbert

Registriert seit: 16. Apr 2008
67 Beiträge
 
#5

AW: [Andorra 2D] Taschenlampe

  Alt 26. Aug 2010, 18:10
Geil es funktioniert

Hab mal ein Screenshot angehängt wie das aussieht

Habe aus Testzwecken mal ein Rechteck als Maske genommen.

Danke für die Hilfe


Edit:
So jetzt muss ich versuchen das so zu implementieren das Das "Licht" nicht durch Wände scheint mal schauen
Miniaturansicht angehängter Grafiken
maske.jpg  
Christian

Geändert von sabbert (26. Aug 2010 um 18:14 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz