互动应用开发p5.js——WebGL太阳系

简介: WebGL太阳系一、实验内容:完成一个太阳系场景,其中至少有三个球体,一个表示太阳,一个表示地球,一个表示月亮;地球不停地绕太阳旋转,月亮绕地球旋转,星球本身有自转。可添加纹理,纹理自行从网络搜寻。画上星球运动的轨道线,并加上适当的光照效果。提交代码(如有纹理则需要提交纹理图片)和文档,要求简要说明功能点和实现方法;评分标准:星球的自转和公转运动准确;(30分)光照效果合理;(30分)场景丰富美观,可自由增加其他物体和光照,如飞船等;(20分)编码规范,文档说明准确清楚;(20分)

 WebGL太阳系

 

一、实验内容:

完成一个太阳系场景,其中至少有三个球体,一个表示太阳,一个表示地球,一个表示月亮;地球不停地绕太阳旋转,月亮绕地球旋转,星球本身有自转。可添加纹理,纹理自行从网络搜寻。画上星球运动的轨道线,并加上适当的光照效果。提交代码(如有纹理则需要提交纹理图片)和文档,要求简要说明功能点和实现方法;

评分标准:

    1. 星球的自转和公转运动准确;(30分)
    2. 光照效果合理;(30分)
    3. 场景丰富美观,可自由增加其他物体和光照,如飞船等;(20分)
    4. 编码规范,文档说明准确清楚;(20分)

    二、实验说明:

    所有实验是通过 Visual Studio Code引入p5.js包编写,所以首先要去p5.js官网下载相关包,或是在联网状态下把html中引入包的代码改成例如<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>等。

    三、实验代码:

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title>sun</title>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.js"></script>
    </head>
    <body>
      <script src="sketch.js"></script>
    </body>
    </html>

    image.gif

    let x0 = 0, y0 = 0, z0 = 0,//初始化太阳坐标
      x1 = 0, y1 = 0, z1 = 0,//初始化地球坐标
      x2 = 0, y2 = 0, z2 = 0;//初始化月球坐标
    let revolutionAngle = 20; // 公转角度
    let rotationAngle = 0; // 自转角度
    let revolutionRadius = 300; //公转半径
    let sun, earth, moon; //加载贴图
    let stars = []; // 繁星
    let camX, camY, camZ = 700; // 视口照相机位置
    function preload() {
      sun = loadImage("picture/sun.png");
      earth = loadImage("picture/earth.png");
      moon = loadImage("picture/moon.png");
      sound = loadSound("sound/sound.mp3");
    }
    function setup() {
      let cnv = createCanvas(windowWidth, windowHeight, WEBGL);
      cnv.mousePressed(canvasPressed);//点击鼠标事件播放声音
      //创造繁星
      for (let i = 0; i < 300; i++) {
        stars.push({
          x: 0,
          y: 0,
          offset: Math.random() * 360,
          orbit: (Math.random() + 0.01) * max(width, height),
          radius: Math.random() * 2,
          vx: Math.floor(Math.random() * 10) - 5,
          vy: Math.floor(Math.random() * 10) - 5,
        });
      }
    }
    function draw() {
      clear();
      background(0);
      setLight();
      drawSun();
      drawEarth();
      drawMoon();
      drawStars();
      // 照相机位置
      camX = (mouseX - width / 2) / 10;
      camY = (mouseY - height / 2) / 10;
      camera(camX, camY-300 , camZ+1000, 0, 0, 0, 0, 1, 0);
      noStroke();
      rotationAngle += 0.01;
    }
    function drawSun() {
      push();
      translate(x0, x0, z0);
      fill(0, 255, 255);
      texture(sun);
      pointLight(255, 255, 255, 0, 0, 100000);
      rotateY(rotationAngle / 5);
      sphere(200);
      pop();
      // 地球轨道
      push();
      translate(x0, y0, z0);
      rotateX((PI / 180) * 90);
      fill(240);
      torus(800, 0.7, 240);
      pop();
    }
    function drawEarth() {
      x1 = x0 + 800 * cos(revolutionAngle);
      z1 = z0 + 800 * sin(revolutionAngle);
      push();
      translate(x1, y1, z1);
      rotateY(rotationAngle);
      texture(earth);
      sphere(40);
      pop();
      // 月球轨道
      push();
      translate(x1, y1, z1);
      rotateX((PI / 180) * 90);
      fill(240);
      torus(60, 0.7, 240);
      pop();
      revolutionAngle += 0.005;
    }
    function drawMoon() {
      x2 = x1 + 60 * cos(revolutionAngle * 5);
      z2 = z1 + 60 * sin(revolutionAngle * 5);
      push();
      translate(x2, y2, z2);
      rotateY(-rotationAngle);
      texture(moon);
      sphere(10);
      pop();
    }
    function drawStars() {
      colorMode(RGB, 255, 255, 255, 1);
      for (let i = 0; i < stars.length; i++) {
        let s = stars[i];
        push();
        translate(s.x - width / 2, s.y - height / 3, -1000);
        sphere(5);
        pop();
      }
      update();
    }
    function update() {
      let originX = width / 2;
      let originY = height / 2;
      for (let i = 0; i < stars.length; i++) {
        let s = stars[i];
        let rad = (frameCount * (1 / (s.orbit * 2 + s.offset)) + s.offset) % TAU;
        s.x = originX + cos(rad) * (s.orbit * 2);
        s.y = originY + sin(rad) * s.orbit;
      }
    }
    function setLight() {
      pointLight(255,255,255,0,0,0,500);
      // let dirX = -(mouseX - width / 2);
      // let dirY = -(mouseY - height / 2);
      ambientLight(0);
      //directionalLight(255, 255, 255, dirX, dirY, -250);
    }
    function mouseWheel(event) {
      if (event.deltaY > 0) {
        camZ += 10; 
      } else {
        camZ -= 10;
      }
    }
    function canvasPressed() {
      if (sound.isPlaying()) {
        sound.pause();
      } else {
        sound.play();
      }
    }

    image.gif

    四、实验结果:

    image.gif编辑

    image.gif编辑

    image.gif编辑

    注:需要预加载4个文件,这里需要自行去找3张图片贴图以及音乐

    相关文章
    |
    4月前
    |
    开发框架 前端开发 JavaScript
    循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
    循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中
    |
    4月前
    |
    开发框架 JSON 前端开发
    循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数
    循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数
    |
    6月前
    |
    JavaScript 前端开发 Java
    webgl学习笔记2_javascript基础快速学习
    webgl学习笔记2_javascript基础快速学习
    51 0
    |
    JavaScript 前端开发 API
    使用three.js与WebGL相比有什么优势?
    简单的说Three.js是WebGL的框架。封装和简化了WebGL的方法。three.js在它的基础上进行了进一步的封装和简化开发开发过程,个人认为类似于jQuery对原生js的关系。下面我们一点一点来了解下。
    302 0
    使用three.js与WebGL相比有什么优势?
    |
    Java API 图形学
    Unity WebGL 程序如何调用Java Script函数
    Unity WebGL 程序如何调用Java Script函数
    226 1
    Unity WebGL 程序如何调用Java Script函数
    |
    传感器 监控 JavaScript
    JavaScript 轻应用开发|学习笔记
    快速学习 JavaScript 轻应用开发
    JavaScript 轻应用开发|学习笔记
    |
    前端开发 UED
    互动应用开发p5.js——网页小游戏——贪吃蛇
    贪吃蛇 一、实验内容: 基于课件改进贪吃蛇或者太空大战的小游戏,可以加入新的视觉效果,比如区分蛇头和蛇身;为食物增加特效;分数排行榜;行进改成可以循环等等; 尽可能丰富游戏的玩法。 评分标准: 游戏界面及功能 (70分) 用户体验 (10分) 代码规范(20分)
    217 0
    互动应用开发p5.js——网页小游戏——贪吃蛇
    |
    数据可视化 前端开发
    互动应用开发p5.js——音视频交互
    音视频交互 一、实验内容: 音频可视化,是指一种以视觉为核心,以音频为载体,以大众为诉求对象,借助多种新媒体技术等传播媒介,通过画面、影像来诠释音乐内容的、视听结合的大众化传播方式。它能为理解、分析和比较音频作品形态的表现力和内外部结构提供的一种直观视觉呈现的技术。 将麦克风获取到的声音转变成图像 获取所需的目标音频信息 将振幅转化为波形与环形的振幅 其他的是通过声音的大小,获取音频的振幅信息,向绘制圆形的大小参数传递声音振幅的值,以达到不同声音大小的圆形。 通过获取音频的振幅信息,将振幅信息传参到小球跳
    428 0
    互动应用开发p5.js——音视频交互
    |
    前端开发
    互动应用开发p5.js——Perlin噪声生成烟雾(柏林噪声)
    Perlin噪声生成烟雾 一、实验内容: 和鼠标交互结合生成Perlin Noise的烟雾效果 要求使用p5.js实现烟雾随机生成效果: 流场利用Perlin噪声实现;(30分) 粒子按照流场运动;(30分) 速度、数量等可由参数控制;(15分)(HTML页面交互传递参数8分,代码中变量控制7分) 使用类来实现粒子;(15分) 文档和注释清楚;(10分) 提交工程目录压缩的zip或者rar,以及一个readme.txt简要说明实现思路和重要参数的功能
    351 0
    互动应用开发p5.js——Perlin噪声生成烟雾(柏林噪声)
    |
    前端开发
    互动应用开发p5.js——星星的运动
    星星的运动 一、实验内容: 按照章节要求使用p5.js实现星星随机向画布边界运动的效果: 星星近大远小;(20分) 能拖出尾迹;(30分) 速度、星星数量等可由参数控制;(20分)(HTML页面交互传递参数20分,代码中变量控制10分) 使用类来实现;(30分) 提交工程目录压缩的zip或者rar,以及一个readme.txt简要说明实现思路和重要参数的功能
    309 0
    互动应用开发p5.js——星星的运动