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 } }