如何让多图形组成的火鸡围绕自身中心旋转?(p5.js)
让组合图形围绕统一中心点旋转的解决方案
问题背景
需求:通过左右箭头键触发旋转,让由多个形状组成的火鸡围绕自身中心点旋转,位置保持不变,仅做纯粹旋转。
当前问题:火鸡围绕随机点旋转,无法统一旋转原点。
核心解决方案
要实现统一中心旋转,必须将整个火鸡的所有绘制操作纳入同一个绘图上下文,避免每个形状单独平移旋转。具体步骤:
- 给火鸡实例添加
rotation属性,记录当前旋转角度 - 绘制火鸡时,先平移到火鸡的中心点(这里选用身体椭圆的位置作为中心),再统一应用旋转,所有形状都以原点(0,0)为基准绘制
- 通过键盘事件修改
rotation值,控制旋转方向和速度
修改后的完整代码
let bubbles = []; function setup() { createCanvas(windowWidth, windowHeight); angleMode(DEGREES); } function mouseDragged() { bubbles.pop(); } function mousePressed() { let d = random(0.5, 1.5); let w = random(50, 180); let b = new Bubble(mouseX, mouseY, d, w); bubbles.push(b); } function draw() { background(255); for (let bubble of bubbles) { bubble.move(); bubble.show(); } } function keyPressed() { // 控制所有火鸡旋转 for (let bubble of bubbles) { if (keyCode === LEFT_ARROW) { bubble.rotation -= 2; } else if (keyCode === RIGHT_ARROW) { bubble.rotation += 2; } } } class Bubble { constructor(x, y, d, w) { this.x = x; this.y = y; this.d = d; this.w = w; this.speedX = random(-15, 15); this.speedY = random(-15, 15); this.rotation = 0; // 新增旋转角度属性 } move() { if (this.x > width - this.w/1.08/2 || this.x < 0 + this.w/1.08/2) { this.speedX = -this.speedX; this.speedX *= 1.1; } if (this.y > height - this.w/1.05 || this.y < 0 + this.w/2/2) { this.speedY = -this.speedY; this.speedY *= 1.1; } this.x += this.speedX; this.y += this.speedY; } show() { push(); // 平移到火鸡的中心点(身体椭圆的位置) translate(this.x, this.y + this.w/2.11); // 应用统一旋转 rotate(this.rotation); // 所有形状都以(0,0)为基准绘制 // 左橙色羽毛 push(); translate(this.w/5, -this.w/2.11 + this.w/8); rotate(25); fill(255,153,51); ellipseMode(CENTER); ellipse(0, 0, this.w/1.67, this.w/0.67); pop(); // 右橙色羽毛 push(); translate(-this.w/5, -this.w/2.11 + this.w/8); rotate(-25); fill(255,153,51); ellipseMode(CENTER); ellipse(0, 0, this.w/1.67, this.w/0.67); pop(); // 右红色羽毛 push(); translate(this.w/2, -this.w/2.11 + this.w/5); rotate(60); fill(255,0,0); ellipseMode(CENTER); ellipse(0, 0, this.w/1.67, this.w/0.67); pop(); // 左红色羽毛 push(); translate(-this.w/2, -this.w/2.11 + this.w/5); rotate(-60); fill(255,0,0); ellipseMode(CENTER); ellipse(0, 0, this.w/1.67, this.w/0.67); pop(); // 黄色羽毛 fill(255,204,0); ellipse(0, -this.w/2.11 + this.w/20, this.w/1.67, this.w/0.67); // 左棕色羽毛 push(); translate(-this.w/2, -this.w/2.11 + this.w/1.67); rotate(10); fill(78,39,0); ellipse(0, 0, this.w/0.8, this.w/1.67); pop(); // 右棕色羽毛 push(); translate(this.w/2, -this.w/2.11 + this.w/1.67); rotate(-10); fill(78,39,0); ellipse(0, 0, this.w/0.8, this.w/1.67); pop(); // 身体 fill(153, 102, 51, 255); ellipse(0, 0, this.w/1.08, this.w/1.08); // 头部 ellipse(0, -this.w/2.11, this.w/2, this.w/2); // 眼睛 fill(255); ellipse(-this.w/10, -this.w/2.11 - this.w/20, this.w/6.67*this.d, this.w/6.67*this.d); ellipse(this.w/10, -this.w/2.11 - this.w/20, this.w/6.67*this.d, this.w/6.67*this.d); // 瞳孔 fill(0); ellipse(-this.w/11.77, -this.w/2.11 - this.w/28.57, this.w/13.33*this.d, this.w/13.33*this.d); ellipse(this.w/8.7, -this.w/2.11 - this.w/28.57, this.w/13.33*this.d, this.w/13.33*this.d); // 肉垂 fill(255, 0, 0); ellipse(-this.w/20, -this.w/2.11 + this.w/5, this.w/10, this.w/5); // 喙 fill(255,153,51); triangle(0, -this.w/2.11 + this.w/3.33, -this.w/10, -this.w/2.11 + this.w/10, this.w/10, -this.w/2.11 + this.w/10); // 左脚 triangle(-this.w/13.33, -this.w/2.11 + this.w/1.05, -this.w/3.08, -this.w/2.11 + this.w/1.05, -this.w/13.33, -this.w/2.11 + this.w/1.29); // 右脚 triangle(this.w/13.33, -this.w/2.11 + this.w/1.05, this.w/3.08, -this.w/2.11 + this.w/1.05, this.w/13.33, -this.w/2.11 + this.w/1.29); // 左翅膀 push(); translate(-this.w/2.22, -this.w/2.11 + this.w/2.22); rotate(30); fill(218,180,142); ellipse(0, 0, this.w/3.64, this.w/1.67); pop(); // 右翅膀 push(); translate(this.w/2.22, -this.w/2.11 + this.w/2.22); rotate(-30); fill(218,180,142); ellipse(0,0, this.w/3.64, this.w/1.67); pop(); pop(); } }
关键修改说明
- 统一旋转上下文:将火鸡所有绘制代码放入外层
push()/pop(),先平移到身体中心,再统一旋转 - 坐标基准调整:所有形状的坐标从基于
this.x/this.y改为基于(0,0),通过相对偏移实现原位置布局 - 旋转控制:新增
rotation属性和keyPressed()函数,通过左右箭头调整旋转角度 - 修复原代码小问题:修正
mouseDragged()的错误写法,调整speedX/speedY的随机范围(原代码是固定15)
内容的提问来源于stack exchange,提问作者user21270064
相关产品推荐
相关产品推荐

