在删掉初始化中一些没用的代码后,在views目录下新建game文件夹,在里面新建一个index.vue,这里就当成游戏的主入口。
目录结构如下:
下面开始尝试创建场景:
一、添加一个div作为threejs的画布对象,之后整个的主要游戏开发内容全在这一个div中(实际threejs会渲染成canvas),并调整样式铺满整个屏幕(注:这个练手的卡牌项目是打算做成移动端的)
<template>
<div ref="sceneRef" class="scene"></div>
</template>
<style lang="scss" scoped>
.scene {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
}
</style>
二、引入threejs变量,之前在main.js中挂载的全局变量可以通过vue中的getCurrentInstance进行获取,如果这里报错,检查是否正确使用了setup
<script setup lang="ts">
import { reactive, ref, onMounted, onBeforeUnmount, watch, defineComponent, getCurrentInstance } from 'vue'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 轨道控制器
// 引入threejs变量
const {proxy} = getCurrentInstance()
const THREE = proxy['THREE']
const scene = proxy['scene']
const camera = proxy['camera']
const renderer = proxy['renderer']
// 场景ref
const senceRef = ref()
// 坐标轴辅助
const axesHelper = new THREE.AxesHelper(5);
// 创建轨道控制器
const controls = new OrbitControls( camera, renderer.domElement );
</script>
三、初始化场景
onMounted(() => {
initScene()
// 监听浏览器窗口变化进行场景自适应
window.addEventListener('resize', onWindowResize, false);
})
// 初始化场景
const initScene = () => {
renderer.setSize( window.innerWidth, window.innerHeight );
senceRef.value.appendChild( renderer.domElement );
scene.add(axesHelper)
camera.position.set( 5, 5, 5 );
camera.lookAt(0, 0, 0)
animate();
}
// 用requestAnimationFrame进行渲染循环
const animate = () => {
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
// 场景跟随浏览器窗口大小自适应
const onWindowResize = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
四、如果一切正常,则页面应该展示如下:
由于引入了轨道控制器,所以按住鼠标拖动可以进行旋转,至此成功创建了场景