技术栈: egret+ts
第一个游戏小项目,有点可惜的是并非独立完成
其实什么方式写出来并没有那么重要,重要的是将这个游戏里面涉及到的知识点最终变成自己的
以后再碰到类似的逻辑处理起来就不会毫无头绪了
私以为,写代码也是一个积累的过程
不断将目前的知识盲区解锁解锁再解锁
自然而然会的就多起来了
别踩白块儿项目效果图
项目需求
1.未开始游戏时 -> 最底层始终全部都是白色方块
2.游戏过程中 -> 每行只能有一个黑色方块,其余都是白色方块
3.游戏上方 -> 存在一个计数器记录游戏时间,计数器走到0,则游戏结束
4.点击黑色方块
1)不跳行点击 -> 黑色方块颜色变为蓝色,同时界面方块行上移,可以持续进行下一步点击操作
2)跳行点击 -> 黑色方块颜色变为蓝色,同时界面弹出蓝色按钮,则提示游戏结束,你走了##步
5.点击白色方块 -> 白色方块颜色变为红色,同时界面弹出蓝色按钮,则提示游戏结束,你走了##步
6.重新开始游戏 -> 回到初始状态
项目逻辑
其实写游戏的时候,一开始不需要过分关注功能的实现
反而可以最简化,也就是暂时不管如何实现游戏中的各种功能
而是先开始从零开始搭建,等需要功能的时候再写
以这个游戏项目为例
1.创建一个方块
2.生成一行方块
3.生成一页方块
4.创建记时面板
5.创建游戏结束界面 -> 1)显示游戏步数 2)再次开始游戏的按钮
上述罗列的是整个游戏项目的骨架,至于游戏里面涉及到的功能逻辑,都是在主干上进行伸展
几处核心代码
- 生成一行方块 -> 同理: 生成一页方块
涉及知识点:
1) for循环
2) 数组 -> push方法
// 生成一行方块 -> 一行四个首尾相连一次排列
private _rects:Array<Rect>;
private createRects(){
this._rects = [];
for(var i=0; i<4; i++){
var rect:Rect = new Rect(); // 实例化单个小方块
this._rects.push(rect);
rect.x = rect.width*i;
this.addChild(rect);
this.addEventListener(egret.TouchEvent.TOUCH_TAP,this.clickRect,this);
}
}
效果示意图
- 每一行方块中随机生成一个黑色方块
涉及知识点:
1) Math.random()
2) if~else语句
private currentBlackRectIndex = 0;
public createBlackRect(){
var n:number = Math.random();
if(n>=0 && n<0.25){
this.currentBlackRectIndex = 0;
}else if(n>=0.25 && n<0.5){
this.currentBlackRectIndex = 1;
}else if(n>=0.5 && n<0.75){
this.currentBlackRectIndex = 2;
}else if(n>=0.75 && n>1){
this.currentBlackRectIndex = 3;
}
this._rects[this.currentBlackRectIndex].type = RectType.CLICKABLE;
}
一行白色方块->内部有一个黑色方块
- 定时器功能 -> 计时结束 -> 游戏结束 -> 弹出结束界面
涉及知识点:
1) 计时器
class TimerPannel extends egret.Sprite{
public constructor(){
super();
this.draw();
this.createTimer();
}
// 计时面板
private label:egret.TextField;
private draw(){
this.label = new egret.TextField();
this.label.x = this.label.width/2;
this.label.y = 300;
this.label.width = egret.MainContext.instance.stage.stageWidth;
this.label.text = "20'00''";
this.label.textColor = 0xff0000; // 默认字体是白色
this.label.textAlign = egret.HorizontalAlign.CENTER;
this.addChild(this.label);
}
// 定时器功能
private timer:egret.Timer;
private num = 20;
private createTimer(){
this.timer = new egret.Timer(1000,this.num); // 间隔,执行次数
this.timer.addEventListener(egret.TimerEvent.TIMER,this.timerFunc,this);
this.timer.addEventListener(egret.TimerEvent.TIMER_COMPLETE,this.timerComFunc,this);
}
private maxTime:number = 20;
private timerFunc(){ // 计时过程中触发
this.maxTime--;
this.label.text = this.maxTime + "'00''";
console.log(this.maxTime);
}
private timerComFunc(){ // 计时结束后触发
this.label.text = this.maxTime + "'00''";
console.log(this.maxTime);
egret.MainContext.instance.stage.dispatchEventWith("gameOver");
}
public start(){
this.label.text = "20'00''";
this.maxTime = 20;
this.timer.reset();
this.timer.start();
}
public stop(){
this.timer.stop();
}
}
逻辑BUG
-
方块生成页之后 -> 点击判断失效 -> 一直进入 "点错了" 这个判断区间
原因: 当前行数逻辑出错 -
下移函数失效
原本以为是下移步骤的逻辑出错 -> 但排查后发现逻辑没问题
// 行数下移逻辑
public move() {
this._currentRow++;
if (this._currentRow === Data.getRectRow()) { // 当前行数 = 总行数
this._currentRow = 0;
this.createBlackRect();
}
// egret.log(this.y)
this.y = this._currentRow * Data.getRectWidth();
// egret.log(this.y)
}
}
// 点击正确 -> 行数向下移动
public nextRow() {
for (var i = 0; i < Data.getRectRow(); i++) {
this._pageRects[i].move();
Data.score++;
}
}
实际原因: 抛出函数没有成功抛出,或者说抛出去的函数,没有被目标接收到!!!
why? -> 两个文档里面,this指向不同
统一 监听事件的发送者
- 定时文本无法实时跟新,并且定时面板无法在 PageRect文件 里面实例化
思考方向: -> 1)容器问题 或者 2)层级问题
网友评论