深圳平湖网站建设公司,长沙做网站nn微联讯点很好,产品设计毕业设计作品,网站做电源引言
一文教会你造一个简易的狙击游戏。
说到狙击#xff0c;相信大家都不陌生#xff0c;无论是影视作品还是网络游戏#xff0c;都经常能看到狙击枪的身影#xff0c;最深刻的是它能够从百里之外#xff0c;一枪爆头。
本文将介绍如何在Cocos Creator中造一个简易的狙…
引言
一文教会你造一个简易的狙击游戏。
说到狙击相信大家都不陌生无论是影视作品还是网络游戏都经常能看到狙击枪的身影最深刻的是它能够从百里之外一枪爆头。
本文将介绍如何在Cocos Creator中造一个简易的狙击游戏非常详细。
本文源工程在文末获取小伙伴们自行前往。
1.狙击游戏常见的元素有什么
以下是狙击游戏中常见的一些元素 狙击枪 各种类型的狙击枪。 瞄准镜 玩家可以使用各种瞄准镜来提高精准度和观察敌人。 目标 狙击目标。
那么实现狙击游戏需要哪些知识点
2.实现狙击游戏的知识点
想要在Cocos Creator中造一个简易的狙击游戏需要掌握以下知识点 动画编辑狙击游戏通常包含一些动画效果例如打开瞄准镜的时候、子弹的运动轨迹等等都需要一些简易的动画效果本文用到动画编辑器和Tween动画。 瞄准镜效果瞄准镜的效果通常使用RTT方法全称RenderToTexture通过把摄像机拍到的内容渲染到2D的UI上。 碰撞检测本文是简易狙击游戏开枪即判断是否命中采用的是屏幕射线检测子弹的物理碰撞不做详细介绍。 圆形遮罩圆形的瞄准镜需要借助一下Mask遮罩。 3D游戏基础例如模型的摆放、坐标的计算转换以及相机的调整。
以上相关知识点笔者前面的文章都有介绍可在文末100个Cocos实例专栏查阅。
话不多说一起来看下如何在Cocos Creator中造一个简易的狙击游戏
3.一起来造一个简易的狙击游戏
我们根据以下的步骤一步一步来造一个简易的狙击游戏
1.环境
引擎版本Cocos Creator 3.8.1
编程语言TypeScript
2.资源准备
首先从市场搞一把帅气的带瞄准镜的狙击枪模型还送了个开火特效(这回节目组可是下重本啊。) 然后找一张简单的瞄准镜画面UI准备做几个小按钮用作瞄准镜开镜、射击和重置复位。 给瞄准镜添加一个Mask组件形成圆形遮罩。 为了营造一个非常好的打鸡效果我们把熟悉的鸡朋友拉过来当靶子。 添加2个摄像机并且分别调整各自的摄像机的机位包括原有的主摄像机瞄准镜摄像机和子弹轨迹跟踪摄像机。 小技巧 瞄准镜摄像机可以和主摄像机一致包括位置、旋转和设置通过改变相机Fov实现放大效果。 通过动画编辑器简单编辑一下开镜动画。 3.编写代码
首先定义一个Snipe组件包含以下几个属性。
ccclass(Snipe)
export class Snipe extends Component {bulletPfb: Node; //子弹预制体animation: Animation; //动画组件sighting: Node null; //瞄准UI节点bullet: Node; //当前子弹checkerCameraNode: Node; //相机检测节点
}然后在start方法里面初始化一下并且监听一下开镜、射击、重置事件。
start() {this.animation this.node.getComponent(Animation);director.getScene().on(PreShoot, this.PreShoot, this);director.getScene().on(Shoot, this.Shoot, this);director.getScene().on(Reset, this.Reset, this);this.bulletPfb this.node.getChildByPath(qiang/Line16);this.SightingCamera();
}开镜、射击、重置事件从UI_Joystick中的按钮发出。
const sighting this.node.getChildByName(Sighting);
this.node.getChildByName(BtnOpen).on(NodeEventType.TOUCH_END, () {this._scene.emit(PreShoot, sighting);
}, this);
this.node.getChildByName(BtnShoot).on(NodeEventType.TOUCH_END, () {if (sighting.active) {this._scene.emit(Shoot, checkerCamera.node);}
}, this);
this.node.getChildByName(BtnReset).on(NodeEventType.TOUCH_END, () {this._scene.emit(Reset);
}, this);实现瞄准镜的核心源码。
创建RenderTexture。设置摄像机的targetTexture为上面创建的RenderTexture。创建SpriteFrame也设置它的texture为上面创建的RenderTexture。最后将瞄准镜Sprite的spriteFrame为上面创建的SpriteFrame。
SightingCamera() {const modelRtt new RenderTexture();modelRtt.reset({width: 1024,height: 1024});const camera find(Main Camera/SightingCamera).getComponent(Camera);camera.targetTexture modelRtt;const spriteFrame new SpriteFrame();spriteFrame.texture modelRtt;find(Canvas/ui_joystick_panel/Sighting/Mask/SightingSprite).getComponent(Sprite).spriteFrame spriteFrame;
}在PreShoot方法中实现开镜动画的播放核心API如下。
通过animation.play播放动画。通过animation.on(Animation.EventType.FINISHED监听动画播放完成。通过animation.targetOff取消监听。
PreShoot(sighting: Node, callback null) {if (this.bullet) return;this.sighting sighting;if (this.node.children[0].active) {this.animation.targetOff(this);this.animation.on(Animation.EventType.FINISHED, (event) {this.sighting.active true;this.node.children[0].active false;}, this);this.animation.play(animation);}else {this.animation.targetOff(this);if (callback) {this.animation.on(Animation.EventType.FINISHED, (event) {callback();}, this);}this.sighting.active false;this.node.children[0].active true;this.animation.play(animation2);}
}在Shoot方法中利用射线检测判断瞄准镜是否瞄准了目标核心API如下。
通过camera.screenPointToRay 产生射线。通过PhysicsSystem.instance.raycast 进行射线碰撞检测并记录结果。通过PhysicsSystem.instance.raycastResults 获取射线检测结果通过名字或者其他信息得到想要的物体。
Shoot(checkerCameraNode: Node) {this.checkerCameraNode checkerCameraNode;var ray new geometry.Ray();var camera find(Main Camera).getComponent(Camera);var size view.getViewportRect();camera.screenPointToRay(size.width / 2, size.height / 2, ray);if (PhysicsSystem.instance.raycast(ray)) {const raycastResults PhysicsSystem.instance.raycastResults;for (let i 0; i raycastResults.length; i) {const item raycastResults[i];if (item.collider.node.name rooster_man_skin) {this.OnShootTarget(item.collider.node, item.hitPoint);return;}}this.OnShoot();} else {this.OnShoot();}
}最后在OnShootTarget中通过Tween动画运行子弹并且击中目标。
OnShootTarget(hitNode: Node, hitPoint: Vec3) {this.checkerCameraNode.active false;this.PreShoot(this.sighting, () {this.node.children[1].active true;const bullet instantiate(this.bulletPfb);this.bullet bullet;bullet.parent this.bulletPfb.parent;bullet.children[0].active true;// tween(bullet.children[1]).by(0.5, { eulerAngles: new Vec3(0, 360, 0) }).repeatForever().start();tween(bullet).by(3, { position: new Vec3(0, -0.5, 0) }).to(1, { worldPosition: hitPoint }).call(() {bullet.getComponentInChildren(MeshRenderer).enabled false;hitNode.getComponent(CharacterMovement).onJump(btn_slot_0);this.node.children[1].active false;}).start();tween(bullet.children[0].getComponent(Camera)).to(3, { fov: 30 }).to(1, { fov: 80 }).start();})
}4.效果演示
瞄准镜动画效果。 瞄准镜效果。 射击效果。
整体效果。 结语
本文源工程可通过阅读原文或者私信发送Snipe付费获取。付费不仅是知识的获取更是对笔者的支持和认可感谢
我是亿元程序员一位有着8年游戏行业经验的主程。在游戏开发中希望能给到您帮助, 也希望通过您能帮助到大家。
AD:笔者线上的小游戏《贪吃蛇掌机经典》《重力迷宫球》《填色之旅》大家可以自行点击搜索体验。
实不相瞒想要个赞和在看请把该文章分享给你觉得有需要的其他小伙伴。谢谢
推荐专栏
100个Cocos实例
8年主程手把手打造Cocos独立游戏开发框架
和8年游戏主程一起学习设计模式
游戏开发的技巧、心得、资讯
从零开始开发贪吃蛇小游戏到上线系列