在很多2D游戏中,都会涉及到角色移动,跳跃等操作,最典型的就是横板闯关游戏。例如经典的魂斗罗、三国战纪等。这两款游戏在地图移动和角色行走的方式中唯一的不同就是魂斗罗是没有纵深的那种。
看似简单,其实涉及了地图,摄像机移动,数学和物理的一些内容。
本片内容先介绍一下移动组件的定义,稍后的文章会一点点讲解地图、自定义摄像机等,最终应用到游戏中,做成一个完整的demo。
首先不得不说的一点,所有的移动都是依托坐标系的。我们这里的坐标系是以左下角为原点,横向向右为x正方向,纵向向上为y正方向,朝向屏幕的方向为z正方向,也就是unity使用的左手坐标系。而cocoscreator使用的是右手坐标系,但是这个转换是比较简单的。
首先列举一下移动中都需要支持哪些功能
import { DIR } from "../../cfw/tools/Define";import PhysicalManager from "./PhysicalManager";const { ccclass, property } = cc._decorator;@ccclassexport default class MoveSystem extends cc.Component { @property({ displayName: '是否受重力' }) g: Boolean = true; @property({ displayName: '是否启用' }) enable: Boolean = true; @property({ displayName: '速度' }) speed: cc.Vec3 = cc.v3(0, 0, 0) // 弹力 @property({ type: cc.Float, displayName: '弹力' }) elasticity: number = 0; //摩擦力 @property({ type: cc.Float, displayName: '摩擦力' }) frictional: number = 1; @property({ type: cc.Float, displayName: '跳跃高度' }) jumpHigh: number = 350; //左右移动方向 protected moveXDir: DIR = DIR.RIGHT; //上下移动方向 protected moveZDir: DIR = DIR.UP; //角色在地图中的位置 protected position: cc.Vec3 = cc.v3(0, 0, 0) start() { if (this.enable) { this.setEnable(true) } } onDestroy() { if (this.enable) { this.setEnable(false) } } setEnable(f: boolean) { this.enable = f; cc.log('MoveSystem setEnable f ', f) if (this.enable) { PhysicalManager.instance().add(this) } else { PhysicalManager.instance().remove(this) } } isEnable() { return this.enable; } setMoveXDir(d: DIR) { this.moveXDir = d; } getMoveXDir() { return this.moveXDir; } setMoveZDir(d: DIR) { this.moveZDir = d; } getMoveZDir() { return this.moveZDir; } getFrictional() { return this.frictional; } setGrictional(n: number) { this.frictional = n; } setElasticity(n: number) { this.elasticity = n; } getElasticity() { return this.elasticity; } isG() { return this.g } setG(f: boolean) { this.g = f; } getJumpHigh() { return this.jumpHigh; } setJumpHight(h: number) { this.jumpHigh = h; } addJumpHigh(h: number) { this.jumpHigh += h; } isJumping() { return this.speed.y != 0; } setX(x: number) { this.position.x = x; } setY(y: number) { this.position.y = y; } getZ() { return this.position.z; } setZ(z: number) { this.position.z = z; this.node.zIndex = -z } getX() { return this.position.x; } getY() { return this.position.y; } getSpeedX() { return this.speed.x; } setSpeedX(s: number) { this.speed.x = s; } setSpeedY(spy: number) { this.speed.y = spy; } getSpeedY() { return this.speed.y } setSpeedZ(z: number) { this.speed.z = z; } getSpeedZ() { return this.speed.z; }}
import { DIR } from "../../cfw/tools/Define";
import PhysicalManager from "./PhysicalManager";
const { ccclass, property } = cc._decorator;
@ccclass
export default class MoveSystem extends cc.Component {
@property({ displayName: '是否受重力' })
g: Boolean = true;
@property({ displayName: '是否启用' })
enable: Boolean = true;
@property({ displayName: '速度' })
speed: cc.Vec3 = cc.v3(0, 0, 0)
// 弹力
@property({ type: cc.Float, displayName: '弹力' })
elasticity: number = 0;
//摩擦力
@property({ type: cc.Float, displayName: '摩擦力' })
frictional: number = 1;
@property({ type: cc.Float, displayName: '跳跃高度' })
jumpHigh: number = 350;
//左右移动方向
protected moveXDir: DIR = DIR.RIGHT;
//上下移动方向
protected moveZDir: DIR = DIR.UP;
//角色在地图中的位置
protected position: cc.Vec3 = cc.v3(0, 0, 0)
start() {
if (this.enable) {
this.setEnable(true)
}
onDestroy() {
this.setEnable(false)
setEnable(f: boolean) {
this.enable = f;
cc.log('MoveSystem setEnable f ', f)
PhysicalManager.instance().add(this)
} else {
PhysicalManager.instance().remove(this)
isEnable() {
return this.enable;
setMoveXDir(d: DIR) {
this.moveXDir = d;
getMoveXDir() {
return this.moveXDir;
setMoveZDir(d: DIR) {
this.moveZDir = d;
getMoveZDir() {
return this.moveZDir;
getFrictional() {
return this.frictional;
setGrictional(n: number) {
this.frictional = n;
setElasticity(n: number) {
this.elasticity = n;
getElasticity() {
return this.elasticity;
isG() {
return this.g
setG(f: boolean) {
this.g = f;
getJumpHigh() {
return this.jumpHigh;
setJumpHight(h: number) {
this.jumpHigh = h;
addJumpHigh(h: number) {
this.jumpHigh += h;
isJumping() {
return this.speed.y != 0;
setX(x: number) {
this.position.x = x;
setY(y: number) {
this.position.y = y;
getZ() {
return this.position.z;
setZ(z: number) {
this.position.z = z;
this.node.zIndex = -z
getX() {
return this.position.x;
getY() {
return this.position.y;
getSpeedX() {
return this.speed.x;
setSpeedX(s: number) {
this.speed.x = s;
setSpeedY(spy: number) {
this.speed.y = spy;
getSpeedY() {
return this.speed.y
setSpeedZ(z: number) {
this.speed.z = z;
getSpeedZ() {
return this.speed.z;
对于移动的需求可能不止如此,但是在我以往的开发过程中,有这些已经可以应付大多数游戏的需求了。代码仅供参考,欢迎留言探讨。
欢迎扫码关注公众号《微笑游戏》,浏览更多内容。
原文链接:http://www.cnblogs.com/cgw0827/p/14249751.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728