零基础学CocosCreator·第七季-制作一款塔防游戏

第七季-制作一款塔防游戏

  • 01.塔防前言
    • 为什么是塔防?
    • 准备
  • 02.使用TileMap创建地图
    • 新建地图
    • 获取地图
    • 编辑地图
    • 代码操控
    • 运行
  • 03-16.实战中
  • 04.状态机
    • 代码
  • 08.事件分发器
  • 13.优化子弹-对象池
  • 1.9→2.0 Api
  • 技巧方法总结
  • 问题及解决方法

01.塔防前言

终于实战了,耶!

为什么是塔防?

1. 单机
2. 多元素
3. 与大型游戏架构设计类似
4. 与前面的知识结合

准备

  1. TileMap
    历史版本下载
  2. 前面的知识已经掌握

02.使用TileMap创建地图

新建地图

出现如图选项,点击"新建地图"
零基础学CocosCreator·第七季-制作一款塔防游戏_第1张图片
弹出

注意地图大小和块大小,已知我们需要的地图大小为2048x1536.所以要调整块大小和块数保证结果和需求一样.
(当然,如果想块大小改为32x32,块数也相应调整也是可以的,但duck不必)

零基础学CocosCreator·第七季-制作一款塔防游戏_第2张图片
点击"另存为",注意一定要将文件存在工程的asset目录下.
我的目录:C:\StudySpace\cocosCreator\KindomRush\assets\Levels命名为"level1"

获取地图

点击在这里插入图片描述新建新图块
源:要选择工程目录下的地图图片,检查下块尺寸没有问题,同样另存为到工程目录Level下,命名为"level1"
零基础学CocosCreator·第七季-制作一款塔防游戏_第3张图片
将图块印到地图到上
按shift选择多个图块,左键印上,右键取消

编辑地图

右侧菜单栏新建对象层

对象层用于创建一些特殊的点

创建放塔点
零基础学CocosCreator·第七季-制作一款塔防游戏_第4张图片

代码操控

在creator里创建场景,并添加一个tileMap节点,将制作的地图资源放入.
零基础学CocosCreator·第七季-制作一款塔防游戏_第5张图片

将塔图片添加到场景下.
零基础学CocosCreator·第七季-制作一款塔防游戏_第6张图片
在代码里获取地图数据并操作图片位置
注意tileMap和creator坐标系不同

零基础学CocosCreator·第七季-制作一款塔防游戏_第7张图片

import Utils from "./Utils";

const {ccclass, property} = cc._decorator;

@ccclass
export default class SelectLevels extends cc.Component {

    @property(cc.TiledMap)
    map: cc.TiledMap = null;

    @property(cc.Sprite)
    sprite: cc.Sprite = null;

    onLoad () {
        this.setSpriteToMapPos();
    }

    //将sprite放到map中标记的位置
    setSpriteToMapPos() {
        /**tileMap里设置的对象层 */
        let towers = this.map.getObjectGroup("towers");
        /**对象层里设置的标记点 */
        let tower0 = towers.getObject("tower0");
        /**标记点的坐标 */
        let tower0Pos = tower0.offset;
        this.sprite.node.position = Utils.tileCoordForPositon(this.map,tower0Pos);
    }
}

将可重复利用的函数放到工具类里

/**工具类 */
export default class Utils {

    /**将tileMap坐标转换为cocos坐标
     * cocos锚点为(0.5,0.5)
     */
    static tileCoordForPositon(map: cc.TiledMap,pos: cc.Vec2): cc.Vec2 {
        /**获取地图有多少个地图块(32x64) */
        let mapSize = map.getMapSize();
        /**获取地图块的大小 */
        let tileSize= map.getTileSize();

        let x = pos.x - (mapSize.width * tileSize.width) / 2;
        let y = (mapSize.height * tileSize.height) / 2 - pos.y;
        return cc.v2(x,y);
    }
}

运行

塔被放到了指定的位置了
零基础学CocosCreator·第七季-制作一款塔防游戏_第8张图片

03-16.实战中

实战写文档就太麻烦了,写完后贴源码吧~
有些新知识,遇到的问题会贴过来的

04.状态机

状态机会管理一些状态,状态之间可以互相转换
零基础学CocosCreator·第七季-制作一款塔防游戏_第9张图片

代码

/**
**Author: Cai QiuYa
**Describe: 状态机
*/

export default class GameActorStatusMachine {

    currentStatus: GameActorStatusBase = null;
    
    /**状态切换 */
    onStatusChange(status: GameActorStatusBase) {
        if (this.currentStatus != status) {
            if (this.currentStatus) {
                this.currentStatus.onExitStatus();
            }
            this.currentStatus = status;
            status.onEnterStatus();
        }
    }
}

/**状态基类 */
export class GameActorStatusBase {
    status: GameActorStatusType = GameActorStatusType.None;

    //进入状态时
    onEnterStatus() {

    }

    //退出状态时
    onExitStatus() {
        
    }

}

export class GameActorStatusIdle extends GameActorStatusBase {
    status = GameActorStatusType.Idle;
}

export class GameActorStatusWalk extends GameActorStatusBase {
    status = GameActorStatusType.Walk;
}

export class GameActorStatusAttack extends GameActorStatusBase {
    status = GameActorStatusType.Attack;
}

export class GameActorStatusDie extends GameActorStatusBase {
    status = GameActorStatusType.Die;
}

/**状态枚举 */
export enum GameActorStatusType {
    None,
    /**空闲状态 */
    Idle,
    /**走路 */
    Walk,
    /**攻击 */
    Attack,
    /**死亡 */
    Die,
}

08.事件分发器

和之前的监听者模式类似
零基础学CocosCreator·第七季-制作一款塔防游戏_第10张图片

13.优化子弹-对象池

零基础学CocosCreator·第七季-制作一款塔防游戏_第11张图片

1.9→2.0 Api

视频里老师用1.9和我的2.0的api有些不同

//1.9
this.moveDir = cc.pNormalize(cc.pSub(this.nextPathPoint,this.machine.actor.node.position));
//2.0
this.moveDir = (this.nextPathPoint.sub(this.machine.actor.node.position)).normalize();
//将弧度变成角度 2π=360
//1.9
cc.pToAngle();
//2.0
cc.misc.radiansToDegrees();
//根据起始结束两坐标点获取行进方向
//1.9
let angle = cc.radiansToDegress(cc.pToAngle(cc.pSub(to,from)));
//2.0
let angle = -cc.misc.radiansToDegrees((to.sub(from)).signAngle(cc.Vec2.RIGHT));
//获取两向量距离
//1.9
cc.pDistance(v1,v2);
//2.0
(v1.sub(v2)).mag();
//向量乘以系数 mult系数
//1.9
cc.pMult(v1,mult);
//2.0
v1.mul(mult);

技巧方法总结

  • 比如当我们需要获取tileMap里的多边形路径各坐标,但是不知道怎么调用,咋办?
    A:我们可以先获取到mileMap的对象,再在浏览器里预览,将对象打断点获取对象信息.这样就可以知道怎么获取坐标了.
    零基础学CocosCreator·第七季-制作一款塔防游戏_第12张图片

问题及解决方法

  • TexturePacker合的图默认会将透明像素裁剪掉,但我并不希望裁剪掉?
  • 在这里插入图片描述

A
零基础学CocosCreator·第七季-制作一款塔防游戏_第13张图片在这里插入图片描述

  • 使用requireComponent报错没有这个字段
    A: 需要将文件引用一下
    const {ccclass, property, requireComponent} = cc._decorator;
    
    或者
    import requireComponent = cc._decorator.requireComponent;
    

你可能感兴趣的:(-,TS)