问题描述
我设法加载了一个预加载器,它可以在游戏开始之前工作,并在显示起始页面之前加载所有资源,但我不想在开始时使用它,而是在按钮单击事件之后。我正在努力移动加载屏幕。不知道是不是渲染的问题。我想要 2 个 HTML 页面,当游戏是菜单(game_state==GAME_MENU)和游戏介绍时显示(game_state==GAME_INTRO),然后在游戏运行之前显示加载屏幕(game_state==GAME_RUN) 这是我在 main.js 中的代码:
//this is the main code that calls up our scene manager
import { SceneManager } from './managers/SceneManager.js';
//global variables
const canvas = document.getElementById("canvas");
const sceneManager = new SceneManager(canvas);
bindEventListeners()
render();
function bindEventListeners() {
/// document.addEventListener('keydown',(event) => onKeyDown(event),false);
window.onresize = resizeCanvas;
resizeCanvas();
}
//========================================================================
//KAMERON-> MOVE THIS TO ANOTHER MANAGER
/*
I did my keyboard stuff in the char controls class,but you'll probably need to make another class and put the event listener there.
I'm not sure how to make a keyboard manager,since char controls and pausing are different events,so that's why I didn't
make one. Because I don't doing everything in one thing is ok... But actually.... Wait
*/
/*function onKeyDown(event) {
switch (event.keyCode) {
case 27: //escape key
//check if game is paused
console.log(event.repeat);
if (event.repeat == false)
{
if (sceneManager.game_state == sceneManager.GAME_PAUSE) {
sceneManager.unpause();
}
else {
sceneManager.pause();
}
}
break;
}
}*/
//=========================================================================
function resizeCanvas() {
canvas.style.width = '100%';
canvas.style.height = '100%';
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
sceneManager.onWindowResize();
}
function render() {
requestAnimationFrame(render);
sceneManager.update();
}
这是我的 SceneManager.js:
//IMPORT STATEMENTS
import { EntityManager } from './EntityManager.js';
import { AudioManager } from './AudioManager.js';
import { LightingManager } from './LightingManager.js';
import { Time } from '../Time.js';
import { PauseMenu } from '../Scenesubjects/Menu/PauseMenu.js';
import { keyboardManager } from './KeyboardManager.js';
import { CollisionsManager } from './CollisionsManager.js'; //Collision Manager
//lights
import { GeneralLights } from '../Scenesubjects/lighting/GeneralLights.js';
import { CeilingLight } from '../Scenesubjects/lighting/CeilingLight.js';
import { AmbientLight } from '../Scenesubjects/lighting/AmbientLight.js';
import { CeilingLightObj } from '../Scenesubjects/objects/CeilingLightObj.js';
//OBJECTS
import { House } from '../Scenesubjects/House.js';
import { Scenesubject } from '../Scenesubjects/objects/Scenesubject.js';
import { TestBlock } from '../Scenesubjects/characters/TestBlock.js';
import { Door } from '../Scenesubjects/objects/Door.js';
import { bedroomPainting } from '../Scenesubjects/objects/bedroomPainting.js';
import { bedroomDrawer } from '../Scenesubjects/objects/bedroomDrawer.js';
import { CupboardDoorR } from '../Scenesubjects/objects/CupboardDoorR.js';
//Characters
import { MainChar } from '../Scenesubjects/characters/MainChar.js';
//study
import { Bookshelf } from '../Scenesubjects/objects/Bookshelf.js';
//other
import { PointerLockControls } from '../../jsm/PointerLockControls.js';
import { OrbitControls } from '../../jsm/OrbitControls.js';
import * as THREE from '../../../jsm/three.module.js';
import { characterControls } from './CharacterControls.js';
//pre-loader
import { ColladaLoader } from '../../jsm/Loaders/ColladaLoader.js';
//==================================================================================================
//Global Variables
//FirstPersonTracker
var isFirstPersonView = true;
//lights
var generalLights = new GeneralLights();
//ceiling lights
var bedroomLightObj = new CeilingLightObj();
var kitchenLightObj = new CeilingLightObj();
var studyLightObj = new CeilingLightObj();
var hallwayLightObj1 = new CeilingLightObj();
var hallwayLightObj2 = new CeilingLightObj();
var bathroomLightObj = new CeilingLightObj();
var loungeLightObj = new CeilingLightObj();
var bedroomLight = new CeilingLight();
var kitchenLight = new CeilingLight();
var studyLight = new CeilingLight();
var hallwayLight1 = new CeilingLight();
var bathroomLight = new CeilingLight();
var hallwayLight2 = new CeilingLight();
var loungeLight = new CeilingLight();
var ambientLight = new AmbientLight();
//objects
var house = new House();
//var scenesubject = new Scenesubject();
//var testBlock = new TestBlock();
var testdoor = new Door();
//study
var bookshelf = new Bookshelf();
var bedroomPainting = new bedroomPainting();
var bedroomDrawer = new bedroomDrawer();
var cupBoardDoorR = new CupboardDoorR();
//pre-loader
export var loadingManager;
//Collision Manager to add all objects that need to be collided with
const collisionManager = new CollisionsManager();
//Add collidable objects here
//collisionManager.addobject(house);
//collisionManager.addobject(testBlock);
collisionManager.addobject(testdoor);
//Pass collidable objects as a parameter to the main character (raycasting implementation)
export var mainChar = new MainChar(collisionManager.returnObjects());
export class SceneManager {
constructor(canvas) {
//this entire function renders a scene where you can add as many items as you want to it (e.g. we can create the house and add as
//many items as we want to the house). It renders objects from other javascript files
//------------------------------------------------------------------------------------------------------------------------------------------
//These are supposed to act like constants. DO NOT CHANGE
this.GAME_PAUSE = "pause";
this.GAME_RUN = "run";
this.GAME_MENU = "menu";
this.GAME_INTRO = "intro";
//------------------------------------------------------------------------------------------------------------------------------------------
this.audioActive = false;
//we use (this) to make variables accessible in other classes
this.time = new Time();
this.objPauseMenu;
this.game_state = this.GAME_MENU;
this.width_screen = canvas.width;
this.height_screen = canvas.height;
this.screenDimensions = {
width: canvas.width,height: canvas.height
};
//the essentials for rendering a scene
this.scene = this.buildScene();
this.renderer = this.buildrender(this.screenDimensions);
this.camera = this.buildCamera(this.screenDimensions);
loadingManager= new THREE.LoadingManager();
loadingManager.onProgress=function(item,loaded,total){
console.log(item,total);
const loadingScreen = document.getElementById( 'loading-screen' );
loadingScreen.classList.add( 'fade-out' );
// optional: remove loader from DOM via event listener
loadingScreen.addEventListener( 'transitionend',this.ontransitionend );
};
loadingManager.onLoad=function(){
console.log('loaded all resources');
const loadingScreen = document.getElementById( 'loading-screen' );
loadingScreen.style.display="none";
// RESOURCES_LOADED=true;
}
//Post-processing Effects
// this.composer = new EffectComposer(this.renderer);
// this.composer.addPass(new RenderPass(this.scene,this.camera));
//comment this out
this.controls = new OrbitControls(this.camera,this.renderer.domElement);
this.controls.mindistance = 7;
this.controls.maxdistance = 12;
this.controls.maxPolarangle = Math.PI / 2.5;
//comment this out
// this.controls = new OrbitControls(this.camera,this.renderer.domElement);
//initialise pointerlock controls
this.pointerLockControls = new PointerLockControls(this.camera,this.renderer.domElement);
//this.pointerLockControls.lock();
//this.scene.add(this.pointerLockControls.getobject());
//====================
//adjust the ceiling light properties in the house
this.setCeilingLightProperties();
this.managers = this.createManagers();
//load things to scene
this.loadToScene(this.managers[0].lights);
this.loadToScene(this.managers[1].entities);
// canvas.requestPointerLock = canvas.requestPointerLock || canvas.mozRequestPointerLock;//request pointer lock from player
// document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock;//exit pointer lock
//Define new listener for clicking on the canvas
canvas.onclick = function () {
canvas.requestPointerLock(); //If canvas clicked,request pointer lock
};
//---------------------------------------------------------------------------------------------------------------------------------
// Ok,Now we have the cube. Next we'll create the hud. For that we'll
// need a separate scene which we'll render on top of our 3D scene. We'll
// use a dynamic texture to render the HUD.
// We will use 2D canvas element to render our HUD.
//---------------------------------------------------------------------------------------------------------------------------------
}
loadToScene(entities) {
for (let i = 0; i < entities.length; i++) {
this.scene.add(entities[i].object);
}
}
//this function creates our scene
buildScene() {
//create a new scene
const scene = new THREE.Scene();
//set the scene's background-> in this case it is our skyBox
const loader = new THREE.CubeTextureLoader();
//it uses different textures per face of cube
const texture = loader.load([
'../skyBox/House/posx.jpg','../skyBox/House/negx.jpg','../skyBox/House/posy.jpg','../skyBox/House/negy.jpg','../skyBox/House/posz.jpg','../skyBox/House/negz.jpg'
]);
scene.background = texture;
//if we wanted it to be a colour,it would have been this commented code:
//scene.background = new THREE.Color("#000");
return scene;
}
//this creates a renderer for us
buildrender({ width,height }) {
const renderer = new THREE.Webglrenderer({
canvas: canvas,antialias: true,alpha: true
});
renderer.setClearColor(0xEEEEEE,1.0);
renderer.shadowMap.enabled = true;
//renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.shadowMapSoft = true;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth,window.innerHeight);
return renderer;
}
//create a camera for the screen
buildCamera({ width,height }) {
//SETTING FIELD OF VIEW,ASPECT RATIO (which should generally be width/ height),NEAR AND FAR (anything outside near/ far is clipped)
const aspectRatio = width / height;
const fieldOfView = 60;
const nearPlane = 1;
const farPlane = 1000;
//there are 2 types of cameras: orthographic and perspective- we will use perspective (more realistic)
const camera = new THREE.PerspectiveCamera(fieldOfView,aspectRatio,nearPlane,farPlane);
//Set camera initial position to main character
let pos = mainChar.returnWorldPosition();
camera.position.set(pos.x,pos.y + 10,pos.z - 10);
return camera;
}
setCeilingLightProperties() {
//set their light positions
bedroomLightObj.setLightPosition(0,21,50);
bedroomLight.setLightPosition(0,16,50);
loungeLightObj.setLightPosition(-45,-60);
loungeLight.setLightPosition(-45,-60);
studyLightObj.setLightPosition(35,-50);
studyLight.setLightPosition(35,-50);
kitchenLight.setLightPosition(-45,5);
kitchenLightObj.setLightPosition(-45,5);
bathroomLight.setLightPosition(45,15);
bathroomLightObj.setLightPosition(45,15);
hallwayLightObj1.setLightPosition(0,-60);
hallwayLight1.setLightPosition(0,-60);
hallwayLightObj2.setLightPosition(0,0);
hallwayLight2.setLightPosition(0,0);
}
//add subjects to the scene
createManagers() {
const managers = [new LightingManager(),new EntityManager(),new AudioManager()];
//can be altered so we can add multiple entities,and depending on which position
//it is,certain ones won't be paused,and some will be
//Note that these variables are declared globally before the class deFinition
/*This is so that we can use any of these object's methods or values later somewhere else*/
//lights
// managers[0].register(generalLights);
managers[0].register(ambientLight);
managers[0].register(bedroomLight);
managers[0].register(loungeLight);
managers[0].register(studyLight);
managers[0].register(hallwayLight1);
managers[0].register(hallwayLight2);
managers[0].register(kitchenLight);
managers[0].register(bathroomLight);
//entities
managers[1].register(loungeLightObj);
managers[1].register(studyLightObj);
managers[1].register(kitchenLightObj);
managers[1].register(bathroomLightObj);
managers[1].register(bedroomLightObj);
managers[1].register(hallwayLightObj1);
managers[1].register(hallwayLightObj2);
managers[1].register(house);
testdoor.setPosition(0,-0.5,33);
//testdoor.setRotation(-Math.PI/2);
managers[1].register(testdoor);
managers[1].register(mainChar);
//managers[1].register(scenesubject);
//managers[1].register(testBlock);
//study
managers[1].register(bookshelf);
managers[1].register(bedroomPainting);
managers[1].register(bedroomDrawer);
managers[1].register(cupBoardDoorR);
managers[2].register("footstep","assets/footstep.mpeg");
managers[2].register("door_open","assets/door_open.mpeg");
managers[2].entities["door_open"].setLoop( false );
managers[2].register("background","assets/back_sound.mp3");
return managers;
}
updateCameraPosition() {
//Match camera position and direction to the character's position and direction
let pos = mainChar.returnWorldPosition();
let dir = mainChar.returnObjectDirection();
//Set y to 10 to move camera closer to head-height
//First Person View
if (isFirstPersonView == true) {
mainChar.setVisibility(false);
this.pointerLockControls.getobject().position.set(pos.x,17.5,pos.z); //Need to sort out position of camera at head height
}
//Third Person View
else if (isFirstPersonView == false) {
mainChar.setVisibility(true);
this.pointerLockControls.unlock(); //Keep PointerLockControls unlocked
this.controls.target.set(pos.x,pos.z + dir.z);//Set position at player model and face the same direction as model
this.controls.update();//Update Orbital Controls
}
this.updatePlayerRotation();//Make player face direction of mouse movement
}
updatePlayerRotation() {
if(isFirstPersonView==true){
var mousePointer = new THREE.Vector3();
mousePointer.normalize();
this.pointerLockControls.getDirection(mousePointer);
mainChar.updateDirection(mousePointer);
}
if(isFirstPersonView==false){
var directionOfCamera = new THREE.Vector3();
directionOfCamera.normalize();
this.camera.getWorldDirection( directionOfCamera );
mainChar.updateDirection(directionOfCamera);
}
}
//this updates the subject/model every frame
update() {
//won't call this loop if it's paused-> only for objects that need to be paused (managers that need to be paused)
if (this.game_state == this.GAME_MENU) { //when the game start
//id the start button
const btnStart = document.getElementById("start");
//start game pressed,remove start screen items
btnStart.addEventListener("click",() => {
const menu = document.getElementsByClassName("mainMenu");
for (let i = 0; i < menu.length; i++) {
menu[i].style.display = 'none';
}
//change state to game intro
this.game_state = this.GAME_INTRO;
});
} else if (this.game_state == this.GAME_INTRO) {
if( this.audioActive == false)
{
this.audioActive = true;
this.managers[2].audioListener.context.resume();
this.managers[2].entities["background"].play();
}
//make intro screen visible
const intro = document.getElementsByClassName("intro");
for (let i = 0; i < intro.length; i++) {
intro[i].style.display = 'flex';
}
//id the continue button
const btnContinue = document.getElementById("continue");
////intro screen game pressed,remove intro screen items
btnContinue.addEventListener("click",() => {
for (let i = 0; i < intro.length; i++) {
intro[i].style.display = 'none';
}
//change state to game run
this.game_state = this.GAME_RUN;
});
} else if (this.game_state == this.GAME_RUN) {
//door open sounds---------------------------------------------------------------------------
if (bedroomPainting.isMoved)
{
testdoor.doCheckVicinity =true;
if (keyboardManager.waspressed('E') && testdoor.checkVicinity) {
if (this.managers[2].entities["door_open"].isPlaying == false)
{
this.managers[2].entities["door_open"].setLoop(0);
console.log("PLAYING DOOR");
this.managers[2].entities["door_open"].play();
}
}
}
//door open sounds---------------------------------------------------------------------------
//TO EXPERIMENT WITH FOR LOOKING AROUND!
// this.camera.position.x += ( keyboardManager.getMouseX() - this.camera.position.x ) ;
// this.camera.position.y += ( - keyboardManager.getMouseY() - this.camera.position.y );
// this.camera.lookAt( this.scene.position );
//character footstep sounds---------------------------------------------------------------------------
if (characterControls.checkMovement())
{
if (this.managers[2].entities["footstep"].isPlaying == false)
{
this.managers[2].entities["footstep"].play();
}
}
else{
this.managers[2].entities["footstep"].pause();
}
//character footstep sounds---------------------------------------------------------------------------
const runTime = this.time.getRunTime();
this.managers[0].update(runTime);
this.managers[1].update(runTime);
//update orbit controls
//comment out this.controls.update()
//this.controls.update();
this.renderer.render(this.scene,this.camera);
//check pause--------------------------------
if ((keyboardManager.keyDownQueue[0] == "P")) {
this.pause();
keyboardManager.keyDownQueue.shift();
}
//--------------------------------------------
//keyboardManager.keyDownQueue.shift();
if ((keyboardManager.keyDownQueue[0] == "V") && isFirstPersonView == true) {
console.log("Switching to Third-Person View");
isFirstPersonView = false;
keyboardManager.keyDownQueue.shift();
}
if ((keyboardManager.keyDownQueue[0] == "V") && isFirstPersonView == false) {
console.log("Switching to First-Person View");
isFirstPersonView = true;
keyboardManager.keyDownQueue.shift();
}
this.updateCameraPosition();
// console.log(this.pointerLockControls.getDirection());
}
else if (this.game_state == this.GAME_PAUSE)
{
if (keyboardManager.keyDownQueue[0] == 'P')
{
this.unpause();
keyboardManager.keyDownQueue.shift();
}
//comment out
this.pointerLockControls.unlock();
// this.controls.update();
this.objPauseMenu.update(this.time.getelapsedtime());
this.renderer.autoClear = true;
//render scene1
this.renderer.render(this.scene,this.camera);
//prevent canvas from being erased with next .render call
this.renderer.autoClear = false;
//just render scene2 on top of scene1
this.renderer.getContext().disable(this.renderer.getContext().DEPTH_TEST);
this.renderer.render(this.objPauseMenu.scene,this.objPauseMenu.camera);
this.renderer.getContext().enable(this.renderer.getContext().DEPTH_TEST);
// renderer.autoClear = true;
}
//update orbit controls
//comment out
//this.controls.update();
//uncomment this
}
//this resizes our game when screen size changed
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth,window.innerHeight);
}
ontransitionend( event ) {
const element = event.target;
element.remove();
}
pause() { //when pause mode is entered. The pause menu needs to be rendered.
if (this.game_state == this.GAME_RUN) {
this.game_state = this.GAME_PAUSE;
this.time.pause();
//hide divs that display instructions/ key prompts
this.instructions = document.getElementById('gameInstructions');
this.instructions.display='none';
this.instructions = document.getElementById('gameBottom');
this.instructions.display='none';
/* for (let sound in this.managers[2].entities)//["footstep"].pause())
{
this.managers[2].entities[sound].pause();
}
*/
//comment out
this.pointerLockControls.lock(); // stop orbit controls from responding to use input
this.objPauseMenu = new PauseMenu(this.width_screen,this.height_screen);
}
}
unpause() {
this.game_state = this.GAME_RUN;
this.time.unpause();
//comment out
this.pointerLockControls.unlock(); // start orbit controls to respond to input
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)