Skip to content

Commit

Permalink
78% done/*PC version completed*/
Browse files Browse the repository at this point in the history
  • Loading branch information
Ezharjan committed Mar 9, 2020
1 parent 479150b commit 5556583
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 25 deletions.
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 25 additions & 10 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {Director} from "./js/Director.js";
import {Background} from "./js/runtime/Background.js";
import {DataStore} from "./js/base/DataStore.js";
import {Land} from "./js/runtime/Land.js";
import {Birds} from "./js/player/Birds.js";
import {StartButton} from "./js/player/StartButton.js";
import {Scores} from "./js/player/Scores.js";

export class Main {
constructor() {
Expand Down Expand Up @@ -62,13 +65,38 @@ export class Main {
}

init() {

//首先,重置游戏状态为尚未结束
this.director.isGameOver = false;

this.dataStore
.put('pencils', [])
.put('background', Background)
.put('land', Land)
.put('birds', Birds)
.put('startButton', StartButton)
.put('score', Scores)
;//可以进行链式操作,一层一层往下put。

this.registerEvent();

//要在游戏运行之前就创建好铅笔!!!
this.director.createPencil();
this.director.run();
}

registerEvent() {
this.canvas.addEventListener('touchstart', e => {
e.preventDefault();//关闭默认的事件冒泡
console.log(this);//使用箭头函数让this指向了部的Main
console.log("触摸了");
//只有使用了箭头函数,director才能够直接被调过来
if (this.director.isGameOver) {
console.log("游戏开始!");
this.init();
} else {
this.director.birdsEvent();//绑定点击事件,导演控制
}
})
}
}
8 changes: 7 additions & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@
}


8.
8. 一般情况下想要提高运行性能时,直接将所有的图片利用图片合成软件混合拼接成为一张图片,
在在执行渲染的时候只不过是将这个图片的不同部分进行选择性剪裁渲染,这样一来就不用在资源加载
的类中加载大量的资源,加载一张图片并对改图片中我们所需要的资源内容进行相对坐标上的定位即可。
但是这样做也无形地位后续增加了资源坐标定位的工作量。二者在合适的情况下应择优选择。

9. 在JS中一旦通过this来创建变量,将相当于Java或C#里面的piblic,就是公开了的变量;
想要创建内部的私有变量,只要将this去掉,声明时使用const即可实现对外不可见!



113 changes: 104 additions & 9 deletions js/Director.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,113 @@ export class Director {
this.dataStore.get('pencils').push(new DownPencil(top))
}

run() {
this.dataStore.get('background').draw();
this.dataStore.get('pencils').forEach(function (value, index, array) {
birdsEvent() {
for (let i = 0; i <= 2; i++) {
//根据玩家点击事件来让小鸟能够向上位移
this.dataStore.get('birds').y[i] =
this.dataStore.get('birds').birdsY[i];
}
//每次点击之后必须要将时间置零,否则速度会越来越快!
this.dataStore.get('birds').time = 0;//置零!!
}

value.draw();
});
static isStrikeWithPen(bird, pencil) {
let striked = false;
if (bird.top > pencil.bottom
|| bird.bottom < pencil.top
|| bird.right < pencil.left
|| bird.left > pencil.right) {
striked = true;
}
return !striked;

}

this.dataStore.get('land').draw();
checkDrop() {
const birds = this.dataStore.get('birds');
const pencils = this.dataStore.get('pencils');
const land = this.dataStore.get('land');
const score = this.dataStore.get('score');

//地板撞击判断
if (birds.birdsY[0] + birds.birdsHeight[0] >= land.y) {
console.log("碰到地板了!");
this.isGameOver = true;
return;
}

//创建小鸟的碰撞体
const birdsBorder = {
top: birds.y[0],
bottom: birds.birdsY[0] + birds.birdsHeight[0],
left: birds.birdsX[0],
right: birds.birdsX[0] + birds.birdsWidth[0]
};

//创建铅笔的碰撞体
const penLength = pencils.length;
for (let i = 0; i < penLength; i++) {
const pencil = pencils[i];
const pencilBorder = {
top: pencil.y,
bottom: pencil.y + pencil.height,
left: pencil.x,
right: pencil.x + pencil.width
};
if (Director.isStrikeWithPen(birdsBorder, pencilBorder)) {
console.log("撞到铅笔啦!");
this.isGameOver = true;
return;
}
}

let timer = requestAnimationFrame(() => this.run());
this.dataStore.put('timer', timer);//将可以终止动画的开关存在DataStore中
// cancelAnimationFrame(this.dataStore.get('timer'));//停止动画
//加分逻辑
if (birds.birdsX[0] > pencils[0].x + pencils[0].width
&& score.isScorable) {
score.isScorable = false;
score.scoreNumber++;
}
}

run() {

this.checkDrop();

if (!this.isGameOver) {
this.dataStore.get('background').draw();

//重要逻辑点!!!pencils数组永远只有4个!!!
const pencils = this.dataStore.get('pencils');
//铅笔的右侧刚好越过了左侧的边界——销毁
if (pencils[0].x + pencils[0].width <= 0
&& pencils.length === 4) {
pencils.shift();//将第一个元素推出数组并将数组个数减一
pencils.shift();

//以便于后续分数的累计
this.dataStore.get('score').isScorable = true;
}
//创建铅笔
if (pencils[0].x <= (window.innerWidth - pencils[0].width) / 2
&& pencils.length === 2) {
this.createPencil();
}

this.dataStore.get('pencils').forEach(function (value, index, array) {
value.draw();
});

this.dataStore.get('land').draw();
this.dataStore.get('score').draw();
this.dataStore.get('birds').draw();

let timer = requestAnimationFrame(() => this.run());
this.dataStore.put('timer', timer);//将可以终止动画的开关存在DataStore中
} else {
console.log("Game is over!");
this.dataStore.get('startButton').draw();//游戏结束的时候呈现开始按钮
cancelAnimationFrame(this.dataStore.get('timer'));//停止动画
this.dataStore.destroy();
}
}
}
78 changes: 76 additions & 2 deletions js/player/Birds.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,77 @@
export class Birds {

import {Sprite} from "../base/Sprite.js";

//循环渲染图片的中的三只小鸟
export class Birds extends Sprite {
constructor() {
const image = Sprite.getImage('birds');
super(image, 0, 0,
image.width, image.height,
0, 0, image.width, image.height);

//小鸟的三种状态需要一个数组去存储
//小鸟的宽是34,上下边距是10,左右边距是9
this.clippingX = [
9,
9 + 34 + 18,
9 + 34 + 18 + 34 + 18
];
this.clippingY = [10, 10, 10];
this.clippingWidth = [34, 34, 34];
this.clippingHeight = [24, 24, 24];

//小鸟的初始位置;私有的声明为const
const birdX = window.innerWidth / 4;
this.birdsX = [birdX, birdX, birdX];
const birdY = window.innerHeight / 2;
this.birdsY = [birdY, birdY, birdY];

const birdWidth = 34;
this.birdsWidth = [birdWidth, birdWidth, birdWidth];
const birdHeight = 24;
this.birdsHeight = [birdHeight, birdHeight, birdHeight];

//根据玩家交互而变化的是小鸟的Y坐标,将其存入数组
this.y = [birdY, birdY, birdY];
this.index = 0;//第几只小鸟
this.count = 0;//次数
this.time = 0;//小鸟自由落体下落时间
}

draw() {
//不能是小数!否则无法在数组中取出对应的index值。
//但是鉴于浏览器刷新速度大,因此必须要通过减小速度来改变小鸟
//在绘制过程中的闪烁问题!使用向下取整对index进行处理!
const changeBirdSpeed = 0.2;
this.count = this.count + changeBirdSpeed;
if (this.index >= 2) {
this.count = 0
}

//直接取,因为速度是小数所以就无法顺序读取
// this.index = this.count;
//使用向下取整的方式,减缓素的并取出对应小鸟
this.index = Math.floor(this.count);//减速器的作用

//添加小鸟的重力——不能直接使用物理学上的重力!!
const g = 0.98 / 2.4;//伪重力

//为了营造飞的真实感,在掉落时需要向上偏移一点
const offsetUp = 30;

//小鸟的位移(直接使用重力公式)
const offsetY = (g * this.time * (this.time - offsetUp)) / 2;
for (let i = 0; i <= 2; i++) {
//注意birdsY和birdY的区别,不要混淆!!!
this.birdsY[i] = this.y[i] + offsetY;
}
this.time++;

super.draw(
this.img,
this.clippingX[this.index], this.clippingY[this.index],
this.clippingWidth[this.index], this.clippingHeight[this.index],
this.birdsX[this.index], this.birdsY[this.index],
this.birdsWidth[this.index], this.birdsHeight[this.index]
);
}
}
20 changes: 19 additions & 1 deletion js/player/Scores.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
import {DataStore} from "../base/DataStore.js";

export class Scores {

constructor() {
this.ctx = DataStore.getInstance().ctx;
this.scoreNumber = 0;

//因为canvas刷新很快,所以需要一个变量控制加分,只加一次
this.isScorable = true;
}

draw() {
this.ctx.font = '25px Arial';
this.ctx.fillStyle = '#00ffed';
this.ctx.fillText(
this.scoreNumber,
window.innerWidth / 2,
window.innerHeight / 18,
1000);
}
}
Loading

0 comments on commit 5556583

Please sign in to comment.