游戏开发之gameplay开发保龄球

683 阅读2分钟

gameplay是什么

gameplay是指游戏性,游戏的可玩性,是一款游戏的核心玩法。

“所谓游戏性,可定义为玩游戏的整体体验。游戏机制一词,把游戏性这个概念变得更为具体。游戏机制通常定义为一些规则,这些规则主宰了游戏中多个实体之间的互动。”____《游戏引擎架构》

gameplay的3c要素

- Character(角色)

- Camera(相机)

- Controller(控制器)

gameplay的3c要素通过字面意思即可以很好的理解,下面结合实例讲解这三个要素在游戏玩法中的运用。

image.png 在“指尖保龄球”这款游戏中,保龄球就是游戏的角色

screenshot-20211112-170030.png 摄像机是用来拍摄游戏场景和画面的工具,在“指尖保龄球”这款游戏中,玩家扔下保龄球之后,保龄球开始运动,摄像机开始拍摄小球的运动,在这里,分为三个阶段。

在代码中这三个阶段用状态机来表示 以typescript为例

// 摄像机状态
enum cameraState {
  idle, // 静止
  follow, // 跟随
  decrease, // 减速
}
// 初始状态
private cameraMode: cameraState = cameraState.idle;

1. 摄像机静止阶段

static阶段:从游戏启动到玩家扔下保龄球,保龄球到球道上滚动一段时间,到了一个距离后,摄像机器开始拍摄之前

保龄球滚动一段距离才开始拍摄,这样会创造更加好的视觉效果,增加游戏性

2. 摄像机跟拍阶段

follow阶段:这个阶段摄像机器跟拍小球,与摄像机器与小球速度一致

记录这个阶段倒数第二帧的距离,与倒数第一帧的距离,记录摄像机这个阶段最后一帧的瞬时速度

3. 摄像机减速阶段

decrease阶段:从跟拍阶段记录的速度做均减速度运动,直到速度为零

使用的数学公式

匀加速直线运动的速度和时间公式为:v(t)=v(0)+atv(t)=v(0)+at

匀加速直线运动的位移和时间公式为:s=v(0)t+1/2at2s=v(0)t+1/2at^2

cocos creater 3.x 实现核心代码

import {
  _decorator,
  Component,
  Node,
  RigidBody,
  v3,
  Camera,
  TERRAIN_SOUTH_INDEX,
} from "cc";
const { ccclass, property } = _decorator;

// 摄像机状态
enum cameraState {
  idle, // 静止
  follow, // 跟随
  decrease, // 减速
}

@ccclass("BallCtrl")
export class BallCtrl extends Component {
  private body: RigidBody = null;
  private zspeed: number = 0;
  private isRunning: boolean = false;
  private cameraMode: cameraState = cameraState.idle;
  private cameraOffsetZ: number = 0;
  private prevPosZ: number = 0;
  private vz: number = 0;

  private add_speed: number = 5;

  @property(Node)
  private camera: Node = null;

  start(): void {
    this.body = this.node.getComponent(RigidBody); // 获取了保龄球上的刚体组件;

    // test
    this.ThrowBall(-2);
    // end
  }

  ThrowBall(zspeed): void {
    this.zspeed = zspeed;
    this.isRunning = true;
    this.cameraMode = cameraState.idle;
    this.body.setLinearVelocity(v3(0, 0, this.zspeed));
    this.body.setAngularVelocity(v3(-this.zspeed * 300, 0, 0));
  }

  lateUpdate(dt: number): void {
    if (this.isRunning === false) return;
    let pos = this.camera.getWorldPosition();
    switch (this.cameraMode) {
      // 摄像机静止状态
      case cameraState.idle:
        if (this.node.position.z <= -0.5) {
          this.cameraMode = cameraState.follow;
          this.cameraOffsetZ = this.camera.position.z - this.node.position.z;
        }
        break;
      // 摄像机器跟随状态
      case cameraState.follow:
        pos.z = this.node.position.z + this.cameraOffsetZ;
        this.camera.setWorldPosition(pos);
        if (this.node.position.z <= -4.5) {
          this.cameraMode = cameraState.decrease;
          // 当前摄像机的z的位置
          let nowZ = this.node.position.z + this.cameraOffsetZ;
          // 摄像机的速度
          this.vz = (nowZ - this.prevPosZ) / dt;
        } else {
          this.prevPosZ = this.node.position.z + this.cameraOffsetZ;
        }
        break;
      // 摄像机减速停下状态
      case cameraState.decrease:
        // s = v0*t + 0.5 * a * dt * dt;
        pos.z += this.vz * dt + 0.5 * this.add_speed * dt * dt;
        this.camera.setWorldPosition(pos);
        // v = v0 + a*dt;
        this.vz += this.add_speed * dt;
        if (this.vz >= 0) {
          this.cameraMode = cameraState.idle;
          this.isRunning = false;
        }
        break;
    }
  }
}

保龄球摄像机demo代码仓库地址

gitee.com/clig/cocos_…