HTML5游戏引擎(十七)-egret引擎实战——踩格子游戏
第六章 踩格子游戏
逻辑分析
游戏配置
class GameData {
private static score:number = 0; //分数
public static row:number = 4; //行数
public static column:number = 4; //列数
public static speed:number = 10; //移动速度
private static _boxWidth:number = 0; //盒子宽度
private static _boxHeight:number = 0; //盒子高度
/**
* getScore
* 获取分数
*/
public static getScore():number {
return GameData.score;
}
/**
* setScore
* 设置分数
*/
public static setScore(val:number) {
GameData.score = val;
GameData.speed = 10+GameData.score;
}
/**
* getBoxWidth
* 获取格子宽度
*/
public static getBoxWidth():number {
if( GameData._boxWidth == 0) {
GameData._boxWidth = egret.MainContext.instance.stage.stageWidth / GameData.column;
}
return GameData._boxWidth;
}
/**
* getBoxHeight
* 获取格子高度
*/
public static getBoxHeight():number {
if( GameData._boxHeight == 0) {
GameData._boxHeight = egret.MainContext.instance.stage.stageHeight / GameData.row;
}
return GameData._boxHeight;
}
/**
* getStageHeight
* 获取当前屏幕高度
*/
public static getStageHeight():number {
return egret.MainContext.instance.stage.stageHeight;
}
/**
* getStageWidth
* 获取当前屏幕宽度
*/
public static getStageWidth():number {
return egret.MainContext.instance.stage.stageWidth;
}
}
入口文件
Main.ts作为项目入口文件,在构造函数中启动init方法
/**
* 游戏主入口文件
*/
class Main extends egret.DisplayObjectContainer {
public constructor() {
super();
console.log('start');
// 添加初始化事件
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.addStage, this);
}
// 移除事件 并初始化游戏
private addStage() {
this.removeEventListener(egret.Event.ADDED_TO_STAGE, this.addStage, this);
this.init()
}
/**
* 游戏参数
* gameview 画布
* timer 定时器
* gameoverPanel 游戏结束画布
* startgamePanel 开始游戏画布
*/
private gameview:GameView ;
private timer:egret.Timer;
private gameoverPanel:GameOverPanel;
private startgamePanel:StartGamePanel;
/**
* 初始化游戏函数
* 初始化gameview
* 初始化定时器
* 初始化开始|结束 画布
* 添加事件监听
*/
private init():void {
// ===1
this.gameview = new GameView();
this.addChild(this.gameview);
this.gameview.addEventListener(GameEvent.GAME_OVER, this.gameover,this);
this.timer = new egret.Timer(20,0);
this.timer.addEventListener(egret.TimerEvent.TIMER, this.timers, this);
this.gameoverPanel = new GameOverPanel();
this.gameoverPanel.addEventListener(GameEvent.GAME_START,this.startgame,this);
this.startgamePanel = new StartGamePanel();
this.startgamePanel.addEventListener(GameEvent.GAME_START, this.startgame, this);
this.addChild(this.startgamePanel);
}
/**
* 自动移动
*/
private timers() {
this.gameview.move();
}
/**
* 游戏结束
*/
private gameover(evt:GameEvent):void {
this.timer.stop();
this.gameoverPanel.update();
this.addChild(this.gameoverPanel);
}
/**
* 开始游戏
* 重新设置游戏速度 分数
* 去除游戏开始|结束画布
*/
private startgame(evt:GameEvent):void {
GameData.speed = 10;
GameData.setScore(0);
this.gameview.startgame();
if(this.startgamePanel.parent) {
this.removeChild(this.startgamePanel);
}
if(this.gameoverPanel.parent) {
this.removeChild(this.gameoverPanel);
}
this.timer.start();
}
}
游戏场景GameView
游戏中的整体逻辑
/**
* GameView
* 游戏界面
*/
class GameView extends egret.Sprite {
public constructor() {
super();
this.init();
}
/**
* _boxGroups
* msg: 一行格子
* type: Array => GroupRect
*/
private _boxGroups:Array<GroupRect>;
// 分数
private scoreText:egret.BitmapText;
/**
* init()
* 初始化函数
*/
private init():void {
this._boxGroups = [];
var len:number = GameData.row+1;
// 循环生成每一列格子
for(var i:number=0;i<len;i++) {
var boxg:GroupRect = new GroupRect();
this._boxGroups.push(boxg);
this.addChild(boxg);
boxg.addEventListener(GameEvent.GAME_OVER, this.gameOver, this);
boxg.addEventListener(GameEvent.GAME_HIT, this.clickRight, this);
}
/*
this.scoreText = new egret.TextField();
this.scoreText.textColor = 0xff0000;
this.scoreText.bold = true;
this.scoreText.size = 100;
*/
// 设置 分数
this.scoreText = new egret.BitmapText();
this.scoreText.x = 180;
this.scoreText.y = 50;
this.scoreText.text = String(0);
this.addChild(this.scoreText);
}
/**
* startgame
* 开始游戏
*/
public startgame():void {
// 初始化分数
this.scoreText.text = String(0);
var len:number = GameData.row+1;
// 循环创建格子
// 给格子赋值对应位置 y
for(var i:number=0;i<len;i++) {
this._boxGroups[i].create();
this._boxGroups[i].y = 0-GameData.getBoxHeight()*(1+i);
}
}
/**
* move()
* 点击正确 移动格子
*/
public move() {
var len:number = GameData.row+1;
for(var i:number=0;i<len;i++) {
// 游戏加速
this._boxGroups[i].y += GameData.speed;
//移动到舞台外侧了
if(this._boxGroups[i].y>=GameData.getStageHeight()){
// 如果格子没有被点击 游戏结束
if(!this._boxGroups[i].isHit) {
this.gameOver();
return;
}
// 设置对应格子的位置
if(i==0) {
this._boxGroups[i].y = this._boxGroups[4].y - GameData.getBoxHeight();
} else {
this._boxGroups[i].y = this._boxGroups[i-1].y - GameData.getBoxHeight();
}
this._boxGroups[i].create();
}
}
}
/**
* gameOver
* 游戏结束
*/
private gameOver(evt:GameEvent=null):void {
var event:GameEvent = new GameEvent(GameEvent.GAME_OVER);
this.dispatchEvent(event);
}
/**
* clickRight
* 游戏继续
*/
private clickRight(evt:GameEvent):void {
GameData.setScore(GameData.getScore()+1);
this.scoreText.text = String(GameData.getScore());
}
}
一行格子GroupRect
每一排格子的抽象类,会生成4个格子。
/**
* GroupRect
* 一行格子
*/
class GroupRect extends egret.Sprite {
public constructor() {
super();
this.init();
}
//Graphics方式
private _boxs:Array<BoxGraphics>;
// 初始化函数
private init():void {
this._boxs = [];
// 生成一行中的每一个格子 并给每个格子添加对应事件
for(var i:number=0;i<GameData.column;i++) {
var box:BoxGraphics = new BoxGraphics();
this._boxs.push(box);
box.addEventListener(GameEvent.GAME_HIT, this.clickRight, this);
box.addEventListener(GameEvent.GAME_OVER, this.boxGameOver, this);
this.addChild(box);
box.x = GameData.getBoxWidth()*i;
}
}
//创建一行新的box
public create():void {
this._isHit = false;
var touchIndex:number = Math.floor(Math.random()*4);
var len:number = this._boxs.length;
for(var i:number=0;i<len;i++) {
if(i==touchIndex) {
this._boxs[i].drawBox(true);
} else {
this._boxs[i].drawBox();
}
}
}
private _isHit:boolean = false; //本行是否被击中
public get isHit():boolean {
return this._isHit;
}
/**
* 点击正确
*/
private clickRight(evt:GameEvent):void {
if(!this._isHit) {
this._isHit = true;
var event:GameEvent = new GameEvent(GameEvent.GAME_HIT);
this.dispatchEvent(event);
}
}
/**
* 点击错误
* 游戏结束事件
*/
private boxGameOver(evt:GameEvent):void {
var event:GameEvent = new GameEvent(GameEvent.GAME_OVER);
this.dispatchEvent(event);
}
}
一个格子BoxGraphics
每一个小格子,可以绑定点击事件,决定游戏的成功与失败。
/**
* BoxGraphics
* 单个格子class
*/
class BoxGraphics extends egret.Shape {
public constructor() {
super();
this.init();
}
/**
* init()
* 初始化格子
*/
private init() {
this.touchEnabled = true;
this.width = GameData.getBoxWidth();
this.height = GameData.getBoxHeight();
this.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.click, this);
}
//参数表示当前方块是否可以备点击
private _canTouch:boolean = false;
/**
* drawBox
* 绘制内容
*/
public drawBox(canTouch:boolean=false) {
this._canTouch = canTouch;
this.graphics.clear();
if(canTouch) {
this.graphics.beginFill(0);
} else {
this.graphics.beginFill(0xffffff);
}
this.graphics.lineStyle(1, 0);
this.graphics.drawRect(0,0,GameData.getBoxWidth(),GameData.getBoxHeight());
this.graphics.endFill();
}
/**
* click
* 当前方块被点击后的响应事件
*/
private click(evt:egret.TouchEvent):void {
this.graphics.clear();
if(this._canTouch) {
this.graphics.beginFill(0xcccccc);
} else {
this.graphics.beginFill(0xff0000);
}
this.graphics.lineStyle(1, 0);
this.graphics.drawRect(0,0,GameData.getBoxWidth(),GameData.getBoxHeight());
this.graphics.endFill();
var event:GameEvent;
//不能点击,抛出错误事件
if(!this._canTouch) {
event = new GameEvent(GameEvent.GAME_OVER);
} else {
event = new GameEvent(GameEvent.GAME_HIT);
}
this.dispatchEvent(event);
}
}
事件绑定
游戏开始与结束的自定义事件
/**
* GameEvent
* 游戏事件
*/
class GameEvent extends egret.Event {
// 游戏结束
public static GAME_OVER:string = "game_over_event";
// 下一步(点击正确)
public static GAME_HIT:string = "game_hit_event";
// 开始游戏
public static GAME_START:string = "game_start_event";
public constructor(type:string, bubbles:boolean = false, cancelable:boolean = false) {
super(type,bubbles,cancelable);
}
}
游戏开始场景
/**
* 游戏开始时画布
*/
class StartGamePanel extends egret.Sprite {
public constructor() {
super();
this.init();
}
// 游戏背景
private _background:egret.Shape;
// 游戏按钮
private _startBtn:egret.TextField;
/**
* 初始化函数
*/
private init() {
// 设置背景
this._background = new egret.Shape();
this._background.graphics.beginFill(0);
this._background.graphics.drawRect(0,0,GameData.getStageWidth(),GameData.getStageHeight());
this._background.graphics.endFill();
this.addChild( this._background );
// 设置按钮
this._startBtn = new egret.TextField();
this._startBtn.text = "开始";
this._startBtn.size = 50;
this._startBtn.x = 180;
this._startBtn.y = 200;
this.addChild( this._startBtn );
this._startBtn.touchEnabled = true;
// 添加事件
this._startBtn.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.click, this);
}
/**
* 开始游戏
* click
*/
private click(evt:egret.TouchEvent):void {
var event:GameEvent = new GameEvent(GameEvent.GAME_START);
this.dispatchEvent(event);
}
}
游戏结束场景
/**
* GameOverPanel
* 游戏结束时的画布
*/
class GameOverPanel extends egret.Sprite {
public constructor() {
super();
this.init();
}
// 结束游戏时背景
private _background:egret.Shape;
// 显示得分
private _score:egret.TextField;
// 重新开始游戏按钮
private _startGameBtn:egret.TextField;
/**
* init()
* 初始化函数
*/
private init():void {
// 绘制背景
this._background = new egret.Shape();
this._background.graphics.beginFill(0);
this._background.graphics.drawRect(0,0,GameData.getStageWidth(),GameData.getStageHeight());
this._background.graphics.endFill();
this.addChild( this._background );
// 添加分数
this._score = new egret.TextField();
this._score.textColor = 0xffffff;
this._score.text = "分数:" + GameData.getScore();
this._score.size = 50;
this._score.x = 150;
this._score.y = 50;
this.addChild( this._score );
// 按钮
this._startGameBtn = new egret.TextField();
this._startGameBtn.text = "重玩";
this._startGameBtn.size = 40;
this._startGameBtn.textColor = 0xffffff;
this._startGameBtn.x = 180;
this._startGameBtn.y = 200;
this.addChild( this._startGameBtn );
this._startGameBtn.touchEnabled = true;
// 添加重新开始游戏事件
this._startGameBtn.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.restartGame,this);
}
/**
* update
* 更新得分
*/
public update() {
this._score.text = "分数:" + GameData.getScore();
}
/**
* restartGame
* 重新开始游戏
*/
private restartGame(evt:egret.TouchEvent) {
var event:GameEvent = new GameEvent(GameEvent.GAME_START);
this.dispatchEvent(event);
}
}