/** * Created by juho on 2016-03-28. */ import * as PIXI from './pixi'; import pixi_spine from './pixi-spine' import GD from './human.min' import { TimelineLite, Sine, TweenMax, Power0 } from './TweenMax.min' import bm from './ButtonManager'; import em from './EffectManager'; import TextStyle from './TextStyle' import { pixelRatioX, pixelRatioY, windowWidth, windowHeight } from './fitConfig'; var gWidth = windowWidth * pixelRatioX var gHeight = windowHeight * pixelRatioY var GraphicManager = (function () { function GraphicManager() { } GraphicManager.drawRect = function (w, h, col) { var g = new PIXI.Graphics(); (!col) ? g.beginFill(0X00FF00, 1) : g.beginFill(col, 1); g.drawRect(0, 0, w, h); g.endFill(); return g; }; GraphicManager.drawCircle = function (r, col) { var g = new PIXI.Graphics(); (!col) ? g.beginFill(0X00FF00, 1) : g.beginFill(col, 1); g.drawCircle(0, 0, r); g.endFill(); return g; }; return GraphicManager; }()); var gc = { isDebug: true, loader: null, stats: null, width: gWidth, height: gHeight, IS_MOBILE: true, onBgm: true, onFx: true, pauseGame: false, stage: null, soundPopup: null, intro: null, tutorial: null, game: null, chapter: 1,//게임 챕터.. 1:카드랜드 2:버섯랜드 3:장미랜드 4:모자랜드 5:나무랜드 bShare: false, showVd: false, recoveryTimes: 1 }; /** * Created by admin on 2018-06-07. */ gc.PopupSound = function () { PIXI.Container.call(this); this.bgBlack = GraphicManager.drawRect(gc.width, gc.height, "0X000000"); this.bgBlack.alpha = 0.7; this.bg = new PIXI.Sprite.fromFrame("popup_bg_sound1.png"); this.bg.anchor.set(0.5); this.btnClose = new PIXI.Sprite.fromFrame("popup_btn_close.png"); this.btnClose.anchor.set(0.5); bm.buttonEvent(this.btnClose, true, null, null, this.closeSoundPopup.bind(this)); this.btnBgm = new PIXI.Sprite.fromFrame("popup_btn_sound1_off.png"); this.btnBgm.anchor.set(0.5); bm.buttonEvent(this.btnBgm, true, null, null, this.setBgm.bind(this)); this.btnFx = new PIXI.Sprite.fromFrame("popup_btn_sound2_off.png"); this.btnFx.anchor.set(0.5); bm.buttonEvent(this.btnFx, true, null, null, this.setFx.bind(this)); this.btnRestart = new PIXI.Sprite.fromFrame("popup_btn_restart.png"); this.btnRestart.anchor.set(0.5); bm.buttonEvent(this.btnRestart, true, null, null, (function () { // restartGame(); this.setInteractive(false); GD.stage.removeChild(this); onGame(); }).bind(this)); }; gc.PopupSound.constructor = gc.PopupSound; gc.PopupSound.prototype = Object.create(PIXI.Container.prototype); gc.PopupSound.prototype.onSoundPopup = function () { this.reset(); this.setBgImg(); this.setButtonImage(); this.setPosition(); this.bg.addChild(this.btnBgm); this.bg.addChild(this.btnFx); this.bg.addChild(this.btnClose); this.addChild(this.bgBlack); this.addChild(this.bg); if (gc.game) { this.bg.addChild(this.btnRestart); gc.game.pause(); } var time = 0.1; TweenMax.fromTo(this.bg.scale, time, { x: 0, y: 0 }, { x: 1.05, y: 1.05, onComplete: (function () { TweenMax.to(this.bg.scale, time / 2, { x: 1, y: 1, onComplete: (function () { this.bg.scale.x = 1; this.bg.scale.y = 1; this.setInteractive(true); }).bind(this) }); }).bind(this) }); GD.stage.addChild(this); }; gc.PopupSound.prototype.closeSoundPopup = function () { gc.pauseGame = false; var time = 0.1; this.bg.scale.x = 1; this.bg.scale.y = 1; TweenMax.to(this.bg.scale, time, { x: 1.1, y: 1.1, onComplete: (function () { TweenMax.to(this.bg.scale, time / 2, { x: 0, y: 0, onComplete: (function () { GD.stage.removeChild(this); if (gc.intro) { gc.intro.setInteractive(true); } else if (gc.game) { gc.game.resume(); } }).bind(this) }); }).bind(this) }); }; //배경 이미지 gc.PopupSound.prototype.setBgImg = function () { if (gc.intro) this.bg.texture = PIXI.Texture.fromFrame("popup_bg_sound2.png"); else if (gc.game) this.bg.texture = PIXI.Texture.fromFrame("popup_bg_sound1.png"); this.bg.scale.x = 1; this.bg.scale.y = 1; }; //버튼 이미지 활성화 설정 gc.PopupSound.prototype.setButtonImage = function () { if (gc.onBgm) this.btnBgm.texture = PIXI.Texture.fromFrame("popup_btn_sound1_on.png"); else this.btnBgm.texture = PIXI.Texture.fromFrame("popup_btn_sound1_off.png"); if (gc.onFx) this.btnFx.texture = PIXI.Texture.fromFrame("popup_btn_sound2_on.png"); else this.btnFx.texture = PIXI.Texture.fromFrame("popup_btn_sound2_off.png"); }; //좌표 설정 gc.PopupSound.prototype.setPosition = function () { this.bg.x = gc.width / 2; this.bg.y = gc.height / 2; var gap = 60; this.btnClose.x = this.bg.width / 2 - 50; this.btnClose.y = -this.bg.height / 2 + gap; if (gc.intro) { gap = this.btnBgm.height + 40; this.btnBgm.y = -this.bg.height / 2 + 190; this.btnFx.y = this.btnBgm.y + gap; this.btnRestart.y = this.btnFx.y + gap; } else if (gc.game) { gap = this.btnBgm.height + 10; this.btnBgm.y = -this.bg.height / 2 + 185; this.btnFx.y = this.btnBgm.y + gap; gap += 30; this.btnRestart.y = this.btnFx.y + gap; } this.btnBgm.x = 0; this.btnFx.x = this.btnBgm.x; this.btnRestart.x = this.btnBgm.x; }; //배경음 설정 gc.PopupSound.prototype.setBgm = function () { gc.onBgm = !gc.onBgm; console.log("gc.onBgm", gc.onBgm); // if(!gc.onBgm) GD.soundMute("sound_bgm_mini"); // else GD.soundUnMute("sound_bgm_mini"); if (gc.game) { if (!gc.onBgm) GD.soundStop("sound_bgm_mini"); else GD.soundPlay("sound_bgm_mini"); } this.setButtonImage(); }; //효과음 설정 gc.PopupSound.prototype.setFx = function () { gc.onFx = !gc.onFx; console.log("gc.onFx", gc.onFx); this.setButtonImage(); }; gc.PopupSound.prototype.setInteractive = function (bool) { this.btnClose.interactive = bool; this.btnBgm.interactive = bool; this.btnFx.interactive = bool; this.btnRestart.interactive = bool; }; gc.PopupSound.prototype.reset = function () { this.removeChildren(); this.bg.removeChildren(); }; gc.PopupSound.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /**Intro */ /** * Created by admin on 2018-04-05. */ gc.Intro = function () { PIXI.Container.call(this); this.bg = new PIXI.Sprite.fromFrame("intro_bg.png"); this.btnStart = new PIXI.Sprite.fromFrame("intro_btn_start.png"); this.btnTuto = new PIXI.Sprite.fromFrame("intro_btn_tutorial.png"); this.btnSound = new PIXI.Sprite.fromFrame("intro_btn_sound.png"); }; gc.Intro.constructor = gc.Intro; gc.Intro.prototype = Object.create(PIXI.Container.prototype); //인트로 init gc.Intro.prototype.init = function () { this.updateTransform(); this.btnStart.anchor.set(0.5); this.btnStart.x = this.bg.width / 2; this.btnStart.y = this.bg.height - 140; bm.buttonEvent(this.btnStart, true, null, null, onGame); var gap = 260; this.btnTuto.anchor.set(0.5); this.btnTuto.x = this.btnStart.x - gap; this.btnTuto.y = this.btnStart.y; bm.buttonEvent(this.btnTuto, true, null, null, null);//튜토리얼 열기 this.btnSound.anchor.set(0.5); this.btnSound.x = this.btnStart.x + gap; this.btnSound.y = this.btnStart.y; bm.buttonEvent(this.btnSound, true, null, null, (function () { this.setInteractive(false); console.log(gc.soundPopup) gc.soundPopup.onSoundPopup(); }).bind(this)); this.bg.addChild(this.btnStart); // this.bg.addChild(this.btnTuto); this.bg.addChild(this.btnSound); this.addChild(this.bg); this.setInteractive(true); }; //터치 이벤트 활성화 gc.Intro.prototype.setInteractive = function (bool) { this.btnStart.interactive = bool; this.btnTuto.interactive = bool; this.btnSound.interactive = bool; }; //인트로 초기화 gc.Intro.prototype.reset = function () { this.setInteractive(false); this.bg.removeChildren(); this.removeChildren(); }; gc.Intro.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /** * Created by admin on 2018-06-07. */ gc.Menu = function (options) { PIXI.Container.call(this); this.options = options; this.bgBlack = GraphicManager.drawRect(gc.width, gc.height, "0X000000"); this.bgBlack.alpha = 0.7; this.bg = new PIXI.Sprite.fromFrame("popup_help_me.png"); this.bg.anchor.set(0.5); this.shareText = new PIXI.Text('分享游戏即可复活哦') this.shareText.anchor.set(.5); this.adText = new PIXI.Text('观看广告后即可复活哦') this.adText.anchor.set(.5); this.btnClose = new PIXI.Sprite.fromFrame("popup_btn_close.png"); this.btnClose.anchor.set(0.5); bm.buttonEvent(this.btnClose, true, null, null, (function () { this.closeMenuPopup(function () { gameEnd() }) }).bind(this)); this.btnShare = new PIXI.Sprite.fromFrame("popup_share_btn.png"); this.btnShare.anchor.set(0.5); bm.buttonEvent(this.btnShare, true, null, null, this.setShare.bind(this)); this.btnAd = new PIXI.Sprite.fromFrame("popup_ad_btn.png"); this.btnAd.anchor.set(0.5); bm.buttonEvent(this.btnAd, true, null, null, this.setAd.bind(this)); this.btnRestart = new PIXI.Sprite.fromFrame("popup_menu_refuse.png"); this.btnRestart.anchor.set(0.5); bm.buttonEvent(this.btnRestart, true, null, null, (function () { this.setInteractive(false); this.closeMenuPopup(function () { gameEnd(); GD.objSdk.showAdIcon(0, 0); }); }).bind(this)); this.init(); }; gc.Menu.constructor = gc.Menu; gc.Menu.prototype = Object.create(PIXI.Container.prototype); gc.Menu.prototype.init = function () { this.setPosition() this.bg.addChild(this.shareText); this.bg.addChild(this.adText); this.bg.addChild(this.btnShare); this.bg.addChild(this.btnAd); this.bg.addChild(this.btnClose); this.bg.addChild(this.btnRestart); this.addChild(this.bgBlack); this.addChild(this.bg); this.visible = false; GD.stage.addChild(this); } //좌표 설정 gc.Menu.prototype.setPosition = function () { this.bg.x = gc.width / 2; this.bg.y = gc.height / 2; var gap = 60; this.btnClose.x = this.bg.width / 2 - 50; this.btnClose.y = -this.bg.height / 2 + gap; this.shareText.position.y = -this.bg.height / 2 + 200 this.shareText.style = { fontSize: 36, wordWrap: true, align: 'center' }; this.adText.position.y = -this.bg.height / 2 + 200 this.adText.style = { fontSize: 36, wordWrap: true, align: 'center' }; gap = this.btnShare.height + 10; this.btnShare.y = this.btnAd.y = this.shareText.position.y + 100; gap += 30; this.btnRestart.y = this.btnShare.y + gap; this.btnShare.x = this.btnAd.x = 0; this.btnRestart.x = this.btnShare.x; }; gc.Menu.prototype.onMenuPopup = function (type) { if (type == 'ad') { this.shareText.visible = false; this.adText.visible = true; this.btnShare.visible = false; this.btnAd.visible = true; } else { this.shareText.visible = true; this.adText.visible = false; this.btnShare.visible = true; this.btnAd.visible = false; } this.visible = true; var time = 0.1; TweenMax.fromTo(this.bg.scale, time, { x: 0, y: 0 }, { x: 1.05, y: 1.05, onComplete: (function () { TweenMax.to(this.bg.scale, time / 2, { x: 1, y: 1, onComplete: (function () { this.bg.scale.x = 1; this.bg.scale.y = 1; this.setInteractive(true); }).bind(this) }); }).bind(this) }); }; gc.Menu.prototype.closeMenuPopup = function (callback) { var time = 0.1; this.bg.scale.x = 1; this.bg.scale.y = 1; TweenMax.to(this.bg.scale, time, { x: 1.1, y: 1.1, onComplete: (function () { TweenMax.to(this.bg.scale, time / 2, { x: 0, y: 0, onComplete: (function () { this.visible = false; callback && callback(); }).bind(this) }); }).bind(this) }); }; //효과음 설정 gc.Menu.prototype.setShare = function () { wx.shareAppMessage({ title: "聪明人都在玩的游戏,快来挑战一下!", imageUrl: "https://pub.dwstatic.com/wxgame/jumpgame/jumpgame_stair/image/json/intro/shareImage.jpg", query: "" }) let showCb = res => { console.log('share 完成') if (gc.onBgm) GD.bgmPlay(0.8); this.closeMenuPopup(function () { gc.game.recovery(); }) wx.offShow(showCb) } wx.onShow(showCb); }; //효과음 설정 gc.Menu.prototype.setAd = function () { console.log('点击了观看广告'); let videoAd = wx.createRewardedVideoAd({ adUnitId: 'adunit-0e83e19c26a8d8fc' }) this.closeMenuPopup(); videoAd.load() .then(() => { GD.bgmStop(); videoAd.show() }) .catch(err => { console.log(err) gameEnd(); }) videoAd.onClose(res => { if (res && res.isEnded || res === undefined) { if (gc.onBgm) GD.bgmPlay(0.8); gc.game.recovery(); } else { gameEnd() } }) }; gc.Menu.prototype.setInteractive = function (bool) { this.btnClose.interactive = bool; this.btnShare.interactive = bool; this.btnAd.interactive = bool; this.btnRestart.interactive = bool; }; gc.Menu.prototype.reset = function () { this.removeChildren(); this.bg.removeChildren(); }; gc.Menu.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /**GameScene */ /** * Created by admin on 2018-04-05. */ gc.GameScene = function () { PIXI.Container.call(this); this.touchBg = new PIXI.Sprite.fromFrame("bg1.png");//터치 감지 배경 this.bg = [new PIXI.Sprite.fromFrame("bg1.png"), new PIXI.Sprite.fromFrame("bg1.png")]; this.bgWall = [new PIXI.Sprite.fromFrame("bg1_1.png"), new PIXI.Sprite.fromFrame("bg1_1.png"), new PIXI.Sprite.fromFrame("bg1_2.png"), new PIXI.Sprite.fromFrame("bg1_2.png")]; this.soundBtn = new PIXI.Sprite.fromFrame("bt_sound_off.png"); this.scoreText = new gc.NumberText("c_score", 'center', -4); this.addScoreText = new PIXI.Text("", TextStyle.makeStyle({ size: 50, fontWeight: 'bold' }));//추가점수 텍스트 gc.somi = new gc.Somi(); gc.menu = new gc.Menu(); this.obstacle = new gc.Obstacle(); gc.resultView = new gc.ResultView(); gc.resultView.on("GOTO_MAINPAGE", onIntro); this.bgContainer = new PIXI.Container(); this.blackoutContainer = this.obstacle.initBlackoutContainer();//장애물 컨테이너 this.birdContainer = this.obstacle.initBirdContainer();//장애물 컨테이너 this.midContainer = new PIXI.Container();//발판, 블랙아웃, 새, 플레이어 ㅓㄴ테이너 설정 this.playerContainer = new PIXI.Container(); this.uiContainer = new PIXI.Container(); this.combo = 0; //충전 사운드 점점 크게 GD.sound['sound_gauge'].on('end', (function () { if (this.myCha.status == "readyJump") { if (this.chargeVolume < 1) this.chargeVolume += 0.1; if (gc.onFx) GD.soundPlay("sound_gauge", this.chargeVolume); } }).bind(this)); this.loadConfig(); gc.recoveryTimes = 1; console.log('set onshow') wx.onShow(res => { if (gc.onBgm) GD.bgmPlay(0.8); }) }; gc.GameScene.constructor = gc.GameScene; gc.GameScene.prototype = Object.create(PIXI.Container.prototype); gc.GameScene.prototype.loadConfig = function () { let loader = new PIXI.loaders.Loader(); loader.add('shareConfig', 'https://pub.dwstatic.com/wxgame/jumpgame/share.json?_=' + (new Date).getTime()) loader.load((loader, resources) => { console.log(resources) if (resources.shareConfig) { gc.showVd = resources.shareConfig.data.showVd; gc.bShare = resources.shareConfig.data.bShare; } }) } //스파인 리스너 gc.GameScene.prototype.setSpineListener = function (obj) { obj.state.addListener({ complete: (function (t) { if (t.animation.name == "scoreEf") { this.removeSpineListener(obj); removeObject(obj); var time = 0.3; TweenMax.to(this.scoreNumContainer, time, { ease: Power0.easeNone, y: this.scoreText.y }); TweenMax.to(this.scoreNumContainer.scale, time, { ease: Power0.easeNone, x: 1, y: 1, onComplete: (function () { removeObject(this.scoreNumContainer); this.scoreText.alpha = 1; }).bind(this) }); } }).bind(this) }); }; gc.GameScene.prototype.removeSpineListener = function (obj) { obj.state.removeListener(); }; gc.GameScene.prototype.setGameBgImage = function () { var bgNames = ['bg1', "bg2", "bg2", "bg2", "bg2"]; var i; for (i = 0; i < this.bg.length; i++) { this.bg[i].texture = PIXI.Texture.fromFrame(bgNames[gc.chapter - 1] + '.png'); } for (i = 0; i < this.bgWall.length; i++) { if (gc.chapter == 1) this.bgWall[i].visible = true; else this.bgWall[i].visible = false; } this.bg[0].y = 0; this.bg[1].y = this.bg[0].y - this.bg[1].height; this.bgWall[0].x = -this.bgWall[0].width / 3; this.bgWall[1].x = this.bgWall[0].x; this.bgWall[1].y = this.bgWall[0].y - (this.bgWall[1].height + 1000); this.bgWall[2].x = gc.width - this.bgWall[2].width / 3; this.bgWall[2].y = gc.height / 2; this.bgWall[3].x = this.bgWall[2].x; this.bgWall[3].y = this.bgWall[2].y - (this.bgWall[3].height + 1000); }; gc.GameScene.prototype.init = function () { this.reset(); this.setGameBgImage();//배경 이미지 설정 //사운드 버튼.. 임시로 좌표만 this.soundBtn.anchor.set(0.5); this.soundBtn.x = gc.width - 60; this.soundBtn.y = 120; bm.buttonEvent(this.soundBtn, true, this.clickSoundBtn.bind(this)); this.soundBtn.interactive = true; //소미 생성 this.somi = gc.somi.init(); //점수 획득 이펙트 this.addScoreText.anchor.set(0.5); //점수 부착 this.addScore(); this.touchBg.alpha = 0; bm.buttonEvent(this.touchBg, false, this.touchStart.bind(this), null, this.touchEnd.bind(this)); //진행률 if (!gc.progress) gc.progress = new gc.Progress(); gc.progress.setEndStep(gc.chapter); gc.progress.resetNowStep(); this.progressContainer = gc.progress.init(); this.offUI(); //다음 맵 정보 if (!gc.maps) gc.maps = new gc.Map(); gc.maps.init(); // gc.maps.reset(); gc.maps.initFootHolds(this.startStep, 1, 'basic');//최초 유저가 서있을 발판 만들기 //중력(점프) 설정 if (!gc.gravity) gc.gravity = new gc.Gravity(); gc.gravity.reset(); //유저 캐릭터 설정 this.initMyCha(); //점프 파워 충전 이펙트 this.effectFoot = new PIXI.spine.Spine(GD.loader.resources["ef1"].spineData); this.effectHead = new PIXI.spine.Spine(GD.loader.resources["ef2"].spineData); this.bgContainer.addChild(this.bg[0]); this.bgContainer.addChild(this.bg[1]); this.bgContainer.addChild(this.bgWall[0]); this.bgContainer.addChild(this.bgWall[1]); this.bgContainer.addChild(this.bgWall[2]); this.bgContainer.addChild(this.bgWall[3]); this.playerContainer.addChild(this.myCha.img); this.uiContainer.addChild(this.scoreText); this.uiContainer.addChild(this.soundBtn); this.uiContainer.addChild(this.progressContainer); this.uiContainer.addChild(this.somi); this.addChild(this.touchBg); this.addChild(this.bgContainer); this.addChild(this.uiContainer); this.addChild(this.midContainer); this.addChild(gc.menu) em.floatByY(this.somi, 0.5, 20, 2, gc.somi.disappearSomi.bind(gc.somi)); }; gc.GameScene.prototype.recovery = function () { this.playerContainer.removeChild(this.myCha.img); gc.maps.firstFh = false; gc.gravity.resetPow(); gc.maps.setNowFootHoldPos(); this.oldMyCha = this.myCha; this.myCha = null; this.initMyCha(); this.setInteractive(true); this.setMidContainer(0) setTimeout(() => { this.playerContainer.addChild(this.myCha.img) }); gc.recoveryTimes--; } //UI화면 보이기 gc.GameScene.prototype.onUI = function () { this.scoreText.x = gc.width / 2; this.scoreText.y = 110; this.progressContainer.x = gc.width * 0.5 - gc.progress.progressbar.width * 0.5; this.progressContainer.y = 250; TweenMax.from(this.scoreText, 0.5, { y: this.scoreText.y - 500 }); TweenMax.from(this.progressContainer, 0.5, { y: this.progressContainer.y - 500 }); }; //UI화면 안보이게하기 gc.GameScene.prototype.offUI = function () { this.scoreText.x = gc.width / 2; this.scoreText.y = -110; this.progressContainer.x = gc.width * 0.5 - gc.progress.progressbar.width * 0.5; this.progressContainer.y = -250; }; //배경 스크롤, 좌표 설정 gc.GameScene.prototype.scrollBackground = function (moveTime, dist) { var i; var runtime = 0; var ticker = new PIXI.ticker.Ticker(); ticker.stop(); ticker.add((function (deltaTime) { runtime += deltaTime; for (i = 0; i < this.bg.length; i++) { if (this.bg[i].y >= gc.height) { if (i == 0) this.bg[i].y = this.bg[1].y - this.bg[i].height; else this.bg[i].y = this.bg[0].y - this.bg[i].height; } this.bg[i].y += dist / (35 * 3); } if (runtime >= moveTime * 50) { ticker.stop(); ticker.remove(); } }).bind(this)); ticker.start(); for (i = 0; i < this.bgWall.length; i++) { TweenMax.to(this.bgWall[i], moveTime, { y: this.bgWall[i].y + parseInt(dist), onComplete: (function (i) { if (this.bgWall[i].y >= gc.height) { if (i % 2 == 0) this.bgWall[i].y = this.bgWall[i + 1].y - (this.bgWall[i].height + 1000); else this.bgWall[i].y = this.bgWall[i - 1].y - (this.bgWall[i].height + 1000); } }).bind(this, i) }); } }; //발판, 장애물, 유저 레이어 순서 설정 gc.GameScene.prototype.setMidContainer = function (type) {//type0: 기본, 암전 1:유저가 가장 아래 2:발판사이에 유저 // return; var i; var mapConList = []; //발판 컨테이너 스텝 별 내림차순 정렬(점점 작아지게) mapConList = gc.maps.mapContainers.sort(function (a, b) { return b.step - a.step; }); if (type == 0) {//기본, 암전 for (i = 0; i < mapConList.length; i++) { this.midContainer.addChild(mapConList[i].center); } this.midContainer.addChild(this.blackoutContainer); this.blackoutContainer.addChild(this.birdContainer); this.midContainer.addChild(this.playerContainer); } else if (type == 1) {//유저가 가장 아래 this.midContainer.addChild(this.playerContainer); for (i = 0; i < mapConList.length; i++) { this.midContainer.addChild(mapConList[i].center); } this.midContainer.addChild(this.blackoutContainer); this.blackoutContainer.addChild(this.birdContainer); } else { for (i = 0; i < mapConList.length; i++) { //발판을 내림차순으로 정렬했기 때문에 유저를 먼저 붙인 후 발판을 붙임 if (mapConList[i].step == this.myCha.step) this.midContainer.addChild(this.playerContainer); this.midContainer.addChild(mapConList[i].center); } this.midContainer.addChild(this.blackoutContainer); this.blackoutContainer.addChild(this.birdContainer); } }; //추가될 점수 계산 gc.GameScene.prototype.setAddScore = function (result) { var score = 1; if (result == "perfect") { if (this.combo < 9) this.combo++; } else this.combo = 0; score += this.combo; return score; }; //점수 추가 gc.GameScene.prototype.addScore = function (addScore) { var prescore = this.score;//점수 강조 이펙트 체크를 위함 if (addScore) { this.score += addScore; gc.progress.addStep();//진행바 스텝 증가 this.checkScoreEffect(prescore);//점수 강조 체크 //점수 획득 이펙트 if (this.scoreEf) this.scoreEf.kill(); this.scoreEf = null; this.addScoreText.text = "+" + addScore; this.addScoreText.alpha = 1; this.addScoreText.x = this.myCha.img.x; this.addScoreText.y = this.myCha.img.y; this.scoreEf = TweenMax.to(this.addScoreText, 2, { y: this.myCha.img.y - 70, alpha: 0, onComplete: (function () { removeObject(this.addScoreText); }).bind(this) }); this.uiContainer.addChild(this.addScoreText); } this.scoreText.setValue(this.score); if (this.mainScoreEfNum) this.mainScoreEfNum.setValue(this.score); }; //스테이지 완료 점수 추가 gc.GameScene.prototype.addChapterClearScore = function () { var addscore = 0; if (gc.chapter == 1) addscore = 400; else if (gc.chapter == 2) addscore = 500; else if (gc.chapter == 3 || gc.chapter == 4 || gc.chapter == 5) addscore = 600; this.score += addscore; this.scoreText.text = this.score; }; //유저 캐릭터 생성 gc.GameScene.prototype.initMyCha = function () { if (!gc.characters) gc.characters = new gc.Characters(); gc.characters.reset(); this.myCha = { img: null, status: "stand", x: 0, y: 0, step: 0, combo: -1, jumpDir: 1 }; this.myCha.img = gc.characters.init(0); this.myCha.status = "stand"; this.myCha.x = gc.maps.nowFootholdPos.x; this.myCha.y = gc.maps.nowFootholdPos.y; this.myCha.img.x = this.myCha.x; this.myCha.img.y = this.myCha.y; this.myCha.jumpDir = this.oldMyCha ? this.oldMyCha.jumpDir : 1; this.myCha.step = this.oldMyCha ? this.oldMyCha.step : 0; gc.characters.standAnimate(this.myCha.img); this.setPlayerStandScale(); }; //유저가 바라볼 방향 gc.GameScene.prototype.setPlayerStandScale = function () { if (this.myCha.jumpDir == 1) this.myCha.img.scale.x = -1;//오른쪽 바라보기 else this.myCha.img.scale.x = 1;//왼쪽 바라보기 }; //화면 갱신.. 발판 내리기, 발판 폭파 gc.GameScene.prototype.setBackground = function () { var delayTime = 0.3; var wait = false;//소미가 나오는 동안 멈추기 위함 gc.maps.setNowFootHoldPos();//유저가 발판에 올라선 후 발판 좌표 저장 gc.maps.pullDownFootHolds();//발판, 유저 내리기 //발판 생성 if (gc.onFx) GD.soundPlay("sound_newblock"); if (gc.progress.endStep - gc.progress.nowStep == 2) {//마지막 발판 직전은 무조건 점프발판 if (gc.chapter == 5) gc.maps.initFootHolds(this.startStep + 1, 1, "jump"); else gc.maps.initFootHolds(this.startStep + 1, 1, "basic"); } else if (gc.progress.endStep - gc.progress.nowStep == 1) {//발판 생성..챕터의 마지막 발판은 무조건 기본 발판 wait = true; gc.maps.initFootHolds(this.startStep + 1, 1, 'basic'); } else { gc.maps.initFootHolds(this.startStep + 1, 1); } //만들어진 발판이 화면 사이드 밖으로 나갔는지 체크 gc.maps.checkFootHoldsOutofScene(); this.obstacle.removeFarBirds();//멀리 있는 새 제거 if (wait) TweenMax.delayedCall(1.6, resumeSetBackground.bind(this)); else resumeSetBackground.bind(this)(); this.onSlideFootHold = false; function resumeSetBackground() { if (gc.maps.nowFootholdPos.info.skillType == "jump") { this.myCha.status = "inJump";//점프 중 상태로 변경 TweenMax.delayedCall(0.15, (function () { this.jumpPlayer(); gc.characters.jumpAnimate(this.myCha.img); gc.maps.jumpAnimate(); }).bind(this)); } else { this.myCha.status = "stand"; this.setInteractive(true); }//터치 제어 //슬라이드 발판 여부 설정 TweenMax.delayedCall(delayTime, (function () { this.slideBlockAct();//현재 발판이 슬라이드 발판이면 다음 발판으로 미끄러짐 }).bind(this)); } //포탈 이미지 화면에 붙이기 if (gc.progress.nowStep == gc.progress.endStep - 1) {//챕터의 마지막 발판이 생겼을 경우 if (this.portal) { removeObject(this.portal); this.removeSpineListener(this.portal); } this.portal = null; // var name = "portal" + gc.chapter; var name = "portal1"; this.portal = new PIXI.spine.Spine(GD.loader.resources[name].spineData); this.portal.x = gc.maps.nextFootholdPos.x; this.portal.y = gc.maps.nextFootholdPos.y - 50; this.setSpineListener(this.portal); this.setAppearAnimate(this.portal); if (gc.chapter != 5) { var con = gc.maps.findContainer(gc.maps.nextFootholdPos.info.step); con.center.addChild(this.portal); TweenMax.delayedCall(0.8, (function () { gc.somi.portalSomi(); }).bind(this)); } else { gc.somi.sitOnLastFootHold(gc.maps.nextFootholdPos.x, gc.maps.nextFootholdPos.y - 50); } } //소미 설정 if (gc.progress.endStep - gc.progress.nowStep == 3) {//목표지점까지 2번 더 뛰어야 할 경우 gc.somi.appearSomi(); } }; //서있는 발판이 슬라이딩 발판이면 미끄러지기 gc.GameScene.prototype.slideBlockAct = function () { var i; this.onSlideFootHold = false; for (i = 0; i < gc.maps.allFootHolds.length; i++) { if (gc.maps.allFootHolds[i].step == this.myCha.step && gc.maps.allFootHolds[i].stair == "top") { if (gc.maps.allFootHolds[i].skillType == "slide") { this.onSlideFootHold = true; break; } } } }; //-----------------------------장애물 발생 여부 //새 장애물 gc.GameScene.prototype.setObstacleBird = function (moveDist, moveTime) {//새가 움직일 거리 var rand = Math.floor(Math.random() * 100); var onBird = false; if (gc.chapter == 3) { if (rand < 10) onBird = true; } else if (gc.chapter == "5") { if (rand < 10) onBird = true; } if (gc.progress.nowStep <= 1 || gc.maps.nowFootholdPos.info.skillType == 'jump' || gc.maps.nextFootholdPos.info.skillType == 'jump') onBird = false; if (this.birdCnt >= 3) onBird = false;//새가 연속으로 3번 이상 나오지 않게끔 하기 if (onBird) { this.birdCnt++; this.onObstacleBird(moveDist, moveTime); } else this.birdCnt = 0; }; gc.GameScene.prototype.onObstacleBird = function (moveDist, moveTime) { var bird = this.obstacle.findBird(); bird.step = this.myCha.step + 1; bird.center.x = gc.maps.nextFootholdPos.x; bird.center.y = gc.maps.nextFootholdPos.y; bird.img.x = 0; bird.img.y = 0; TweenMax.from(bird.center, moveTime, { y: bird.center.y + moveDist, onComplete: (function () { TweenMax.delayedCall(0.1, (function () { var birdDist = bird.img.y + 140; TweenMax.to(bird.img, 0.3, { y: birdDist }); bird.isFly = true; this.obstacle.flyAnimate(bird.img); }).bind(this)); }).bind(this) }); this.birdContainer.addChildAt(bird.center, 0); }; //암전 장애물 gc.GameScene.prototype.setObstacleBlackout = function () {//정전 여부 if (gc.progress.nowStep > 1 && gc.maps.nowFootholdPos.info.skillType != 'jump') { var rand = Math.floor(Math.random() * 100); this.obstacle.offLight = false; if (gc.chapter == 4) { if (rand < 5) this.obstacle.offLight = true; } else if (gc.chapter == "5") { if (rand < 5) this.obstacle.offLight = true; //엔딩컷 전에는 슬로우 모션이 되야하므로. if (gc.progress.endStep - gc.progress.nowStep == 1) this.obstacle.offLight = false; } if (this.obstacle.offLight) { this.onSpecialMessage(2); this.obstacle.offGameLight(); } } }; //--------------터치 이벤트 gc.GameScene.prototype.touchStart = function () { //점프 준비중 애니메이션으로 //서있는 상태일 때 if (this.myCha.status == "stand") { this.chargeVolume = 0.3; if (gc.onFx) GD.soundPlay("sound_gauge", this.chargeVolume); this.myCha.status = "readyJump";//점프 준비 상태로 변경 gc.characters.waitJumpAnimate(this.myCha.img); gc.maps.waitJumpAnimate(); } }; gc.GameScene.prototype.touchEnd = function () { //점프하는 이미지 if (this.myCha.status == "readyJump") { GD.soundStop("sound_gauge"); this.setInteractive(false);//터치 제어 removeObject(this.effectFoot); removeObject(this.effectHead); this.myCha.status = "inJump";//점프 중 상태로 변경 this.jumpPlayer(); gc.characters.jumpAnimate(this.myCha.img); gc.maps.jumpAnimate(); } gc.gravity.resetGuideLight(); }; //플레이어 충전 이펙트 보이기 gc.GameScene.prototype.onChargeEffect = function () { this.setEffectAnimate(this.effectFoot); this.setEffectAnimate(this.effectHead); this.effectFoot.skeleton.setToSetupPose(); this.effectHead.skeleton.setToSetupPose(); this.effectFoot.x = this.myCha.x; this.effectFoot.y = this.myCha.y; this.effectHead.x = this.myCha.x; this.effectHead.y = this.myCha.y - 50; var time = 0.3;//발판 움직이는 시간보다 좀 더 짧게 TweenMax.from(this.effectFoot, time, { x: this.myCha.img.x, y: this.myCha.img.y }); TweenMax.from(this.effectHead, time, { x: this.myCha.img.x, y: this.myCha.img.y }); this.playerContainer.addChildAt(this.effectFoot, 0); this.playerContainer.addChild(this.effectHead); }; //사운드 버튼 클릭 gc.GameScene.prototype.clickSoundBtn = function () { if (this.myCha.status != "readyJump") { gc.soundPopup.onSoundPopup(); } }; //점프 대기중 상태 체크 gc.GameScene.prototype.checkInJumpWait = function () { if (this.myCha.status == "readyJump") { gc.gravity.addPow(); } }; //얼음 블록 터질때 유저가 얼음 발판에 있는지 확인 gc.GameScene.prototype.checkPlayerInIceFootHold = function (fhStep) { if (this.myCha.step == fhStep) { if (this.myCha.status != "inJump" && this.myCha.status != "over") { this.myCha.status = 'over'; removeObject(this.effectFoot); removeObject(this.effectHead); gc.characters.standFailAnimate(this.myCha.img); } } }; //슬라이드 발판에 서있는지 확인 gc.GameScene.prototype.checkOnSlide = function () { if (!gc.pauseGame) { var frame = 60 * 5;//60프레임이라 보고 5초당 해당 거리만큼 움직여라 var vx = gc.maps.nowFootholdPos.info.fhWidth; var vy = gc.maps.nowFootholdPos.info.fhHeight; if (this.myCha.jumpDir == -1) vx = -vx; if (this.onSlideFootHold) { if (this.myCha.status == "stand") { gc.maps.setNowFootHoldPos();//발판 좌표 재설정 this.myCha.x += vx / frame; this.myCha.y -= vy / frame; this.myCha.img.x = this.myCha.x; this.myCha.img.y = this.myCha.y; gc.maps.setFootHoldDist();//다음 발판까지 거리 설정 var result = gc.gravity.checkInSameFootHold(); if (result.result == "danger" || result.result == "weak" || result.result == "too much") { this.myCha.status = 'over'; if (result.result == "danger") gc.characters.standFailAnimate(this.myCha.img); else if (result.result == "weak") gc.characters.hitWallAnimate(this.myCha.img); else if (result.result == "too much") gc.characters.fallDownAnimate(this.myCha.img); } } } } }; //점프하기 gc.GameScene.prototype.jumpPlayer = function () { if (gc.onFx) GD.soundPlay("sound_jump"); var result = {}; if (gc.maps.nowFootholdPos.info.skillType == "jump") { gc.gravity.chargePow = gc.maps.footHoldGap; result = gc.gravity.calcJumpResult(); } else { result = gc.gravity.calcJumpResult(); } console.log("점프결과", result); var movetime = 0.4; var vx = result.vx; var vy = result.vy; if (result.result == "weak") {//벽에 부딪치는 경우 목표 x좌표의 조정 vx += gc.gravity.calcSideGapWithPlayer(this.myCha.x + vx);//유저와 다음발판 줄기 사이의 거리 } //점프할 최대 높이 var topY = vy - (this.myCha.y - vy) * 0.05; var upGoalX = 0; var upGoalY = topY; if (result.result == "too much") upGoalX = vx * 0.68; else upGoalX = vx * 0.6; var startUpX = this.myCha.x; var startUpY = this.myCha.y; //올라선 발판이 점프발판인 경우 유저 오브젝트 이미지의 좌표로 계산 if (gc.maps.nowFootholdPos.info.skillType == "jump") startUpY = this.myCha.img.y; var startDownX = startUpX + upGoalX; var startDownY = startUpY + upGoalY; this.myCha.x += vx; this.myCha.y += vy; var landingAniY = (this.myCha.img.y + vy) * 0.95; var landingAniX = (this.myCha.img.x + vx) * 0.8; //마지막 챕터의 마지막 점프 var allGameClear = false; if (gc.chapter == 5 && gc.progress.endStep - gc.progress.nowStep == 1) { if (result.result == "perfect" || result.result == "nice" || result.result == "good") { movetime *= 5; var g = GraphicManager.drawRect(gc.width, gc.height, "0XFFFFFF"); TweenMax.from(g, movetime * 0.5, { alpha: 0, onComplete: (function () { console.log("엔딩컷신"); }).bind(this) }); this.addChild(g); allGameClear = true; } } var upTweener = TweenMax.to(this.myCha.img, movetime * 0.6, { ease: Power0.easeNone, bezier: { type: "quadratic", values: [{ x: startUpX, y: startUpY }, { x: (startUpX + upGoalX * 0.2), y: startUpY + upGoalY * 0.9 }, { x: (startUpX + upGoalX), y: startUpY + upGoalY }] }, onUpdate: (function () { this.checkHitWithBird(upTweener); }).bind(this), // onComplete:downTween.bind(this) onComplete: (function () { if (!allGameClear) downTween.bind(this)(); }).bind(this) }); function downTween() { var isLandingAni = (result.result == "perfect" || result.result == "nice" || result.result == "good"); var downGoalX = vx - upGoalX; var downGoalY = (topY - vy); var downTime = movetime * 0.3; var inSameFoothold = gc.gravity.checkInSameFootHold(); console.log("같은 발판에 올라섬", inSameFoothold); if (inSameFoothold != "stand") { if (!isLandingAni) {//다음 발판에 올라가지 못함 if (result.result != "danger") { if (result.result != "too much") { this.checkDepth(this.myCha.x); } else {// 벽에 부딪침 this.checkDepth(this.myCha.x + downGoalX); downGoalY = -(gc.height - this.myCha.img.y); downGoalX = vx * 0.5; downTime = movetime * 0.7; } } } } var downTweener = TweenMax.to(this.myCha.img, downTime, { ease: Power0.easeNone, bezier: { type: "quadratic", values: [{ x: startDownX, y: startDownY }, { x: (startDownX + downGoalX * 0.85), y: (startDownY - downGoalY * 0.1) }, { x: startDownX + downGoalX, y: startDownY - downGoalY }] }, onUpdate: (function () { this.checkHitWithBird(downTweener); // - 착지에 가까운 위치에 도달했을 때 애니메이션 변경 if (isLandingAni === true && this.myCha.img.y >= landingAniY) { if (this.myCha.img.x >= landingAniX) { isLandingAni = false; gc.characters.standClearAnimate(this.myCha.img); } } }).bind(this), onComplete: (function () { if (result.result == "perfect" || result.result == "nice" || result.result == "good") { //유저가 바라볼 방향 설정 this.myCha.jumpDir = gc.maps.initFootholdInfo.dir; this.setPlayerStandScale(); this.startStep += this.jumpStep; this.myCha.step = this.startStep; gc.gravity.resetPow(); gc.maps.jumpIn();//올라선 발판 안착 애니메이션 //암전 취소 this.obstacle.onGameLight(); //점수 추가, 점수 이펙트 여부, 발판 생성(챕터 클리어) var score = this.setAddScore(result.result); this.addScore(score); if (gc.maps.nowFootholdPos.info.skillType == "jump") this.onSpecialMessage(0); else if (gc.maps.nowFootholdPos.info.skillType == "ice" || gc.maps.nowFootholdPos.info.skillType == "slide") this.onSpecialMessage(1); } else {//跳得不好或者更跑的时候 gc.maps.setNowFootHoldPos();//登上跳板后,把坐标储存起来 //미리 체크해둠 if (inSameFoothold == "stand") {//제자리에 올라갔을 때 this.combo = 0; this.myCha.status = "stand"; this.setPlayerStandScale(); gc.maps.setFootHoldDist(); gc.gravity.resetPow(); gc.maps.jumpIn();//올라선 발판 안착 애니메이션 TweenMax.delayedCall(0.1, (function () { this.setInteractive(true);//터치 제어 }).bind(this)); gc.characters.standAnimate(this.myCha.img); } else {//허공에 떨어질 때 this.myCha.status = 'over'; if (result.result == "danger") { if (gc.onFx) GD.soundPlay("sound_dangling"); gc.characters.standFailAnimate(this.myCha.img); }//발판에서 떨어짐 else if (result.result == "weak") { if (gc.onFx) GD.soundPlay("sound_wallhit"); gc.characters.hitWallAnimate(this.myCha.img); var ef = this.onHitEffect(); ef.x = this.myCha.img.x; ef.y = this.myCha.img.y; this.midContainer.addChild(ef); }//벽에 부딪침 else if (result.result == "too much") {//허공에 떨어짐 if (gc.onFx) GD.soundPlay("sound_falling"); removeObject(gc.game.myCha.img); gameOver(); } } } }).bind(this) }) } }; //새와 부딪침 처리 gc.GameScene.prototype.checkHitWithBird = function (tween) { var isHitBird = this.obstacle.checkHitWithBird();//새와 부딪쳤는지 체크 if (isHitBird) { if (gc.onFx) GD.soundPlay("sound_birdhit"); tween.kill(); gc.characters.hitWallAnimate(this.myCha.img); } }; //레이어 처리 gc.GameScene.prototype.checkDepth = function (checkX) { if (this.obstacle) { if (this.obstacle.offLight) this.setMidContainer(0);//암전상태일때는 유저가 가장 위에 보임 else { var px = checkX;//this.myCha.img.x; var fh = gc.maps.nextFootholdPos; if (this.myCha.jumpDir == 1) {//오른쪽으로 뛸 때 if (px <= fh.x) this.setMidContainer(2);//발판 사이에 떨어짐 else this.setMidContainer(1);//너무 멀리 뜀 } else {//왼쪽으로 뛸 때 if (px <= fh.x) this.setMidContainer(1);//너무 멀리 뜀 else this.setMidContainer(2);//발판 사이에 떨어짐 } } } }; //점수 강조 체크 gc.GameScene.prototype.checkScoreEffect = function (preScore) { var prescore = preScore; var nowscore = this.score; //1000단위 변화 체크 var preUnit = Math.floor(prescore / 1000); var nowUnit = Math.floor(nowscore / 1000); if (preUnit != nowUnit) { this.onScoreEffect("1000"); return; } else { prescore -= preUnit * 1000; nowscore -= nowUnit * 1000; //100단위 체크 preUnit = Math.floor(prescore / 100); nowUnit = Math.floor(nowscore / 100); if (preUnit != nowUnit) { this.onScoreEffect("100"); return; } else { prescore -= preUnit * 100; nowscore -= nowUnit * 100; //50단위 체크 preUnit = Math.floor(prescore / 50); nowUnit = Math.floor(nowscore / 50); if (preUnit != nowUnit) { this.onScoreEffect("50"); return; } } } this.checkChapterOver();//해당 챕터가 완료되었는지 체크 }; //벽에 부딪치는 이펙트 gc.GameScene.prototype.onHitEffect = function () { var ef = new PIXI.spine.Spine(GD.loader.resources["cha_hit"].spineData); ef.skeleton.setToSetupPose(); ef.state.timeScale = 1.2; ef.state.setAnimation(0, "cha_hit", false, 0); return ef; }; //점수 강조 이펙트 gc.GameScene.prototype.onScoreEffect = function (type) { this.scoreText.alpha = 0; var soundName = "sound_" + type; if (gc.onFx) GD.soundPlay(soundName); //점수 강조 이펙트 생성 this.scoreEfBg = null; this.scoreEfBg = new PIXI.spine.Spine(GD.loader.resources["scoreEf" + type].spineData); this.setSpineListener(this.scoreEfBg); this.scoreEfBg.x = this.scoreText.x; this.scoreEfBg.y = this.scoreText.y + 30; //강조할 점수 텍스트 if (!this.mainScoreEfNum) { this.scoreNumContainer = new PIXI.Container(); this.scoreNumContainer.x = this.scoreText.x; this.scoreNumContainer.y = this.scoreText.y + 15; this.mainScoreEfNum = new gc.NumberText("c_score", 'center', -4); this.mainScoreEfNum.setValue(0); this.scoreNumContainer.addChild(this.mainScoreEfNum); } this.setScoreEfAnimate(this.scoreEfBg); this.uiContainer.addChild(this.scoreEfBg); //점수 텍스트 이펙트 this.mainScoreEfNum.setValue(this.score); this.scoreNumContainer.x = this.scoreText.x; this.scoreNumContainer.y = this.scoreText.y - 30; var time1 = 0.4, time2 = 0.1, time3 = 0.3; TweenMax.from(this.scoreNumContainer, time1, { y: this.scoreNumContainer.y - 220, onComplete: (function () { TweenMax.to(this.scoreNumContainer, time2, { y: this.scoreNumContainer.y - 20 }); }).bind(this) }); TweenMax.fromTo(this.scoreNumContainer.scale, time1, { ease: Power0.easeNone, x: 4.8, y: 4.8, alpha: 0 }, { x: 1.4, y: 1.4, alpha: 1, onComplete: (function () { TweenMax.to(this.scoreNumContainer.scale, time2, { ease: Power0.easeNone, x: 1.7, y: 1.7 }); }).bind(this) }); this.uiContainer.addChild(this.scoreNumContainer); this.checkChapterOver();//해당 챕터가 완료되었는지 체크 }; //게임 상태 메세지 이펙트 gc.GameScene.prototype.onStateMessage = function (type) { var name = ""; if (type == 0) name = "t_begin";//처음 시작 else if (type == 1) name = "t_again";//챕터 시작 else if (type == 2) name = "t_gameover";//게임오버 if (!this.messageText) this.messageText = new PIXI.Sprite.fromFrame(name + ".png"); else this.messageText.texture = PIXI.Texture.fromFrame(name + ".png"); this.messageText.x = gc.width / 2; this.messageText.y = gc.height / 2; this.messageText.alpha = 1; if (type < 2) {//게임 시작, 새로운 챕터 시작 this.messageText.anchor.x = 0.5; this.messageText.anchor.y = 1; var time = 0.4; TweenMax.from(this.messageText, time, { ease: Power0.easeNone, y: this.messageText.y + 40, alpha: 0 }); time = 0.3; em.bumpToY(this.messageText, time, 0.1, returnMessage.bind(this)); } else if (type == 2) {//게임오버 this.messageText.anchor.set(0.5); em.bumpFromToX(this.messageText, 0.3, 0, 1.1, 1, returnMessage.bind(this)); } //이펙트가 끝난 후 리턴 함수 function returnMessage() { if (type < 2) { TweenMax.delayedCall(0.5, (function () { TweenMax.to(this.messageText, time, { y: this.messageText.y + 40, alpha: 0, onComplete: (function () { removeObject(this.messageText); }).bind(this) }); }).bind(this)); } else if (type == 2) { //this.addResult();//네이버 결과 저장 onIntro();//로컬 실행 } } this.uiContainer.addChild(this.messageText); }; gc.GameScene.prototype.onSpecialMessage = function (type) { var name = ""; if (type == 0) name = "t_lucky";//점프발판 else if (type == 1) name = "t_watchout";//얼음, 슬라이드발판 else if (type == 2) name = "t_sodark";//암전 if (type == 0 || type == 1) { if (!this.specialMessage) this.specialMessage = new PIXI.Sprite.fromFrame(name + ".png"); else this.specialMessage.texture = PIXI.Texture.fromFrame(name + ".png"); if (this.specialEf) this.specialEf.kill(); this.specialEf = null; var time = 0.5; if (type == 1 || type == 2) time = 1; this.specialMessage.alpha = 1; this.specialMessage.anchor.set(0.5); this.specialMessage.x = this.myCha.img.x; this.specialMessage.y = this.myCha.img.y - 80; this.specialEf = TweenMax.to(this.specialMessage, time, { ease: Power0.easeNone, y: this.specialMessage.y - 70, alpha: 0, onComplete: returnMessage.bind(this) }); this.uiContainer.addChild(this.specialMessage); } else if (type == 2) { if (!this.blackoutMessage) this.blackoutMessage = new PIXI.Sprite.fromFrame(name + ".png"); this.blackoutMessage.anchor.set(0.5); this.blackoutMessage.alpha = 1; this.blackoutMessage.x = gc.width / 2; this.blackoutMessage.y = gc.height / 3; em.bumpFromToX(this.blackoutMessage, 0.3, 0, 1.2, 1, (function () { TweenMax.to(this.blackoutMessage, 0.5, { alpha: 0, onComplete: (function () { removeObject(this.blackoutMessage); }).bind(this) }); }).bind(this)); this.uiContainer.addChild(this.blackoutMessage); } //이펙트가 끝난 후 리턴 함수 function returnMessage() { removeObject(this.specialMessage); } }; //챕터 완료 확인 gc.GameScene.prototype.checkChapterOver = function () { if (gc.progress.nowStep == gc.progress.endStep) this.chapterClear = true; else { this.chapterClear = false; } if (this.chapterClear) { if (gc.onFx) GD.soundPlay("sound_clear"); this.obstacle.resetBirds(); //스테이지별 추가 점수 this.addChapterClearScore(); var light = new PIXI.Sprite.fromFrame("light1.png"); light.anchor.set(0.5); light.x = this.portal.x; light.y = this.portal.y; this.addChild(light); var time = 2; TweenMax.fromTo(light.scale, time, { x: 0, y: 0 }, { x: 30, y: 30, onComplete: (function () { gc.chapter++; this.setNextChapterScene(); var con = gc.maps.findContainer(gc.maps.nowFootholdPos.info.step); con.center.addChild(this.portal); this.portal.x = gc.maps.nowFootholdPos.x; this.portal.y = gc.maps.nowFootholdPos.y - 50; light.x = this.portal.x; light.y = this.portal.y; TweenMax.to(light.scale, time / 2, { x: 0, y: 0, onComplete: (function () { if (gc.onFx) GD.soundPlay("sound_newtheme"); removeObject(light); em.floatByY(this.somi, 0.5, 20, 2, gc.somi.disappearSomi.bind(gc.somi)); }).bind(this) }) }).bind(this) }); } else { this.setBackground();//발판 내리기, 다음 발판 생성 } }; //다음 챕터 화면으로 갱신 gc.GameScene.prototype.setNextChapterScene = function () { this.offUI(); this.setGameBgImage();//배경 이미지 설정 gc.somi.resetSomi(); this.uiContainer.addChild(this.somi); this.onSlideFootHold = false; gc.maps.resetAllFootHold(); gc.maps.reset();//발판 초기화 gc.progress.setEndStep();//스테이지별 스텝 설정 gc.progress.resetNowStep();//진행바 초기화 gc.maps.initFootHolds(this.startStep, 1, 'basic'); this.myCha.status = "stand"; this.myCha.x = gc.maps.nowFootholdPos.x; this.myCha.y = gc.maps.nowFootholdPos.y; this.myCha.img.x = this.myCha.x; this.myCha.img.y = this.myCha.y; this.myCha.jumpDir = 1; this.setPlayerStandScale(); }; //눌렸을때 이펙트 gc.GameScene.prototype.setEffectAnimate = function (obj) { obj.skeleton.setToSetupPose(); obj.state.setAnimation(0, "ef", true, 0); }; //--------------------이벤트 활성화 gc.GameScene.prototype.setInteractive = function (bool) { this.touchBg.interactive = bool; //this.soundBtn.interactive = bool;/*네이버 연동 후 활성화 시키기*/ }; //스파인 애니메이션 //포탈 생성 애니 gc.GameScene.prototype.setAppearAnimate = function (obj) { this.resetAnimate(obj); var aniname = "portal_appear"; var aniObj = obj.state.setAnimation(0, aniname, false, 0); obj.state.addAnimation(0, "portal_normal", true, aniObj.animationEnd); }; //점수 강조 이펙트 gc.GameScene.prototype.setScoreEfAnimate = function (obj) { this.resetAnimate(obj); var aniname = "scoreEf"; obj.state.setAnimation(0, aniname, false, 0); }; gc.GameScene.prototype.resetAnimate = function (obj) { obj.state.clearTracks(); obj.skeleton.setToSetupPose(); obj.state.timeScale = 1; // obj.update(1); // obj.state.setEmptyAnimation(0,1); }; gc.GameScene.prototype.reset = function () { gc.gravity = null; gc.maps = null; this.progressContainer = null;//진행률 컨테이너 this.scoreEfBg = null; this.chapterClear = true;//처음 발판 생성시 기본 좌표에 생성하기 위함 this.removeChildren(); this.playerContainer.removeChildren(); if (this.portal) removeObject(this.portal); this.portal = null; this.myCha = null; this.combo = 0; this.score = 0; this.birdCnt = 0;//새가 연속으로 나온 횟수 this.chargeVolume = 0.3; this.startStep = 0;//현재 유저가 서있는 스텝 this.jumpStep = 1;//현재 스텝과 다음 스텝의 차이 this.onSlideFootHold = false;//슬라이드 발판 위에 있는지 여부 }; gc.GameScene.prototype.pause = function () { gc.pauseGame = true; this.setFlag(); TweenMax.pauseAll(); console.log("일시정지"); }; gc.GameScene.prototype.resume = function () { gc.pauseGame = false; this.setFlag(); TweenMax.resumeAll(); console.log("계속하기"); }; gc.GameScene.prototype.setFlag = function () { this.myCha.img.autoUpdate = !gc.pauseGame; this.somi.autoUpdate = !gc.pauseGame; if (this.portal) this.portal.autoUpdate = !gc.pauseGame; if (this.scoreEfBg) this.scoreEfBg.autoUpdate = !gc.pauseGame; for (var i = 0; i < gc.maps.allFootHolds.length; i++) gc.maps.allFootHolds[i].img.autoUpdate = !gc.pauseGame; this.setInteractive(!gc.pauseGame); }; gc.GameScene.prototype.addResult = function () { GamePocket.Sdk.Ranking.addMyScore(this.score, (function (response) { //this.loadingHide(); if (response.code === GamePocket.Sdk.ResponseCode.SUCCESS) { var ranking = response.result; //console.log("랭킹을 남긴 사용자 수 : " + ranking.countOfAllUsers); //console.log("" + ranking.percentile); //console.log("" + ranking.group); //console.log("" + ranking.groupIcon); //console.log("" + ranking.score); this.onResultView(this.score, ranking.score, "", ranking.groupIcon, 1); } else { if (response.code == GamePocket.Sdk.ResponseCode.NOT_FOUND_GAME || response.code == GamePocket.Sdk.ResponseCode.NO_AUTHENTICATION) { this.onResultView(this.score, 0, 0, "DIAMOND", 2, 2); } else { this.onResultView(this.score, 0, 0, "DIAMOND", 2, 1); } //console.log(response.code); }//fail process }).bind(this)); }; gc.GameScene.prototype.onResultView = function (score, bestScore, rank, group, type, message) { console.log("onResultView score:" + score + " best Score:" + bestScore + " rank:" + rank + " group:" + group + " tpye:" + type + " message:" + message); gc.resultView.init(score, bestScore, rank, group, type, message); GD.stage.addChild(gc.resultView); }; gc.GameScene.prototype.updateTransform = function () { try { this.checkInJumpWait(); this.checkOnSlide(); if (this.obstacle) this.obstacle.flyBird(); PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /** * Created by juho on 2016-03-30. */ gc.NumberText = function (fileName, align, space, iconName, iconAlign, commaName) { this.CENTER = 'center'; this.RIGHT = 'right'; this.LEFT = 'left'; this.value = 0; this.isChange = false; this.list = []; this.tmpList = []; this.fileName = fileName; this.align = align; this.space = space; this.iconName = iconName; this.iconAlign = iconAlign; this.commaName = commaName; this.icon = null; PIXI.Container.call(this); this.container = new PIXI.Container(); this.addChild(this.container); this.setValue(0); }; gc.NumberText.constructor = gc.NumberText; gc.NumberText.prototype = Object.create(PIXI.Container.prototype); gc.NumberText.prototype.setValue = function (value) { this.value = value; this.isChange = true; }; gc.NumberText.prototype.getNumberSprite = function (num) { var sprite, name; name = this.fileName + num + '.png'; if (this.tmpList.length > 0) { sprite = this.tmpList.shift(); sprite.texture = PIXI.Texture.fromFrame(name); } else { sprite = PIXI.Sprite.fromFrame(name); } return sprite; }; gc.NumberText.prototype.getCommaSprite = function () { var sprite, name = this.commaName + '.png'; if (this.tmpList.length > 0) { sprite = this.tmpList.shift(); sprite.texture = PIXI.Texture.fromFrame(name); } else { sprite = PIXI.Sprite.fromFrame(name); } return sprite; }; gc.NumberText.prototype.removeAll = function () { var txt, i = this.list.length; while (i--) { txt = this.list.shift(); this.tmpList.push(txt); } if (this.container) this.container.removeChildren(); }; gc.NumberText.prototype.updateTransform = function () { if (this.isChange) { this.removeAll(); var numStr = (this.commaName) ? Util.comma(this.value) : this.value.toString(); var index = 0, txt, str, space = 0, i = numStr.length; if (this.iconName) { if (!this.icon) this.icon = PIXI.Sprite.fromFrame(this.iconName); this.container.addChild(this.icon); if (this.iconAlign == 'left') { space += this.icon.width + this.space; } } while (i--) { str = numStr.substr(index, 1); if (str == '.') { txt = this.getCommaSprite(); } else { txt = this.getNumberSprite(parseInt(str) + 1); } txt.x = space; space += txt.width; if (i > 0) space += this.space; index++; this.container.addChild(txt); this.list[i] = txt; } if (this.iconAlign == 'right') { this.icon.x = space; space += this.icon.width + this.space; } if (this.align == this.CENTER) { this.container.x = -space / 2; } else if (this.align == this.RIGHT) { this.container.x = -space; } this.isChange = false; } PIXI.Container.prototype.updateTransform.call(this); }; /** * Created by admin on 2018-06-14. */ gc.Somi = function () { PIXI.Container.call(this); this.somi = new PIXI.spine.Spine(GD.loader.resources["somi"].spineData); }; gc.Somi.constructor = gc.Somi; gc.Somi.prototype = Object.create(PIXI.Container.prototype); gc.Somi.prototype.setSpineListener = function (obj) { obj.state.addListener({ complete: (function (t) { if (t.animation.name == "somi") { this.removeSpineListener(obj); removeObject(obj); } }).bind(this) }); }; gc.Somi.prototype.removeSpineListener = function (obj) { obj.state.removeListener(); }; gc.Somi.prototype.init = function () { this.resetSomi(); this.somiHelpAnimate(this.somi); return this.somi; }; //화면 밖으로 날아가기 gc.Somi.prototype.disappearSomi = function () { this.resetSomi(); TweenMax.to(this.somi, 1, { y: -250, onComplete: (function () { //유저가 생성된 후 건너가야 할 발판 생성 gc.maps.initFootHolds(gc.game.startStep + 1, 1); gc.maps.setFootHoldDist();//유저와 다음 발판 사이 거리 계산 gc.game.setInteractive(true); var message = (gc.chapter == 1) ? 0 : 1; gc.game.onStateMessage(message);//게임 시작 문구 gc.game.onUI(); }).bind(this) }); }; //화면으로 나타나기 gc.Somi.prototype.appearSomi = function () { this.resetSomi(); TweenMax.from(this.somi, 1, { y: -250 }); }; //포탈로 넘어가기 gc.Somi.prototype.portalSomi = function () { if (gc.chapter != 5) { TweenMax.to(this.somi, 0.3, { x: gc.game.portal.x, y: gc.game.portal.y + 40, onComplete: (function () { TweenMax.to(this.somi.scale, 0.1, { x: 0, y: 0, onComplete: (function () { var ef = gc.game.onHitEffect(); this.setSpineListener(ef); ef.x = gc.game.portal.x; ef.y = gc.game.portal.y; gc.game.uiContainer.addChild(ef); removeObject(this.somi); }).bind(this) }); }).bind(this) }); } }; //마지막 발판 위에 앉아있기 gc.Somi.prototype.sitOnLastFootHold = function (x, y) { TweenMax.to(this.somi, 1, { x: x, y: y }); }; //소미 상태 초기화 gc.Somi.prototype.resetSomi = function () { this.somi.scale.x = 1; this.somi.scale.y = 1; this.somi.rotation = 0; this.somi.x = gc.width * 0.5; this.somi.y = 450; }; //소미 애니메이션 gc.Somi.prototype.somiHelpAnimate = function (obj) { this.resetAnimate(obj); var aniname = "somi"; obj.state.setAnimation(0, aniname, true, 0); }; gc.Somi.prototype.resetAnimate = function (obj) { obj.state.clearTracks(); obj.skeleton.setToSetupPose(); obj.state.timeScale = 1; // obj.update(1); // obj.state.setEmptyAnimation(0,1); }; gc.Somi.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /** * Created by admin on 2018-05-18. */ gc.Obstacle = function () { PIXI.Container.call(this); this.birds = []; this.blackout = null; this.offLight = false; this.blackoutCon = new PIXI.Container(); this.birdCon = new PIXI.Container(); }; gc.Obstacle.constructor = gc.Obstacle; gc.Obstacle.prototype = Object.create(PIXI.Container.prototype); //------------초기화 gc.Obstacle.prototype.initBirdContainer = function () { this.birdCon.removeChildren(); this.resetBirds(); return this.birdCon; }; gc.Obstacle.prototype.initBlackoutContainer = function () { this.blackoutCon.removeChildren(); this.offLight = false; return this.blackoutCon; }; //사용할 새 생성 gc.Obstacle.prototype.findBird = function () { var i; var bird = null; for (i = 0; i < this.birds.length; i++) { if (!this.birds[i].isWork) { bird = this.birds[i]; this.birds[i].isWork = true; break; } } if (!bird) { bird = { center: new PIXI.Container(), img: new PIXI.spine.Spine(GD.loader.resources['bird3'].spineData), step: null, isWork: true, isFly: false } //히트영역 저장 var element = bird; var img = element.img; var bounds = new pixi_spine.core.SkeletonBounds(); bounds.update(img.skeleton, true); var hitboxVertex = Array.prototype.slice.call(bounds.polygons[0]); bird.hitArea = new PIXI.Polygon(hitboxVertex); bird.center.addChild(bird.img); this.birds.push(bird); } this.resetAnimate(bird.img); return bird; }; //모든 새 초기화 gc.Obstacle.prototype.resetBirds = function () { var i = 0; for (i = 0; i < this.birds.length; i++) { this.resetBird(this.birds[i]); } }; //멀리있는 새 초기화 gc.Obstacle.prototype.removeFarBirds = function () { for (var i = 0; i < this.birds.length; i++) { if (this.birds[i].isWork && (gc.game.myCha.step - this.birds[i].step) >= 2) { this.resetBird(this.birds[i]); } } }; //새 한마리씩 없애기 gc.Obstacle.prototype.resetBird = function (bird) { bird.img.rotation = 0; bird.img.scale.x = 1; bird.img.x = 0; bird.img.y = 0; bird.step = null; bird.isWork = false; bird.isFly = false; bird.center.rotation = 0; removeObject(bird.center); }; //새 날아다니기 gc.Obstacle.prototype.flyBird = function () { var i; for (i = 0; i < this.birds.length; i++) { if (this.birds[i].isWork && this.birds[i].isFly) { var preAngle = this.birds[i].center.rotation; this.birds[i].center.rotation += Math.PI / 60;//2초에 한바퀴.. 60프레임 기준 if (this.birds[i].center.rotation >= Math.PI * 2) { this.birds[i].center.rotation -= Math.PI * 2; } this.birds[i].img.rotation = -this.birds[i].center.rotation;//1초에 한바퀴 } } }; //새와 유저 부딪침 체크 gc.Obstacle.prototype.checkHitWithBird = function () { var isCollide = false; var bx, by;//새 좌표 var dx, dy, dist; for (var i = 0; i < this.birds.length; i++) { if (this.birds[i].isWork) { bx = this.birds[i].img.worldTransform.tx; by = this.birds[i].img.worldTransform.ty; dx = Math.abs(gc.game.myCha.img.worldTransform.tx - bx); dy = Math.abs(gc.game.myCha.img.worldTransform.ty - by); dist = Math.sqrt(dx * dx + dy * dy); if (dist < 70) { isCollide = true; this.birds[i].isFly = false; break; } } } return isCollide; }; //새 애니메이션 gc.Obstacle.prototype.flyAnimate = function (obj) { var aniname = "animation"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, true); }; gc.Obstacle.prototype.frontAnimate = function (obj) { var aniname = "front_normal"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, true); }; gc.Obstacle.prototype.backAnimate = function (obj) { var aniname = "back_normal"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, true); }; gc.Obstacle.prototype.explodeAnimate = function (obj) { var aniname = "back_burst"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, false); }; gc.Obstacle.prototype.resetAnimate = function (obj) { obj.state.clearTracks(); obj.skeleton.setToSetupPose(); obj.state.timeScale = 1; obj.update(1); obj.state.setEmptyAnimation(0, 1); }; //암전 gc.Obstacle.prototype.offGameLight = function () { if (!this.blackout) this.blackout = GraphicManager.drawRect(gc.width, gc.height, "0X000000"); var time = 0.2; TweenMax.from(this.blackout, time, { alpha: 0 }); this.blackoutCon.addChildAt(this.blackout, 0); this.offLight = true; }; gc.Obstacle.prototype.onGameLight = function () { if (this.blackout) removeObject(this.blackout); this.offLight = false; }; gc.Obstacle.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /** * created by */ gc.ResultView = function () { PIXI.Container.call(this); this.darkBg = new PIXI.Graphics(); this.darkBg.lineStyle(1, 0x000, 1); this.darkBg.beginFill(0x000, 0.8); this.darkBg.drawRect(0, 0, gc.width, gc.height); this.darkBg.endFill(); this.darkBg.interactive = true; this.setTouchEnd(this.darkBg); this.bg = PIXI.Sprite.fromFrame("popup_bg1.png"); this.bg.anchor.set(0.5); this.bg.x = gc.width / 2; this.bg.y = gc.height / 2; this.scoreTxt = new gc.NumberText("c_score_", "center", 0, null, null, "c_score_11"); this.scoreTxt.x = 0; this.scoreTxt.y = -130; this.scoreTxt.setValue(1000000); this.bg.addChild(this.scoreTxt); this.bestScoreTxt = new gc.NumberText("c_score2_", "center", 0, null, null, "c_score2_11"); this.bestScoreTxt.x = 0; this.bestScoreTxt.y = 20; this.bg.addChild(this.bestScoreTxt); this.gropImg = PIXI.Sprite.fromFrame("popup_icon_1.png"); this.gropImg.anchor.set(0.5); this.gropImg.scale.set(0.4); this.gropImg.x = 30; this.gropImg.y = 97; this.bg.addChild(this.gropImg); this.reStartBtn = PIXI.Sprite.fromFrame("popup_bt_retry.png"); this.reStartBtn.anchor.set(0.5); this.reStartBtn.y = 220; this.bg.addChild(this.reStartBtn); this.setTouchStartAction(this.reStartBtn, function () { this.requestCloseWindow(); }, this); this.errorMessageTxt = new PIXI.Text("게임 점수 저장에 실패 했습니다.\n다시 한번 게임에 참여 해 주세요.", { fontSize: '24px', fontWeight: 'bold' }); this.errorMessageTxt.anchor.set(0.5); this.errorMessageTxt.x = 0; this.errorMessageTxt.y = 50; this.bg.addChild(this.errorMessageTxt); }; gc.ResultView.constructor = gc.ResultView; gc.ResultView.prototype = Object.create(PIXI.Container.prototype); // 초기화 gc.ResultView.prototype.init = function (score, bestScore, rank, group, type, message) { this.removeAll(); if (score <= 0) { this.scoreTxt.setValue(0); } else { this.scoreTxt.setValue(score); } if (bestScore <= 0) { this.bestScoreTxt.setValue(0); } else { this.bestScoreTxt.setValue(bestScore); } var flag = false; if (false) { if (group == "DIAMOND") { flag = true; this.gropImg.texture = PIXI.Texture.fromFrame("popup_icon_1.png"); } else if (group == "GOLD") { flag = true; this.gropImg.texture = PIXI.Texture.fromFrame("popup_icon_2.png"); } else if (group == "SILVER") { flag = true; this.gropImg.texture = PIXI.Texture.fromFrame("popup_icon_3.png"); } else if (group == "BRONZE") { flag = true; this.gropImg.texture = PIXI.Texture.fromFrame("popup_icon_4.png"); } } else { try { flag = true; this.gropImg.texture = PIXI.Texture.fromImage(group); } catch (e) { flag = false; } } if (flag) { this.gropImg.visible = true; } else { this.gropImg.visible = false; } this.initPage(type, message); this.addChild(this.darkBg); this.addChild(this.bg); this.setInteractive(true); }; gc.ResultView.prototype.initPage = function (type, message) { if (type == 1) { this.bg.texture = PIXI.Texture.fromFrame("popup_bg1.png"); this.scoreTxt.x = 0; this.scoreTxt.y = -130; this.reStartBtn.y = 220; this.bestScoreTxt.visible = true; //this.gropImg.visible = true; this.errorMessageTxt.visible = false; } else { if (message == 1) { this.errorMessageTxt.text = "게임 점수 저장에 실패 했습니다.\n다시 한번 게임에 참여 해 주세요."; } else { this.errorMessageTxt.text = '비로그인 시에는 점수가\n 저장되지 않습니다.'; } this.bg.texture = PIXI.Texture.fromFrame("popup_bg4.png"); this.scoreTxt.x = 0; this.scoreTxt.y = -60; this.reStartBtn.y = 155; this.bestScoreTxt.visible = false; this.gropImg.visible = false; this.errorMessageTxt.visible = true; } }; gc.ResultView.prototype.requestCloseWindow = function () { this.setInteractive(false); this.removeChildren(); this.emit("GOTO_MAINPAGE"); }; gc.ResultView.prototype.removeAll = function () { this.removeChildren(); }; gc.ResultView.prototype.setInteractive = function (bool) { this.reStartBtn.interactive = bool; }; gc.ResultView.prototype.updateTransform = function () { PIXI.Container.prototype.updateTransform.call(this); }; /** * Created by admin on 2018-05-15. */ gc.Progress = function () { PIXI.Container.call(this); this.mainContainer = new PIXI.Container(); this.progressDia = new PIXI.spine.Spine(GD.loader.resources["target"].spineData); this.progressbar = new PIXI.Sprite.fromFrame("navigation_bg.png"); this.progresspin = new PIXI.Sprite.fromFrame("navigation_bar.png"); this.endStepList = [40, 50, 60, 60, 60]; // this.endStepList = [5, 5, 5, 5, 5]; this.endStep = this.endStepList[0]; this.nowStep = 0; }; gc.Progress.constructor = gc.Progress; gc.Progress.prototype = Object.create(PIXI.Container.prototype); //진행 바 이미지 전달 gc.Progress.prototype.init = function () { this.progressDia.x = this.progressbar.width + 30; this.progressDia.state.setAnimation(0, "target", true); this.progressbar.anchor.y = 0.5; this.progresspin.anchor.x = 0.5; this.progresspin.anchor.y = 0; this.progresspin.y = 5; this.setNowPosition(); this.mainContainer.addChild(this.progressDia); this.mainContainer.addChild(this.progressbar); this.mainContainer.addChild(this.progresspin); return this.mainContainer; }; //진행바 목표점 설정 gc.Progress.prototype.setEndStep = function () {//현재 챕터 1부터 시작 this.endStep = this.endStepList[gc.chapter - 1]; }; //현재 스텝 gc.Progress.prototype.addStep = function () { this.nowStep++; this.setNowPosition(); }; //현재 스텝 초기화 gc.Progress.prototype.resetNowStep = function () { this.nowStep = 0; this.setNowPosition(); }; //현재 진행률에 맞춘 좌표 gc.Progress.prototype.setNowPosition = function () { this.progresspin.x = this.progressbar.width / this.endStep * this.nowStep; if (this.nowStep != 0) { var moveTime = 0.2; TweenMax.from(this.progresspin, moveTime, { x: this.progressbar.width / this.endStep * (this.nowStep - 1) }); TweenMax.to(this.progresspin.scale, moveTime / 2, { x: 1.2, y: 1.2, onComplete: (function () { TweenMax.to(this.progresspin.scale, moveTime / 2, { x: 1, y: 1 }); }).bind(this) }); } }; gc.Progress.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /*Created by admin on 2018-04-05.*/ gc.Map = function () { PIXI.Container.call(this); this.allFootHolds = [];//모든 발판 this.quakeTweeners = [];//흔들리고 있는 발판 리스트 this.nextfhFloor = 2;//건너가야 할 발판 높이 //발판 종류 리스트 this.fhNames = []; this.fhNames[0] = "foothold1";//챕터1 this.fhNames[1] = "foothold2";//챕터2 this.fhNames[100] = "foothold_ice"; this.fhNames[200] = "foothold_rail"; this.fhNames[300] = "foothold_jump"; this.mapContainers = []; }; gc.Map.constructor = gc.Map; gc.Map.prototype = Object.create(PIXI.Container.prototype); //-----------애니메이션 완료 리스너 gc.Map.prototype.setSpineListener = function (obj) { obj.state.addListener({ complete: (function (t) { if (t.animation.name == "foothold_basic2") {//발판 튕기기 this.setBasicAnimate(obj); } else if (t.animation.name == "bg_basic2") {//줄기 발판 튕기기 this.setBarAnimate(obj); } else if (t.animation.name == "bg_basic3") {//줄기 발판 튕기기 this.setBasicAnimate(obj); } else if (t.animation.name == "foothold_burst") {//발판 폭파 애니 removeObject(obj); this.resetIceFootHoldData(obj); } }).bind(this) }); }; //최초 본인이 서있을 발판 생성 gc.Map.prototype.init = function () { this.allFootHolds = [];//모든 발판 this.reset(); }; //발판 생성 脚踏板 gc.Map.prototype.initFootHolds = function (step, dist, skilltype) { var i; //챕터별 사용할 발판 선정 var fhImgType = gc.chapter - 1;//발판 이미지 타입 if (fhImgType >= 2) fhImgType = Math.floor(Math.random() * 2); //발판의 스킨 타입 설정 var skinName = ["foothold1_skin", "foothold2_skin", "foothold3_skin"];//스킨 이름 var pngName = ["foothold1", "foothold2", "foothold3"];//스킨에 따라 이미지 이름 바꿔주기.. 발판 크기 찾기 위함 var skinIndex = Math.floor(Math.random() * skinName.length); var fhSkillType = (skilltype) ? skilltype : this.setFootHoldSkillType();//발판 기능 종류(기본, 점프, 얼음, 슬라이드) if (fhSkillType == "ice") fhImgType = 100; else if (fhSkillType == "slide") fhImgType = 200; else if (fhSkillType == "jump") fhImgType = 300; var footholds = [];//아래쪽 발판부터 생성 //발판 높이 설정 var basegapFloor = [2, 2, 2, 2, 2]; var maxgapFloor = [3, 5, 8, 9, 10]; //발판 높이 if (this.firstFh) this.nextfhFloor = this.initFootholdInfo.floor;//각 챕터 첫 발판.. 최소 3층 else this.nextfhFloor = 3 + basegapFloor[gc.chapter - 1] + parseInt(Math.random() * maxgapFloor[gc.chapter - 1]);//최소 3개 + 기본 차 + 추가 차이 // else this.nextfhFloor = 3 + 2 + 10;//최소 3개 + 기본 차 + 추가 차이 this.initFootholdInfo.floor = this.nextfhFloor; //다음 발판 생성 방향 설정.. 같은 방향으로 2번 이상 갔을 때만 방향 전환 가능. if (this.sameDirCnt >= 2) this.nextDir = (Math.floor(Math.random() * 2) == 0) ? 1 : -1; if (this.preDir == this.nextDir) { this.sameDirCnt++; } else { this.sameDirCnt = 0; this.preDir = this.nextDir; } //발판 생성 for (i = 0; i < this.nextfhFloor; i++) { footholds.push(this.findFootHold(fhImgType, skinName[skinIndex], pngName[skinIndex], fhSkillType, this.nextDir)); footholds[footholds.length - 1].stair = (i == this.nextfhFloor - 1) ? "top" : i; footholds[footholds.length - 1].step = step; } //유저가 생성되기 전일 경우 if (this.firstFh) { this.setNowFootHoldPos(); } this.attachFootHold(footholds, dist); this.firstFh = false; }; //발판 기능 설정 gc.Map.prototype.setFootHoldSkillType = function () { var type = 'basic'; var rand = Math.floor(Math.random() * 100); if (gc.chapter == 1) {//카드랜드 if (rand < 20) type = 'jump'; } else if (gc.chapter == 2) {//버섯랜드 if (rand < 10) type = 'ice'; else if (rand < 30) type = 'jump'; } else if (gc.chapter == 3) {//장미랜드 if (rand < 10) type = 'slide'; else if (rand < 30) type = 'ice'; // type = 'slide'; } else if (gc.chapter == 4) {//모자랜드 if (rand < 15) type = 'slide'; else if (rand < 30) type = 'ice'; else if (rand < 40) type = 'jump'; } else if (gc.chapter == 5) {//나무랜드 if (rand < 15) type = 'slide'; else if (rand < 30) type = 'ice'; else if (rand < 40) type = 'jump'; } // type = 'jump'; // type = 'basic'; // type = 'slide'; // type = 'ice'; return type; }; //현재 유저 위치와 다음 발판 사이 거리 계산 gc.Map.prototype.setFootHoldDist = function () { if (gc.game.myCha) { this.footHoldGapX = Math.abs(gc.game.myCha.x - this.nextFootholdPos.x); this.footHoldGapY = Math.abs(gc.game.myCha.y - this.nextFootholdPos.y); this.footHoldGap = Math.sqrt(this.footHoldGapX * this.footHoldGapX + this.footHoldGapY * this.footHoldGapY) + this.nextfhFloor * 20; } // console.log("유저와 발판 사이 거리 측정 x", this.footHoldGapX, "y", this.footHoldGapY, "dist", this.footHoldGap); }; //사용가능한 발판 찾기 gc.Map.prototype.findFootHold = function (imgType, skinName, mainImgName, skillType, dir) { var fh = null; var size = null; for (var i = 0; i < this.allFootHolds.length; i++) { size = null; if (!this.allFootHolds[i].isWork) { if (this.allFootHolds[i].imgType == imgType && this.allFootHolds[i].skillType == skillType) { // console.log("imgType", this.fhNames[imgType], "skillType", skillType, "기존 발판", i); fh = this.allFootHolds[i]; size = this.setFootHoldSize(fh.imgType, mainImgName); if (size) { fh.fhWidth = size.width; fh.fhHeight = size.height; } this.setFootHoldSkin(fh, skinName); this.setFootHoldPolygons(fh); fh.isWork = true; fh.dir = dir; break; } } } if (!fh) fh = this.makeFootHold(imgType, skinName, mainImgName, skillType, dir); return fh; }; //발판 오브젝트 만들기 gc.Map.prototype.makeFootHold = function (imgType, skinName, mainImgName, skillType, dir) { var size = null; var fhWidth, fhHeight; if (imgType == 100) {//얼음 발판 fhWidth = 90; fhHeight = 45; } else if (imgType == 200) {//슬라이드 발판 fhWidth = 90; fhHeight = 45; } else if (imgType == 300) {//점프 발판 fhWidth = 90; fhHeight = 45; } var fhName = this.fhNames[imgType]; //발판 크기 설정 size = this.setFootHoldSize(imgType, mainImgName); if (size) { fhWidth = size.width; fhHeight = size.height; } this.allFootHolds.push({ img: new PIXI.spine.Spine(GD.loader.resources[fhName].spineData), imgType: imgType, skillType: skillType, fhWidth: fhWidth, fhHeight: fhHeight, dir: dir, step: null, stair: null, isWork: true }); this.setSpineListener(this.allFootHolds[this.allFootHolds.length - 1].img);//애니메이션 완료 리스너 설정 this.setFootHoldSkin(this.allFootHolds[this.allFootHolds.length - 1], skinName); this.setFootHoldPolygons(this.allFootHolds[this.allFootHolds.length - 1]); return this.allFootHolds[this.allFootHolds.length - 1]; }; //발판 너비 설정 gc.Map.prototype.setFootHoldSize = function (imgType, mainImgName) { var w = null, h = null; if (imgType != 100 && imgType != 200 && imgType != 300) { var fhName = this.fhNames[imgType]; var atlasData = GD.loader.resources[fhName].spineAtlas; var region = atlasData.findRegion(mainImgName); w = region.originalWidth * 0.5; h = region.originalHeight * 0.5; return { width: w, height: h }; } return false; }; //발판 스킨 설정 gc.Map.prototype.setFootHoldSkin = function (fh, skinName) { if (fh.imgType != 100 && fh.imgType != 200 && fh.imgType != 300) { var skeleton = fh.img.skeleton; skeleton.setSkin(null); skeleton.setSkinByName(skinName); skeleton.setSlotsToSetupPose(); } }; //발판 히트영역 도형 설정 gc.Map.prototype.setFootHoldPolygons = function (fh) { if (fh.imgType != 100 && fh.imgType != 200 && fh.imgType != 300) { if (fh.hitArea) fh.hitArea = null; if (fh.dangerArea) fh.dangerArea = null; } if (!fh.hitArea && !fh.dangerArea) { var img = fh.img; var bounds = new pixi_spine.core.SkeletonBounds(); bounds.update(img.skeleton, true); var hitbox1Vertex = Array.prototype.slice.call(bounds.polygons[0]); var hitbox2Vertex = Array.prototype.slice.call(bounds.polygons[1]); fh.hitArea = new PIXI.Polygon(hitbox1Vertex); fh.dangerArea = new PIXI.Polygon(hitbox2Vertex); // var g = new PIXI.Graphics(); // fh.img.addChild(g); // g.alpha = 0.5; // g.beginFill(0X00FF00); // g.drawPolygon(hitbox1Vertex); // g.endFill(); // // g.beginFill(0X0000FF); // g.drawPolygon(hitbox2Vertex); // g.endFill(); } }; //현재 발판 위치 저장 gc.Map.prototype.setNowFootHoldPos = function () { for (var i = 0; i < this.allFootHolds.length; i++) { if (this.firstFh && this.allFootHolds[i].stair == "top") { this.nowFootholdPos = { info: this.allFootHolds[i], x: this.baseX, y: this.allFootHolds[i].img.y }; break; } else { if (gc.game.myCha) { if (this.allFootHolds[i].step == gc.game.myCha.step && this.allFootHolds[i].stair == "top") { this.nowFootholdPos = {//실제 이미지 좌표가 아닌 값만 바꿔야 하는 경우기 있기 때문에 x, y 좌표 따로 저장 info: this.allFootHolds[i], x: this.allFootHolds[i].img.x, y: this.allFootHolds[i].img.y }; break; } } } } }; //발판 내리기 gc.Map.prototype.pullDownFootHolds = function () { // console.log("발판 내리기"); var i; var moveTime = 0.35; var moveDist = (this.baseY - this.nowFootholdPos.info.fhHeight * 2) - this.nowFootholdPos.y; gc.game.scrollBackground(moveTime, moveDist); this.nowFootholdPos.y -= moveDist; var moveList = []; //발판 내리기 for (i = 0; i < this.allFootHolds.length; i++) { if (this.allFootHolds[i].isWork) { this.allFootHolds[i].img.y += moveDist; moveList.push(this.allFootHolds[i].img); } } if (gc.game.portal) { gc.game.portal.y += moveDist; moveList.push(gc.game.portal); } //유저 내리기 gc.game.myCha.y += moveDist; var pushPlayer = false;//유저를 완전히 내릴지 여부 if (gc.chapter == 5 && gc.progress.endStep - gc.progress.nowStep == 1) pushPlayer = true; if (this.nowFootholdPos.info.skillType != "jump") pushPlayer = true; if (pushPlayer) { gc.game.myCha.img.y = gc.game.myCha.y; moveList.push(gc.game.myCha.img);//점프타입 발판에 올라선 경우 내려가는 애니 없이 바로 이미지 내리기 } else { var time = 0.15;//점프발판 자동 점프 딜레이 시간 TweenMax.to(gc.game.myCha.img, time, { y: gc.game.myCha.y - moveDist * (0.3) }); } //새 장애물 내리기 for (i = 0; i < gc.game.obstacle.birds.length; i++) { if (gc.game.obstacle.birds[i].isWork) { gc.game.obstacle.birds[i].center.y += moveDist; moveList.push(gc.game.obstacle.birds[i].center); } } this.setNowFootHoldPos();//유저가 서있는 발판 좌표저장 if (moveList.length > 0) this.inPulldownFh = true; for (i = 0; i < moveList.length; i++) { TweenMax.from(moveList[i], moveTime, { y: moveList[i].y - moveDist, onComplete: (function (i) { if (i == moveList.length - 1) { this.resetFootHoldsData();//보이지 않는 발판 정보 초기화 this.removeUnusedFootHolds();//발판을 내리고 나서 쓰이지 않는 발판 제거 this.inPulldownFh = false; } }).bind(this, i) }); } }; //발판 부착 gc.Map.prototype.attachFootHold = function (fhs, dist) { var i; var initEf = false; var vx = null; var con = null; for (i = fhs.length - 1; i >= 0; i--) { fhs[i].img.scale.x = 1; if (fhs[i].skillType == "slide") { if (fhs[i].dir == 1) fhs[i].img.scale.x = -1; } vx = (this.nowFootholdPos.info.fhWidth + fhs[i].fhWidth) * (0.8) * dist; if (this.initFootholdInfo.dir == -1) vx *= -1; if (this.firstFh) vx = 0; fhs[i].img.x = this.nowFootholdPos.x + vx; fhs[i].img.y = this.baseY - 65 * (i); //맨 아래 발판 생성시 좌표, 정보 저장 if (i == 0) { this.initFootholdInfo.x = fhs[i].img.x; this.initFootholdInfo.dir = fhs[i].dir; this.initFootholdInfo.step = fhs[i].step; } //맨 위 발판 생성시 다음 발판 위치로 저장 if (fhs[i].stair == "top") { this.nextFootholdPos.info = fhs[i]; this.nextFootholdPos.x = fhs[i].img.x; this.nextFootholdPos.y = fhs[i].img.y; this.resetAnimateFull(fhs[i].img);//최상위 발판 이미지는 세팅 이미지도 초기화 this.setBasicAnimate(fhs[i].img); } else { this.setBarAnimate(fhs[i].img); } } if (!this.inPulldownFh) this.setNowFootHoldPos();//유저가 서있는 발판 저장 this.setFootHoldDist();//현재 유저 위치와 도달해야 할 발판 사이 거리 //생성 이펙트 발생 여부 for (i = fhs.length - 1; i >= 0; i--) { initEf = this.checkInitEffect(fhs[i]); if (initEf) { var moveTime = 0.3; if (i == 0) {//장애물 발생 설정 gc.game.setObstacleBird(fhs.length * fhs[i].fhHeight, moveTime); } TweenMax.delayedCall(0.03 * ((fhs.length - 1) - i), (function (i) { TweenMax.from(fhs[i].img, moveTime, { y: fhs[i].img.y + fhs.length * fhs[i].fhHeight, onComplete: (function (i) { this.updateTransform(); if (fhs[i].stair == "top") this.setBasicAnimate2(fhs[i].img); else this.setBarAnimate2(fhs[i].img); // if(fhs[i].stair == "top") this.setInitAnimate(fhs[i].img); // else this.setBarInitAnimate(fhs[i].img); if (i == fhs.length - 1) {//발판이 모두 올라온 후 장애물 발생 설정 gc.game.setObstacleBlackout(); } }).bind(this, i) }); //필요한 컨테이너 찾기 con = this.findContainer(fhs[i].step); con.center.addChildAt(fhs[i].img, 0);//위쪽 발판부터 붙이기 gc.game.setMidContainer(0);//레이어 설정 }).bind(this, i)); } else { //필요한 컨테이너 찾기 con = this.findContainer(fhs[i].step); con.center.addChildAt(fhs[i].img, 0);//위쪽 발판부터 붙이기 gc.game.setMidContainer(0);//레이어 설정 } } }; //필요한 컨테이너 찾기 gc.Map.prototype.findContainer = function (step) { var i; var con = null; for (i = 0; i < this.mapContainers.length; i++) { if (this.mapContainers[i].step == parseInt(step) || this.mapContainers[i].center.children.length == 0) {//스텝이 같거나 컨테이너에 차일드가 없을 때 this.mapContainers[i].step = parseInt(step); con = this.mapContainers[i]; break; } } if (!con) { this.mapContainers.push({ step: step, center: new PIXI.Container() }); con = this.mapContainers[this.mapContainers.length - 1]; } return con; }; //화면에 붙일 때 떨어지는 애니 여부 gc.Map.prototype.checkInitEffect = function (target) { var onEf = true; if (this.firstFh) { onEf = false; } return onEf; }; //얼음 발판 폭파 타이머 gc.Map.prototype.setQuakeFootHolds = function (step) { var i; var list = []; for (i = 0; i < this.allFootHolds.length; i++) { if (this.allFootHolds[i].isWork && this.allFootHolds[i].step == step) { if (this.allFootHolds[i].skillType == "ice") { list.push(this.allFootHolds[i]); } } } for (i = 0; i < list.length; i++) { this.earthquakeFootholds(list[i], list[i].img.x, true);//3초간 발판 흔들기 } }; //얼음 흔들림 취소 gc.Map.prototype.stopQuakeFootHold = function (fh) { for (var i = 0; i < this.quakeTweeners.length; i++) { if (this.quakeTweeners[i].fh == fh) { this.quakeTweeners[i].tween.kill(); this.quakeTweeners[i].explodeDelay.kill(); this.quakeTweeners.splice(i, 1); break; } } }; //모든 얼음 흔들림 취소 gc.Map.prototype.resetQuakeFootHolds = function () { for (var i = 0; i < this.quakeTweeners.length; i++) { this.quakeTweeners[i].tween.kill(); this.quakeTweeners[i].explodeDelay.kill(); } this.quakeTweeners = []; }; //3초간 발판 흔들기.. 0.1초동안 한 방향으로 움직임->30번 움직이면 3초 gc.Map.prototype.earthquakeFootholds = function (fh, xPos, firstQuake) { var aimX; var tweener = this.findQuakeTween(fh, xPos, firstQuake); if (firstQuake) { var explodeTime = 3; tweener.explodeDelay = TweenMax.delayedCall(explodeTime, (function () { this.setExplodeAnimate(tweener.fh.img); gc.game.checkPlayerInIceFootHold(tweener.fh.step); }).bind(this)); } firstQuake = false; if (tweener) { if (tweener.cnt % 2 == 0) aimX = tweener.centerX + 0.2 * tweener.cnt; else aimX = tweener.centerX - 0.2 * tweener.cnt; tweener.tween = TweenMax.to(tweener.fh.img, 0.1, { x: aimX, onComplete: (function () { tweener.cnt++; if (tweener.cnt < 28) this.earthquakeFootholds(tweener.fh, xPos, firstQuake); else fh.img.x = xPos; }).bind(this) }); } }; //흔들리고 있는 트위너 찾기 gc.Map.prototype.findQuakeTween = function (fh, xPos, firstQuake) { var tween = null; for (var i = 0; i < this.quakeTweeners.length; i++) { if (fh == this.quakeTweeners[i].fh) { tween = this.quakeTweeners[i]; break; } } if (!tween && firstQuake) { this.quakeTweeners.push({ tween: null, fh: fh, centerX: xPos, cnt: 0, explodeDelay: null }); tween = this.quakeTweeners[this.quakeTweeners.length - 1]; } return tween; }; //유저가 점프해서 자리에 안착 gc.Map.prototype.jumpIn = function () { for (var i = 0; i < this.allFootHolds.length; i++) { if (this.allFootHolds[i].step == gc.game.myCha.step) { if (this.allFootHolds[i].stair == "top") { // console.log("유저가 안착한 발판"); this.setBasicAnimate2(this.allFootHolds[i].img); break; } } } }; //보이지 않는 발판 정보 초기화 gc.Map.prototype.resetFootHoldsData = function () { var i = 0; var resetList = []; for (i = 0; i < this.allFootHolds.length; i++) { if (this.allFootHolds[i].isWork) { //내 스텝보다 발판 스텝이 낮고, 화면 밖에 있는 경우 if (this.allFootHolds[i].step < gc.game.myCha.step && this.allFootHolds[i].img.y >= gc.height + 300) { if (this.allFootHolds[i].skillType == "ice") this.stopQuakeFootHold(this.allFootHolds[i]);//흔들리고 있는 발판 취소 resetList.push(this.allFootHolds[i]); } } } for (i = 0; i < resetList.length; i++) { resetList[i].isWork = false; resetList[i].step = null; resetList[i].stair = null; resetList[i].dir = null; } }; //폭파된 발판 정보 초기화 gc.Map.prototype.resetIceFootHoldData = function (obj) { var i; var fh = null; for (i = 0; i < this.allFootHolds.length; i++) { if (this.allFootHolds[i].img == obj) { fh = this.allFootHolds[i]; break; } } if (fh) { fh.isWork = false; fh.step = null; fh.stair = null; fh.dir = null; } }; //모든 발판 초기화 gc.Map.prototype.resetAllFootHold = function () { for (var i = 0; i < this.allFootHolds.length; i++) { this.allFootHolds[i].isWork = false; this.allFootHolds[i].step = null; this.allFootHolds[i].stair = null; this.allFootHolds[i].dir = null; } }; //발판 다시 그리기 gc.Map.prototype.removeUnusedFootHolds = function () { for (var i = 0; i < this.allFootHolds.length; i++) { if (!this.allFootHolds[i].isWork) removeObject(this.allFootHolds[i].img); } }; //현재 서있는 발판 찾아서 점프 대기 상태 애니 실행 gc.Map.prototype.waitJumpAnimate = function () { for (var i = 0; i < this.allFootHolds.length; i++) { if (this.allFootHolds[i].isWork) { if (this.allFootHolds[i].step == gc.game.myCha.step && this.allFootHolds[i].stair == "top") { this.setPressAnimate(this.allFootHolds[i].img); break; } } } }; //유저가 점프했던 발판 복구 gc.Map.prototype.jumpAnimate = function () { for (var i = 0; i < this.allFootHolds.length; i++) { if (this.allFootHolds[i].isWork) { if (this.allFootHolds[i].step == gc.game.myCha.step && this.allFootHolds[i].stair == "top") { // console.log("유저가 뛴 발판"); if (this.allFootHolds[i].skillType == "jump") this.setBasicAnimate3(this.allFootHolds[i].img); else this.setBasicAnimate2(this.allFootHolds[i].img); break; } } } }; //발판이 화면 사이드 밖으로 나갔는지 체크 gc.Map.prototype.checkFootHoldsOutofScene = function () { // console.log("발판 사이드 아웃 확인"); this.resetQuakeFootHolds();//흔들림 멈추기 var i; var moveTime = 0.3; var maxPos = this.baseX + 440; var moveList = []; var isOut = false; if (this.nextFootholdPos.x < this.baseX || this.nextFootholdPos.x > maxPos) { // console.log("발판 사이드로 나갔음"); isOut = true; var outDist = 0; if (this.nextFootholdPos.x < this.baseX) {//화면 왼쪽 바깥에 발판이 생겼을 때 outDist = this.nextFootholdPos.x - this.baseX; } else if (this.nextFootholdPos.x > maxPos) {//화면 오른쪽 바깥에 발판이 생겼을 때 outDist = this.nextFootholdPos.x - (maxPos); } //바뀔 현재 좌표와 다음 발판 좌표 변경 this.nowFootholdPos.x -= outDist; this.nextFootholdPos.x -= outDist; //추가점수 텍스트 옮기기 TweenMax.to(gc.game.addScoreText, moveTime, { x: this.nowFootholdPos.x }); //특수 이펙트 텍스트 옮기기 if (gc.game.specialMessage) TweenMax.to(gc.game.specialMessage, moveTime, { x: this.nowFootholdPos.x }); //발판 옮기기 for (i = 0; i < this.allFootHolds.length; i++) { this.allFootHolds[i].img.x -= outDist; moveList.push(this.allFootHolds[i].img); // TweenMax.to(this.allFootHolds[i].img, moveTime, {x: this.allFootHolds[i].img.x - outDist}); } gc.game.myCha.x -= outDist; gc.game.myCha.img.x = gc.game.myCha.x; moveList.push(gc.game.myCha.img); //새 장애물이 있는 경우 함께 이동 for (i = 0; i < gc.game.obstacle.birds.length; i++) { if (gc.game.obstacle.birds[i].isWork) { gc.game.obstacle.birds[i].center.x -= outDist; moveList.push(gc.game.obstacle.birds[i].center); // TweenMax.from(gc.game.obstacle.birds[i].center, moveTime, {x:gc.game.obstacle.birds[i].center.x + outDist}); } } } if (isOut) { for (i = 0; i < moveList.length; i++) { TweenMax.from(moveList[i], moveTime, { x: moveList[i].x + outDist }); } TweenMax.delayedCall(moveTime + 0.1, (function () { this.setQuakeFootHolds(gc.game.myCha.step); }).bind(this)); } else { this.setQuakeFootHolds(gc.game.myCha.step); } }; //-----------발판 애니메이션 //최상단 발판 기본 애니 gc.Map.prototype.setBasicAnimate = function (obj) { var aniname = "foothold_basic"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, true, 0); }; //하단 발판 기본 애니 gc.Map.prototype.setBarAnimate = function (obj) { var aniname = "bg_basic"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, true, 0); }; //튕기는 애니 gc.Map.prototype.setBasicAnimate2 = function (obj) { var aniname = "foothold_basic2"; this.resetAnimate(obj); obj.state.setAnimation(2, aniname, false, 0); }; //점프발판 튕기기 gc.Map.prototype.setBasicAnimate3 = function (obj) { var aniname = "foothold_basic3"; this.resetAnimate(obj); obj.state.setAnimation(2, aniname, false, 0); }; gc.Map.prototype.setBarAnimate2 = function (obj) { var aniname = "bg_basic2"; this.resetAnimate(obj); obj.state.setAnimation(10, aniname, false, 0); }; //발판 폭파 gc.Map.prototype.setExplodeAnimate = function (obj) { var aniname = "foothold_burst"; this.resetAnimate(obj); obj.state.setAnimation(3, aniname, false, 0); }; //누르고 있을 때 애니 gc.Map.prototype.setPressAnimate = function (obj) { var aniname = "foothold_on"; this.resetAnimate(obj); obj.state.setAnimation(4, aniname, false, 0); }; //포탈 애니메이션 gc.Map.prototype.setPortalAppear = function (obj) { var aniname = "portal_appear"; this.resetAnimate(obj); obj.state.setAnimation(100, aniname, false, 0); }; gc.Map.prototype.resetAnimate = function (obj) { obj.state.clearTracks(); obj.state.timeScale = 1; // obj.update(1); // obj.state.setEmptyAnimation(0,1); }; //발판의 경우 최초 세팅 이미지가 다를 수 있으므로(장애물 발판의 경우) 맨 위의 발판 이미지만 최초 이미지로 설정시킴 gc.Map.prototype.resetAnimateFull = function (obj) { obj.skeleton.setToSetupPose(); this.resetAnimate(obj); }; //리셋 gc.Map.prototype.reset = function () { for (var i = 0; i < this.mapContainers.length; i++) { this.mapContainers[i].center.removeChildren(); } this.preDir = 0; this.nextDir = 1; this.sameDirCnt = 0; this.baseX = 140; this.baseY = 1160; this.nowFootholdPos = { info: null, x: this.baseX, y: this.baseY };//유저가 서있는 발판 좌표 this.nextFootholdPos = { info: null, x: 0, y: 0 };//건너가야할 발판 좌표 this.initFootholdInfo = { x: this.baseX, y: this.baseY, dir: 1, step: 0, floor: 3 };//생성되는 발판 정보 this.footHoldGapX = 0; this.footHoldGapY = 0; this.footHoldGap = 0;//다음 발판까지의 거리..기본 거리*층수 this.firstFh = true;//각 챕터의 첫번째 발판인지 여부 this.inPulldownFh = false;//발판 내리는 중 }; gc.Map.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /** * Created by admin on 2018-04-05. */ gc.Gravity = function () { PIXI.Container.call(this); this.gravity = 9.8; this.chargePow = 0; if (this.jumpAngle >= 0) this.jumpAngle -= Math.PI / 180; this.guideLight = []; this.onGuide = false; }; gc.Gravity.constructor = gc.Gravity; gc.Gravity.prototype = Object.create(PIXI.Container.prototype); gc.Gravity.prototype.addPow = function () { var prePow = this.chargePow; var limit = 70; this.chargePow += this.setChargeVelocity(); //일정 파워 이상 충전했을 때 충전 이펙트 보이기 if (prePow < limit && this.chargePow >= limit) { gc.game.onChargeEffect(); } // if(gc.chapter == 1 && gc.progress.nowStep <10) this.onGuide = true; if (gc.progress.nowStep < 10) this.onGuide = true; else this.onGuide = false; if (this.onGuide) this.setGuideLine(this.chargePow, 1 - (gc.progress.nowStep / 10));//가이드라인 그리기 if (this.chargePow >= 1500) this.chargePow = 1500; }; //충전되는 속도 조절 gc.Gravity.prototype.setChargeVelocity = function () { var velocity = 8; //기존 수치 // if(this.chargePow > 1000) velocity = 15; // else if(this.chargePow > 500) velocity = 13; // else if(this.chargePow > 300) velocity = 10; // else if(this.chargePow > 100) velocity = 8; // else velocity = 5; //변경수치1 if (this.chargePow > 1000) velocity = 8 * 1.5 * 1.5 * 1.5 * 1.5; else if (this.chargePow > 500) velocity = 8 * 1.5 * 1.5 * 1.5; else if (this.chargePow > 300) velocity = 8 * 1.5 * 1.5; else if (this.chargePow > 100) velocity = 8 * 1.5; else velocity = 8; return velocity; }; gc.Gravity.prototype.resetPow = function () { this.chargePow = 0; }; //점프 결과 값 계산 gc.Gravity.prototype.calcJumpResult = function (pow) { // this.chargePow = gc.maps.footHoldGap; var result = null; var vx, vy; var chargePow = pow || this.chargePow; vx = (gc.maps.footHoldGapX) * (chargePow / gc.maps.footHoldGap); vx = (gc.game.myCha.jumpDir == 1) ? vx : -vx; vy = -(gc.maps.footHoldGapY) * (chargePow / gc.maps.footHoldGap); console.log(vx, vy, chargePow) //유저가 도달할 위치 var px = gc.game.myCha.x + vx; var py = gc.game.myCha.y + vy; //발판 히트 영역 확인 var hitClone = gc.maps.nextFootholdPos.info.hitArea.clone(); var inside = this.checkInside("nextFh", px, py, hitClone); //거리 체크할 발판 좌표 var fhX = gc.maps.nextFootholdPos.x, fhY = gc.maps.nextFootholdPos.y; var dist = Math.sqrt((px - fhX) * (px - fhX) + (py - fhY) * (py - fhY)); if (inside) {//범위내에 올라갔을 때 //y좌표 수정.. 블럭 가운데 라인에 있게끔하기 hitClone = gc.maps.nextFootholdPos.info.hitArea.clone(); if (gc.game.myCha.jumpDir == 1) py = fhY - (px - fhX); else py = fhY - (fhX - px); dist = Math.sqrt((px - fhX) * (px - fhX) + (py - fhY) * (py - fhY)); //좌표를 옮긴 후 다시 체크 inside = this.checkInside("nextFh", px, py, hitClone); if (inside) { vx = px - gc.game.myCha.x; vy = py - gc.game.myCha.y; if (dist <= 10) result = "perfect"; else if (dist <= 40) result = "nice"; else result = "good"; } else {//좌표를 옮긴 후 발판에서 떨어지는 경우 result = this.checkFalldown("nextFh", px, py).result; } } else {//범위내에 올라가지 못했을 때 result = this.checkFalldown("nextFh", px, py).result; } return { result: result, vx: vx, vy: vy }; }; //발판 줄기와 유저의 목적지 사이 거리.. 유저가 더 가야할 거리 gc.Gravity.prototype.calcSideGapWithPlayer = function (px) { var moveDist = 0; var fh = gc.maps.nextFootholdPos.info; var fhName = gc.maps.fhNames[fh.imgType]; var imgName = null; if (fh.imgType == 0) { if (gc.game.myCha.jumpDir == 0) imgName = "foothold" + (fh.skin + 1) + "_side1"; else imgName = "foothold" + (fh.imgType + 1) + "_side2"; } else if (fh.imgType == 1) {//버섯 imgName = "foothold_side0"; } else if (fh.imgType == 100) {//얼음 if (gc.game.myCha.jumpDir == 1) imgName = "ice_side1"; else imgName = "ice_side2"; } else if (fh.imgType == 200) {//슬라이드 if (gc.game.myCha.jumpDir == 1) imgName = "foothold_rail_side1"; else imgName = "foothold_rail_side2"; } else if (fh.imgType == 300) {//점프 imgName = "foothold_jump_back2"; } var atlasData = GD.loader.resources[fhName].spineAtlas; var region = atlasData.findRegion(imgName); var fhWidth = region.originalWidth * 0.7; var gap = Math.abs(fh.img.x - px);//유저와 발판 사이 거리 if (gap > fhWidth) moveDist = gap - fhWidth; if (gc.game.myCha.jumpDir == -1) moveDist *= -1; return moveDist; }; //발판 위에 올라섰는지 확인 gc.Gravity.prototype.checkInside = function (checkFh, px, py, hitClone) { var i; if (checkFh == "nextFh") {//다음 발판에 올라섰는지 확인 for (i = 0; i < hitClone.points.length; i++) { if (i % 2 == 0) hitClone.points[i] += gc.maps.nextFootholdPos.x; else hitClone.points[i] += gc.maps.nextFootholdPos.y; } } else if (checkFh == "nowFh") {//현재 발판에 올라섰는지 확인 for (i = 0; i < hitClone.points.length; i++) { if (i % 2 == 0) hitClone.points[i] += gc.maps.nowFootholdPos.x; else hitClone.points[i] += gc.maps.nowFootholdPos.y; } } return hitClone.contains(px, py); }; //떨어지는 경우 분리 gc.Gravity.prototype.checkFalldown = function (checkFh, px, py) { var hitClone = null; var danger = false; var dist = null;//발판과 유저 사이 거리 var fh = null;//해당 발판 var result = null; if (checkFh == "nextFh") { fh = gc.maps.nextFootholdPos; } else if (checkFh == "nowFh") { fh = gc.maps.nowFootholdPos; } hitClone = fh.info.dangerArea.clone(); danger = this.checkInside(checkFh, px, py, hitClone); dist = Math.abs(px - fh.x);//발판과 유저 사이 거리 if (danger) result = "danger"; else if (dist > fh.info.fhWidth) result = "too much"; else { if (gc.game.myCha.jumpDir == 1) { if (px <= fh.x) result = "weak"; else result = "too much"; } else { if (px <= fh.x) result = "too much"; else result = "weak"; } } return { result: result }; }; //제자리 점프 체크 gc.Gravity.prototype.checkInSameFootHold = function () { var result = null; var px = gc.game.myCha.x; var py = gc.game.myCha.y; var hitClone = gc.maps.nowFootholdPos.info.hitArea.clone(); var inside = this.checkInside("nowFh", px, py, hitClone); if (inside) result = "stand"; else result = this.checkFalldown("nowFh", px, py); return result; }; //점프경로 저장.. 뛸때마다 계산 or 미리 만들어두고 좌표만 조금씩 바꾸기 gc.Gravity.prototype.setGuideLine = function (pow, alpha) { console.log(pow) this.resetGuideLight(); var px, py; var vx, vy; //목적지 좌표 구하기 px = gc.game.myCha.x; py = gc.game.myCha.y; var result = this.calcJumpResult(pow); vx = Math.abs(result.vx); if (gc.game.myCha.jumpDir == -1) vx *= -1; vy = result.vy; // 벽에 부딪치는 경우 목표 x좌표의 조정 if (result.result == "weak") vx += this.calcSideGapWithPlayer(px + vx);//유저와 다음발판 줄기 사이의 거리 var topY = vy - (py - vy) * 0.05; var upGoalX = 0; var upGoalY = topY; if (result.result == "too much") upGoalX = vx * 0.68; else upGoalX = vx * 0.6; //시작 좌표 var startUpX = px; var startUpY = py; if (gc.maps.nowFootholdPos.info.skillType == "jump") startUpY = this.myCha.img.y; var startDownX = startUpX + upGoalX; var startDownY = startUpY + upGoalY; //꼭대기 좌표 var peakX = startUpX + upGoalX; var peakY = startUpY + upGoalY; var downGoalX = vx - upGoalX; var downGoalY = (topY - vy); var isLandingAni = (result.result == "perfect" || result.result == "nice" || result.result == "good"); if (!isLandingAni) {//다음 발판에 올라가지 못함 if (result.result != "danger") { if (result.result == "too much") { downGoalY = -(gc.height - peakY); downGoalX = vx * 0.5; } } } //목표 좌표 var endX = startDownX + downGoalX; var endY = startDownY - downGoalY; var onGuide = true; if (result.result == "too much") { if (gc.game.myCha.jumpDir == 1 && endX <= gc.maps.nextFootholdPos.x) onGuide = false; else if (gc.game.myCha.jumpDir == -1 && endX >= gc.maps.nextFootholdPos.x) onGuide = false; } if (onGuide) { var i, i_len; //위로 올라갈 때 경로 var upLine = new PIXI.Graphics(); upLine.lineStyle(10, 0x0000ff); upLine.moveTo(px, py); upLine.quadraticCurveTo((startUpX + upGoalX * 0.2), (startUpY + upGoalY * 0.9), peakX, peakY); var points = upLine.currentPath.shape.points; points = this.setUseGuidePoint(points); //점이 너무 많으니 걸러내기 var light = null; for (i = points.length - 1; i > 0; i -= 2) { //점 이미지 그리기 light = null; light = this.findGuideLight(); light.img.x = points[i - 1]; light.img.y = points[i]; light.img.alpha = alpha; var childCnt = gc.game.midContainer.children.length; gc.game.midContainer.addChildAt(light.img, childCnt - 1); } //내려올 때 경로 var downLine = new PIXI.Graphics(); downLine.lineStyle(5, 0x0000ff); downLine.moveTo(peakX, peakY); downLine.quadraticCurveTo((startDownX + downGoalX * 0.85), (startDownY - downGoalY * 0.1), endX, endY); points = downLine.currentPath.shape.points; points.splice(0, 2); points = this.setUseGuidePoint(points); points.push(endX); points.push(endY); if (result.result == "too much") i = 2; else i = 2; for (i, i_len = points.length; i < i_len; i += 2) { //점 이미지 그리기 light = null; light = this.findGuideLight(); light.img.x = points[i]; light.img.y = points[i + 1]; light.img.alpha = alpha; if (gc.game.myCha.jumpDir == 1) { if (light.img.x >= gc.maps.nextFootholdPos.x + gc.maps.nextFootholdPos.info.fhWidth * 0.2) gc.game.midContainer.addChildAt(light.img, 0); else gc.game.midContainer.addChild(light.img); } else { if (light.img.x >= gc.maps.nextFootholdPos.x - gc.maps.nextFootholdPos.info.fhWidth * 0.2) gc.game.midContainer.addChild(light.img); else gc.game.midContainer.addChildAt(light.img, 0); } } } }; //사용할 점 리스트 추리기 gc.Gravity.prototype.setUseGuidePoint = function (list) { var points = list; var dist = 0; // for(var i=0; i=i+2; j-=2) { // dist = Math.pow((points[i] - points[j]), 2) + Math.pow((points[i+1] - points[j+1]), 2); // if(dist <= Math.pow(50,2)) { // points.splice(j, 2); // } // } // } for (var i = points.length - 2; i >= 3; i -= 2) { for (var j = 0; j < i; j += 2) { dist = Math.pow((points[i] - points[j]), 2) + Math.pow((points[i + 1] - points[j + 1]), 2); if (dist <= Math.pow(50, 2)) { points.splice(j, 2); } } } return points; }; //레이어 처리 gc.Gravity.prototype.checkDepth = function (checkX) { if (this.obstacle) { if (this.obstacle.offLight) this.setMidContainer(0);//암전상태일때는 유저가 가장 위에 보임 else { var px = checkX;//this.myCha.img.x; var fh = gc.maps.nextFootholdPos; if (this.myCha.jumpDir == 1) {//오른쪽으로 뛸 때 if (px <= fh.x) this.setMidContainer(2);//발판 사이에 떨어짐 else this.setMidContainer(1);//너무 멀리 뜀 } else {//왼쪽으로 뛸 때 if (px <= fh.x) this.setMidContainer(1);//너무 멀리 뜀 else this.setMidContainer(2);//발판 사이에 떨어짐 } } } }; //가이드라인 이미지 생성 gc.Gravity.prototype.findGuideLight = function () { var light = null; for (var i = 0; i < this.guideLight.length; i++) { if (!this.guideLight[i].isWork) { light = this.guideLight[i]; light.isWork = true; break; } } if (light === null) { this.guideLight.push({ img: new PIXI.Sprite.fromFrame("guide.png"), isWork: true }); this.guideLight[this.guideLight.length - 1].img.anchor.x = 0.5; this.guideLight[this.guideLight.length - 1].img.anchor.y = 1; light = this.guideLight[this.guideLight.length - 1]; } return light; }; //가이드라인 이미지 초기화 gc.Gravity.prototype.resetGuideLight = function () { for (var i = 0; i < this.guideLight.length; i++) { removeObject(this.guideLight[i].img); this.guideLight[i].isWork = false; } }; gc.Gravity.prototype.reset = function () { this.resetPow(); }; gc.Gravity.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; /** * Created by admin on 2018-04-05. */ gc.Characters = function () { PIXI.Container.call(this); this.charNames = [ 'cha1' ]; this.chaList = []; }; gc.Characters.constructor = gc.Characters; gc.Characters.prototype = Object.create(PIXI.Container.prototype); gc.Characters.prototype.init = function (myCha) { this.makeCharacters(); return this.chaList[myCha]; }; //캐릭터 만들어두기 gc.Characters.prototype.makeCharacters = function () { var i = 0; for (i = 0; i < this.charNames.length; i++) { this.chaList[i] = new PIXI.spine.Spine(GD.loader.resources[this.charNames[i]].spineData); this.setSpineListener(this.chaList[i]); } }; //-----------애니메이션 완료 리스너 gc.Characters.prototype.setSpineListener = function (obj) { obj.state.addListener({ complete: (function (t) { if (t.animation.name == "cha_fail_over" || t.animation.name == "cha_fail_over2" || t.animation.name == "cha_fail_hit") {//착지 실패 gameOver(); } }).bind(this), event: (function (t, event) { if (t.animation.name == "cha_fail_over" && event.data.name == "cha_event1") { gc.game.checkDepth(gc.game.myCha.img.x);//이벤트를 받을 때 유저 오브젝트 이미지 위치로 레이어 설정 } }) }); }; //------------애니메이션 //가만히 서있는 애니메이션 gc.Characters.prototype.standAnimate = function (obj) { var aniname = "cha_basic"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, true); }; //점프 대기 gc.Characters.prototype.waitJumpAnimate = function (obj) { var aniname = "cha_touchon"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, false, 0); }; //점프 중 gc.Characters.prototype.jumpAnimate = function (obj) { var aniname = "cha_touchoff"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, true, 0); // # 캐릭터 회전애니 반복재생 }; //착지 성공 gc.Characters.prototype.standClearAnimate = function (obj) { this.resetAnimate(obj); var aniname = "cha_landing"; var aniObj = obj.state.setAnimation(0, aniname, false, 0); obj.state.addAnimation(0, "cha_basic", true, aniObj.animationEnd);//착지 성공 후 서있는 애니 실행 }; //착지 지점 실패.. 발판 끝에 떨어지기 gc.Characters.prototype.standFailAnimate = function (obj) { var aniname = "cha_fail_over"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, false, 0); }; //허공에 착지 gc.Characters.prototype.fallDownAnimate = function (obj) { var aniname = "cha_fail_over2"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, false, 0); }; //벽에 부딪쳐 떨어지기 gc.Characters.prototype.hitWallAnimate = function (obj) { var aniname = "cha_fail_hit"; this.resetAnimate(obj); obj.state.setAnimation(0, aniname, false, 0); }; gc.Characters.prototype.resetAnimate = function (obj) { obj.state.clearTracks(); obj.skeleton.setToSetupPose(); obj.state.timeScale = 1; //obj.update(1); //obj.state.setEmptyAnimation(0,1); }; //------------리셋 gc.Characters.prototype.reset = function () { if (gc.game.myCha) { this.standAnimate(gc.game.myCha); } }; gc.Characters.prototype.updateTransform = function () { try { PIXI.Container.prototype.updateTransform.call(this); } catch (e) { } }; // 게임 function onGame() { var chapterValue = window.localStorage.getItem('chapter'); if (chapterValue === undefined || chapterValue === null || chapterValue === '') { chapterValue = 1; } gc.chapter = JSON.parse(chapterValue); if (gc.intro) { gc.intro.reset(); GD.objSdk.hideAdIcon(); removeObject(gc.intro); } gc.intro = null; removeObject(gc.game); gc.game = null; if (!gc.game) gc.game = new gc.GameScene(); gc.game.init(); GD.stage.addChild(gc.game); GD.bgmStop(); if (gc.onBgm) GD.bgmPlay(0.8); if (gc.onFx) GD.soundPlay("sound_start"); } //游戏真正结束 function gameEnd() { window.localStorage.setItem('chapter', gc.chapter.toString()); if (gc.onFx) GD.soundPlay("sound_gameover"); gc.game.onStateMessage(2); removeObject(gc.game.myCha.img); GD.bgmStop(); } //게임오버 function gameOver() { // gameEnd(); if (gc.recoveryTimes <= 0) { gameEnd(); return; } if (gc.showVd && window.wx.createRewardedVideoAd) { afterGameEndWithShowVd(); } else if (gc.bShare) { afterGameEndWithShare(); } else { gameEnd(); } } function afterGameEndWithShare() { gc.menu.onMenuPopup('share') } function afterGameEndWithShowVd() { gc.menu.onMenuPopup('ad'); } //오브젝트 지우기 function removeObject(obj) { //어디에 붙어있던 부모를 찾아서 지우므로 어디에 붙어있는지 몰라도 됨. if (obj && obj.parent) obj.parent.removeChild(obj); }; // 인트로 function onIntro() { //사운드 팝업 if (!gc.soundPopup) gc.soundPopup = new gc.PopupSound(); //개별 인트로 if (gc.game) { TweenMax.killAll(); removeObject(gc.game); } gc.game = null; removeObject(gc.intro); gc.intro = null; if (!gc.intro) gc.intro = new gc.Intro(); gc.intro.init(); GD.stage.addChild(gc.intro); } module.exports = gc