import GuideBase from "../evnet/guide/GuideBase"; import FF from "../FF"; import FSprite from "../object/FSprite"; const { ccclass, property } = cc._decorator; @ccclass export default class FMap extends cc.Component { @property(cc.Node) mSprites: cc.Node = null;//精灵层 @property(cc.Node) mInit: cc.Node = null;//初始位置 @property(cc.Node) mRooms: cc.Node = null;//地图 @property(cc.AudioClip) mBgm: cc.AudioClip = null;//背景音乐 @property(GuideBase) mGuide: GuideBase = null;//地图进入场景时候的引导 @property(cc.TiledLayer) mColliderTiled: cc.TiledLayer = null;//地图碰撞层 public ff: FF; shoot: cc.Vec2 = cc.v2();//摄像机位置 public mCamera: cc.Camera = null//地图上的摄像机 /** * 所有房间 */ public rooms: Array = null private midWidth = 360; private midHeidht = 640; //当前所处房间 private curRoom: cc.Node = null; /** * 单元格尺寸 */ private cellSize = 64; onLoad() { this.midWidth = cc.winSize.width / 2; this.midHeidht = cc.winSize.height / 2; this.rooms = this.mRooms.children this.addCollider() // cc.log('xxxxxxxxxxxxxx = ',this.checkCollision(64,64)) } /** * 添加碰撞 */ private addCollider() { //地图边界碰撞墙 // let width = this.node.width; // let height = this.node.height; // let node = new cc.Node(); // node.group = 'map' // let body = node.addComponent(cc.RigidBody); // body.type = cc.RigidBodyType.Static; // this._addBound(node, width/2, height, width, 20); // this._addBound(node, width/2, 0, width, 20); // this._addBound(node, 0, height/2, 20, height); // this._addBound(node, width, height/2, 20, height); // node.parent = this.node; //地形碰撞处理 if (this.mColliderTiled) { let size = this.mColliderTiled.getLayerSize(); for (let i = size.height - 1; i >= 0; i--) { let count = 0; let isEnd = true; let startX = 0; let startY = size.height - i - 1; for (let j = 0; j < size.width; j++) { let t = this.mColliderTiled.getTileGIDAt(j, i); if (t > 0) { if (count <= 0) { startX = j; } count++ isEnd = false; } else { isEnd = true } if (count > 0 && isEnd) { isEnd = true; let node = new cc.Node(); node.x = startX * this.cellSize node.y = startY * this.cellSize node.group = 'map' let body = node.addComponent(cc.RigidBody); body.type = cc.RigidBodyType.Static; let cwidth = this.cellSize * count this._addBound(node, cwidth / 2, 32, cwidth, this.cellSize); node.parent = this.node; count = 0; } } if (count > 0) { let node = new cc.Node(); node.x = startX * this.cellSize node.y = startY * this.cellSize node.group = 'map' let body = node.addComponent(cc.RigidBody); body.type = cc.RigidBodyType.Static; let cwidth = this.cellSize * count this._addBound(node, cwidth / 2, 32, cwidth, this.cellSize); node.parent = this.node; } } } } private _addBound(node, x, y, width, height) { // cc.log('nodeXY:',node.x,node.y) // cc.log(x,y,width,height) let collider: cc.PhysicsBoxCollider = node.addComponent(cc.PhysicsBoxCollider); collider.offset.x = x; collider.offset.y = y; collider.size.width = width collider.size.height = height; collider.tag = 100; } /** * 获取当前所在房间 */ private getRoom() { for (let i = 0; i < this.rooms.length; i++) { const element = this.rooms[i]; if (this.inRoom(element)) { return element; } } return null; } private inRoom(node: cc.Node): boolean { if (this.shoot.x <= node.x || this.shoot.y <= node.y || this.shoot.x >= node.x + node.width || this.shoot.y >= node.y + node.height ) { return false; } return true; } public setFF(ff: FF) { this.ff = ff; let nodes = this.mSprites.children; nodes.forEach(node => { if (this.checkIn(node.name)) { node.destroy(); } }); if (this.mBgm) { ff.main.playMusicByClip(this.mBgm); } } public checkIn(name: string): boolean { let stage = this.ff.main.player.stage; return stage.element.indexOf(name) >= 0; } /** * 初始化摄像机位置 */ public initCamera() { let winSize = cc.winSize; let targetPos = this.shoot;//摄像机的目标位置 let targetX = targetPos.x - this.midWidth; if (targetX != this.mCamera.node.x) { this.mCamera.node.x = targetX; if (this.mCamera.node.x < 0) { this.mCamera.node.x = 0; } if (this.mCamera.node.x > this.node.width - winSize.width) { this.mCamera.node.x = this.node.width - winSize.width; } } let targetY = targetPos.y - this.midHeidht; if (targetY != this.mCamera.node.y) { this.mCamera.node.y = targetY; if (this.mCamera.node.y < 0) { this.mCamera.node.y = 0; } if (this.mCamera.node.y > this.node.height - winSize.height) { this.mCamera.node.y = this.node.height - winSize.height; } } if (this.mGuide) { this.mGuide.ff = this.ff; this.mGuide.run(); } } private pauseFF() { this.ff.mainSprite.setPause(true); cc.tween(this).sequence( cc.delayTime(0.6), cc.callFunc(() => { this.ff.mainSprite.setPause(false); }) ).start() } lateUpdate(dt) { this.spriteOrder(); this.ff.mMu.x = this.mCamera.node.x + this.midWidth this.ff.mMu.y = this.mCamera.node.y + this.midHeidht if (!this.ff.lockCamera) { return; } let room = this.getRoom(); if (!room) { return; } if (this.curRoom != room) { if (this.curRoom != null) { this.pauseFF(); } this.curRoom = room; } let winSize = cc.winSize; let targetPos = this.shoot;//摄像机的目标位置 if (room.width > winSize.width) { let targetX = targetPos.x - this.midWidth; let sideWidth = room.x + room.width - winSize.width; if (targetX < room.x) { targetX = room.x } else if (targetX > sideWidth) { targetX = sideWidth } if (targetX != this.mCamera.node.x) { let offsetx = targetX - this.mCamera.node.x; if (offsetx >= -5 && offsetx <= 5) { this.mCamera.node.x = targetX; } else { let dx = offsetx / 10; if (Math.abs(dx) < 5) { if (dx > 0) { dx = 5; } else { dx = -5; } } dx = dx * (1 + dt) this.mCamera.node.x += dx; } } } else { let targetX = room.x - this.midWidth; if (targetX < room.x) { targetX = room.x } if (targetX != this.mCamera.node.x) { let offsetx = targetX - this.mCamera.node.x; if (offsetx >= -5 && offsetx <= 5) { this.mCamera.node.x = targetX; } else { let dx = offsetx / 10; if (Math.abs(dx) < 5) { if (dx > 0) { dx = 5; } else { dx = -5; } } dx = dx * (1 + dt) this.mCamera.node.x += dx; } } } if (room.height > winSize.height) { let targetY = targetPos.y - this.midHeidht; let sideHeight = room.y + room.height - winSize.height; if (targetY < room.y) { targetY = room.y } else if (targetY > sideHeight) { targetY = sideHeight } if (targetY != this.mCamera.node.y) { let offsety = targetY - this.mCamera.node.y; if (offsety >= -5 && offsety <= 5) { this.mCamera.node.y = targetY; } else { let dy = offsety / 10; if (Math.abs(dy) < 5) { if (dy > 0) { dy = 5; } else { dy = -5; } } dy = dy * (1 + dt) this.mCamera.node.y += dy; } } } else { let targetY = room.y - this.midHeidht; if (targetY < room.y) { targetY = room.y } if (targetY != this.mCamera.node.y) { let offsety = targetY - this.mCamera.node.y; if (offsety >= -5 && offsety <= 5) { this.mCamera.node.y = targetY; } else { let dy = offsety / 10; if (Math.abs(dy) < 5) { if (dy > 0) { dy = 5; } else { dy = -5; } } dy = dy * (1 + dt) this.mCamera.node.y += dy; } } } } /** * 地图上所有精灵显示排序 */ private spriteOrder() { let children = this.mSprites.children; for (let i = 0; i < children.length; i++) { const e = children[i]; if (e.zIndex == 9999 || e.zIndex == -9999) { } else { let zIndex = (cc.macro.MAX_ZINDEX - e.y) / 10; e.zIndex = zIndex; } } } public addSprite(sprite: FSprite) { sprite.ff = this.ff; sprite.map = this; this.mSprites.addChild(sprite.node); } public setCamera(mCamera: cc.Camera) { this.mCamera = mCamera; } public updateShoot(x, y): boolean { if (this.shoot.x == x && this.shoot.y == y) { return false; } this.shoot.x = x; this.shoot.y = y; return true; } public getSprites(): Array { return this.mSprites.children; } /** * 当前摄像机是否停止 */ public cameraStop(): boolean { return false; } /** * 检查当前坐标是否在碰撞区域 * @param x * @param y */ public checkCollision(x, y) { let size = this.mColliderTiled.getLayerSize(); let dx = x / 64 let dy = size.height - y / 64 if (dy > size.height) { dy = size.height - 1 } let t = this.mColliderTiled.getTileGIDAt(dx, dy); return t > 0 } }