前言
完成效果
gif 图较大,耐心等待,源码见文末
为了上班摸鱼合理的玩游戏,我写了一个3d塔防游戏,其中功能包含动画、敌人运动、放置武器、升级武器、销毁武器、动态检测等功能。请动动小手,点赞收藏,这就发车~
目录结构
思维导图
具体功能和思路如下
有了这个思维导图,就可以按部就班,一步一步的实现游戏功能
技术栈
- typescript
- vite
- threejs
- astarjs
由于项目体系较大,内容覆盖较广,下面挑几个关键内容介绍一下
地图
首先要加载一个地图,地图功能包含可放置模块,不可放置模块(敌人路线,装饰元素),大概思路就是根据floorSize生成一个长和宽相等的地图,每个地图都是一个plane。
const createPlane = (texture: THREE.Texture): THREE.Mesh => {
const geometry = new THREE.PlaneGeometry(1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide });
let plane = new THREE.Mesh(geometry, material);
plane.rotation.x = Math.PI * 0.5;
plane.material.map = texture;
plane.material.needsUpdate = true;
castShadow(plane)
return plane
}
生成轨迹
第一步用for循环,生成一个二维数组存放在mapUseV2中,设定一个起点const startPoint = new THREE.Vector2(0, 0)和终点const endPoint = new THREE.Vector2(floorSize - 1, floorSize - 1),用于生成敌人运动轨迹。
生成轨迹的代码
const maps = new (window as any).Graph(mapUseV2);
// 夸过阻碍的随机点位,生成怪物的路线图
var starPosition = maps.grid[startPoint.x][startPoint.y];
var endPosition = maps.grid[endPoint.x][endPoint.y];
// 计算路线图
let trailPoints = (window as any).astar.search(maps, starPosition, endPosition, {
closest: false
});
寻路生成后的数据结构如下
这些14个点位都是敌人的路线,所以不可以放置武器