 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 17.05.2005, 22:28 Titel: Raycaster-Problem ! |
|
|
1.
2. Moin, ich hab da mal ein "kleines" Problem. Will mir mal nen Raycaster zusammenfrickeln, hab schon unglaublich viele Tutos dazu studiert, aber die Code-Umsetzung will einfach net funzen *trauer*
Hier mal mein 19. Codeversuch:
Code: |
defint A-Z
dim shared MapWidth, MapHeight
MapWidth = 6
MapHeight = 6
dim shared Map(0 to MapWidth - 1, 0 to MapHeight - 1) as string * 1
DATA "w","w","w","w","w","w"
DATA "w"," "," "," "," ","w"
DATA "w"," "," "," "," ","w"
DATA "w"," "," "," "," ","w"
DATA "w"," "," "," "," ","w"
DATA "w","w","w","w","w","w"
for x = 0 to MapWidth - 1
for y = 0 to MapHeight - 1
read Map(x, y)
next y
next x
const PI = 3.141592654
dim shared TANT(0 to 359) as double, SINT(0 to 359) as double, COST(0 to 359) as double
for a = 0 to 359
TANT(a) = TAN(a * PI / 180)
SINT(a) = SIN(a * PI / 180)
COST(a) = COS(a * PI / 180)
next a
dim Shared ScrResX, ScrResY
ScrResX = 320
ScrResY = 200
screen 13
cls
dim shared Fov, PlayerSize, UnitSize, Dist2Wall, DeltaAngle as single
Fov = 90
PlayerSize = 32
UnitSize = 64
Dist2Wall = (ScrResX \ 2) / TANT(FOV \ 2)
DeltaAngle = FOV / ScrResX
dim shared Facing, PlayerX, PlayerY, PPlayerX, PPlayerY
Facing = 60
PlayerX = 1
PlayerY = 3
PPlayerX = PlayerX * UnitSize + UnitSize \ 2
PPlayerY = PlayerY * UnitSize + UnitSize \ 2
'-------------------------------------------------------------------------------
' H O R I Z O N T A L
if 0 < Facing and Facing < 180 then 'ray is facing up
Ay = (PPlayerY \ UnitSize) * UnitSize - 1
DeltaYA = -UnitSize
eLSE 'ray is facing down
Ay = (PPlayerY \ UnitSize) * UnitSize + 64
DeltaYA = UnitSize
end if
Ax = PPlayerX + (PPlayerY - Ay) / TANT(Facing)
DeltaXA = -DeltaYA / TANT(Facing)
do
AxG = Ax \ UnitSize
AyG = Ay \ UnitSize
if NOT Map(AxG, AyG) = " " then exit do
Ax = Ax + DeltaXA
Ay = Ay + DeltaYA
loop
print AxG, AyG
'-------------------------------------------------------------------------------
' V E R T I K A L
if 270 < Facing and Facing < 360 then 'ray is facing left
Bx = (PPlayerX \ UnitSize) * UnitSize - 1
DeltaXB = -UnitSize
eLSE 'ray is facing right
Bx = (PPlayerX \ UnitSize) * UnitSize + 64
DeltaXB = UnitSize
end if
By = PPlayerX + (PPlayerX - By) * TANT(Facing)
DeltaYB = -DeltaXB * TANT(Facing)
do
BxG = Bx \ UnitSize
ByG = By \ UnitSize
if NOT Map(BxG, ByG) = " " then exit do
Bx = Bx + DeltaXB
By = By + DeltaYB
loop
print BxG, ByG
sleep
end
'-------------------------------------------------------------------------------
|
Als Anhaltspunkt für den Code diente marzecs Spielegrafik-Tutorial und das sehr ähnliche Onlinetutorial http://www.permadi.com/tutorial/raycast/
Der Code soll erstmal einfach nur die horizontalen und vertikalen Schnittpunkte des Strahls mit einer Mauer ausgeben.
Die Variable Facing gibt den Winkel des Strahls an, der Rest ergibt sich von selbst.
Das horizontale Checken geht auch schon teilweise, aber nicht richtig...vom vertikalen Checken will ich erst garnicht reden
Ich wette da ist nur ein kleiner Denkfehler oder so drin, aber ich stehe total auf dem Schlauch und hoffe dass ihr mir aus dieser Situation raushelfen könnt
PS: Der Code wurde und wird übrigens in FB geschrieben.
PS: Nein, ich will nicht mit was leichterem Anfangen. Hab ich nämlich schon lange. Aber das Pixelweise durchchecken einer Map wie in diesen Billig-Castern dauert zu lange und gibt ne miese Auflösung und keine Texturen. _________________
 |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 18.05.2005, 10:32 Titel: |
|
|
Also um das ganze Formelgesocks zu verstehen und mir merken zu können brauch ich mindestens ne Stunde, den Rest hab ich glaub ich schon drin, aber das hilft dir ned
Hast du dir einfach mal den JavaSource angeschaut und versucht, die entsprechenden Stellen zu verstehen/portieren? _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 18.05.2005, 11:33 Titel: |
|
|
Ja hab ich. Und SCHEIßE, nein ich habs net hinbekommen
Und außerdem muss ichs ja selbst verstehen, später sollen ja Texturen, Fußboden+Deckentexturen etc. hinzukommen _________________
 |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 18.05.2005, 18:12 Titel: |
|
|
hm, ich hab leider im Moment ned so viel Zeit.. Sonst würd ich mich ma einarbeiten.. sry.. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 19.05.2005, 16:15 Titel: |
|
|
*verzweiflung*
Mensch, hilf mir doch ma einer  _________________
 |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 19.05.2005, 19:23 Titel: |
|
|
schon mal in nem anderen Forum versucht? wie zB das von c-plusplus.de? die können dir eigentlich bei dem meisten helfen.. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 19.05.2005, 19:29 Titel: |
|
|
hm ich schätze mal wenn das Forum schon cplusplus heißt, dann kennen die sich net mit QB aus
nagut ich probiers trotzdem mal, danke
/edit: das cplusplus.de - forum is geschlossen  _________________
 |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 19.05.2005, 19:32 Titel: |
|
|
oh.. das is schlecht.. dann weiß ich auch ned sollte mir mal langweilig sein versuch ichs zu verstehen.. dann kann ich dir vllt helfen.. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 19.05.2005, 20:10 Titel: |
|
|
das wäre sehr nett von dir
hm marzec war schon länger net im Forum, auf ne PN von mir hat er noch net geantwortet
der könnte mir am meisten helfen (immerhin sind die Formeln aus seinem eigenen Tutorial ) _________________
 |
|
Nach oben |
|
 |
surfer87
Anmeldungsdatum: 16.09.2004 Beiträge: 103
|
Verfasst am: 19.05.2005, 20:15 Titel: |
|
|
hm was genau ist das Ziel bei einem fertigen Raycaster Programm? |
|
Nach oben |
|
 |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 19.05.2005, 20:20 Titel: |
|
|
lol ? -> www.google.de
ein raycaster ist eine semi-3d-engine
aus einer 2d-map wird ein 3d-bild erzeugt
das ganze soll eine art ego-shooter werden _________________
 |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 19.05.2005, 20:31 Titel: |
|
|
OH YEAH! ICC-Shootout Professional edition 19.3! _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
Dusky_Joe

Anmeldungsdatum: 07.01.2005 Beiträge: 1007 Wohnort: Regensburg/Oberpfalz
|
Verfasst am: 19.05.2005, 21:57 Titel: |
|
|
Ich frage mich, ob ich ein Programm kaufen würde, das schon beim first release V19.xx.yy hat
Aber mach nur weiter, wir sind gespannt  _________________ fully biological degradable
Once, the big wave arrives, you've got two ways, you can go:
Either, you ride it, or you don't do.
But, if you don't ride, you'll never know wether you'd have gone wet. |
|
Nach oben |
|
 |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 19.05.2005, 22:24 Titel: |
|
|
Zitat: | Aber mach nur weiter |
was denkst du was ich vorhab..aber du siehst ja meine aktuelle situation mit der scheiß engine  _________________
 |
|
Nach oben |
|
 |
marzec
Anmeldungsdatum: 13.10.2004 Beiträge: 267
|
Verfasst am: 20.05.2005, 04:01 Titel: |
|
|
zers,
tut ma leid zur zeit is arbeit angesagt und ich find kaum zeit zum atmen ( leichte übertreibung ). das tut hab ich vor jahren geschrieben, hab mich mit dem thema daher auch schon enorm lang nicht mehr auseinander gesetzt. als grundlage diente mir jenes englische tutorial welches du angesprochen hast. dieses ist im grunde die referenz dafür im netz ( außer natürlich der doom sourcecode... ). die formeln aus dem tut *könnten* fehler enthalten bin mir aber nicht mehr ganz sicher. ich würde dir jedenfalls empfehlen zuerst einen bruteforce raycaster zu basteln, sprich erstmal die geschichte mit der optimierten schrittweite vergessen und einfach in kleinsten schritten ( z.b. eine einheit ) über die map zu scannen. im grunde recht einfach, du hast bereits die direction vom spieler ( also seine rotation um die y-achse von der ich annehme, dass sie nach oben zeigt ). zudem hast du ein gewisses field of view welches in grad angegeben ist ( könnte man auch anders konstruieren aber vergiss das bringt keinen vorteil ). gut direction in grad, field of view in grad. dann hast du natürlich deine screen resolution ws. 320x200 ( höhere modi sind rechenintensiver klarerweise ). du willst jetzt für jede spalte am bildschirm einen strahl aussenden und sehen ob dieser eine wand trifft. 320 strahlen für ein field of view von 90° ( merke dieses is nicht optimal ) ergibt eine schrittweite für die grad ( also der unterschied in der richtung eines strahls und seinem nachbarn ) von 90/360. die direction gibt dabei den strahl für den spalt in der mite des schirms an. du beginnst daher beim rechten spalt welcher die richtung direction - fieldofview/2 hat. von diesem "winkel" errechnest du jetzt die komponenten des vektors der den strahl beschreibt. das geht wunderbar mit unseren freunden cosinus und sinus die uns jeweils die x und y komponente angeben. vorsicht in qbasic muß der winkel in bogenmaß an die COS und sIN funktionen übergeben werden. von grad auf bogenmaß kommst du über die formel bogenmaß = grad * ( PI / 180 ). mit hilfe dieses vektors schickst ( castest ) du jetzt den strahl für die erste spalte aus. als startpunkt verwendest du die aktuelle postiion des beobachters auf der karte. gut, alles sehr verwirrend ich versuch no kurz nicht funktionfähigen pseudocode zu schreiben:
Code: |
const DEGTORRAD = 3.14 / 180.0 '' konstante zum umrechnen von grad in bogenmaß
const FIELDOFVIEW = 90 '' field of view, gesichtsfeld in grad
const WALLUNIT = 64 '' einheit für wände ( höhe breite länge )
dim posx, posy as singe '' position des beobachters auf der map
dim direction '' aktuelle blickrichtung des beobachters
dim rayx, rayy as single '' aktuell errechneter punkt des aktuellen strahls
dim raydirx, raydiry as single '' aktuelle richtung des aktuellen strahls als vektor
dim raylength as single '' abstand vom beobachter zu einer getroffenen wand, brauchma um höhe der wand am bildschirm zu errechenn
dim currraydir '' aktuelle richtung des aktuellen strahls in grad
dim map ( 10, 10 ) '' unsere karte, initialisierung spar ich mir...
do
'' jeden strahl ausschicken
for currraydir = direction - FIELDOFVIEW / 2 to direction + FIELDOFVIEW / 2
'' richtung des aktuellen strahls berechnen
raydirx = cos( DEGTORAD * currraydir )
raydiry = sin( DEGTORAD * curraydir )
'' startpunkt für den strahl errechnen, länge auf null setzen
rayx = posx: rayy = posy
raylength = 0.0
'' strahl casten, prinzip: schaun ob aktuelle position auf karte = wand
'' wenn ja dann abstand von beobachter zur wand nehmen und daraus
'' höhe der wand berechnen ( dies bitte den tuts entnehmen, höhe
'' berechnen mein ich
do
'' checkn ob strahl überhaupt noch auf der map is
if( rayx < 0 or rayx > 10 * WALLUNIT ) then exit loop
if( rayy < 0 or rayy > 10 * WALLUNIT ) then exit loop
'' checkn ob aktuelle position des strahls auf einem wandfeld is
'' wenn ja wand zeichnen, map sollte integer codiert sein nicht
'' als string speichern ob wand oder leer :)
if( map( rayx / WALLUNIT, rayy / WALLUNIT ) = "wand" ) then
'' hier wandhöhe aus länge des strahls und WALLUNIT errechen
'' siehe dazu formeln im tut..., dann für aktuelle spalte vertikalen
'' strich mit errechneter länge zeichenn...
end if
'' nix getroffen, also gehn wir weiter auf dem strahl
rayx = rayx + raydirx
rayy = rayy + raydiry
'' länge des strahls um schrittweite erhöhen, da cos sinus is
'' schrittweite eins ( radius einheitskreis )
raylength = raylength + 1
loop
next currraydir
loop while INKEY$ = ""
|
doch länger als gedacht aber nur wegen der kommentar. mehr is es nicht. das dingens is natürlich komplett unoptimiert und wird arschlangsam sein. um dass zu ändern sollte man sich dann wie gesagt methoden überlegen die größere schritteweiten verwendet, oder diese halt je nach situation optimiert ( hier setzt tutorial an ). ich würde vorschlagen zuerst einen solchen 08/15 raycaster zu machen. auch wenn der arschlangsam is is es gut zuerst damit zu arbeiten, den zu erweitern ist dann kein problem.
so genug geschrieben muß wieder arbeiten. werd mich möglicherweise nochmal melden und auf fragen antworten aber net bös sein wenn ich das nicht mach, arsch voll arbeit.
bisch den
[EDIT] super, da schreib ich mir den arsch ab und dann seh ich dein zweites p.s. trotz alle dem. wenn ich ehrlich sein darf, dann sieht dein code so aus als hättest du einfach ein wenig copy and paste betrieben ( englishsprachige variablen namen sind in der deutschen community teilweise verpönnt ich hab nur kurz drüber geschaut, aber irgendwie hast du einen leichten denkfehler drinnen. die horizontal und vertikal aufteilung ergibt sich aus der tatsache heraus, dass man das kartesische koordinatensystem in oktanten aufteilen kann die jeweils 90° der gesamten fläche einnehmen. befindet sich ein vektor innerhalb eines solchen oktanten dann haben seine x und y komponente eine spezielle beziehung. vektoren in den oktanten 1, 4, 5 und 8 haben gemein, dass deren x komponente größer als deren y komponente ist. in den oktanten 2, 3, 6 und sieben ist dies umgekehrt. ( leicht nazuprüfen mit stift und papier oder auf wikipedia... ). wie man sieht kann man vektoren also dadurch gruppieren und MUß die beiden typen seperat behandeln. das hat etwas mit der schrittweite zu tun und ist sehr verwand mit dem problem des zeichnens von normalen linien am schrim. wenn man die falsche komponente des vektors hernimmt zum inkrementieren ( uhm "zählen" ) dann entstehen löcher, d.h. es werden nicht alle relevanten punkte auf der linie/strahl abgetastet. darum die unterteilung in vertikale ( y kompontene > x komponente ) und horizontale ( x komponente > y komponente ). du kannst nicht einfach beides machen und hoffen, dass das richtige herauskommt. daher mein rat. beginne mit einem "billigraycaster" auch wenn es deinen stolz verletzen mag.
btw, einen raycaster in purem qb/fb zu schreiben ist zeitverschwendung... _________________ Yagl - yet another gameprogramming library |
|
Nach oben |
|
 |
Paul aka ICC, HV-Freak
Anmeldungsdatum: 11.09.2004 Beiträge: 588 Wohnort: Uelzen
|
Verfasst am: 20.05.2005, 07:23 Titel: |
|
|
Moin, erstmal danke für die ausführliche Antwort
Wie gesagt, so einen Raycaster der die Map "Pixelweise" prüft hab ich schon lange geschrieben.
Und nein, der Code ist nicht einfach kopiert, sondern hab mich schon intensiv damit beschäftigt. Auch auf mathematischem Wege kann ich das nachvollziehen..
Das Problem liegt wie du bereits sagtest in x/y Aufteilung, hab ich gemerkt.
Aber das hilft mir auch net weiter.
PS: Ich benutze immer englische Variablennamen  _________________
 |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|