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

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>

 

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();
  }
}

四、实验结果:

 

 

 

 

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

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平杨猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值