games/Legend-of-the-Water-Cup/assets/scripts/GameDraw.ts

528 lines
17 KiB
TypeScript

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() {
}
}