用Cocos Creator 3.7开发一款3D台球游戏

这篇具有很好参考价值的文章主要介绍了用Cocos Creator 3.7开发一款3D台球游戏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Cocos Creator 3.7 开发一款3D台球游戏

Hello大家好,一转眼学习Cocos已经两年多了,经过努力,终于从萌新小白进阶为疑似程序猿……

转入正题,话说今年年初突然有做一个3D台球游戏的想法。说起缘由是因为当年想学习游戏开发的时候,不知应该选择什么引擎。一次无意间网上看到博毅创为 blake老师的趣味桌球小游戏制作教学,从此入坑。今年刚过完年还没开工,闲来无事,想研究研究物理反射线的原理,一开始只是当个demo来做,后来索性一想何不干脆做个台球游戏。于是用了几个月的空余时间(有空就写点,三天打鱼两天晒网)开发出这么一款作品。

欢迎大家来体验

blake cocos creator,小程序,游戏,3d,js,cocos2d
下面分享一些游戏开发过程的心得,和技术上的实现。

游戏引擎:Cocos Creator 3.7.3

该项目源码已发布

下载地址:
CocosStore

先发几个截图看看效果 怎么样 是不是还可以
blake cocos creator,小程序,游戏,3d,js,cocos2d
blake cocos creator,小程序,游戏,3d,js,cocos2d
blake cocos creator,小程序,游戏,3d,js,cocos2d
blake cocos creator,小程序,游戏,3d,js,cocos2d

导入模型:

首先,万丈高楼平地起,我们先找到需要的资源,是3D就离不开模型了。

台球就是引擎提供的Sphere 球体
blake cocos creator,小程序,游戏,3d,js,cocos2d
为每个球体添加刚体组件和碰撞组件
blake cocos creator,小程序,游戏,3d,js,cocos2d
球体的一些物理属性
blake cocos creator,小程序,游戏,3d,js,cocos2d
台球的纹理贴图
blake cocos creator,小程序,游戏,3d,js,cocos2d
球桌的模型:
blake cocos creator,小程序,游戏,3d,js,cocos2d

制作球杆:

既然是台球,就一定要有个球杆,总不能用手指去怼。首先按照游戏的逻辑。肯定是玩家发球时,球杆要围绕母球旋转,以此来作为打球角度,然后还要有一个发球力度。 一步一步来,我们先找到一个球杆的模型,我们需要将-z轴作为球杆的正方向,并将球杆往后挪,让它对齐父节点原点的合适位置。 往z方向挪动一定距离是因为要跟母球有一定间隔,这个距离起码要大于球体的半径。因为每次发球,球杆要移动到白球的位置,这样做是避免母球遮住一部分球杆,视觉上就不好看了。然后让球杆倾斜一定角度 我这里设置的x轴旋转-8°。
blake cocos creator,小程序,游戏,3d,js,cocos2d
blake cocos creator,小程序,游戏,3d,js,cocos2d
有了球杆我们发球时候让他跑到母球的位置,然后用onTouch事件返回的 touch.getDelta()方法来判断玩家是往左还是往右移动,以此控制球杆旋转角度,再用场景摄像机跟随球杆旋转,这样就有了打球的第一视角效果。

    //触摸注册事件
       this.touch.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
       this.touch.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
       this.touch.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
       this.touch.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);

不过光判断左右还不行,这样一来我们只能给球杆一个固定的旋转加成,要么是正要么是负,玩家在控制上无法根据滑动大小调整打球角度,很影响体验。我们还需要给他个判断。根据玩家手指滑动的大小写一些算法来控制球杆旋转角度,可以达到一个能微调的效果。

以下是相关代码。关键地方都加了注释。(代码包含上下移动的逻辑)

private onTouchStart(touch: EventTouch) {


        if (GameApp.Instance.Game_state != GAME_STATE.MOVE) {
            return
        }

        const location = touch.getUILocation()
        //当玩家按下时候 move_Tag移动标记等于触摸起始位置
        const pos2 = this.node.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(location.x, location.y, 0))
        this.move_Tag.setPosition(pos2)
        //按下时候显示反射线的一些逻辑 事件发布
        EventMgr.Instance.Emit(constant.EVENT_NAME.onTouch, null)



    }
    private onTouchMove(touch: EventTouch) {
        if (GameApp.Instance.Game_state != GAME_STATE.MOVE) {
            return
        }

        let _dir: number = -1
        const location = touch.getUILocation()
        //左右滑动
        const getD_X: number = touch.getDeltaX()
        //上下滑动
        const getD_Y: number = touch.getDeltaY()

        //默认是记录左右滑动的
        this.x_y = getD_X
        //只要长度 防止负数
        const xAbs: number = Math.abs(getD_X)
        const yAbs: number = Math.abs(getD_Y)
        //x和y的距离大小判断玩家是倾向于上下还是左右滑动
        //this.isMove是判断当前状态是松开了还是正在滑动中
        //如果正在滑动中 对上下还是左右不做判断 防止游戏移动中控制冲突
        //如果正在滑动中 this.x_y = getD_X 默认就是左右移动
        if ((xAbs < yAbs) && (!this.isMove)) {
            //如果x距离小于y就是上下滑动了。
            this.isUP = true
            this.x_y = getD_Y
        }


       
        if (this.isUP) {
            this.x_y = getD_Y
        }
        //判断本次移动方向跟上次是否一样
        if (this.x_y > 0) {
            _dir = 1
        } else if (this.x_y < 0) {
            _dir = 0
        } else {

            _dir = this.dir
        }
        //正在移动中
        this.isMove = true


        //如果上次的移动方向跟这次不一致 move_Tag 移动标记换到新位置计算移动距离
        if (this.dir != _dir) {

            this.dir = _dir

            const pos = this.node.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(location.x, location.y, 0))

            this.move_Tag.setPosition(pos)

        }
        //实际移动距离
        const pos2 = this.move_Tag.getComponent(UITransform).convertToNodeSpaceAR(new Vec3(location.x, location.y, 0))




        if (!this.isUP) {
            //如果是左右移动
            //限制左右移动角度
            //球杆移动角度 除以的数越大移动的越慢
            let d: number = pos2.x / 10
            if (d > 150) {
                d = 150
            } else if (d < -150) {
                d = -150
            }
            //把角度传给球杆
            EventMgr.Instance.Emit(constant.EVENT_NAME.touchMove, d)

        } else {
            //如果是上下平移 
            //偏移量的数非常小 除以的数越大移动的越慢
            let yCoord: number = pos2.y / 10


            let add: number = GameApp.Instance.upPosCamera
            //限制一下摄像机Y的偏移 就是上下最大可以移动多少
            if (yCoord > 0) {

                add -= 0.08
            } else {
                add += 0.08
            }
            if (add > 8) {
                add = 8
            } else if (add < 3) {
                add = 3
            }
            //如果是上下移动只要改变摄像机的偏移y坐标就可以了
            GameApp.Instance.upPosCamera = add
            GameApp.Instance.ThirdCamera.init(GameApp.Instance.club, GameApp.Instance.club, new Vec3(0, add, 15), 0.02, 0.03)

        }

    }


    private onTouchEnd(touch: EventTouch) {
        if (GameApp.Instance.Game_state != GAME_STATE.MOVE) {
            return
        }
        //没有移动
        this.isMove = false
        //向上默认为否
        this.isUP = false
        //球杆停止旋转
        EventMgr.Instance.Emit(constant.EVENT_NAME.endTouch, 0)
    }

计算发球方向:

在线性代数中,获取两点方向,需要用B的坐标减A的坐标。得到的就是A到B的方向。也就是说随着球杆的旋转,用白球位置减掉球杆坐标得到的就是发球方向了,这个方向单位化在乘以一个速度,得到的就是母球的线性速度。

摄像机跟球杆旋转的代码

private SetFollowTrackRotation() {
    //摄像机跟随目标旋转

        if (!this.target && !this.lookAt) {
            return
        }
    
        let u = Vec3.multiplyScalar(new Vec3(), Vec3.UP, this.positionOffset.y);
        let f = Vec3.multiplyScalar(new Vec3(), this.target.forward, this.positionOffset.z);
        let pos = Vec3.add(new Vec3(), this.target.position, u);
        Vec3.subtract(pos, pos, f);
        this.node.position = VectorTool.SmoothDampV3(this.node.position, pos, this.velocity, this.moveSmooth, 100000, 0.02);

 
        this.forwardView = Vec3.subtract(this.forwardView, this.node.position, this.target.getWorldPosition());
        this.node.lookAt(this.target.worldPosition);
      
    }
    

发球的方向

  //发球方向 用白球的坐标减去球杆坐标 这里startPos是球杆头部一个节点 比球杆原点要靠后一小段距离。
this.dir = Vector3.sub(this.whiteBall.worldPosition, this.club.getChildByName("startPos").getWorldPosition())
this.dir.normalize()
 //方向乘以发球力度得到线性速度 因为台球是平面移动的所以Y方向速度为0
this.dir = new Vec3(this.dir.x * this.ballForce, 0, this.dir.z * this.ballForce)
//设置白球线性速度
this.whiteBody.setLinearVelocity(this.dir)

有了发球的线性速度。我们只需要控制力度条,传入一个ballForce。在球杆击球动画结束时把这个线性速度传给白球就实现了打球的操作了。

好了, 到此为止已经实现了球杆的移动。我们来看看效果

blake cocos creator,小程序,游戏,3d,js,cocos2d

今天先写到这里,下次讲解球杆力度条、出杆动画、瞄准线的制作。如果觉得文章对您有帮助,欢迎关注我。

周无邪 微信:tuya7078
文章来源地址https://www.toymoban.com/news/detail-841189.html

到了这里,关于用Cocos Creator 3.7开发一款3D台球游戏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【基于Cocos Creator实现的赛车游戏】9.实现汽车节点的控制逻辑

     转载 知识星球 | 深度连接铁杆粉丝,运营高品质社群,知识变现的工具 项目地址: 赛车小游戏-基于Cocos Creator 3.5版本实现: 课程的源码,基于Cocos Creator 3.5版本实现 在上一节的课程中,您已经实现了通过触控给刚体施加里的方式来对汽车节点进行简单的控制。在这一章节中

    2024年02月07日
    浏览(74)
  • Cocos Creator3D:制作可任意拉伸的 UI 图像

    推荐:将 NSDT场景编辑器 加入你的3D工具链 3D工具集: NSDT简石数字孪生 UI 系统核心的设计原则是能够自动适应各种不同的设备屏幕尺寸,因此我们在制作 UI 时需要正确设置每个控件元素的尺寸(size),并且让每个控件元素的尺寸能够根据设备屏幕的尺寸进行自动的拉伸适配

    2024年02月13日
    浏览(45)
  • 最新开源方案!Cocos Creator 写一个ECS框架+行为树,实现格斗游戏 AI

    引言: 实现游戏 AI 的方式有很多,目前最为常用的主要有有限状态机和行为树。和有限状态机相比,行为树有更好的可扩展性和灵活性,能实现更复杂的 AI 需求。开发者  honmono 在 Cocos Creator 中用一个  ECS + BehaviorTree 框架 实现了一个格斗 AI Demo,一起来看看他的方案。 De

    2024年02月12日
    浏览(50)
  • 用23种设计模式打造一个cocos creator的游戏框架----(十四)观察者模式

    模式名称:观察者模式 模式分类:行为型 模式意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 结构图: 适用于: 1、当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两者封装在

    2024年02月04日
    浏览(50)
  • Cocos Creator小游戏-文字斗争(H5、小程序)益智类 项目展示+完整项目源码

    文字斗争(H5、小程序)益智类 项目展示+完整项目源码 玩家有着自己的战场,可以作为进攻方去挑战其他战场,也可以作为防守方抵御其他玩家的进攻。 玩家可以挑战游戏里设置的各个关卡,提高自己的指挥能力和布局能力,最终可以战胜其他玩家的同时能够不被其他玩家

    2024年02月08日
    浏览(72)
  • Cocos Creator小游戏-2048(PC、安卓、H5)益智类 项目展示+完整项目源码

    Cocos Creator小游戏-2048 在棋盘上,每次会增加一个 小 动物,你可以选择四个方向 滑动 ,然后 小 动物会按方向移动,遇到相同的 小 动物就会 合并,看谁合并的最多。 1 .初始化格子小动物的位置。 2.手势滑屏移动屏幕中的小动物。 3.自动寻找棋盘中没有小动物的格子,自动

    2024年02月12日
    浏览(60)
  • cocos creator上架字节跳动(抖音)小游戏注意事项(匿名登录、录屏、分享等踩坑记录)

    常见拒绝原因1:小游戏无录屏功能,不符合平台要求 2:小游戏录屏时间小于3S,分享按钮点击无反应或提示错误文案,不符合平台要求 3:小游戏录屏时间大于300S,分享按钮点击无反应或无法正常分享录屏,不符合平台要求 不久前写了款小游戏,最近上架了字节跳动小游戏平

    2024年01月16日
    浏览(50)
  • cocos creator对接字节跳动(抖音)小游戏激励视频广告注意事项(审核不通过,次数不一致和重复获得奖励等)

    首先是官方文档里的对接方式:(https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/open-interface/ads/rewarded-video/tt-createRewardedVideoAd) 在cocos creator开发的小游戏中,把onLoad换成start就差不多了,场景初始化的时候把视频对象初始化好,事件绑定好,如果是单场景的游戏确

    2024年02月16日
    浏览(52)
  • 【Cocos 3d】从零开始自制3d出租车小游戏

    本文很长,建议收藏食用。 课程来源: 游戏开发教程 | 零基础也可以用18堂课自制一款3D小游戏 | Cocos Creator 3D 中文教程(合集)p1~p6 简介: 资源下载:https://github.com/cocos-creator/tutorial-taxi-game 适合学习人群:本教程假定你对编程有一定的了解,ts,js 学习过其中之一。 如果不

    2024年02月02日
    浏览(55)
  • Cocos Creator3.8 项目实战(二)cocos creator编辑器中绑定事件引发的bug解决

    问题描述: 编辑器里面多个按钮绑定同一个脚本,并配置事件,脚本中有其他消息监听,引起逻辑混乱。 问题原因: 编辑器里面多个按钮绑定同一个脚本, 每次绑定一个按钮事件,就会导致加载一次脚本 ,如上绑定了多个按钮的事件,脚本也就被加载多次,导致初始化接

    2024年02月07日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包