Att göra en grundläggande 3D-motor i Java (4 / 5 steg)

Steg 4: Beräkning av skärmen

Skärmen är där majoriteten av beräkningarna som är gjort för att få programmet arbetar. För att arbeta, måste klassen import av följande produkter:

import java.util.ArrayList;
import java.awt.Color;

Den faktiska klassen börjar såhär:

allmän klass skärmen {
Public int [] [] karta;
Public int mapWidth, mapHeight, bredd, höjd;
offentliga ArrayList texturer;

Kartan är samma karta skapas i klassen spel. Skärmen använder denna för att räkna ut var väggarna är och hur långt bort från spelaren de är. Bredd och höjd definiera storleken på skärmen, och bör alltid vara samma som bredden och höjden av ramen skapad i klassen spel. Texturer är en lista över alla texturer så att skärmen kan komma åt bildpunkter med texturer. Efter dessa variabler deklareras de måste initieras i konstruktören som så:

offentliga skärmen (int [] [] m, ArrayList tex, int w, int h) {
karta = m;
texturer = tex;
bredd = w;
höjd = h;
}

Nu är det dags att skriva en metod i klassen har: en uppdateringsmetoden. Metoden update beräknar om hur skärmen ska se till användare baserat på deras position i kartan. Metoden kallas ständigt, och returnerar uppdaterade pixlar till klassen spel. Metoden börjar med att "rensa" på skärmen. Det gör detta genom att alla bildpunkter på toppen hälften till en färg och alla bildpunkter på botten till en annan.

Public int [] uppdatering (kamera kamera, int [] bildpunkter) {
för (int n = 0; n < pixels.length/2; n ++) {
om (pixlar [n]! = Color.DARK_GRAY.getRGB()) pixlar [n] = Color.DARK_GRAY.getRGB();
}
för (int i=pixels.length/2; i < pixels.length; i ++) {
om (pixlar [i]! = Color.gray.getRGB()) pixlar [i] = Color.gray.getRGB();
}

Med toppen och botten av skärmen vara två olika färger gör det verka som om det finns ett golv och ett tak också. Efter pixeln avmarkeras array då är det dags att gå vidare till de viktigaste beräkningarna. Programmet loopar igenom varje lodrätt streck på skärmen och kastar en ray att räkna ut vilken vägg bör vara på skärmen på det lodräta strecket. I början av slingan ser ut så här:

för (int x = 0; x < bredd, x = x + 1) {
Double cameraX = 2 * x / (double)(width) -1;
Double rayDirX = camera.xDir + camera.xPlane * cameraX;
Double rayDirY = camera.yDir + camera.yPlane * cameraX;
Karta position
int mapX = (int)camera.xPos;
int mapY = (int)camera.yPos;
längden på ray från nuvarande position till nästa x eller y-sida
dubbla sideDistX;
dubbla sideDistY;
Längden på ray från en sida till nästa karta
Double deltaDistX = Math.sqrt (1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
Double deltaDistY = Math.sqrt (1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
dubbla perpWallDist;
Riktning att gå i x och y
int stepX, stepY;
booleska hit = false; //was en vägg hit
int sida = 0; //was vägg vertikal eller horisontell

Allt som händer här är vissa variabler som kommer att användas av resten av loopen beräknas. CameraX är x-koordinaten för nuvarande vertikala strecket på kameran planet rayDir variabler göra en vektor för strålen. Alla variabler slutar med DistX eller DistY beräknas så att endast kontrolleras för kollisioner på de platser där kollisioner kan eventuellt förekomma. perpWallDist är avståndet från spelaren till första väggen strålen kolliderar med. Detta kommer att beräknas senare. När det är gjort måste vi räkna ut några av de andra variablerna baserat på den beräknade vi redan.

Räkna ut steg riktningen och ursprungliga avståndet till en sida
om (rayDirX < 0)
{
stepX = -1;
sideDistX = (camera.xPos - mapX) * deltaDistX;
}
annat
{
stepX = 1;
sideDistX = (mapX + 1.0 - camera.xPos) * deltaDistX;
}
om (rayDirY < 0)
{
stepY = -1;
sideDistY = (camera.yPos - mapY) * deltaDistY;
}
annat
{
stepY = 1;
sideDistY = (mapY + 1.0 - camera.yPos) * deltaDistY;
}

När det är klart det är dags att räkna ut där strålen kolliderar med en vägg. Att göra detta program går igenom en slinga där det kontrolleras om ray har kommit i kontakt med en mur, och om inte flyttas till nästa möjliga sammanstötningen kopplingspunkt innan du kontrollerar igen.

Slinga för att hitta där strålen träffar en vägg
While(!hit) {
Hoppa till nästa ruta
om (sideDistX < sideDistY)
{
sideDistX += deltaDistX;
mapX += stepX;
sidan = 0;
}
annat
{
sideDistY += deltaDistY;
mapY += stepY;
sida = 1;
}
Kontrollera om ray har drabbat en vägg
om (karta [mapX] [kartor] > 0) hit = sant;
}

Nu när vi vet där strålen träffar en vägg som vi kan börja räkna ut hur väggen ska se i vertikala stripe vi är för tillfället. För att göra detta vi först beräkna avståndet till väggen och sedan använda denna sträcka för att räkna ut hur lång väggen ska visas i den vertikala band. Vi översätter det höjden en start och slut i form av pixlar på skärmen. Koden ser ut så här:

Beräkna avstånd till islagspunkten
IF(Side==0)
perpWallDist = Math.abs ((mapX - camera.xPos + (1 - stepX) / 2) / rayDirX);
annat
perpWallDist = Math.abs ((mapY - camera.yPos + (1 - stepY) / 2) / rayDirY);
Nu beräkna höjden på väggen beroende på avståndet från kameran
int lineHeight;
om (perpWallDist > 0) lineHeight = Math.abs((int)(height / perpWallDist));
annat lineHeight = höjd;
Beräkna lägsta och högsta pixel fylla i nuvarande stripe
int drawStart = - lineHeight / 2 + höjd/2.
IF(drawStart < 0)
drawStart = 0;
int drawEnd = lineHeight/2 + höjd/2.
om (drawEnd > = höjd)
drawEnd = höjd - 1.

Efter som beräknas är det dags att börja räkna ut vilka pixlar från strukturen på väggen faktiskt kommer att visas för användaren. För detta måste vi först räkna ut vilken konsistens är associerad med väggen vi bara hit och sedan räkna ut x-koordinaten på textur av pixlar som visas för användaren.

lägga en textur
int texNum = karta [mapX] [kartor] - 1.
dubbla wallX; //Exact position där väggen blev påkörd
IF(Side==1) {//If det är en y-vägg
wallX = (camera.xPos + ((mapY - camera.yPos + (1 - stepY) / 2) / rayDirY) * rayDirX);
} annat {//X-axis vägg
wallX = (camera.yPos + ((mapX - camera.xPos + (1 - stepX) / 2) / rayDirX) * rayDirY);
}
wallX-= Math.floor(wallX);
x-koordinat på konsistens
int texX = (int) (wallX * (textures.get(texNum). STORLEK));
om (sidan == 0 & & rayDirX > 0) texX = textures.get(texNum). STORLEK - texX - 1;
om (sidan == 1 & & rayDirY < 0) texX = textures.get(texNum). STORLEK - texX - 1;

X-koordinaten beräknas genom att den exakta positionen av där väggen blev påkörd på 2D-kartan och subtrahera heltalsvärdet, lämnar bara decimalen. Denna decimal (wallX) multipliceras sedan med storleken på strukturen på väggen för att få exakta x-koordinaten på väggen vi vill rikta bildpunkter. När vi vet att det enda som återstår att göra är att beräkna y-koordinaterna för pixlarna på konsistens och dra dem på skärmen. Att göra detta vi loopa igenom alla bildpunkter på skärmen i den vertikala band vi gör beräkningar för och beräkna den exakta y-koordinaten för pixeln i texturen. Med detta programmet sedan skriver data från pixeln på konsistens till mängd pixlar på skärmen. Programmet gör också horisontella väggarna mörkare än vertikala väggar här att ge en grundläggande ljuseffekt.

beräkna y-koordinaten på konsistens
för (int y = drawStart, y < drawEnd; y ++) {
int texY = (((y * 2 - höjd + lineHeight) << 6) / lineHeight) / 2;
int färg;
IF(Side==0) färg = textures.get (texNum) .pixels [texX + (texY * textures.get(texNum). STORLEK)];
annan färg = (textures.get (texNum) .pixels [texX + (texY * textures.get(texNum). STORLEK)] >> 1) & 8355711; //Make y sidor mörkare
pixlar [x + y*(width)] = färg;
}

Efter det, allt som är kvar i klassen skärm är tillbaka arrayen pixel

returnera pixlar.

Och klassen är gjort. Nu allt vi behöver göra är att lägga några rader kod i spelet klass att få skärmen fungerar. Lägg till detta med variablerna högst upp:

offentliga skärmen;

Och Lägg till detta någonstans efter texturer har initierats i konstruktören.

skärmen = ny skärm (karta, mapWidth, mapHeight, texturer, 640, 480);

Och slutligen, i kör metoden Lägg till

screen.Update (kamera, pixlar);

precis innan camera.update(map). Och programmet är klar!

Se Steg
Relaterade Ämnen

Att göra en grundläggande privat server i Minecraft

Vill ha ett enkelt sätt att spela Minecraft med dina vänner utan alla troll och irriterande människor på publika servrar? Här är det enklaste sättet att göra en grundläggande lösenordsskyddad server! Detta görs på en mac. Jag tror det är liknande til...

Att göra en grundläggande pappersflygplan

Här är hur man gör en grundläggande pappersflygplan.Steg 1: Få papperUtforma det så det är liggande orienteringSteg 2: Vik papperet på mittenSteg 3: VikSteg 4: Vik ner högra hörnet för att centrera fodrar?Steg 5: Vik ner vänstra hörnet för att centre...

Att göra en grundläggande Roux

göra en grundläggande Roux kan vara en av de enklaste matlagning tekniker som du kan lära dig. Dock kan det användas i på så många sätt. Det är startmotorn för vita frukost sås, till cheesy såser för mac-n-ost och gå över grönsaker, det är också anvä...

Introduktion till ShapeCrete (att göra en grundläggande leaf print)

Detta instructable beskriver att göra en leaf avtryck med ShapeCrete och måla den. Främst, kommer vi att diskutera vad ShapeCrete är och vad man ska göra med detta awesome material.I ett nötskal, är här vad vi kommer att täcka:1. vi kommer att gå öve...

Hur du gör Windows 7 snabbare genom att ändra några grundläggande inställningar - se upp för några knep

Att köra din arbetsdrift systemet snabbare än någonsin tidigare - här är några enkla tips att göra det - inte Glöm att starta om datorn när du har ändrat alla dessa inställningar att göra förändringar effektivt....

Att göra en grundläggande HTML webbplats

vissa människor tror att att göra en hemsida är svårt. De är felSteg 1: där? Du kan prod is html webbplatser med något så enkelt som anteckningar eller text editSteg 2: Se webbplats Html. TypSteg 3: Lägga till innehåll Nu du kan lägga till punkterna...

Android-utveckling: Att skapa en grundläggande kalkylator

Välkommen till en rolig tutorial på att göra en grundläggande kalkylator på en Android-applikation. I denna tutorial guidar jag dig genom dataöverföring all nödvändig programvara, utforma layouten för ansökan, kodning till att få det att fungera orde...

Hur man knyter en grundläggande siffran åtta Knut & att följa genom

en siffra åtta med en bight är en berömd knut i bergsklättring världen. När klättring, skulle du använda en siffra åtta med en bight (ett bett är en loop) att knyta dig själv till din sele för att hindra dig från att falla. Du uppnå knyta en siffra å...

Grundläggande remskiva mekanismer

Från tank slitbanor till cykel redskap till fiske linjer, som remskivor används överallt när det gäller mekaniska transmissioner. Alla typer av remskiva mekanismerna består av någon form av flexibelt bälte (kedja, kabel, rep, etc.) vrida runt omkrets...

Grundläggande raden efter Robot med Arduino

09/07/2015Det har varit några år eftersom vi Ursprungligen postat denna grundläggande linje följande Robot med Arduino handledning, och det verkar så många människor tyckte att det bra att vi ska skicka en uppdatering som löper nuvarande Arduino bibl...

Grundläggande elektronik

att komma igång med grundläggande elektronik är lättare än du kanske tror. Detta Instructable kommer förhoppningsvis att avmystifiera grunderna i elektronik så att alla med intresse i att bygga kretsar kan slå i marken kör. Detta är en snabb översikt...

Grundläggande elmotor Masco G37

Användningen av detta instructable gör att vem som helst att skapa en liten motor. Genom att använda vissa grundläggande material, kan du bygga en motor som snurrar. Den använder de grundläggande principerna för en motor, spolen bildar en elektromagn...

Grundläggande mänskliga skanna med Kinect & ReconstructMe konsolen

detta instructable kommer att täcka den grundläggande processen för att göra en 3D skanning av en mänsklig kropp med hjälp av XBOX 360 Kinect, en Windows-dator och programvara ReconstructMe (konsolen upplaga).ErkännandeNicolas Brunet gjorde en underb...

Justerbar utarbetandet bord med grundläggande verktyg och material

jag har spelat runt med tanken på att få mig en liten utarbetandet bord, som jag hittar den justerbar vinkeln ganska bekväm för ett antal olika saker: Rita, läsa, skriva, arbetar med tangentbord/mus, etc. Först testade jag det ut genom att bara sätta...

1/3 grundläggande skal utmatning pistol.

3 veckor ska jag försöka få till du stötarna skal avkastad steg i att börja på grundläggande då nästa t jag kommer bygga en mellanliggande shell utmatning pistol och då är kommer att göra en expert shell utmatning pistol. så 3 veckor hoppas jag kunna...

Grundläggande läder halvmask

Välkommen!Här hittar du en handledning om att göra en grundläggande läder halfmask (som visar på 2: a bilden).Jag har arbetat med läder i över 15 år, och ville bara dela en grundläggande gå igenom om hur man gör en bra mask av din alldeles egna :)Gär...

Bygga en grundläggande lap steel-gitarr

i detta, min första Instructable, kommer jag försöka krönika byggandet av en enkel Lap Steel guitar. Ansvarsfriskrivning; elverktyg och skarp skärande verktyg kommer att användas och jag tar inget ansvar för människor som använder dessa saker slarvig...

Grundläggande modifierbara Lödstation

Välkommen till min första Instructable för en Lödstation.Det finns många lödning stationer på denna webbplats så varför är detta en speciell?Det är mycket material effektivt, kan fungera för en variant av brödunderläggen, du kan arbeta i olika vinkla...

Grundläggande för verilog

HDl design:Här jag kommer för att förklara om grundläggande funadamental av handstil tvättprogram i verilog .here jag visar att eller operationen gjort av mig med design såväl som testa bänk. prova detta på online programmering webbplatser.Design: fo...