原来微信小游戏用的技术就是web, 有想法的直接可以做
12月玩了2个微信小游戏, 发现都是在玩数值, 其实就是同一个游戏场景, 于是想自己写一个试试.
然后看了微信小游戏文档, 推荐 cocos creator, 学了下发现 web 开发者那是根本不用学.
自己写了2个demo, 于是分享给大家.
cocos creator
cocos creator 是个游戏引擎, 他推荐使用 vscode 和 chrome, 并且 ts 是唯一支持的脚本语言.
他的预览就是打开chrome的一个网页, 主体是个canvas, 这个场景下cc可能就是一系列资源的执行器.
重要的是他可以打包到微信小游戏, 也是微信小游戏推荐的框架.
也就是我可以用 ts 写小程序了.
其实也就是个 html5 的小游戏, 而 cc 包装了h5小游戏要手动写的requestAnimationFrame
执行器, 提供了更方便的编辑器, 包装了一些游戏开发要用到的概念.
网页开发和游戏开发的区别
显然网页开发和游戏开发是不同的, 来稍作分析.
游戏元素
网页元素一般由div布局, 终端的节点一般是文字, 或者输入框.
游戏元素看起来容易一些, 因为没有输入. 手机小游戏只有通过点击来传达一些指令.
游戏元素也有布局, 但没网页 bfc, flex 这些复杂的东西, 全部绝对定位, 也有z轴.
再细看游戏元素, 其实每个元素就是个图片.
简单总结, 游戏的所有元素就是图片, 通过设置x, y, z的数值来定位. 比网页开发容易得多.
游戏交互
网页的功能主要是2个部分: 输入和展示.
所以网页的交互也就是改变参数后刷新列表.
我们来分析游戏的交互, 也分为2个部分: 改变位置与结算.
随着游戏的开始和玩家的点击, 其实就是元素的位置发生改变而已.
我们只要通过脚本控制元素的位置. 这些位置和具体游戏场景相关, cc 也会提供常用工具库.
另外一个是结算, 判断分数高低, 或者数组比较, 最多通过位置计算碰撞, 来判断游戏结果.
可以看到这些计算都是在脚本中进行的, 也都是比较简单的数据结构或者数学公式.
在游戏场景外, 一些菜单, 设置的界面就和网页差不多了.
cc 系统介绍
我看了一个视频, 自己写了2个demo, 简单总结下 cc 的系统.
总的来说, cc 像是个低代码平台.
编辑器界面
编辑器就是典型的低代码.
- 场景界面. 就是把元素拖拖拽拽的地方.
- 资源列表. 放代码和图片的地方, 就是网页开发的
src
目录. 资源的类型值得下文展开. - 节点层级. 在编辑场景的时候, 场景通常是有多个节点的, 节点之间有层级关系便于维护, 所以有个界面展示.
- 节点属性. 在场景界面里选中节点, 肯定是可以编辑这个节点的属性的, 大小/位置什么的.
这些元素一看就是低代码了, 应该是低代码借鉴了这些游戏引擎的.
这些面板都是可以拖动位置, 或者合并成tab的, 很方便.
资源类型介绍
上面说到资源, 资源类型还挺多的. 这里介绍一点我用到的.
- ts文件, 图片文件.
脚本文件和图片文件都是用来拖到节点里, 和节点绑定的.
- 场景.
应该是 cc 的核心了. 从文件看来, 就是个 json. 所以拖拖拽拽的结果就是修改 json. 然后通过 json schema 执行渲染或打包.
场景是由节点组成的. 在场景里新建节点并嵌套, 来构建游戏场景.
节点的种类是很多的, 可以插入图片变为元素, 也可以绑定脚本, 作为一个"虚拟节点", 只是为了维护方便.
场景有必须的节点是 canvas 和 camera.
- prefab.
可以理解为"组件". 在场景中编辑了一些节点, 如果觉得可以复用, 直接把整个节点拖到资源列表里, 就会产生一个 prefab. 使用的时候拖动这个 prefab 到场景, 就会产生一个实例了.
更多的应该是用脚本批量创建.
- 动画.
其实和ts文件与图片文件一样, 是关联到节点上的. 但他是 cc 特有的, 可以在 cc 里编辑动画内容, 可以对各个属性做帧动画, 也可以导入动画软件做的动画.
开发流程
我写了2个算能跑的项目, 来说说开发的过程.
- 资源目录下新建一些文件夹: scripts, imgs, animation, scene.
- 主要开发就是编辑场景. 在场景里添加节点, 然后给节点贴图, 从"资源列表"把资源拖到"节点属性面板"就好了, 容易.
我的节点很简单, 就是玩家角色, 和背景.
- 建立个空节点, 写游戏逻辑. 具体操作是新建个 ts 文件, 然后拖到这个节点属性上.
- 游戏逻辑需要操作的内容, 包括动画, 都以"拖动"的方式关联到"节点属性面板"上.
这样就写好一个游戏了.
游戏逻辑开发是和 html5 游戏一样的, 最后一小节我再赘述下吧.
游戏逻辑编写
游戏逻辑在 ts 的脚本文件中编写.
所有新建的 ts 文件都会有一个初始模板. 内容是export class XXX extends cc.Component {}
.
这个类有2个生命周期方法. start()
和update()
.
update()
方法的参数deltatime
是离上一帧的时间, 不了解的去看下 h5 游戏的执行就好了.
游戏逻辑一定涉及到元素, 只要在脚本文件里声明一个属性, 就能在节点属性面板上看到一个属性.
把这个属性需要控制的元素拖过去就行.
然后元素节点也可以绑定脚本. 这个脚本可以通过this.node
提供的 api 来操作元素的位置.
元素节点一般会绑定动画, 也需要把动画声明在属性里, 然后从资源列表把动画拖动到自己的节点属性面板上, 就可以在脚本里调用动画了.
我现在理解的层级是这样的:
- 总脚本gameControl写在单独节点里. 写游戏逻辑与结算判断.
- 会动的元素, 自己绑定节点, 写一些方法供总脚本调用.
- 编辑一些动画, 供上一步"会动的元素"调用. 一般是和元素位置的移动同时调用的.
贴一些代码
这里分享个具体的demo代码. demo内容很简单, 按方向键角色就会在地图上走路.
走路的时候会播放一个帧动画, 是从微信表情里导出的20个png.
脚本文件只有2个. 一个是gameControl游戏控制, 只做了监听键盘事件, 并调用player脚本的对应方法.
另一个player脚本写了对应的方法, 改变一些参数, 在update()
方法根据参数来设置角色的位置.
gameControl.ts
import { _decorator, Component, Node, input, Input, EventKeyboard } from 'cc'
const { ccclass, property } = _decorator
import { player } from './player'
@ccclass('gameControl')
export class gameControl extends Component {
@property(player)
public player: player = null
start() {
input.on(Input.EventType.KEY_DOWN, (event) => {
switch (event.keyCode) {
case 37:
this.player.left()
break
case 38:
this.player.up()
break
case 39:
this.player.right()
break
case 40:
this.player.down()
break
}
})
}
update(deltaTime: number) {
}
}
player.ts
import { _decorator, Component, Node, Animation, tween, Vec3, math } from 'cc'
const { ccclass, property } = _decorator
@ccclass('player')
export class player extends Component {
@property(Animation)
anim: Animation = null
@property(Node)
lulu: Node = null
private direction = new Vec3(1, 0, 0)
private isMoving = false
private movePeriod = 0
start() {
}
update(deltaTime: number) {
if (this.isMoving) {
if (this.movePeriod < 1) {
let target = this.node.position
Vec3.add(target, this.node.position, this.direction)
this.node.setPosition(target)
this.movePeriod += deltaTime
} else {
this.isMoving = false
}
}
}
left() {
if (!this.isMoving) {
this.lulu.setRotationFromEuler(0, 0, 180)
this.direction = new Vec3(-1, 0, 0)
this.startMove()
}
}
right() {
if (!this.isMoving) {
this.lulu.setRotationFromEuler(0, 0, 0)
this.direction = new Vec3(1, 0, 0)
this.startMove()
}
}
up() {
if (!this.isMoving) {
this.lulu.setRotationFromEuler(0, 0, 90)
this.direction = new Vec3(0, 1, 0)
this.startMove()
}
}
down() {
if (!this.isMoving) {
this.lulu.setRotationFromEuler(0, 0, 270)
this.direction = new Vec3(0, -1, 0)
this.startMove()
}
}
startMove() {
this.anim.play()
this.isMoving = true
this.movePeriod = 0
}
}
另外做的demo是跟着cocos creator 文档的2d游戏做的. 有兴趣的也可以跟我一样, 先照着这个做一遍, 再自己新建个空项目自己操作.
最后
我认为 cocos creator 对 web 开发者来说真的是非常好上手了.
我认为小游戏的设计分为2个吧. 核心游戏场景, 与, 游戏运营.
其实核心游戏场景都不复杂的, 那怎么能让玩家一直玩呢.
其实就是策划运营, 操作一些数据, 让每次玩同一个场景, 看到不同的数字, 和不同的皮肤.
用户就会为了这些数字(pay for ability), 和皮肤(pay for love)来付费了.
我认为游戏脚本不难. 难在2点:
- 游戏的完整度, 需要美术和动画, 程序只能控制角色的位置, 加上动画才让人有操作角色的感觉. 精美的游戏场景也能让玩家觉得真实.
- 策划: 数值系统, 货币系统, 奖励系统, 活动这些. 让玩家重复玩同一个场景几百遍还觉得自己在成长, 真是牛逼.
来源:juejin.cn/post/7456805812045725734