互动应用开发p5.js——WebGL太阳系
WebGL太阳系
一、实验内容:
完成一个太阳系场景,其中至少有三个球体,一个表示太阳,一个表示地球,一个表示月亮;地球不停地绕太阳旋转,月亮绕地球旋转,星球本身有自转。可添加纹理,纹理自行从网络搜寻。画上星球运动的轨道线,并加上适当的光照效果。提交代码(如有纹理则需要提交纹理图片)和文档,要求简要说明功能点和实现方法;
评分标准:
-
星球的自转和公转运动准确;(30分)
-
光照效果合理;(30分)
-
场景丰富美观,可自由增加其他物体和光照,如飞船等;(20分)
-
编码规范,文档说明准确清楚;(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张图片贴图以及音乐
分类:
互动应用开发p5.js
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码