import Config from "./Config"; import LineLogic from "./LineLogic"; import Model from "./Model"; import MetaballMgr from "./MetaballMgr"; import Ball from "./Ball"; import TipLine from "./TipLine"; import {TrackingManager, TrackingType} from "./Tracking/TrackingManager"; const { ccclass, property } = cc._decorator; @ccclass export default class GameDraw extends cc.Component { @property(cc.Prefab) Ball: cc.Prefab = null; @property(cc.Prefab) TopUI: cc.Prefab = null; @property(cc.Prefab) BottomUI: cc.Prefab = null; @property(cc.Prefab) Cup: cc.Prefab = null; @property(cc.Prefab) Line: cc.Prefab = null; @property(cc.Node) metaBall: cc.Node = null; lock: boolean = false; @property(cc.Node) waterPipe: cc.Node = null; @property(cc.Node) progressNode: cc.Node = null; @property(cc.Node) waterContainer: cc.Node = null; @property(cc.Prefab) SmokeEff: cc.Prefab = null; @property({type:cc.AudioClip}) winClip: cc.AudioClip = null; @property({type:cc.AudioClip}) waterClip: cc.AudioClip = null; currentLine: cc.Node cup: cc.Node @property([cc.Prefab]) allObjs: cc.Prefab[] = [] totalInk = 40; totalWater = 50 waterCount = 0 waters: any = [] faceChange: boolean = false; linePosY: number = 0; //记录动态的物体,画线后才变动态,之前为静态 dynamicObjs = [] redObjs = [] //在水杯中的水滴数量 cupInWaterObj: any = {}; cupWater: number = 0; @property(cc.Node) tip: cc.Node = null; colliderPoints: cc.Vec2[]; //已经绘制的长度,由于可以绘制多条 hasDrawLen: number = 0 onLoad() { Config.init() Model.game.selectedModel = 4 //开启物理效果 cc.director.getPhysicsManager().enabled = true cc.director.getPhysicsManager().gravity = new cc.Vec2(0, -1200); cc.director.getActionManager()['enabledAccumulator'] = true; cc.director.getActionManager()['FIXED_TIME_STEP'] = 1 / 30; cc.director.getPhysicsManager()['VELOCITY_ITERATIONS'] = 8; // cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_jointBit | cc.PhysicsManager.DrawBits.e_shapeBit; this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this); this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this); this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this); var size = cc.view.getVisibleSize(); if (size.height / size.width > 2) { this.progressNode.getComponent(cc.Widget).top = 200 } else { this.progressNode.getComponent(cc.Widget).top = 145 } this.createWorld() var top = cc.instantiate(this.TopUI) this.node.addChild(top) this.metaBall.getComponent(MetaballMgr).waters = this.waters; var bottom = cc.instantiate(this.BottomUI) this.node.addChild(bottom); bottom.on('showTip', this.showTip, this); //开启抗锯齿 // cc.macro.ENABLE_WEBGL_ANTIALIAS=true; this.progressNode.zIndex = 100 this.tip.zIndex = 100 this.node.getChildByName('gameTip').active = Model.game.selectedLevel == 1 } createWorld() { //createCup var level = Model.game.selectedLevel; var data = Config.drawLevels[level]; var cupPos = data[0] var cup = cc.instantiate(this.Cup); cup.getComponent(cc.RigidBody).type = cc.RigidBodyType.Static; cup.x = cupPos[0] cup.y = cupPos[1] this.waterContainer.addChild(cup) this.cup = cup; if (cupPos.length > 2) { cup.angle = -cupPos[2] } var cupData = Config.cupDatas[1] // for (var i = 0; i < cupData.polygonColliderList.length; i++) { // var collider = cup.addComponent(cc.PhysicsPolygonCollider) // collider.points = cupData.polygonColliderList[i] // collider.density = 10 // collider.apply() // } cup.getComponent(cc.RigidBody).enabledContactListener = true cup.getComponent(cc.RigidBody).onBeginContact = (contact, selfCollider, otherCollider) => { this.onBeginContact(contact, selfCollider, otherCollider) } this.linePosY = cupData.linePosY + cup.y; //添加一个传感器用于检测水杯中的水滴 var collider = this.cup.addComponent(cc.PhysicsPolygonCollider); this.colliderPoints = [cc.v2(-43, -82), cc.v2(43, -82), cc.v2(72, 70), cc.v2(-69, 70)] collider.points = this.colliderPoints collider.sensor = true collider.apply() //水龙头 var pipeInfo = data[1] this.waterPipe.x = pipeInfo[0] this.waterPipe.y = pipeInfo[1] this.waterPipe.angle = -pipeInfo[2] this.totalInk = data[3] this.totalWater = data[4] //平台 for (var i = 5; i < data.length; i++) { var brickType = data[i][0] var brick = cc.instantiate(this.allObjs[brickType - 1]) brick.x = data[i][1] brick.y = data[i][2] if (brickType == 3 || brickType == 8 || brickType == 11 || brickType == 13)//矩形 { brick.setContentSize(cc.size(data[i][3], data[i][4])) brick.getComponent(cc.PhysicsBoxCollider).size = cc.size(cc.size(data[i][3], data[i][4])) brick.getComponent(cc.PhysicsBoxCollider).apply() //火焰特殊处理 if (brickType == 11) { brick.getComponent(cc.RigidBody).onBeginContact = (contact, selfCollider, otherCollider) => { this.onBeginContact(contact, selfCollider, otherCollider) } } if (brickType == 13) { var size = brick.getComponent(cc.PhysicsBoxCollider).size var points = [cc.v2(brick.x - size.width * 0.5, brick.y - size.height * 0.5), cc.v2(brick.x + size.width * 0.5, brick.y - size.height * 0.5), cc.v2(brick.x + size.width * 0.5, brick.y + size.height * 0.5), cc.v2(brick.x - size.width * 0.5, brick.y + size.height * 0.5)] this.redObjs.push(points) } } else if (brickType == 7 || brickType == 4)//圆 { brick.setContentSize(cc.size(data[i][3], data[i][4])) brick.getComponent(cc.PhysicsCircleCollider).radius = data[i][3] * 0.5 brick.getComponent(cc.PhysicsCircleCollider).apply() } brick.angle = -data[i][5] if (brickType == 13) this.waterContainer.addChild(brick, -1) else this.waterContainer.addChild(brick) if (brick.getComponent(cc.RigidBody) != null) { if (brick.getComponent(cc.RigidBody).type == cc.RigidBodyType.Dynamic) { this.dynamicObjs.push(brick); } brick.getComponent(cc.RigidBody).type = cc.RigidBodyType.Static } if (Model.game.selectedLevel == 32 && brickType == 6)//特殊处理下这个球 { brick.getComponent(cc.PhysicsCircleCollider).density = 0.01 brick.getComponent(cc.PhysicsCircleCollider).apply() } } } start() { //提示 var level = Model.game.selectedLevel; var data = Config.drawLevels[level]; this.tip.getComponent(TipLine).points = data[2] this.tip.active = false; } checkInRed(pos: cc.Vec2) { var size = cc.view.getVisibleSize(); for (var temp of this.redObjs) { if (cc.Intersection.pointInPolygon(cc.v2(pos.x - size.width * 0.5, pos.y - size.height * 0.5), temp)) { console.log('lllllllllllllllllllll') return true } } return false; } canMove: boolean = true; onTouchStart(e) { if (this.lock) return; var pos = e.getLocation(); if (this.checkInRed(pos)) { this.canMove = false; return } else { this.canMove = true; } if (this.currentLine != null) { this.hasDrawLen += this.currentLine.getComponent(LineLogic).points.length } var line = cc.instantiate(this.Line); this.node.addChild(line); this.currentLine = line this.currentLine.getComponent(LineLogic).onTouchStart(e) return true } onTouchMove(e) { if (!this.canMove) return var totalLen = this.currentLine.getComponent(LineLogic).points.length + this.hasDrawLen; if (totalLen <= this.totalInk) { this.currentLine.getComponent(LineLogic).onTouchMove(e) var p = (this.totalInk - totalLen) / this.totalInk; this.progressNode.getComponent(cc.ProgressBar).progress = p; this.progressNode.getChildByName('progress_label').getComponent(cc.Label).string = Math.floor(p * 100) + '%' if (p < 0.8) { this.progressNode.getChildByName('star3').active = false; this.progressNode.getChildByName('stargray3').active = true; } if (p < 0.6) { this.progressNode.getChildByName('star2').active = false; this.progressNode.getChildByName('stargray2').active = true; } if (p < 0.1) { this.progressNode.getChildByName('star1').active = false; this.progressNode.getChildByName('stargray1').active = true; } } } onTouchEnd(e) { if (!this.canMove) return this.currentLine.getComponent(LineLogic).onTouchEnd(e) this.cup.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic; for (var obj of this.dynamicObjs) { obj.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic; } this.startDropWater() } //开始滴水 startDropWater() { console.log('开始创建水') this.schedule(this.createWater, 0.06) } waterSoundDelay = 0.2; waterSoundDelayCount = 10; createWater() { if (this.waterCount < this.totalWater) { this.waterCount++ var ball = cc.instantiate(this.Ball); this.waterSoundDelayCount += 0.06 if (this.waterSoundDelayCount > this.waterSoundDelay) { this.waterSoundDelayCount = 0 cc.audioEngine.playEffect(this.waterClip, false) } // console.log(this.waterPipe.rotation) if (this.waterPipe.angle == 0) { ball.x = this.waterPipe.x + Math.random() * 8 - 16 ball.y = this.waterPipe.y + Math.random() * 5 - 75 ball.getComponent(cc.RigidBody).linearVelocity = cc.v2(0, -0) } else if (this.waterPipe.angle >= 181 && this.waterPipe.angle <= 178) { ball.x = this.waterPipe.x + Math.random() * 8 - 16 ball.y = this.waterPipe.y + Math.random() * 5 + 75 ball.getComponent(cc.RigidBody).linearVelocity = cc.v2(0, 100) } else { var center = this.cup.getComponent(cc.RigidBody).getWorldCenter(); var sign = this.waterPipe.angle < 0 ? -1 : 1 ball.x = this.waterPipe.x + 60 * sign + Math.random() * 8 - 4 ball.y = this.waterPipe.y + Math.random() * 10 - 5 ball.getComponent(cc.RigidBody).linearVelocity = cc.v2(sign * 150, 0) // ball.getComponent(cc.RigidBody).applyLinearImpulse(cc.v2(200000,200000), cc.v2(center.x, center.y), true); // ball.getComponent(cc.RigidBody).applyForce(cc.v2(1000,0),center,true) } ball.getComponent(Ball).id = this.waterCount ball.getComponent(cc.PhysicsCircleCollider).density = 1 ball.getComponent(cc.PhysicsCircleCollider).restitution = 0.2 ball.getComponent(cc.PhysicsCircleCollider).apply() this.waterContainer.addChild(ball, -1) this.waters.push(ball); } else { this.unschedule(this.createWater) this.schedule(this.checkGame, 0.1) } } showFace(type: number) { this.cup.getChildByName('facenormal').active = false; this.cup.getChildByName('facewin').active = false; this.cup.getChildByName('facelose').active = false; if (type == 2) { this.cup.getChildByName('facewin').active = true; } else if (type == 1) { this.cup.getChildByName('facelose').active = true; } else if (type == 0) { this.cup.getChildByName('facenormal').active = true; } } update(dt) { if (this.waterCount > 0) { this.metaBall.getComponent(MetaballMgr).draw() for (var i = 0; i < this.waters.length; i++) { if (this.waters[i].y < -1000) { this.waters.splice(i, 1) i-- } } } } checkGame() { if (this.lock) return //检测胜利 if (this.waters.length >= 39) { var newRect = [] for (var a of this.colliderPoints) { newRect.push(cc.v2(this.cup.x + a.x, a.y + this.cup.y)) } var count = 0 for (var temp of this.waters) { if (cc.Intersection.pointInPolygon(temp.position, newRect)) { count++; } } //console.log(count); if (count >= 39) { this.gameWin(); } } //失败检测 this.checkLose(); } checkLose() { if (this.waters.length <= 15) { this.gameLose() return; } var allSleep: boolean = true for (var ball of this.waters) { if (ball.getComponent(cc.RigidBody).awake) { allSleep = false break } } if (allSleep) { this.gameLose() } } gameWin() { if (this.lock) return this.unscheduleAllCallbacks() this.lock = true Model.game.win = true this.showFace(2) this.scheduleOnce(this.delayShowEnd, 1) cc.audioEngine.playEffect(this.winClip, false) this.saveData(); } gameLose() { if (this.lock) return this.unscheduleAllCallbacks() this.lock = true Model.game.win = false this.showFace(1) this.scheduleOnce(this.delayShowEnd, 1) } delayShowEnd() { cc.director.loadScene('gameEnd') } showTip() { console.log('显示提示') this.tip.active = true TrackingManager.send(TrackingType.Tip); } onBeginContact(contact, selfCollider, otherCollider) { // console.log(selfCollider.node.name, otherCollider.node.name) if ((selfCollider instanceof cc.PhysicsBoxCollider) && selfCollider.node.name == 'Cup3' && otherCollider.node.name == 'Ball') { //selfCollider.getAABB() // if (this.cupInWaterObj[otherCollider.node.getComponent(Ball).id] == null) { // this.cupInWaterObj[otherCollider.node.getComponent(Ball).id] = true // this.cupWater++ // // console.log(this.cupWater,'aaaaa') // if (this.cupWater >= 30) { // this.gameWin() // } // } if (!this.faceChange) { this.faceChange = true this.showFace(1); } } //火焰 if (selfCollider.node.name == 'r11' && otherCollider.node.name == 'Ball') { for (var i = 0; i < this.waters.length; i++) { if (this.waters[i] == otherCollider.node) { this.waters.splice(i, 1) i-- this.createSmokeEff(otherCollider.node.x, otherCollider.node.y) otherCollider.node.destroy() break; } } } } saveData() { var star = 0; if (this.progressNode.getChildByName('star1').active) star++ if (this.progressNode.getChildByName('star2').active) star++ if (this.progressNode.getChildByName('star3').active) star++ Model.game.getStar = star; //存储 if (Model.game.selectedLevel == Model.game.drawLevel) { Model.game.drawLevelInfo[Model.game.selectedLevel - 1] = star Model.game.drawLevelInfo[Model.game.selectedLevel] = -1 Model.game.drawLevel = Model.game.selectedLevel + 1; Model.game.saveDraw() } else { if (star > Model.game.drawLevelInfo[Model.game.selectedLevel - 1]) { Model.game.drawLevelInfo[Model.game.selectedLevel - 1] = star Model.game.saveDraw(); } // Model.game.selectedLevel++ } } createSmokeEff(x, y) { var eff = cc.instantiate(this.SmokeEff); eff.x = x; eff.y = y; this.node.addChild(eff); } checkFace() { } }