二次贝塞尔需要三个点,开始点,控制点(控制杆顶部所在的点),结束点。

    我们通过改变结束点的位置来实现摇摆。

    加入 alpha 添加透明度,根据近实远虚原理构建空间感,加入 amp,摆动振幅。

    1. import { deltaTime } from "./game-loop";
    2. enum FruitType{
    3. Blue = 1,
    4. Orange
    5. }
    6. class Fruits{
    7. num: number = 30; // 绘画果实的数量
    8. alive: boolean[] =[]; // 判断果实是否存活
    9. x : number[]= []; // 果实的 x 坐标数组
    10. y : number[] = []; // 果实的 y 坐标数组
    11. diameter : number[] = []; // 果实的直径数组
    12. speed: number[] = []; // 控制果实成长速度、上浮速度的数组
    13. fruitType: FruitType[] = []; // 控制果实类型的枚举数组
    14. orange = new Image(); // 黄色果实
    15. blue = new Image(); // 蓝色果实
    16. aneNum: number[] = []; // 记录出生时候所在的海葵
    17. constructor(){
    18. for (let i = 0; i < this.num; ++i) {
    19. this.aneNum[i] = 0; // 初始化
    20. this.born(i);
    21. }
    22. this.orange.src = 'assets/img/fruit.png';
    23. this.blue.src = 'assets/img/blue.png';
    24. }
    25. // 绘制果实
    26. draw(){
    27. for (let i = 0; i < this.num; ++i) {
    28. // 只有属性为存活的时候才绘制
    29. if(this.alive[i]){
    30. if(this.diameter[i] <= 17) {
    31. this.diameter[i] += this.speed[i] * deltaTime; // 随着时间半径不断变大 也就是果实长大
    32. this.x[i] = anemones.headx[this.aneNum[i]]
    33. this.y[i] = anemones.heady[this.aneNum[i]] // 得到海葵顶点的 x 和 y
    34. }else{
    35. this.y[i] -= this.speed[i] * deltaTime; // 果实成熟之后, y 坐标减小,果实开始上升
    36. }
    37. // 把果实绘制出来,为了让果实居中,所以要减去图片高度一半,宽度一半
    38. // 就像实现水平居中一样 left: 50px; margin-left: -(图片宽度 / 2);
    39. // 第一个参数 图片, 第二三个参数,坐标轴的 x 和 y,第四五个参数,图片的宽高
    40. ctx_two.drawImage(img, this.x[i] - this.diameter[i] / 2, this.y[i] - this.diameter[i], this.diameter[i], this.diameter[i]);
    41. }
    42. if(this.y[i] <= -10) {
    43. this.alive[i] = false; // 果实出去了之后 存活状态为 flase
    44. }
    45. }
    46. }
    47. // 初始化果实
    48. born(i){
    49. let aneId = Math.floor( Math.random() * anemones.num ) // 随机拿到一个果实的 ID
    50. this.aneNum[i] = aneId
    51. this.speed[i] = Math.random() * 0.04 + 0.007; // 设置速度在区间 0.003 - 0.03 里
    52. this.alive[i] = true; // 先设置它的存活为 true
    53. this.diameter[i] = 0; // 未生长出来的果实半径为0
    54. }
    55. // 监视果实
    56. monitor() : void {
    57. let num = 0;
    58. for (let i = 0; i < this.num ; ++i) {
    59. if(this.alive[i]) num++; // 计数存活果实的数量
    60. if(num < 15) {
    61. // 产生一个果实
    62. this.reset()
    63. return ;
    64. }
    65. }
    66. }
    67. //重置果实的状态
    68. reset() {
    69. for (let i = 0; i < this.num; ++i) {
    70. if(!this.alive[i]) {
    71. this.born(i); // 假如存活为 false , 让它重新出生。
    72. return ; // 每次只重置一个果实
    73. }
    74. }
    75. }
    76. // 果实死亡
    77. dead(i){
    78. this.alive[i] = false;
    79. }
    80. }
    81. export default Fruits;
    82. export { FruitType };