中秋-疯狂的月桂树-“既然没人在意我,我就要…““不,我在意你!”

825 阅读6分钟

提到中秋,就会想到月亮,想到月亮就会想到嫦娥,提到嫦娥就会想到玉兔,吴刚和那棵悲催的桂花树。

关于嫦娥,从古至今对她的描写不尽其数,惜其孤寂,有云母屏风烛影深,长河渐落晓星沉。嫦娥应悔偷灵药,碧海青天夜夜心。 赞其清冷,有初闻征雁已无蝉,百尺楼高水接天。青女素娥俱耐冷,月中霜里斗婵娟。 …… 关于玉兔,虽然写玉兔的没有嫦娥的多,但是其也出现在过苏轼,李贺,温庭筠等名家之作品。吴刚,呵,还有人为其抒发怨诉。

可我呢,那棵每日都要被吴刚砍的树,有人在意我吗?有人在意我的感受吗!!!明明是四个生物的电影,而我总是被遗忘的那个。还有王法吗,还有天理吗,我不当人了(哦好像本来我也不是人),我不当树了!!!树也有树权,树树我啊今天就要创翻整个世界!!!既然没人在意我,我就要在阴暗角落默默创翻整个世界!!!

idea来源

本来也是想做个兔兔吃星星或者兔兔吃月饼的温馨可爱的小游戏的,可是洗澡的时候突然想到,月亮上还有棵树啊,但好像所有人都不在意它,它一直都在敬业的当那个背景板,于是作为一个非常具有同理心的人(精神十分“正常”的人),我决定不要什么可爱兔兔了,我要为树树发声!就让树树当主角,让它可不被砍,让它肆意生长。(前端小白,如有不准确的地方,请讲)

游戏玩法及展示

通过左右键控制树绕着月亮移动,或者上下键控制树左右摇摆去接月饼。

动画.gif

代码

月亮及背景

中秋别的看有没有,月亮肯定是必须要有的,所以先来画个黄黄的月亮。但是因为月亮+树占的空间会比较大,于是只展示半个月亮在底端。(ps.在找参考的月亮代码时,突然发现一个很奇怪的是,国内大家大部分画的都是黄色的月亮,但是国外都是白色的,一点小小的文化差异) 可以将月亮放到一个div中,然后把div的高度设置为月亮的半径长度,宽度设置为月亮的直径长度。这时候再利用overflow属性将超出div的圆形部分隐藏即可。

.mask2{
    height: 300px;
    overflow: hidden;
    }
.moon { 
    width: 600px; 
    height: 600px;
    border-radius: 50%; 
    background: linear-gradient(145deg, #f5f985 15%, #fbcc21 70%, #deb618 100%);
    box-shadow: 0 0 20px 8px rgba(249, 218, 59, 0.2); 
    justify-content: center; 
    align-items: center; 
    flex-direction: column;
 } 

image.png 但是光秃秃只有一个月亮感觉有一些单调,那就加些星星吧。 星星就很简单的用圆形,然后加一个缩放的动画显示闪烁的效果。最后在页面随机位置生成。

 .blinkstar {
  width: 2px;
  height: 2px;
  background-color: white; /* 星星的颜色 */
  position: absolute;
  border-radius: 50%; /* 使元素呈圆形,实现星星效果 */
  animation: blink 3s infinite alternate; /* 使用 CSS 动画制作闪烁效果 */
}
@keyframes blink {
  0% {
      opacity: 1;元素完全不透明,即可见
      transform: scale(1);
  }
  100% {
      opacity: 0;元素完全透明,即不可见
      transform: scale(1.2);
  }
}
    const arr = new Array(60);
    for (const item of arr) {
      const dom = document.createElement('div');
      dom.className = 'blinkstar';
      dom.style.left = `${Math.random() * 100}vw`;
      dom.style.top = `${Math.random() * 100}vh`;
      setTimeout(() => {
        document.body.appendChild(dom);
      }, 10000 * Math.random());
    }

树就用的可画上面找的树的素材,然后调整下位置。

image.png

掉落的月饼

其实随机掉月饼这里跟上面随机生成星星一样,只不过呢月饼的动画不是闪烁而是下坠。 使用transform: translateY就可以啦。然后关于判定树和月饼的碰撞呢,就实时判断月饼和树left,right,bottom,top是否有重叠。有的话就score+1,然后移除。如果星星位置到达底端也直接移除

  function createStar() {
  const star = document.createElement("div");
  star.classList.add("star");
  star.style.left =  Math.random()*window.innerWidth /3+window.innerWidth/3+ "px";
  star.style.top = "0";
  document.body.appendChild(star);
  // 更新星星的位置
  function updateStarPosition() {
    const starTop = parseInt(star.style.top);
    star.style.top = starTop + "px";
    // 获取方块和星星的位置信息
    const box = document.getElementById("tree");
    const starRect = star.getBoundingClientRect();
    const boxRect = box.getBoundingClientRect();
    const moon = document.getElementById("moon");
    // 检测碰撞
    if (
      starRect.left < boxRect.right &&
      starRect.right > boxRect.left &&
      starRect.top < boxRect.bottom &&
      starRect.bottom > boxRect.top
    ) {
      // 星星和方块碰撞,移除星星
      document.body.removeChild(star);
      score++;
      updateCollisionCount();
      console.log(score);
      updatetreesize()
    } else if (starTop < window.innerHeight) {
      // 星星还没有移出屏幕底部,继续更新位置
      requestAnimationFrame(updateStarPosition);
    } else {
      // 星星移出屏幕底部,移除星星
      document.body.removeChild(star);
    }
  }
  // 启动星星的位置更新
  requestAnimationFrame(updateStarPosition);
}

控制树的移动

控制树左右摇摆还是比较简单的,但是控制树绕着月亮(圆形)跑的时候由于自己浅薄的数学积累,是想了好久。如果在高中可能很快就能想到但是现在大学毕业了,100以外加减法都算的不快了,何况还要有cos和sin😭,好吧其实就是绕着转的圆心(也就是月亮的圆心)+度数的cos或者sin在乘上半径。

  let x0=0
  let y0=300
  let i=-90
  document.addEventListener("keydown", function(event) {
    var tree = document.getElementById("tree");

    if (event.key === "ArrowUp") {
      tree.style.transform = "rotate(-50deg)";
    } else if (event.key === "ArrowDown") {
      tree.style.transform = "rotate(50deg)";
    }
    else if (event.key === "ArrowRight") {
        i=i+2
        let deg=i*Math.PI/180
        x=x0+300*Math.cos(deg)
        y=y0+300*Math.sin(deg)
        tree.style.left=x+'px'
        tree.style.top=y+'px'

    }
    else if (event.key === "ArrowLeft") {
        i=i-2
        let deg=i*Math.PI/180
        x=x0+300*Math.cos(deg)
        y=y0+300*Math.sin(deg)
        tree.style.left=x+'px'
        tree.style.top=y+'px'
    }
  });
  document.addEventListener("keyup", function(event) {
    var tree = document.getElementById("tree");
    if (event.key === "ArrowUp" || event.key === "ArrowDown") {
      tree.style.transform = "rotate(0deg)";
    }
  });

嗯基本上就是这样,还有一些什么够多少分树变大一倍啥的就不说啦。

结算画面

本来自己对结算画面的预想是让月球裂开,或者整个屏幕碎掉然后再出现一些“温馨小寄语”,不过还是在洗澡的时候又想到算了毕竟中秋佳节还是得正面积极向上,加上又灵光一闪,想到一既能把主题圆回来又复合节日氛围的。 然后落下的中秋快乐的字就跟月饼星星都一个原理。 image.png

恭喜你,月桂树!你成功得完成了自己创翻世界的心愿! 可是就在世界毁灭时,月桂树知道了其实世界上是有人在乎自己的,在某个神秘的东方国度有一个善良的人把它当做了作品的主角。 月桂树突然有些后悔,或许不该唐突的毁灭世界。 …… “哦,原来只是一场梦。”月桂树从梦中惊醒,睁开眼月球还在,嫦娥还在,玉兔还在,那个死吴刚也还在砍自己。 月桂树仍然还在自己的工作岗位上恪尽职守得充当背景板,那个悲催的被砍的背景板。不过他已经不想创翻世界了。 月桂树虽然还是回不到树林里,还是要自己一棵树树在离地球十万八千里的月球上 但是当它知道在遥远的地方有某个人在乎自己,挂念自己,想念自己,自己就不再是孤单的树树了,这就够了。着就是属于树树的中秋团圆。