为了吃鸡苦练狙击,避免坑队友自己造一个狙击游戏!

2023-12-16 14:12

本文主要是介绍为了吃鸡苦练狙击,避免坑队友自己造一个狙击游戏!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

引言

一文教会你造一个简易的狙击游戏。

说到狙击,相信大家都不陌生,无论是影视作品还是网络游戏,都经常能看到狙击枪的身影,最深刻的是它能够从百里之外,一枪爆头

本文将介绍如何在Cocos Creator中造一个简易的狙击游戏非常详细

本文源工程在文末获取,小伙伴们自行前往。

1.狙击游戏常见的元素有什么?

以下是狙击游戏中常见的一些元素

  1. 狙击枪: 各种类型的狙击枪。

  2. 瞄准镜: 玩家可以使用各种瞄准镜来提高精准度和观察敌人。

  3. 目标: 狙击目标。

那么实现狙击游戏需要哪些知识点?

2.实现狙击游戏的知识点

想要在Cocos Creator中造一个简易的狙击游戏,需要掌握以下知识点:

  1. 动画编辑:狙击游戏通常包含一些动画效果,例如打开瞄准镜的时候、子弹的运动轨迹等等都需要一些简易的动画效果,本文用到动画编辑器Tween动画。

  2. 瞄准镜效果:瞄准镜的效果通常使用RTT方法,全称RenderToTexture,通过把摄像机拍到的内容渲染到2DUI上。

  3. 碰撞检测:本文是简易狙击游戏,开枪即判断是否命中,采用的是屏幕射线检测,子弹的物理碰撞不做详细介绍。

  4. 圆形遮罩:圆形的瞄准镜,需要借助一下Mask遮罩。

  5. 3D游戏基础:例如模型的摆放、坐标的计算转换以及相机的调整

以上相关知识点笔者前面的文章都有介绍,可在文末100个Cocos实例专栏查阅。

话不多说,一起来看下如何在Cocos Creator中造一个简易的狙击游戏

3.一起来造一个简易的狙击游戏

我们根据以下的步骤一步一步来造一个简易的狙击游戏:

1.环境

引擎版本:Cocos Creator 3.8.1

编程语言:TypeScript

2.资源准备

首先从市场搞一把帅气带瞄准镜狙击枪模型,还送了个开火特效!(这回节目组可是下重本啊。)

下重本了

然后找一张简单的瞄准镜画面UI,准备做几个小按钮用作瞄准镜开镜、射击和重置复位。

与技术无关,没有他我能闭着眼爆头

给瞄准镜添加一个Mask组件形成圆形遮罩。

方便好用

为了营造一个非常好的打鸡效果,我们把熟悉的鸡朋友拉过来当靶子

给我摆高一点

添加2个摄像机,并且分别调整各自的摄像机的机位,包括原有的主摄像机瞄准镜摄像机子弹轨迹跟踪摄像机

没想到做个Demo都那么不容易

小技巧

瞄准镜摄像机可以和主摄像机一致,包括位置、旋转和设置,通过改变相机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
  • 最后将瞄准镜SpritespriteFrame为上面创建的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年游戏主程一起学习设计模式

游戏开发的技巧、心得、资讯

从零开始开发贪吃蛇小游戏到上线系列

这篇关于为了吃鸡苦练狙击,避免坑队友自己造一个狙击游戏!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500768

相关文章

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

如何来避免FOUC

FOUC(Flash of Unstyled Content)是指在网页加载过程中,由于CSS样式加载延迟或加载顺序不当,导致页面出现短暂的无样式内容闪烁现象。为了避免FOUC,可以采取以下几种方法: 1. 优化CSS加载 内联CSS:将关键的CSS样式直接嵌入到HTML文档的<head>部分,这样可以确保在页面渲染之前样式就已经加载和应用。提前引入CSS:将CSS文件放在HTML文档的<he

火柴游戏java版

代码 /*** 火柴游戏* <p>* <li>有24根火柴</li>* <li>组成 A + B = C 等式</li>* <li>总共有多少种适合方式?</li>* <br>* <h>分析:</h>* <li>除去"+"、"="四根,最多可用火柴根数20根。</li>* <li>全部用两根组合成"1",最大数值为1111。使用枚举法,A和B范围在0~1111,C为A+B。判断</li>** @

国产游戏行业的崛起与挑战:技术创新引领未来

国产游戏行业的崛起与挑战:技术创新引领未来 近年来,国产游戏行业蓬勃发展,技术水平不断提升,许多优秀作品在国际市场上崭露头角。从画面渲染到物理引擎,从AI技术到服务器架构,国产游戏已实现质的飞跃。然而,面对全球游戏市场的激烈竞争,国产游戏技术仍然面临诸多挑战。本文将探讨这些挑战,并展望未来的机遇,深入分析IT技术的创新将如何推动行业发展。 国产游戏技术现状 国产游戏在画面渲染、物理引擎、AI

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

第四次北漂----挣个独立游戏的素材钱

第四次北漂,在智联招聘上,有个小公司主动和我联系。面试了下,决定入职了,osg/osgearth的。月薪两万一。 大跌眼镜的是,我入职后,第一天的工作内容就是接手他的工作,三天后他就离职了。 我之所以考虑入职,是因为 1,该公司有恒歌科技的freex平台源码,可以学学,对以前不懂的解解惑。 2,挣点素材钱,看看张亮002的视频,他用了6000多,在虚幻商城买的吸血鬼游戏相关的素材,可以玩两年。我

nyoj 1038 纸牌游戏

poj 的一道改编题,说是翻译题更恰当,因为只是小幅度改动。 一道模拟题,代码掌控能力比较好,思维逻辑清晰的话就能AC。 代码如下: #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;struct node{char c[5];int rk;char da[5];int nu

如果出一个名叫白神话悟空的游戏

最近黑神话由于与原著不符引起了原著派的争议。 所以我在摸鱼的时候想到如果游科或者某个别的公司“痛改前非”不夹带私货完全复刻吴承恩百回版剧情制作一个“重走西游路”的游戏,会有一个什么样的销量?(设定为原著派已经多方渠道认证,此游戏的确没有夹带私货,绝大部分复刻了原著剧情) 游戏玩法我想了几类 超长线性有岔路蜈蚣形状地图,蜈蚣的腿部是探索区域和支线,重走西游路线,开篇就是开始取经前唐玄宗御弟cg

Qt: 详细理解delete与deleteLater (避免访问悬空指针导致程序异常终止)

前言 珍爱生命,远离悬空指针。 正文 delete 立即删除:调用 delete 后,对象会立即被销毁,其内存会立即被释放。调用顺序:对象的析构函数会被立即调用,销毁该对象及其子对象。无事件处理:如果在对象销毁过程中还涉及到信号和槽、事件处理等,直接 delete 可能会导致问题,尤其是在对象正在处理事件时。适用场景:适用于在确定对象已经不再被使用的情况下,并且不涉及异步处理或事件循环中的

《黑暗之魂2:原罪学者》是什么类型的游戏 《黑暗之魂》可以在苹果Mac电脑上玩吗?

在宏大的世界观游戏中,《黑暗之魂2:原罪学者》脱颖而出,以其探索性和挑战性征服了全球玩家的心灵。下面我们来看看《黑暗之魂2:原罪学者》是什么类型的游戏,《黑暗之魂2:原罪学者》可以在苹果电脑玩吗的相关内容。 一、《黑暗之魂2:原罪学者》是什么类型的游戏 《黑暗之魂2:原罪学者》作为《黑暗之魂2》的增强版和重制版,是一款FromSoftware制作、BANDAI NAMCO和FromSoft