12. Hinkar, nycklar och dörrar
Målet
Låt spelaren hitta två nycklar under hinkar, låsa upp två rustika metalldörrar och faktiskt kunna passera genom öppningarna. Samma interaktionsfunktion används för desktop och VR. Öppna main.js.
Den lilla tillståndskedjan
Första nyckeln finns redan i scenen men är osynlig. Hinken är synlig och går att använda. När hinken flyttas ändras key.visible till true; ljus, ring och markör gör den lättare att upptäcka. Nyckeln är ännu inte insamlad. Först collectKey() ändrar state.keys[0]. Motsvarande gäller nyckel 2 och state.keys[1].
hink kvar → hink flyttad → nyckel synlig → nyckel insamlad → dörr öppnad
Testa varje pil i kedjan innan du bygger nästa. Om dörren öppnar sig när nyckeln bara syns, har synlighet och spelstatus blandats ihop.
Första hinken finns nära startplatsen. Den andra finns i banans bakre del, efter den första dörren. När spelaren trycker E på desktop eller grip i VR flyttas hinken åt sidan. Nyckeln visas då ovanför golvet med ett guldljus och en markör. Tryck E/grip en gång till för att ta nyckeln, eller gå riktigt nära efter den korta visningsfördröjningen. Att gå på hinken ska inte kasta upp spelaren i luften.
canOpenDoor() i reglerna kräver motsvarande nyckel och en pågående omgång. Öppningen är ungefär två meter bred, medan den nedladdade dörrmodellen är ungefär en meter bred. Spelet använder därför två dörrblad som möts i mitten. Vart och ett har en egen hinge-grupp och roterar åt motsatt håll. DOOR_WIDTH styr också den stängda dörrens kollision; en väggbit över dörrbladen fyller resten upp till taket. När dörren låses upp slutar öppningen blockera förflyttning och monster-pathfinding. Den synliga dörranimationen och kollisionsregeln är två separata system som måste säga samma sak.
Bygg dörren så den passar öppningen
- Öppna
level.js. De två väggdelarna slutar vid X = −1 och börjar vid X = 1: öppningen är alltså ungefär 2 meter.DOOR_WIDTHär 2,08 meter så bladens ytterkanter går in lite i väggarna.DOOR_HEIGHTär 2,7 meter. En smal väggbit, en lintel, fyller utrymmet ovanför bladen upp till respektive väggs överkant. - Öppna
makeDoor()imain.js. Skapa tvåhinge-grupper vid öppningens vänstra och högra kant. Varje dörrmodell ligger som barn till sin grupp, med halva bladets bredd mellan modellen och gångjärnet. När GLB-filen har laddats skalas modellens bredd till halvaDOOR_WIDTH; höjden ändras inte. Den högra modellen vänds så handtagen hamnar vid mitten. - Vid upplåsning roteras vänster gångjärn med negativ vinkel och höger med positiv vinkel. Den osynliga dörrkollisionen täcker hela öppningen medan dörren är stängd.
blocked()använder sammaDOOR_WIDTHoch slutar blockera närstate.doors[number - 1]blirtrue.
const half = DOOR_WIDTH / 2;
// Två gångjärn: ett vid var sida av öppningen.
const hinges = [-half, half].map((x) => {
const hinge = new THREE.Group();
hinge.position.set(x, 0, z);
scene.add(hinge);
return hinge;
});
// När dörren öppnas:
hinges[0].rotation.y = -angle;
hinges[1].rotation.y = angle;
Skala inte hela banan för att täcka en glipa vid dörren. Mät först öppningen och dörrmodellen var för sig. Om modellen fortfarande inte fyller öppningen, kontrollera att breddanpassningen körs efter att loadModel() har avslutats.
nearestAction() väljer ett objekt inom 1,6 meter. Tryck E eller grip för att flytta hinken; gör en andra interaktion för att ta nyckeln. Efter en kort paus kan nyckeln också plockas automatiskt när spelaren går mycket nära. Hinken är inte en studsande fysik-kropp: den flyttas med en kontrollerad animation.
CC0-modeller
- Bucket 3 av plaggy
- Key – low poly av codeinfernogames
- Door av NotionHD
- Dörrmiljö och metall: Rusty Metal Sheet
Testa
Prova både utan och med nyckel vid varje dörr. Båda dörrbladen ska täcka öppningen från sidan och mötas i mitten. Dörren ska bara öppnas med sin egen nyckel. Efter öppning ska passagen vara fri; öppna dörrblad ska inte fungera som en osynlig vägg.
Gör själv
I din kopia: gör nyckelmarkörens guldljus lite starkare eller svagare. Kontrollera att nyckeln fortfarande syns från normal ögonhöjd. Ändra sedan bara hinkens X-position med en halv meter och se om spelaren fortfarande kan nå den utan att öppna första dörren. Återställ om ordningen går sönder.