掌玩手机网 手游攻略 手游评测 Threejs开发塔防游戏

Threejs开发塔防游戏

时间:2024-12-03 13:27:18 来源:未知 浏览:0

gif较大,请耐心等待。源码见文章最后。

目录结构

思维导图

具体功能及思路如下

有了这张思维导图,你就可以一步步实现游戏功能了

技术栈

typescriptvite Threejsastarjs 由于项目体系庞大,内容覆盖面广,我们选取几个重点内容进行介绍。

地图

首先,加载地图。地图功能包括可放置模块和不可放置模块(敌人路线、装饰元素)。总体思路是根据floorSize生成长宽相等的地图,每个地图都是一个平面。

const createPlane=(texture: THREE.Texture): THREE.Mesh={ const Geometry=new THREE.PlaneGeometry(1, 1); const 材质=new THREE.MeshBasicMaterial({ color:0xffffff, side: THREE.DoubleSide });让平面=新的THREE.Mesh(几何,材料);平面.旋转.x=Math.PI * 0.5;平面.材质.贴图=纹理; plane.material.needsUpdate=true; castShadow(plane) returnplane}

生成轨迹

首先使用for循环生成一个二维数组并存储在mapUseV2中。设置起点const startPoint=new THREE.Vector2(0, 0) 和终点const endPoint=new THREE.Vector2(floorSize - 1, FloorSize - 1)。用于生成敌人的移动轨迹。

生成轨迹的代码

constmaps=new (window asany).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个点是敌人的路线,所以不能放置武器,所以mapUseV2中数据必须设置为0

mapUseV2[trailPoints[i].x][trailPoints[i].y]=0;这样我们就得到了一张地图,其中包含了敌人的移动路线、装饰以及可放置的区域。

敌人

前面定义的startPoint被用作敌人的出生点。生成敌人的方法是EnemyCrouched类,它初始化敌人的生命条、移动速度、攻击力和等级。

继承基类Enemy_Level,定义添加方法、动作和动画更新。如果想再添加一种敌人类型,继承Enemy_Level即可(项目目前只有一种敌人类型),Enemy_Level还继承了公共类ModelCheck。该公共类的主要功能是修改位置、旋转角度、获取包围盒。武器、子弹、敌人、水晶塔都继承了这个公共类。

生成敌人

通过bindAnimite绑定动画,可以将模型中提供的骨骼动画绑定到模型上并播放动画。

bindAnimite(animations: GltfModel['animations']) { if (this.model) { this.modelAnimation=new Animation(this.model, 动画); this.modelAnimation.once(['death']) this.modelAnimation.play('walking');这里先说一下Animation类,它提供动画播放、切换动画fadeToAction、显示骨骼createSkeleton、过滤一次跳跃、死亡、敬礼等一次性动画,这些都是非循环动画。更新动画updateDate。此方法接受镜头参数。如果传入镜头参数,就可以实现镜头跟踪功能。

生成武器

通过点击操作栏上相应的按钮生成武器。

关于武器的定位

点击弩按钮后,会触发鼠标的射线检测,检测目标设置为地板。当鼠标移动到可以放置模型的位置时,会显示一个蓝色框。如果检测到鼠标位置,则无法放置模型。辅助色块变成红色,点击无效,需要重新选择位置。

Threejs开发塔防游戏

初始化武器

Crossbow_level初始化十字弓,Rifle_level初始化火炮。这两个类区分不同的武器,在初始化时加载武器模型并提供武器的upDate方法。这两个类都继承其基类Weapon。武器提供目标探测、射击等功能。 Weapon继承公共类ModelCheck,为武器提供边界框、尺寸和模型校正功能。初始化武器时有几个重要的属性:武器系数和等级。这两个值影响武器的子弹发射间隔、威力和单价(包括升级的价格)。

基于setAnimationLoop做的定时器

这里介绍一下IntervalTime

.setAnimationLoop(回调:函数):未定义

回调— 每个可用帧调用的函数。如果传入“null”,则所有正在进行的动画将停止。可以用来代替内置函数requestAnimationFrame。对于WebXR项目,必须使用此函数。

熟悉Threejs 的人都知道requestAnimationFrame 方法。根据屏幕刷新率来调用,通常为60次/秒。计时的原理非常简单。调用一次,获取当前时间,并用当前调用的now时间减去上次保存的时间。上次时间。如果超过指定的循环间隔时间时调用回调,则lastTime会被设置为time,并进行新一轮的计时。这就是项目中炮弹发射间隔的完成方式。当然,你也可以在Threejs以外的项目中使用它。

导出类IntervalTime {lastTime=0构造函数(){}间隔(time:数字,callback:()=void){let now=Performance.now(); //使用Performance.now() 获取高精度时间let deltaTime=now - this.lastTime; if (deltaTime time) { //执行一秒内需要完成的事情callback() //重置时间this.lastTime=now; } }}

子弹跟踪

武器生成后会发射子弹,调用TransmitDiscards类。根据不同的武器生成不同的子弹,并在render中调用bullet类的upDate方法。子弹会跟踪检测敌人的位置,找到最近的敌人进行攻击,得到最近的敌人位置和子弹发射位置,生成一条开口向下的抛物线,让子弹沿着抛物线移动,直到子弹到达终点点,并利用敌人的包围盒来检测子弹的位置,并判断子弹是否进入敌人的包围盒的范围内。如果在射程内,敌人会损失相应的生命值并摧毁子弹。

upDate() { //子弹检测敌人EnemyGroup.traverse((enemy)={ if (enemy.example) { if (this.model) { this.getBox() const worldPos=new THREE.Vector3() this.model. getWorldPosition(worldPos) this.position=worldPos.clone(); const contains=heaven.example.box3.containsPoint(this.position) //子弹击中敌人if (contains) { console .log('击中敌人'); 让hp=敌人.example.HP - this.power 敌人.example.HP=hp 敌人.example.hpDom.element.innerHTML=`HP:${Math.max(0, hp) }` this.dispose() } } } }) }当敌人生命值归零时,消灭敌人并添加相应数量的金币。

敌人的更新方法

upDate() { this.getBox() if (this.modelAnimation) { this.modelAnimation.upDate() } if (this.HP=0) { this.dispose(); }钱包.add(this.price); }}

武器升级

操作栏功能区提供了几个属性来区分放置、升级、销毁等功能。

//导出存储全局变量const buttonState={ DOWN_HERO: false, //是否可以放置模型CHECK_HERO: true, //模型HREO_TYPE: 是否可以选择'crossbow' 为'crossbow' | 'rifle', UPGRADE_HERO: false, //是否升级英雄DISPOSE_HERO: false, //是否摧毁英雄SHOW_BOX3_HELPER: true, //是否显示辅助线GAME_STOP: false //暂停游戏} 前面提到过,放置时武器,射线检测的对象是楼层组,升级时将去掉射线检测组改为武器组,并使用检测到的模型升级对应的第二层和第三层。当武器达到三级时,将无法升级。升级武器时,销毁原有武器并添加新模型。目前,武器升级仅增加系数。如果你有兴趣,可以根据武器等级生成多发子弹,从单一攻击变为群体攻击。

水晶塔

相比水晶塔,可以复用子弹的逻辑。把敌人当子弹,把水晶塔当敌人。在水晶塔的upDate方法中,探测敌人的位置。如果敌人的包围盒与水晶塔的包围盒相同,则如果包围盒相交,则会减去水晶塔相应的生命值。如果水晶塔的生命值归零,则视为游戏失败。

全局配置

金币

金币方法比较简单。我们这里没有VIP充值,所以你不用考虑多少钻石换算1个648,多少金币换算1颗钻石。游戏的金币系统只有一加一减,创造和升级。武器减去相应的金币,消灭敌人则增加相应的金币。

import { Money } from './variable';//钱包实例类Wallet { Money: number=Money;钱Dom: HTMLDivElement |未定义的构造函数() { const dom=document.querySelector('.money') as HTMLDivElement |未定义if (dom ) { this.moneyDom=dom; this.changeText() } } add(money: 数字) { this.money +=钱; this.changeText() } sub(money: 数字) { if (this.money 钱) { return false } else { this.money -=钱; this.changeText() } return true } changeText() { if (this.moneyDom) { this.moneyDom.innerText=this.money + '金币' } }}export const wallet=new Wallet()

金手指

cheat 支持初始化金币数量、武器系数、地图大小。通过路径参数提供

const searchParams=getParams()const getValue=(field: 字符串, def: 数字): 数字={ console.log('searchParams',searchParams); const f=searchParams[字段] 让fz=f ?编号(f) : def; return fz}export const FloorSize=getValue('floorSize', 8) //必须是偶数,否则后续计算会有问题//Coefficient //弩系数export const crossbow_coefficient=getValue('crossbow_coefficient', 10) //火炮系数export constrifle_coefficient=getValue('rifle_coefficient', 10) * 2//初始化金币export const Money: number=getValue('money', 100);如果在路径地址后面添加该参数

?crossbow_coefficient=100rifle_coefficient=100floorSize=16money=500,

那么你就会有500金币,一把基础攻击力100的武器,地图尺寸会变大,敌人的弹道也会变长。

这会影响游戏的平衡性。当然,我们的游戏并没有考虑公平性和平衡性。

用户评论

心悸╰つ

哇,听闻在Three.js中开发出一款塔防游戏真是个了不起的壮举!场景效果和动态非常棒。

    有10位网友表示赞同!

迁心

这款游戏让我深陷其中,Three.js 的利用使得视觉上超乎想象,令人惊艳不已。

    有13位网友表示赞同!

箜篌引

我喜欢塔防游戏带来的策略性和挑战性。使用Three.js来构建3D环境简直提升了一个档次。

    有12位网友表示赞同!

别留遗憾

游戏的渲染效果特别好,每一个小村庄、城镇和城堡都栩栩如生。

    有19位网友表示赞同!

无望的后半生

第一次在塔防游戏中体验到如此逼真的战场特效,非常值得一试。

    有8位网友表示赞同!

高冷低能儿

通过Three.js开发的游戏能直观展现3D世界的动态,真的是一个技术上的飞跃。

    有7位网友表示赞同!

凉月流沐@

游戏中的光影效果处理得当,白天和夜晚的转换让玩家更沉浸在游戏中。

    有14位网友表示赞同!

堕落爱人!

对于想了解Three.js的人来说,这款游戏是绝佳的教学实例,融合了游戏与代码的魅力。

    有14位网友表示赞同!

疯人疯语疯人愿

视觉体验上乘的游戏,尤其是那动态光影系统,每一帧都让我震撼。

    有17位网友表示赞同!

安之若素

我在塔防的路上迷失了,但这款游戏的美让我找到了新的方向,视觉上的享受太赞了!

    有7位网友表示赞同!

像从了良

技术与娱乐并重,这游戏是Three.js粉丝和塔防死忠粉不能错过的杰作。

    有10位网友表示赞同!

昂贵的背影

塔防与3D场景的结合完美无缺,让玩家们可以在丰富的视觉环境中战斗。

    有15位网友表示赞同!

将妓就计

这款游戏证明了只要创意无限,即使是复杂的图形处理也能够融入到简单的游戏中。

    有9位网友表示赞同!

﹎℡默默的爱

Three.js开发的游戏细节精良,每一波防御都是一次视觉盛宴和策略思考的双重享受。

    有6位网友表示赞同!

暖瞳

我喜欢这款基于Three.js技术的塔防游戏,它不仅考验玩家的战略思维,还让人欣赏到美丽的效果。

    有10位网友表示赞同!

余温散尽ぺ

游戏中的3D动画让我印象深刻,每一次战斗的变化都有其独特的魅力。

    有20位网友表示赞同!

安好如初

Create with Three.js, play with pleasure. 一款让开发者和普通用户都能沉浸其中的游戏体验。

    有12位网友表示赞同!

暮光薄凉

这不仅仅是一款塔防游戏,更是一次对Three.js编程语言学-的完美实践。

    有19位网友表示赞同!

孤败

游戏内环境构建极其精致,感觉像是在现实世界中进行一场虚拟的战略游戏。

    有5位网友表示赞同!

凝残月

Three.js带来的不仅仅是高颜值的视觉享受,更是深化策略决策的艺术表达。

    有17位网友表示赞同!

代价是折磨╳

用Three.js打造塔防游戏的团队真是了不起,将科技与乐趣完美融合,体验太棒!

    有12位网友表示赞同!

标题:Threejs开发塔防游戏
链接:https://izhangwan.com/news/sypc/26684.html
版权:文章转载自网络,如有侵权,请联系删除!
资讯推荐
更多
绯红之境兑换码最新2021 礼包兑换码大全

绯红之境兑换码最新2021 礼包兑换码大全[多图],绯红之境兑换码怎么领取?绯红之境兑换码有哪些?绯红之境在今日

2024-12-03
妄想山海怎么加好友 加好友方法大全

妄想山海怎么加好友 加好友方法大全[多图],妄想山海添加好友功能在哪里?妄想山海添加好友的方法是什么?好友添

2024-12-03
三国群英传7霸王再临攻略 霸王再临攻略技巧开启方法

三国群英传7霸王再临攻略 霸王再临攻略技巧开启方法[多图],三国群英传7霸王再临怎么玩?三国群英传7霸王再临

2024-12-03
江南百景图又见桃花村钓鱼位置在哪?又见桃花村钓鱼攻略

江南百景图又见桃花村钓鱼位置在哪?又见桃花村钓鱼攻略[多图],江南百景图又见桃花村钓鱼怎么钓?又见桃花村钓

2024-12-03