当前位置: 首页 > news >正文

WebXR教学 05 项目3 太空飞船小游戏

准备工作

自动创建 package.json 文件

npm init -y 

安装Three.js 3D 图形库,安装现代前端构建工具Vite(用于开发/打包)

npm install three vite 

启动 Vite 开发服务器(推荐)(正式项目开发)

npm run dev

启动 Vite 开发服务器(快速测试或临时使用)

npx vite
npm init -y 

说明:

  1. 自动创建 package.json 文件
  2. -y 参数表示接受所有默认选项
  3. 生成包含项目基本信息、依赖和脚本的基础配置文件
    npm install three vite 说明:
  4. three - 安装 Three.js 3D 图形库(当前项目核心依赖)
  5. vite - 安装现代前端构建工具(用于开发/打包)
  6. 安装后会生成 node_modules 目录和 package-lock.json
    VS Code颜色高亮插件:Color Highlight

项目结构

在这里插入图片描述

代码

package.json

{"name": "test","version": "1.0.0","main": "main.js","devDependencies": {},"scripts": {"test": "echo \"Error: no test specified\" && exit 1","dev": "vite","build": "vite build","preview": "vite preview"},"keywords": [],"author": "","license": "ISC","description": "","dependencies": {"three": "^0.148.0","vite": "^6.2.0"}
}

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>太空飞船小游戏</title><link rel="stylesheet" href="./style.css">
</head>
<body><div id="score">0</div><div id="gameOver">游戏结束</div><script type="module" src="./main.js"></script>
</body>
</html>
style.css
body {margin: 0;/* background-color: black; */overflow: hidden;
}#gameOver {position: absolute;/* 以自身宽度和高度向左、上移动一定距离,使其居中 */transform: translate(-50%, -50%);left: 50%;top: 50%;color: red;display: none;font-size: 48px;
}#score {position: absolute;transform: translate(-50%,0);left: 50%;color: white;display: block;font-size: 50px;margin: 0 auto;
}

main.js

// ============== 全局声明区 ==============
import * as THREE from 'three';// 游戏状态相关变量
let scene, camera, renderer, ship, stone;
let stones = [];
let moveLeft = false, moveRight = false;
let gameActive = true;
let score = 0; 
let lastScoreUpdate = Date.now();// ============== 核心逻辑模块 ==============
// 初始化游戏基础设置
function init(){// 场景初始化三要素scene = new THREE.Scene();camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);renderer = new THREE.WebGLRenderer();// 渲染基础配置scene.background = new THREE.Color(0);renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);camera.position.z = 10;// 光照系统初始化const ambientLight = new THREE.AmbientLight(0x404040);scene.add(ambientLight);// 游戏实体初始化ship = new Ship(scene);stone = new Stone(scene);// 事件系统启动setupEventListeners();// 启动游戏主循环gameLoop();
}// 主游戏循环(每帧执行)
function gameLoop(){if(!gameActive) return;requestAnimationFrame(gameLoop);// === 分数系统 ===const now = Date.now();if (now - lastScoreUpdate >= 1000) {score++;document.getElementById('score').textContent = score;lastScoreUpdate = now;}// === 玩家控制 ===if(moveLeft) ship.move('left');if(moveRight) ship.move('right');// === 陨石管理系统 ===// 生成逻辑(30%概率/帧)if(Math.random() < 0.3) {stones.push(new Stone(scene));}// 更新循环stones.forEach((stone, index) => {// 运动逻辑stone.move();// 碰撞检测if(checkCollision(ship.object, stone.object)) {endGame();}// 对象回收if(stone.isOutOfScreen()) {scene.remove(stone.object);stones.splice(index, 1);}});// 场景渲染renderer.render(scene, camera);
}// ============== 输入控制模块 ==============
function setupEventListeners() {// 键盘事件监听document.addEventListener('keydown', (e) => {if(e.key === 'ArrowLeft') moveLeft = true;if(e.key === 'ArrowRight') moveRight = true;});document.addEventListener('keyup', (e) => {if(e.key === 'ArrowLeft') moveLeft = false;if(e.key === 'ArrowRight') moveRight = false;});// 窗口自适应window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);});
}// ============== 游戏逻辑模块 ==============
// 简易距离碰撞检测
function checkCollision(objA, objB) {return objA.position.distanceTo(objB.position) < 1.2;
}// 游戏结束处理
function endGame() {gameActive = false;document.getElementById('gameOver').style.display = 'block';
}// ============== 游戏对象类 ==============
// 玩家飞船实体
class Ship {constructor(scene) {this.object = this.createShip();this.speed = 0.2;scene.add(this.object);}// 飞船建模createShip() {const geometry = new THREE.ConeGeometry(0.5, 1, 8);const material = new THREE.MeshBasicMaterial({color: 0x00ff00});const ship = new THREE.Mesh(geometry, material);geometry.rotateX(Math.PI/2);ship.position.set(0, -4, 0);// 线框增强显示const wireframe = new THREE.LineSegments(new THREE.EdgesGeometry(geometry),new THREE.LineBasicMaterial({ color: 0xffffff }));ship.add(wireframe);return ship;}// 移动控制逻辑move(direction) { const maxX = 10;if(direction === 'left' && this.object.position.x > -maxX) {this.object.position.x -= this.speed;}if(direction === 'right' && this.object.position.x < maxX) {this.object.position.x += this.speed;}}
}// 陨石实体
class Stone {constructor(scene) {this.object = this.create();this.speed = 0.1;scene.add(this.object);this.resetPosition();}// 陨石建模create() {return new THREE.Mesh(new THREE.IcosahedronGeometry(0.5, 1),new THREE.MeshPhongMaterial({color: 0xff4500,emissive: 0xff6347,emissiveIntensity: 0.6,specular: 0xffffff,shininess: 50,wireframe: true}));}// 位置初始化resetPosition() {this.object.position.set((Math.random() - 0.5) * 20,9,0);}// 下落逻辑move() {this.object.position.y -= this.speed;}// 边界检测isOutOfScreen() {return this.object.position.y < -5;}
}// ============== 程序入口 ==============
init();

相关文章:

  • 安装Jupyter Notebook 之不断报错 差点放弃版
  • 第一篇:Django简介
  • 【网络原理】TCP提升效率机制(一):滑动窗口
  • Linux内核编译全流程详解与实战指南
  • 【正则表达式】核心知识点全景解析
  • MySQL数据库精研之旅第十期:打造高效联合查询的实战宝典(一)
  • 基于SpringBoot的课程管理系统
  • linux与c语言基础知识(未全部完成)
  • Python图形界面编程(一)
  • 常用第三方库精讲:cached_network_image图片加载优化
  • 每天五分钟深度学习PyTorch:图像的处理的上采样和下采样
  • 第四节:核心概念高频题-Vue生命周期钩子变化
  • 解锁webpack:对html、css、js及图片资源的抽离打包处理
  • 麒麟信安与中教汇控达成战略合作,共绘教育信息化新蓝图
  • 修电脑之电脑没有声音
  • HarmonyOS-ArkUI: 组件内转场(transition)
  • rpm包管理
  • C语言 ——— 分支循环语句
  • 第51讲:AI在农业政策支持系统中的应用——用人工智能点亮科学决策的新范式
  • 绿色森林人文生活纪实摄影Lr调色教程,手机滤镜PS+Lightroom预设下载!
  • 人民日报整版聚焦第十个“中国航天日”:星辰大海,再启新程
  • 游客大理古城买瓜起争执:170克手机称出340克
  • 创单次出舱活动时长世界纪录,一组数据盘点神十九乘组工作成果
  • IMF将今年全球经济增长预期由3.3%下调至2.8%
  • 上海消保委调查二次元消费:手办与卡牌受欢迎,悦己和社交是动力
  • 外汇局:将持续强化外汇形势监测,保持汇率弹性,坚决对市场顺周期行为进行纠偏