cocos creator 3.x开发RPG游戏从零起步(人物地图素材、摇杆控制人物移动,场景障碍物判断)

编程入门 行业动态 更新时间:2024-10-26 09:25:21

cocos creator 3.x开发RPG游戏从零起步(<a href=https://www.elefans.com/category/jswz/34/1769923.html style=人物地图素材、摇杆控制人物移动,场景障碍物判断)"/>

cocos creator 3.x开发RPG游戏从零起步(人物地图素材、摇杆控制人物移动,场景障碍物判断)

最近躺平了,基本没怎么写游戏,挂着NovelAi烧显卡画妹子,把之前开发的一款RPG游戏拿来写个简单的教程,水篇文章,大概的效果如下:

本文主要内容有以下几点:1.制作人物及地图素材 2.使用cocos creator 3.x(本demo使用3.8)实现人物移动和地形障碍

一、制作人物及地图素材

这个对于个人开发者而言(比如我)是个非常头痛的难题,请不起美工(妹子),自己又没有美术天赋,只能从网上找素材东拼西凑,还要留意版权毕竟是拿来上微信字节平台的…
个人首选的素材网是kenney()这个不解释,全CC0可商用素材,用过的都说好。
像爱给这种的,虽然素材多,但是七拼八凑做出来的游戏,素材会显得非常不协调,既然是做RPG游戏,我想到一款神器:RPG Maker!
RPG Maker即RPG制作大师,是款开发单机RPG游戏的神器,里面包含了地图制作器、人物生成器等必要的素材制作工具,我们不一定要会用RPG Maker来做游戏,只要会拿它来生成地图素材就行了,生成的png图片放到cocos里用,这样就能保证游戏素材的协调性,人物和地图元素融为一体不会显得突兀,而且RPG Maker还有丰富的DLC,以及很多国外大神制作好的场景,拿来即用,时间和成本立省300%!

本文使用RPG Maker MV,网上资源一大堆请自行百度,下载解压后双击exe运行。

打开软件后,新建一个项目,然后右键点击左下角的project

右键载入,可以看到有很多官方的demo

我们随便选一个,点击确定,本文就以石窟地图为例(demo中我对该地图做了修改,只保留了上面一半,大家可以自己尝试),选择后软件会自动加载场景,右键保存为图像,就能将该地图以PNG格式保存在本地了,我们直接放到cocos下面作为地图素材使用。(可以根据实际需要对图片进行压缩)

地图搞定了,下面开始生成人物。
点击菜单里的“人物生成器”按钮

可以看到这是个非常牛皮的生成器,游戏里会用到“行走图”,后续的战斗场景也需要“战斗图”

导出PNG格式,是一个合批图,我们可以使用PngSplit等工具将图片切割成独立的小图,然后挑选需要使用的素材放到游戏目录中。

二、使用cocos creator 3.x(本demo使用3.8)实现人物移动和地形障碍

打开cocos creator,新建个项目,把第一步中生成的素材放到资源文件夹中,撸起袖子码代码。

首先是摇杆,cocos store上有大神写的demo,拿来用不解释。

默认手机横向,长宽设置为1334 * 750,背景放大一些,我放了2000*1200。
大概是这么个比例:

节点有以下这些:

游戏设计成玩家人物始终在屏幕中间,因此控制摇杆的操作,就等于反向移动背景,也就是说人物和摇杆是固定不动的,我们使用一个相机观察摇杆和人物,另一个相机观察背景。
两个相机的层级如下:
第一个相机:

第二个相机

把玩家人物和摇杆的Layer设置为“摇杆”,其余节点默认为UI_2D

Canvas的相机设置为观察UI_2D的那个相机
场景内新增节点DefaultManage,用于挂载场景脚本(代码在后面):

同时配置好摇杆的属性节点:

摇杆的目标是在场景脚本里绑定的,我们绑定的是背景节点,并非玩家节点,这个和摇杆demo不一样。

不出意外,背景就会跟随摇杆移动了,但是摇杆可以斜着移动,但我们的人物素材只有上下左右四种,所以把摇杆修改一下,比如玩家把摇杆操作为40度时,我们让背景水平移动,而非斜着移动,当角度大于45度时,只进行垂直移动。

参考摇杆demo的代码,我们在这增加判断,保证只进行水平或垂直移动。

摇杆移动时,记录方向,显示人物面对的方向。

关于障碍物,我们使用刚体+碰撞体,设置一个分组,用于表示禁止移动的地区。
打开碰撞体的editing勾选框,可以自由移动和伸缩,两三分钟就能把一个场景内的全部障碍物铺完,非常效率。

地图移动时,在玩家面对的方向发射射线检测,当射线检测到障碍物时return掉,不做移动,即可达到障碍效果。
这里为什么用两条射线呢,人往下走时,需要在左手和右手各发射一条,都没有碰撞才能走,防止一半身子穿透障碍物的情况,其他方向同理。

节点的完整代码如下:

import { _decorator, CCFloat, Component, ERaycast2DType, Node, PhysicsSystem2D, Prefab, resources, Sprite, SpriteAtlas, Vec2, Vec3 } from 'cc';
import joy from "./Joystick"
const { ccclass, property } = _decorator;@ccclass('DefaultManage')
export class DefaultManage extends Component {@property({ displayName: "摇杆脚本所在节点", tooltip: "摇杆脚本Joystick所在脚本", type: joy })public joy: joy = null!;@property({ displayName: "角色(受摇杆控制的节点)", tooltip: "角色(受摇杆控制的节点)", type: Node })background: Node = null!;@property({ displayName: "是否根据方向旋转角色", tooltip: "角色是否根据摇杆的方向旋转" })is_angle: boolean = false;@property({ displayName: "是否禁锢角色", tooltip: "是否禁锢角色,如果角色被禁锢,角色就动不了了" })is_fbd_background: boolean = false;@property({ displayName: "角色移动速度", tooltip: "角色移动速度,不建议太大,1-10最好", type: CCFloat })speed: number = 3;@property({ displayName: "玩家人物", tooltip: "玩家人物", type: Node })player: Node = null!;// 角色的移动向量vector: Vec2 = new Vec2(0, 40);// 角色旋转的角度angle: number = 0;private lastX: number = 0;private direction: string = 'down'start() {}update(deltaTime: number) {// 如果没有禁锢角色if (this.is_fbd_background === false) {// 获取角色移动向量this.vector = this.joy.vector;// 向量归一化let dir = this.vector.normalize();// 乘速度let dir_x = dir.x * this.speed;let dir_y = dir.y * this.speed;// 角色坐标加上方向if (Math.abs(dir_x) > Math.abs(dir_y)) {//X大于Y,表示只进行横向移动,不考虑纵向if (dir_x > 0) {//摇杆往右移动,地图往左移let x = this.background.position.x - dir_x;this.direction = 'right'this.playerMoving()const results_1 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x + 40, this.player.getWorldPosition().y), ERaycast2DType.Any);const results_2 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x + 40, this.player.getWorldPosition().y - 60), ERaycast2DType.Any);if ((results_1 && results_1.length > 0) || (results_2 && results_2.length > 0)) {return}this.background.setPosition(x, this.background.position.y);}else if (dir_x < 0) {//摇杆往左移动,地图往右移let x = this.background.position.x - dir_x;this.direction = 'left'this.playerMoving()const results_1 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x - 40, this.player.getWorldPosition().y), ERaycast2DType.Any);const results_2 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x - 40, this.player.getWorldPosition().y - 60), ERaycast2DType.Any);if ((results_1 && results_1.length > 0) || (results_2 && results_2.length > 0)) {return}this.background.setPosition(x, this.background.position.y);}}else if (Math.abs(dir_x) < Math.abs(dir_y)) {//只考虑纵向if (dir_y > 0) {//摇杆往上移动,地图往下移let y = this.background.position.y - dir_y;this.direction = 'up'this.playerMoving()const results_1 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x + 30, this.player.getWorldPosition().y + 5), ERaycast2DType.Any);const results_2 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x - 30, this.player.getWorldPosition().y + 5), ERaycast2DType.Any);if ((results_1 && results_1.length > 0) || (results_2 && results_2.length > 0)) {return}this.background.setPosition(this.background.position.x, y);}else if (dir_y < 0) {//摇杆往下移动,地图往上移let y = this.background.position.y - dir_y;this.direction = 'down'this.playerMoving()const results_1 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x + 30, this.player.getWorldPosition().y - 65), ERaycast2DType.Any);const results_2 = PhysicsSystem2D.instance.raycast(this.player.getWorldPosition(), new Vec3(this.player.getWorldPosition().x - 30, this.player.getWorldPosition().y - 65), ERaycast2DType.Any);if ((results_1 && results_1.length > 0) || (results_2 && results_2.length > 0)) {return}this.background.setPosition(this.background.position.x, y);}}else {//没有移动摇杆,设置玩家为非移动状态this.playerStop()}}}private playerMoving() {if (this.direction === 'up' || this.direction === 'down') {//角色进行上下移动let dis = Math.floor(Math.abs(this.background.position.y - 0) / 20);if (dis % 2 === 0) {resources.load("person/主角1", SpriteAtlas, (err, atlas) => {this.player.getChildByName('Sprite').getComponent(Sprite).spriteFrame = atlas.getSpriteFrame(this.direction === 'up' ? '主角1_11' : '主角1_2');});}else {resources.load("person/主角1", SpriteAtlas, (err, atlas) => {this.player.getChildByName('Sprite').getComponent(Sprite).spriteFrame = atlas.getSpriteFrame(this.direction === 'up' ? '主角1_12' : '主角1_3');});}}else {//左右只需要用同一张图,进行节点的水平翻转即可this.player.setScale(this.direction === 'right' ? -1 : 1, 1, 1)let dis = Math.floor(Math.abs(this.background.position.x - 0) / 20);if (dis % 2 === 0) {resources.load("person/主角1", SpriteAtlas, (err, atlas) => {this.player.getChildByName('Sprite').getComponent(Sprite).spriteFrame = atlas.getSpriteFrame('主角1_5');});}else {resources.load("person/主角1", SpriteAtlas, (err, atlas) => {this.player.getChildByName('Sprite').getComponent(Sprite).spriteFrame = atlas.getSpriteFrame('主角1_6');});}}}private playerStop() {switch (this.direction) {case 'up':resources.load("person/主角1", SpriteAtlas, (err, atlas) => {this.player.getChildByName('Sprite').getComponent(Sprite).spriteFrame = atlas.getSpriteFrame('主角1_10');});break;case 'down':resources.load("person/主角1", SpriteAtlas, (err, atlas) => {this.player.getChildByName('Sprite').getComponent(Sprite).spriteFrame = atlas.getSpriteFrame('主角1_1');});break;case 'left':case 'right':this.player.setScale(this.direction === 'right' ? -1 : 1, 1, 1)resources.load("person/主角1", SpriteAtlas, (err, atlas) => {this.player.getChildByName('Sprite').getComponent(Sprite).spriteFrame = atlas.getSpriteFrame('主角1_4');});break;}}
}

十二点了,太困了…还有一些细节请自己阅读代码吧,是个非常简单的demo。

代码和素材基本都在上面了,需要此demo打包的代码也可以私信我,如果能点个关注那就太棒了…

祝大家早日开发出自己梦想中的那款RPG~

更多推荐

cocos creator 3.x开发RPG游戏从零起步(人物地图素材、摇杆控制人物移动,场景障碍物判断)

本文发布于:2024-03-08 20:52:30,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1722305.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:人物   摇杆   障碍物   素材   场景

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!