给蓝色的大鱼身体加点反馈,当吃了蓝色果实,启动双倍模式的时候,大鱼的身体变成蓝色。
这里新建一个私有的存放蓝色身体的序列数组,私有变量不会被继承。
private _pBigBody: Array<HTMLImageElement> = []; // 只属于鱼妈妈的特殊颜色身体
import { ctx_one, cvs_height, cvs_width, mouse_x, mouse_y, fish_mother, score } from "./init";
import { deltaTime } from "./game-loop";
import utils from "./utils";
// 鱼妈妈
class FishMother{
x: number = cvs_width / 2; // 坐标轴 x
y: number = cvs_height / 2 ; // 坐标轴 y
bigEye : Array<HTMLImageElement> = []; // 眼睛
bigBody : Array<HTMLImageElement> = []; // 身体
private _pBigBody: Array<HTMLImageElement> = []; // 只属于鱼妈妈的特殊颜色身体
BigTail : Array<HTMLImageElement> = []; // 尾巴
angle: number = 0; // 鱼的角度
EyeIndex = 0; // 需要渲染哪个眼睛的索引值
BodyIndex = 0;
TailIndex = 0;
EyeTimer = 0; // 计算眼睛时间
BodyTimer = 0;
TailTimer = 0;
EyeInterval = 300; // 通过这个变量动态的设置眨眼睛的间隔
BodyInterval = 300;
TailInterval = 50;
constructor(){
for (let i = 0; i < 2; ++i) {
this.bigEye[i] = new Image();
this.bigEye[i].src = `assets/img/bigEye${i}.png`;
}
for (let i = 0; i < 8; ++i) {
this._pBigBody[i] = new Image();
this._pBigBody[i].src = `assets/img/bigSwimBlue${i}.png`;
}
for (let i = 0; i < 8; ++i) {
this.bigBody[i] = new Image();
this.bigBody[i].src = `assets/img/bigSwim${i}.png`;
}
for (let i = 0; i < 8; ++i) {
this.BigTail[i] = new Image();
this.BigTail[i].src = `assets/img/bigTail${i}.png`;
}
}
checkImageIndex(){
this.EyeTimer += deltaTime;
this.TailTimer += deltaTime;
this.BodyTimer += deltaTime;
// 当计时器大于某个值的时候才进行修改
if(this.EyeTimer > this.EyeInterval) {
this.EyeIndex = (this.EyeIndex + 1) % 2;
// 重置一下定时器
this.EyeTimer %= this.EyeInterval;
// 判断是眨眼的哪个过程
if(this.EyeIndex === 0) {
this.EyeInterval = Math.random() * 1500 + 2000 // 设置下一次眨眼的间隔长一点
}else{
// 先闭眼后睁眼,这个过程应该非常短
this.EyeInterval = 300;
}
}
if(this.TailTimer > this.TailInterval) {
this.TailIndex = (this.TailIndex + 1) % 8;
this.TailTimer %= this.TailInterval
}
if(this.BodyTimer > this.BodyInterval) {
this.BodyIndex = this.BodyIndex + 1;
this.BodyTimer %= this.BodyInterval
if(this.BodyIndex > 7) {
this.BodyIndex = 7
}
}
}
checkMove(){
this.x = utils.lerpDistance(mouse_x, this.x , .95)
this.y = utils.lerpDistance(mouse_y, this.y , .95)
let instance_X = mouse_x - this.x; // 边 a
let instance_Y = mouse_y - this.y; // 边 b
let ag = Math.atan2(instance_Y, instance_X) + Math.PI // [-PI, PI]
this.angle = utils.lerpAngle(ag, this.angle, .9)
}
draw(){
this.checkMove()
this.checkImageIndex()
ctx_one.save();
ctx_one.translate(this.x, this.y); // 定义相对定位的坐标中心点
ctx_one.rotate(this.angle);
ctx_one.scale(.8, .8);
ctx_one.drawImage(this.BigTail[this.TailIndex], -this.BigTail[this.TailIndex].width / 2 + 30, -this.BigTail[this.TailIndex].height / 2); // 这里的尾巴,往右移动30像素,让它在身体的后面。
if(score.doubleMode === 2) {
ctx_one.drawImage(this._pBigBody[this.BodyIndex], -this._pBigBody[this.BodyIndex].width / 2, -this._pBigBody[this.BodyIndex].height / 2);
}else{
ctx_one.drawImage(this.bigBody[this.BodyIndex], -this.bigBody[this.BodyIndex].width / 2, -this.bigBody[this.BodyIndex].height / 2);
}
ctx_one.drawImage(this.bigEye[this.EyeIndex], -this.bigEye[this.EyeIndex].width / 2, -this.bigEye[this.EyeIndex].height / 2); // 居中,所以向左移动宽度的一半,向上移动宽度的一半
ctx_one.restore();
}
}
// 鱼宝宝
class FishBaby extends FishMother {
x: number = cvs_width / 2 + 50; // 坐标轴 x
y: number = cvs_height / 2 + 50; // 坐标轴 y
constructor() {
super()
for (let i = 0; i < 2; ++i) {
this.bigEye[i] = new Image();
this.bigEye[i].src = `assets/img/babyEye${i}.png`;
}
for (let i = 0; i < 20; ++i) {
this.bigBody[i] = new Image();
this.bigBody[i].src = `assets/img/babyFade${i}.png`;
}
for (let i = 0; i < 8; ++i) {
this.BigTail[i] = new Image();
this.BigTail[i].src = `assets/img/babyTail${i}.png`;
}
}
checkImageIndex(){
this.EyeTimer += deltaTime;
this.TailTimer += deltaTime;
this.BodyTimer += deltaTime;
// 当计时器大于某个值的时候才进行修改
if(this.EyeTimer > this.EyeInterval) {
this.EyeIndex = (this.EyeIndex + 1) % 2;
// 重置一下定时器
this.EyeTimer %= this.EyeInterval;
// 判断是眨眼的哪个过程
if(this.EyeIndex === 0) {
this.EyeInterval = Math.random() * 1500 + 2000 // 设置下一次眨眼的间隔长一点
}else{
// 先闭眼后睁眼,这个过程应该非常短
this.EyeInterval = 300;
}
}
if(this.TailTimer > this.TailInterval) {
this.TailIndex = (this.TailIndex + 1) % 8;
this.TailTimer %= this.TailInterval
}
if(this.BodyTimer > this.BodyInterval) {
this.BodyIndex = this.BodyIndex + 1;
this.BodyTimer %= this.BodyInterval
if(this.BodyIndex > 19) {
this.BodyIndex = 19
console.log('game over');
}
}
}
// 重置身体的图片,也就是得到能量满血复活
recover(){
this.BodyIndex = 0;
}
checkMove(){
this.x = utils.lerpDistance(fish_mother.x, this.x , .98)
this.y = utils.lerpDistance(fish_mother.y, this.y , .98)
let instance_X = fish_mother.x - this.x; // 边 a
let instance_Y = fish_mother.y - this.y; // 边 b
let ag = Math.atan2(instance_Y, instance_X) + Math.PI // [-PI, PI]
this.angle = utils.lerpAngle(ag, this.angle, .7)
}
draw(){
this.checkMove()
this.checkImageIndex()
ctx_one.save();
ctx_one.translate(this.x, this.y); // 定义相对定位的坐标中心点
ctx_one.rotate(this.angle);
ctx_one.scale(.8, .8);
ctx_one.drawImage(this.BigTail[this.TailIndex], -this.BigTail[this.TailIndex].width / 2 + 24, -this.BigTail[this.TailIndex].height / 2); // 这里的尾巴,往右移动30像素,让它在身体的后面。
ctx_one.drawImage(this.bigBody[this.BodyIndex], -this.bigBody[this.BodyIndex].width / 2, -this.bigBody[this.BodyIndex].height / 2);
ctx_one.drawImage(this.bigEye[this.EyeIndex], -this.bigEye[this.EyeIndex].width / 2, -this.bigEye[this.EyeIndex].height / 2); // 居中,所以向左移动宽度的一半,向上移动宽度的一半
ctx_one.restore();
}
}
export {
FishMother,
FishBaby
}
此时我们在喂给小鱼之后还需要重置大鱼图片序列的索引为0,以及身体的定时器改大一点。
// 把能力给小鱼,果实数清零,计算分数一次
score.reset()
// 把大鱼的 bodyindex 恢复成 0
fish_mother.BodyIndex = 0;
BodyInterval = 1000;
此时我们发现小鱼的身体变化又太慢了,所以我们重新定义一个覆盖父类的
// 鱼宝宝
class FishBaby extends FishMother {
x: number = cvs_width / 2 + 50; // 坐标轴 x
y: number = cvs_height / 2 + 50; // 坐标轴 y
BodyInterval = 300;
constructor() {
当前内容版权归 nodelover.me 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 nodelover.me .