碰撞检测
assets/Scripts/Tile/TileManager.ts
在设置人物移动的地方加上判断当前位置是否可移动与转向的逻辑
import { _decorator, Component, Sprite, SpriteFrame, UITransform } from 'cc'
import { TILE_TYPE_ENUM } from '../../Enum'
const { ccclass, property } = _decorator
export const TILE_WIDTH = 55
export const TILE_HEIGHT = 55
@ccclass('TileManager')
export class TileManager extends Component {
type: TILE_TYPE_ENUM
moveable: boolean //可走
turnable: boolean //可转向
async init(type: TILE_TYPE_ENUM, spriteFrame: SpriteFrame, i: number, j: number) {
this.type = type
// 墙壁
const wallet: Array = [
TILE_TYPE_ENUM.WALL_COLUMN,
TILE_TYPE_ENUM.WALL_ROW,
TILE_TYPE_ENUM.WALL_LEFT_TOP,
TILE_TYPE_ENUM.WALL_RIGHT_TOP,
TILE_TYPE_ENUM.WALL_LEFT_BOTTOM,
TILE_TYPE_ENUM.WALL_RIGHT_BOTTOM,
]
// 悬崖
const cliff: Array = [
TILE_TYPE_ENUM.CLIFF_CENTER,
TILE_TYPE_ENUM.CLIFF_LEFT,
TILE_TYPE_ENUM.CLIFF_RIGHT,
]
if (wallet.indexOf(this.type) !== -1) {
// 当前是墙壁,不可走也不可旋转
this.moveable = false
this.turnable = false
} else if (cliff.indexOf(this.type) !== -1) {
// 当前是悬崖 不可走 可转
this.moveable = false
this.turnable = true
} else if (this.type === TILE_TYPE_ENUM.FLOOR) {
// 当前是地板 可走 可转
this.moveable = true
this.turnable = true
}
const sprite = this.addComponent(Sprite)
sprite.spriteFrame = spriteFrame
const transform = this.getComponent(UITransform)
transform.setContentSize(TILE_WIDTH, TILE_HEIGHT)
this.node.setPosition(i * TILE_WIDTH, -j * TILE_HEIGHT)
}
}
assets/Runtime/DataManager.ts
给数据中心单例加上位置信息,位置类型,包括是否可转向的信息
import Singleton from '../Base/Singleton'
import { ITile } from '../Levels'
import { TileManager } from '../Scripts/Tile/TileManager'
/**
* 单例模式
* 当前渲染的地图数据
*/
export default class DataManager extends Singleton {
static get Instance() {
return super.GetInstance()
}
mapInfo: Array = [] // 地图数据
tileInfo: Array //当前位置信息,当前位置类型,是否可走可转
mapRowCount: number = 0 //行数
mapColumnCount: number = 0 //列数
levelIndex: number = 1 // 当前关卡
reset() {
this.mapInfo = []
this.tileInfo = []
this.mapColumnCount = 0
this.mapRowCount = 0
}
}
export const DataManagerInstance = new DataManager()
assets/Scripts/Tile/TileMapManager.ts
在渲染地图时,将瓦片信息存储到数据中心中的瓦片信息中,DataManager.Instance.tileInfo
@ccclass('TileMapManager')
export class TileMapManager extends Component {
async init() {
// 从数据中心取出
const { mapInfo } = DataManager.Instance
// 加载资源
const spriteFrames = await ResourceManager.Instance.loadDir('texture/tile/tile')
DataManager.Instance.tileInfo = []
for (let i = 0; i disX 靠近Y轴,如果 disY < disX 则靠近X轴
// 当人物在移动为对角线的时候,NPC不做转向操作
if (disX === disY && !isInit) {
return
}
if (playerX >= this.x && playerY disX) {
// 在第一象限0~45°夹角中 靠近Y轴,朝上
this.direction = DIRECTION_ENUM.TOP
} else {
// 在第一象限45~90°夹角中 靠近X轴,朝右
this.direction = DIRECTION_ENUM.RIGHT
}
} else if (playerX disX ? DIRECTION_ENUM.BOTTOM : DIRECTION_ENUM.LEFT
} else if (playerX >= this.x && playerY >= this.y) {
// 在第四象限
this.direction = disY > disX ? DIRECTION_ENUM.BOTTOM : DIRECTION_ENUM.RIGHT
}
}
}
assets/Scripts/Scene/BattleManager.ts
在人物初始化时触发PLAYER_BORN事件,
// 创建人物
async generatePlayer() {
const player = createUINode()
player.setParent(this.stage)
const playerManager = player.addComponent(PlayerManager)
await playerManager.init()
DataManager.Instance.player = playerManager
EventManager.Instance.emit(EVENT_ENUM.PLAYER_BORN, true)
}
// 创建NPC
async generateEnemies() {
const woodenSkeleton = createUINode()
woodenSkeleton.setParent(this.stage)
const woodenSkeletonManager = woodenSkeleton.addComponent(WoodenSkeletonStateManager)
await woodenSkeletonManager.init()
DataManager.Instance.enemies.push(woodenSkeletonManager)
}
assets/Scripts/Player/PlayerManager.ts
人物移动的时候触发事件
move(){
//...
EventManager.Instance.emit(EVENT_ENUM.PLAYER_MOVE_END)
//...
}
本节源码地址:
https://gitee.com/yuan30/cramped-room-of-death/tree/day4/