遊戲關卡概念
每個遊戲一般都會需要關卡的概念,也就是過關後可以再重新進行遊戲,並且需要有關卡結局畫面。
今天我們就是要製作這樣的一個過關或遊戲結束的畫面,如下圖:
在pixi內使用文字
在pixi4.0之後可以直接利用pixi來做出很漂亮的文字效果,以下為官網的範例
var app = new PIXI.Application(800, 600, {backgroundColor: 0x1099bb}); document.body.appendChild(app.view); var basicText = new PIXI.Text('Basic text in pixi'); basicText.x = 30; basicText.y = 90; app.stage.addChild(basicText); var style = new PIXI.TextStyle({ fontFamily: 'Arial', fontSize: 36, fontStyle: 'italic', fontWeight: 'bold', fill: ['#ffffff', '#00ff99'], // gradient stroke: '#4a1850', strokeThickness: 5, dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6, wordWrap: true, wordWrapWidth: 440 }); var richText = new PIXI.Text('Rich text with a lot of options and across multiple lines', style); richText.x = 30; richText.y = 180; app.stage.addChild(richText);
成果如下:
現在更支援Bitmap font,請參見官網的demo
var app = new PIXI.Application(); document.body.appendChild(app.view); // // Load them google fonts before starting...! window.WebFontConfig = { google: { families: ['Snippet', 'Arvo:700italic', 'Podkova:700'] }, active: function() { // do something init(); } }; // include the web-font loader script /* jshint ignore:start */ (function() { var wf = document.createElement('script'); wf.src = ('https:' === document.location.protocol ? 'https' : 'http') + '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js'; wf.type = 'text/javascript'; wf.async = 'true'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(wf, s); })(); /* jshint ignore:end */ function init() { PIXI.loader .add('desyrel', 'required/assets/desyrel.xml') .load(onAssetsLoaded); function onAssetsLoaded() { var bitmapFontText = new PIXI.extras.BitmapText('bitmap fonts are\n now supported!', { font: '35px Desyrel', align: 'right' }); bitmapFontText.x = app.screen.width - bitmapFontText.textWidth - 20; bitmapFontText.y = 20; app.stage.addChild(bitmapFontText); } }
顯示成果如下:
新增遊戲關卡畫面
新增檔案GameRoundEnd.ts
,內容如下:
import Container = PIXI.Container; import { eventEmitter } from "../Main"; import { GameFlowEvent } from "../core/Event"; export class GameRoundEnd extends Container { private text:PIXI.Text; constructor() { super(); this.interactive = true; this.visible = false; eventEmitter.on(GameFlowEvent.GameEndWithTimeout, ()=>{ this.text.text = "Time is up!"; this.text.x = 260; this.text.y = 200; this.visible = true; }); eventEmitter.on(GameFlowEvent.GameEndWithNoPath, ()=>{ this.text.text = "Game over"; this.text.x = 260; this.text.y = 200; this.visible = true; }); eventEmitter.on(GameFlowEvent.GamePass, ()=>{ this.text.text = "Congratulations! \nYou passed!"; this.text.x = 210; this.text.y = 200; this.visible = true; }); //黑底 let gt = new PIXI.Graphics(); gt.beginFill(0x000000, 0.9); gt.drawRect(0,0,860,540); gt.endFill(); this.addChild(gt); //文字 this.text = new PIXI.Text("Congratulations! \nYou passed!", { fontWeight: 'bold', fontSize: 60, fontFamily: 'Arial', fill: '#ff0000', align: 'center', stroke: '#FFFFFF', strokeThickness: 3 }); this.addChild(this.text); //再玩一次按鈕 let btn = new PIXI.Graphics(); btn.beginFill(0x75C7ED); btn.drawRoundedRect(700,480,115,35,10); btn.endFill(); btn.buttonMode = true; btn.interactive = true; btn.on("mouseup", this.trigger.bind(this)); btn.on("touchend", this.trigger.bind(this)); this.addChild(btn); let newGame = new PIXI.Text("New Game", { fontWeight: 'bold', fontSize: 20, fontFamily: 'Arial', fill: '#75C6ED', align: 'center', stroke: '#FFFFFF', strokeThickness: 6 }); newGame.x = 705; newGame.y = 483; this.addChild(newGame); } public trigger(){ eventEmitter.emit(GameFlowEvent.CreateNewGameRequest); this.visible = false; } }
並修改GameBoard.ts
內iconClickHandler的內容如下
let iconClickHandler = ()=>{ this.cancelTips(); if (this.selected) { let selectCorrect = false; this.select2 = new Point(x, y); this.iconSelected(this.select2); setTimeout(()=>{ if (board.hasSameValue(this.select1, this.select2)) { if (! (this.select1.x == x && this.select1.y == y) ) { let path = new Path(this.select1, this.select2, board); if(path.canLinkInLine()){ this.pathHistory.push(path); this.valueHistory.push(board.getValue(this.select1)); LinkedLine.instance.drawPath(path); this.clearIcon(this.select1); this.clearIcon(this.select2); eventEmitter.emit(GameFlowEvent.LinkedLineSuccess); selectCorrect = true; //判斷還有沒有路走 if(board.gameRoundEnd()){ eventEmitter.emit(GameFlowEvent.GamePass); }else if(board.getFirstExistPath() == null){ if(reloadTimes > 0){ this.reloadBoard(); eventEmitter.emit(GameFlowEvent.BoardNeedReload); }else{ eventEmitter.emit(GameFlowEvent.GameEndWithNoPath); } } } } } if(selectCorrect){ SoundMgr.play('Sound_select_crrect'); }else{ SoundMgr.play('Sound_select_error'); this.iconUnSelected(this.select1); this.iconUnSelected(this.select2); } this.selected = false; },0); } else { this.select1 = new Point(x, y); this.iconSelected(this.select1); this.selected = true; SoundMgr.play('Sound_select_1'); } };
今日成果
線上demo:http://claire-chang.com/ironman2018/1109/
今日成果下載:ironman20181109