processing画一个时钟:音乐、控制转动等
程序员文章站
2022-04-27 13:26:35
...
processing画一个时钟:音乐、控制转动等
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012428012/article/details/79676759
分析
钟表的功能主要实现以下几个功能:
- 画钟表的表盘、数字等
- 通过 s 或 S 键控制旋转,t 或 T 键暂停旋转
- 设置音乐的定时播放、秒针转动播放音乐
- 右上角显示当前时间
- 设置时针的转动
- 设置分针的转动
- 设置秒针的转动
- 最终效果
1. 画钟表的表盘、数字等
- 在屏幕中间画一个半径为150的圆
- 表盘上一圈有60个刻度线,对应360度。因此,一个刻度线对应6度。
- 将坐标系平移到屏幕中间,并每次旋转:每次旋转6度并画一条刻度线,总共60次。整点的刻度(如1点、3点、6点等)应该较长,所以每5次让线的更长更粗。
- 设置3点、6点、9点、12点的文字。
void setup () {
size(500, 500);
}
void draw () {
// 表盘
ellipseMode(CENTER);
strokeWeight(10);
fill(0);
ellipse(width/2, height/2, 300, 300);
// 刻度线
for(int i = 1; i <= 60; i++) {
pushMatrix(); // 拷贝一份坐标系位置
translate(width/2, height/2); // 移动坐标系(0,0)到(width/2, height/2)
rotate(radians(i * 6));
if(i % 5 == 0) { // 整点的刻度线
strokeWeight(3);
line(120, 0, 130, 0);
} else { // 非整点的刻度线
strokeWeight(1);
line(125, 0, 130, 0);
}
popMatrix(); // 恢复坐标系位置
}
// 0-12时
textSize(25);
fill(255);
stroke(255);
strokeWeight(1);
text(12, 235, 155); //12
text(3, 350, 260) ;//3
text(9, 135, 260) ;//9
text(6, 245, 365) ;//6
}
2. 通过 s 或 S 键控制旋转,t 或 T 键暂停旋转
- 设置全部变量flag,用于控制时针等是否旋转
- 按下s或S时旋转,按下t或T时停止转动
Boolean flag = true;
void draw () {
if (key == 's' || key == 'S') {
flag = true;
} else if (key=='t' || key=='T') {
flag = false;
}
}
3. 设置音乐的定时播放、秒针转动播放音乐
- 定义三个整型变量currentHour、currentMinute、currentSecond保存系统当前的时分秒信息
- 定义两个浮点型变量currentMinuteFloat、currentHourFloat。
- currentMinuteFloat为实际的分钟(minute() + currentSecond / 60.0)
- currentHourFloat为实际的小时(hour() + currentMinuteFloat / 60.0)。
- 两个if条件:设定闹钟音乐播放时间,和闹钟音乐停止时间。
- flag为true时,秒针转动的音乐一直播放。flag为false时,秒针不转动,音乐停止播放。
import ddf.minim.*;
Minim minim;
AudioPlayer player; // 闹钟音乐
AudioPlayer player1; // 秒针转动的音乐
PImage img; // 背景图片
int currentSecond; // second,秒
int currentMinute; // minute,分
int currentHour; // hour,时
float currentMinuteFloat; // minute,分,实际分钟 minute() + currentSecond / 60.0;
float currentHourFloat; // hour,时,实际小时 hour() + currentMinuteFloat / 60.0;
void setup () {
size(500, 500);
img = loadImage("1.jpg");
minim = new Minim(this);
player = minim.loadFile("music.mp3");
player1 = minim.loadFile("zhongbiao1.mp3");
}
void draw () {
// 当前时间的时、分、秒。08:02:03,10:32:13
currentSecond = second();
currentMinute = minute();
currentHour = hour();
currentMinuteFloat = minute() + currentSecond / 60.0;
currentHourFloat = hour() + currentMinuteFloat / 60.0;
// 播放音乐:指定时间段内播放音乐。闹钟功能
if (currentSecond == 30 && currentMinute == 30 && currentHour == 22) {
player.play();
}
if (currentSecond == 40 && currentMinute == 30 && currentHour == 22) {
if (player.isPlaying()) {
player.pause();
}
}
// 播放秒针转动的音乐
if(flag) {
if (player1.position() == player1.length()) {
player1.rewind();
player1.play();
} else {
player1.play();
}
} else {
if (player1.isPlaying()) {
player1.pause();
}
}
}
4. 右上角显示当前时间
- 右上角显示当前时间:时间一般显示格式为08:02:03 或10:32:13,所以当currentSecond<10的时候,数字前面加上一个0。
- 右上角第二行显示当前日期:调用year()/month()/day()函数显示
- 右下角显示作品作者
void draw () {
// 右上角显示当前时间
String secondBeatiful = currentSecond + "";
String minuteBeatiful = currentMinute + "";
String hourBeatiful = currentHour + "";
if (currentSecond < 10) {
secondBeatiful = "0" + currentSecond;
}
if (currentMinute < 10) {
minuteBeatiful = "0" + currentMinute;
}
if (currentHour < 10) {
hourBeatiful = "0" + currentHour;
}
String currentTime = hourBeatiful + ":" + minuteBeatiful + ":" + secondBeatiful;
textSize(50);
text(currentTime, width - 230, 50);
String currentDate = year() + "/" + month() + "/" + day();
textSize(25);
text(currentDate, width - 150, 100);
String author = "Author: Yuanhao Zheng";
textSize(20);
text(author, width - 250, height - 10);
}
5. 设置时针的转动
- 时针转动一圈为12个小时,因此一个小时为30度。
- 平移坐标系原点到屏幕*,然后旋转坐标系达到旋转时针的效果。
- 当时针为3点到12点(或15点到24点)时,应该转动的角度是0到270度,所以旋转的角度为
angleHour = radians(30 * (currentHourFloat - 3)); - 当时针为1点到2点(或13点到14点)时,应该转动的角度是270到360度,所以旋转的角度为angleHour = radians(30 * (currentHourFloat - 1) + 300);
- 当时针为3点到12点(或15点到24点)时,应该转动的角度是0到270度,所以旋转的角度为
- 根据之前设定好的是否转动值flag来控制坐标系转动。(flag默认是true,按下t后为false)
- 画线:设置线条颜色(白色)和粗细(7),注意此时线条起始点和终止点的坐标都为0,横坐标不同。
void draw () {
// hour:时针
// 12个小时为360度,一个小时30度。
// 3点到12点的角度是0到270;0到3点的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleHour = radians(270);
if ((currentHourFloat >= 3 && currentHourFloat <= 12) || (currentHourFloat >= 15 && currentHourFloat <= 24)) {
angleHour = radians(30 * (currentHourFloat - 3));
} else {
angleHour = radians(30 * (currentHourFloat - 1) + 300);
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleHour);
} else {
rotate(radians(270));
}
stroke(255);
strokeWeight(7);
line(-10, 0, 50, 0);
popMatrix();
}
6. 设置分针的转动
- 分针转动一圈为60分钟,因此一分钟为6度。
- 平移坐标系原点到屏幕*,然后旋转坐标系达到旋转分针的效果。
- 当分针为15分钟到60分钟时,应该转动的角度是0到270度,所以旋转的角度为
angleMinute = radians(6 * (currentMinuteFloat - 15)); - 当分针为0分钟到15分钟时,应该转动的角度是270到360度,所以旋转的角度为angleMinute = radians(270 + 6 * currentMinuteFloat);
- 当分针为15分钟到60分钟时,应该转动的角度是0到270度,所以旋转的角度为
- 根据之前设定好的是否转动值flag来控制坐标系转动。(flag默认是true,按下t后为false)
- 画线:设置线条颜色(白色)和粗细(5),注意此时线条起始点和终止点的坐标都为0,横坐标不同。
void draw () {
// minute:分针
// 60分钟为360度,一分钟为6度。
// 15分钟到60分钟的角度是0到270;0到15分钟的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleMinute = radians(270);
if ((currentMinuteFloat >= 0 && currentMinute <= 15)) {
angleMinute = radians(270 + 6 * currentMinuteFloat);
} else {
angleMinute = radians(6 * (currentMinuteFloat - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleMinute);
} else {
rotate(radians(0));
}
stroke(255);
strokeWeight(5);
line(-10, 0, 70, 0);
popMatrix();
}
7. 设置秒针的转动
- 秒针转动一圈为60秒,因此一秒为6度。
- 平移坐标系原点到屏幕*,然后旋转坐标系达到旋转秒针的效果。
- 当秒针为15秒到60秒时,应该转动的角度是0到270度,所以旋转的角度为
angleSecond = radians(6 * (currentSecond - 15)); - 当秒针为0秒到15秒时,应该转动的角度是270到360度,所以旋转的角度为angleMinute = angleSecond = radians(270 + 6 * currentSecond);
- 当秒针为15秒到60秒时,应该转动的角度是0到270度,所以旋转的角度为
- 根据之前设定好的是否转动值flag来控制坐标系转动。(flag默认是true,按下t后为false)
- 画线:设置线条颜色(红色)和粗细(3),注意此时线条起始点和终止点的坐标都为0,横坐标不同。并且还画了一个圆表示线头。
void draw () {
// second and ellipse:秒针
// 60秒为360度,一秒为6度。
// 15秒到60秒的角度是0到270;0到15秒的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleSecond = radians(270);
if ((currentSecond >= 0 && currentSecond <= 15)) {
angleSecond = radians(270 + 6 * currentSecond);
} else {
angleSecond = radians(6 * (currentSecond - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleSecond);
} else {
rotate(radians(180));
}
stroke(255,0,0);
strokeWeight(3);
line(-15, 0, 90, 0);
fill(255,0,0);
ellipse(115, 0, 10, 10);
stroke(255);
popMatrix();
}
8. 最终效果
实现代码
具体实现为:
import ddf.minim.*;
Minim minim;
AudioPlayer player; // 闹钟音乐
AudioPlayer player1; // 秒针转动的音乐
PImage img; // 背景图片
Boolean flag = true; // 控制是否播放音乐
// 时间相关全部变量
int currentSecond; // second,秒
int currentMinute; // minute,分
int currentHour; // hour,时
float currentMinuteFloat; // minute,分,实际分钟 minute() + currentSecond / 60.0;
float currentHourFloat; // hour,时,实际小时 hour() + currentMinuteFloat / 60.0;
void setup () {
size(500, 500);
img = loadImage("1.jpg");
minim = new Minim(this);
player = minim.loadFile("music.mp3");
player1 = minim.loadFile("zhongbiao1.mp3");
}
void draw () {
// 背景图
image(img, 0, 0, 500, 500);
// 表盘
ellipseMode(CENTER);
strokeWeight(10);
fill(0);
ellipse(width/2, height/2, 300, 300);
// 刻度线
for(int i = 1; i <= 60; i++) {
pushMatrix(); // 拷贝一份坐标系位置
translate(width/2, height/2); // 移动坐标系(0,0)到(width/2, height/2)
rotate(radians(i * 6));
if(i % 5 == 0) { // 整点的刻度线
strokeWeight(3);
line(120, 0, 130, 0);
} else { // 非整点的刻度线
strokeWeight(1);
line(125, 0, 130, 0);
}
popMatrix(); // 恢复坐标系位置
}
// 0-12时
textSize(25);
fill(255);
stroke(255);
strokeWeight(1);
text(12, 235, 155); //12
text(3, 350, 260) ;//3
text(9, 135, 260) ;//9
text(6, 245, 365) ;//6
// 判断是否按下暂停和启动键
if (key == 's' || key == 'S') {
flag = true;
} else if (key == 't' || key == 'T') {
flag = false;
}
// 当前时间的时、分、秒。08:02:03,10:32:13
currentSecond = second();
currentMinute = minute();
currentHour = hour();
currentMinuteFloat = minute() + currentSecond / 60.0;
currentHourFloat = hour() + currentMinuteFloat / 60.0;
// 播放音乐:指定时间段内播放音乐。闹钟功能
if (currentSecond == 30 && currentMinute == 30 && currentHour == 22) {
player.play();
}
if (currentSecond == 40 && currentMinute == 30 && currentHour == 22) {
if (player.isPlaying()) {
player.pause();
}
}
// 播放秒针转动的音乐
if(flag) {
if (player1.position() == player1.length()) {
player1.rewind();
player1.play();
} else {
player1.play();
}
} else {
if (player1.isPlaying()) {
player1.pause();
}
}
// 右上角显示当前时间
String secondBeatiful = currentSecond + "";
String minuteBeatiful = currentMinute + "";
String hourBeatiful = currentHour + "";
if (currentSecond < 10) {
secondBeatiful = "0" + currentSecond;
}
if (currentMinute < 10) {
minuteBeatiful = "0" + currentMinute;
}
if (currentHour < 10) {
hourBeatiful = "0" + currentHour;
}
String currentTime = hourBeatiful + ":" + minuteBeatiful + ":" + secondBeatiful;
textSize(50);
text(currentTime, width - 230, 50);
String currentDate = year() + "/" + month() + "/" + day();
textSize(25);
text(currentDate, width - 150, 100);
String author = "Author: Yuanhao Zheng";
textSize(20);
text(author, width - 250, height - 10);
// hour:时针
// 12个小时为360度,一个小时30度。
// 3点到12点的角度是0到270;0到3点的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleHour = radians(270);
if ((currentHourFloat >= 3 && currentHourFloat <= 12) || (currentHourFloat >= 15 && currentHourFloat <= 24)) {
angleHour = radians(30 * (currentHourFloat - 3));
} else {
angleHour = radians(30 * (currentHourFloat - 1) + 300);
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleHour);
} else {
rotate(radians(270));
}
stroke(255);
strokeWeight(7);
line(-10, 0, 50, 0);
popMatrix();
// minute:分针
// 60分钟为360度,一分钟为6度。
// 15分钟到60分钟的角度是0到270;0到15分钟的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleMinute = radians(270);
if ((currentMinuteFloat >= 0 && currentMinute <= 15)) {
angleMinute = radians(270 + 6 * currentMinuteFloat);
} else {
angleMinute = radians(6 * (currentMinuteFloat - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleMinute);
} else {
rotate(radians(0));
}
stroke(255);
strokeWeight(5);
line(-10, 0, 70, 0);
popMatrix();
// second and ellipse:秒针
// 60秒为360度,一秒为6度。
// 15秒到60秒的角度是0到270;0到15秒的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleSecond = radians(270);
if ((currentSecond >= 0 && currentSecond <= 15)) {
angleSecond = radians(270 + 6 * currentSecond);
} else {
angleSecond = radians(6 * (currentSecond - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleSecond);
} else {
rotate(radians(180));
}
stroke(255,0,0);
strokeWeight(3);
line(-15, 0, 90, 0);
fill(255,0,0);
ellipse(115, 0, 10, 10);
stroke(255);
popMatrix();
}
void keyPressed() {
if (key == 'z' || key == 'Z') {
player.pause();
}
if (key == 'x' || key == 'X') {
player.play();
}
if (key == 'c' || key == 'C') {
player.rewind();
}
}
实现代码2(函数版)
抽象成函数,具体实现为:
import ddf.minim.*;
Minim minim;
AudioPlayer player; // 闹钟音乐
AudioPlayer player1; // 秒针转动的音乐
PImage img; // 背景图片
Boolean flag = true; // 控制是否播放音乐
// 时间相关全部变量
int currentSecond; // second,秒
int currentMinute; // minute,分
int currentHour; // hour,时
float currentMinuteFloat; // minute,分,实际分钟 minute() + currentSecond / 60.0;
float currentHourFloat; // hour,时,实际小时 hour() + currentMinuteFloat / 60.0;
void setup () {
size(500, 500);
img = loadImage("1.jpg");
minim = new Minim(this);
player = minim.loadFile("music.mp3");
player1 = minim.loadFile("zhongbiao1.mp3");
}
void draw () {
// 背景图
image(img, 0, 0, 500, 500);
// 计算当前时间的时、分、秒。08:02:03,10:32:13
currentSecond = second();
currentMinute = minute();
currentHour = hour();
currentMinuteFloat = minute() + currentSecond / 60.0;
currentHourFloat = hour() + currentMinuteFloat / 60.0;
// 画钟表的基本形状
drawClock();
// 播放音乐
playMusic();
// 右上角显示当前时间和日期
showTimeAndDate();
// hour:时针
hourPointer();
// minute:分针
minutePointer();
// second and ellipse:秒针
secondPointer();
}
// 画钟表的基本形状
void drawClock() {
// 表盘
ellipseMode(CENTER);
strokeWeight(10);
fill(0);
ellipse(width/2, height/2, 300, 300);
// 刻度线
for(int i = 1; i <= 60; i++) {
pushMatrix(); // 拷贝一份坐标系位置
translate(width/2, height/2); // 移动坐标系(0,0)到(width/2, height/2)
rotate(radians(i * 6));
if(i % 5 == 0) { // 整点的刻度线
strokeWeight(3);
line(120, 0, 130, 0);
} else { // 非整点的刻度线
strokeWeight(1);
line(125, 0, 130, 0);
}
popMatrix(); // 恢复坐标系位置
}
// 0-12时
textSize(25);
fill(255);
stroke(255);
strokeWeight(1);
text(12, 235, 155); //12
text(3, 350, 260) ;//3
text(9, 135, 260) ;//9
text(6, 245, 365) ;//6
}
// 判断是否按下暂停和启动键
void keyPressed() {
// 判断是否按下暂停和启动键
if (key == 's' || key == 'S') {
flag = true;
} else if (key=='t' || key=='T') {
flag = false;
}
}
// 播放音乐
void playMusic() {
// 播放音乐:指定时间段内播放音乐。闹钟功能
if (currentSecond == 30 && currentMinute == 30 && currentHour == 22) {
player.play();
}
if (currentSecond == 40 && currentMinute == 30 && currentHour == 22) {
if (player.isPlaying()) {
player.pause();
}
}
// 播放秒针转动的音乐
if(flag) {
if (player1.position() == player1.length()) {
player1.rewind();
player1.play();
} else {
player1.play();
}
} else {
if (player1.isPlaying()) {
player1.pause();
}
}
}
// 右上角显示当前时间和日期
void showTimeAndDate() {
// 右上角显示当前时间。08:02:03,10:32:13
String secondBeatiful = currentSecond + "";
String minuteBeatiful = currentMinute + "";
String hourBeatiful = currentHour + "";
if (currentSecond < 10) {
secondBeatiful = "0" + currentSecond;
}
if (currentMinute < 10) {
minuteBeatiful = "0" + currentMinute;
}
if (currentHour < 10) {
hourBeatiful = "0" + currentHour;
}
String currentTime = hourBeatiful + ":" + minuteBeatiful + ":" + secondBeatiful;
textSize(50);
text(currentTime, width - 230, 50);
String currentDate = year() + "/" + month() + "/" + day();
textSize(25);
text(currentDate, width - 150, 100);
String author = "Author: Yuanhao Zheng";
textSize(20);
text(author, width - 250, height - 10);
}
// hour:时针
void hourPointer() {
// hour:时针
// 12个小时为360度,一个小时30度。
// 3点到12点的角度是0到270;0到3点的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleHour = radians(270);
if ((currentHourFloat >= 3 && currentHourFloat <= 12) || (currentHourFloat >= 15 && currentHourFloat <= 24)) {
angleHour = radians(30 * (currentHourFloat - 3));
} else {
angleHour = radians(30 * (currentHourFloat - 1) + 300);
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleHour);
} else {
rotate(radians(270));
}
stroke(255);
strokeWeight(7);
line(-10, 0, 50, 0);
popMatrix();
}
// minute:分针
void minutePointer() {
// minute:分针
// 60分钟为360度,一分钟为6度。
// 15分钟到60分钟的角度是0到270;0到15分钟的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleMinute = radians(270);
if ((currentMinuteFloat >= 0 && currentMinute <= 15)) {
angleMinute = radians(270 + 6 * currentMinuteFloat);
} else {
angleMinute = radians(6 * (currentMinuteFloat - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleMinute);
} else {
rotate(radians(0));
}
stroke(255);
strokeWeight(5);
line(-10, 0, 70, 0);
popMatrix();
}
// second and ellipse:秒针
void secondPointer() {
// second and ellipse:秒针
// 60秒为360度,一秒为6度。
// 15秒到60秒的角度是0到270;0到15秒的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleSecond = radians(270);
if ((currentSecond >= 0 && currentSecond <= 15)) {
angleSecond = radians(270 + 6 * currentSecond);
} else {
angleSecond = radians(6 * (currentSecond - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleSecond);
} else {
rotate(radians(180));
}
stroke(255,0,0);
strokeWeight(3);
line(-15, 0, 90, 0);
fill(255,0,0);
ellipse(115, 0, 10, 10);
stroke(255);
popMatrix();
}
实现代码3(函数 + 数组)
将时间相关的变量放到数组中,具体实现为:
import ddf.minim.*;
Minim minim;
AudioPlayer player; // 闹钟音乐
AudioPlayer player1; // 秒针转动的音乐
PImage img; // 背景图片
Boolean flag = true; // 控制是否播放音乐
// 时间相关全部变量
int[] time = new int[3]; // 数组:秒、分、时
float[] timeFloat = new float[2];
//int currentSecond; // second,秒
//int currentMinute; // minute,分
//int currentHour; // hour,时
//float currentMinuteFloat; // minute,分,实际分钟 minute() + currentSecond / 60.0;
//float currentHourFloat; // hour,时,实际小时 hour() + currentMinuteFloat / 60.0;
void setup () {
size(500, 500);
img = loadImage("1.jpg");
minim = new Minim(this);
player = minim.loadFile("music.mp3");
player1 = minim.loadFile("zhongbiao1.mp3");
}
void draw () {
// 背景图
image(img, 0, 0, 500, 500);
// 计算当前时间的时、分、秒。08:02:03,10:32:13
time[0] = second();
time[1] = minute();
time[2] = hour();
timeFloat[0] = minute() + time[0] / 60.0;
timeFloat[1] = hour() + timeFloat[0] / 60.0;
//currentSecond = second();
//currentMinute = minute();
//currentHour = hour();
//currentMinuteFloat = minute() + currentSecond / 60.0;
//currentHourFloat = hour() + currentMinuteFloat / 60.0;
// 画钟表的基本形状
drawClock();
// 播放音乐
playMusic();
// 右上角显示当前时间和日期
showTimeAndDate();
// hour:时针
hourPointer();
// minute:分针
minutePointer();
// second and ellipse:秒针
secondPointer();
}
// 画钟表的基本形状
void drawClock() {
// 表盘
ellipseMode(CENTER);
strokeWeight(10);
fill(0);
ellipse(width/2, height/2, 300, 300);
// 刻度线
for(int i = 1; i <= 60; i++) {
pushMatrix(); // 拷贝一份坐标系位置
translate(width/2, height/2); // 移动坐标系(0,0)到(width/2, height/2)
rotate(radians(i * 6));
if(i % 5 == 0) { // 整点的刻度线
strokeWeight(3);
line(120, 0, 130, 0);
} else { // 非整点的刻度线
strokeWeight(1);
line(125, 0, 130, 0);
}
popMatrix(); // 恢复坐标系位置
}
// 0-12时
textSize(25);
fill(255);
stroke(255);
strokeWeight(1);
text(12, 235, 155); //12
text(3, 350, 260) ;//3
text(9, 135, 260) ;//9
text(6, 245, 365) ;//6
}
// 判断是否按下暂停和启动键
void keyPressed() {
// 判断是否按下暂停和启动键
if (key == 's' || key == 'S') {
flag = true;
} else if (key=='t' || key=='T') {
flag = false;
}
}
// 播放音乐
void playMusic() {
// 播放音乐:指定时间段内播放音乐。闹钟功能
if (time[0] == 30 && time[1] == 30 && time[2] == 22) {
player.play();
}
if (time[0] == 40 && time[1] == 30 && time[2] == 22) {
if (player.isPlaying()) {
player.pause();
}
}
// 播放秒针转动的音乐
if(flag) {
if (player1.position() == player1.length()) {
player1.rewind();
player1.play();
} else {
player1.play();
}
} else {
if (player1.isPlaying()) {
player1.pause();
}
}
}
// 右上角显示当前时间和日期
void showTimeAndDate() {
// 右上角显示当前时间。08:02:03,10:32:13
String secondBeatiful = time[0] + "";
String minuteBeatiful = time[1] + "";
String hourBeatiful = time[2] + "";
if (time[0] < 10) {
secondBeatiful = "0" + time[0];
}
if (time[1] < 10) {
minuteBeatiful = "0" + time[1];
}
if (time[2] < 10) {
hourBeatiful = "0" + time[2];
}
String currentTime = hourBeatiful + ":" + minuteBeatiful + ":" + secondBeatiful;
textSize(50);
text(currentTime, width - 230, 50);
String currentDate = year() + "/" + month() + "/" + day();
textSize(25);
text(currentDate, width - 150, 100);
String author = "Author: Yuanhao Zheng";
textSize(20);
text(author, width - 250, height - 10);
}
// hour:时针
void hourPointer() {
// hour:时针
// 12个小时为360度,一个小时30度。
// 3点到12点的角度是0到270;0到3点的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleHour = radians(270);
if ((timeFloat[1] >= 3 && timeFloat[1] <= 12) || (timeFloat[1] >= 15 && timeFloat[1] <= 24)) {
angleHour = radians(30 * (timeFloat[1] - 3));
} else {
angleHour = radians(30 * (timeFloat[1] - 1) + 300);
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleHour);
} else {
rotate(radians(270));
}
stroke(255);
strokeWeight(7);
line(-10, 0, 50, 0);
popMatrix();
}
// minute:分针
void minutePointer() {
// minute:分针
// 60分钟为360度,一分钟为6度。
// 15分钟到60分钟的角度是0到270;0到15分钟的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleMinute = radians(270);
if ((timeFloat[0] >= 0 && timeFloat[0] <= 15)) {
angleMinute = radians(270 + 6 * timeFloat[0]);
} else {
angleMinute = radians(6 * (timeFloat[0] - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleMinute);
} else {
rotate(radians(0));
}
stroke(255);
strokeWeight(5);
line(-10, 0, 70, 0);
popMatrix();
}
// second and ellipse:秒针
void secondPointer() {
// second and ellipse:秒针
// 60秒为360度,一秒为6度。
// 15秒到60秒的角度是0到270;0到15秒的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleSecond = radians(270);
if ((time[0] >= 0 && time[0] <= 15)) {
angleSecond = radians(270 + 6 * time[0]);
} else {
angleSecond = radians(6 * (time[0] - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleSecond);
} else {
rotate(radians(180));
}
stroke(255,0,0);
strokeWeight(3);
line(-15, 0, 90, 0);
fill(255,0,0);
ellipse(115, 0, 10, 10);
stroke(255);
popMatrix();
}
实现代码4(函数 + 类)
将时间相关的抽象成一个类,具体实现为:
import ddf.minim.*;
Minim minim;
AudioPlayer player; // 闹钟音乐
AudioPlayer player1; // 秒针转动的音乐
PImage img; // 背景图片
Boolean flag = true; // 控制是否播放音乐
// 时间类
class Time {
// 时间相关全部变量
int currentSecond; // second,秒
int currentMinute; // minute,分
int currentHour; // hour,时
float currentMinuteFloat; // minute,分,实际分钟 minute() + currentSecond / 60.0;
float currentHourFloat; // hour,时,实际小时 hour() + currentMinuteFloat / 60.0;
// 构造函数,函数名和类名(Time)相同,没有返回类型
Time(int s, int m, int h, float mf, float hf) {
currentSecond = s;
currentMinute = m;
currentHour = h;
currentMinuteFloat = mf;
currentHourFloat = hf;
}
}
void setup () {
size(500, 500);
img = loadImage("1.jpg");
minim = new Minim(this);
player = minim.loadFile("music.mp3");
player1 = minim.loadFile("zhongbiao1.mp3");
}
void draw () {
// 背景图
image(img, 0, 0, 500, 500);
// 计算当前时间的时、分、秒。08:02:03,10:32:13
int s = second();
int m = minute();
int y = hour();
float mf = minute() + s / 60.0;
float hf = hour() + mf / 60.0;
Time time = new Time(s, m, y, mf, hf);
// 画钟表的基本形状
drawClock();
// 播放音乐
playMusic(time);
// 右上角显示当前时间和日期
showTimeAndDate(time);
// hour:时针
hourPointer(time);
// minute:分针
minutePointer(time);
// second and ellipse:秒针
secondPointer(time);
}
// 画钟表的基本形状
void drawClock() {
// 表盘
ellipseMode(CENTER);
strokeWeight(10);
fill(0);
ellipse(width/2, height/2, 300, 300);
// 刻度线
for (int i = 1; i <= 60; i++) {
pushMatrix(); // 拷贝一份坐标系位置
translate(width/2, height/2); // 移动坐标系(0,0)到(width/2, height/2)
rotate(radians(i * 6));
if (i % 5 == 0) { // 整点的刻度线
strokeWeight(3);
line(120, 0, 130, 0);
} else { // 非整点的刻度线
strokeWeight(1);
line(125, 0, 130, 0);
}
popMatrix(); // 恢复坐标系位置
}
// 0-12时
textSize(25);
fill(255);
stroke(255);
strokeWeight(1);
text(12, 235, 155); //12
text(3, 350, 260) ;//3
text(9, 135, 260) ;//9
text(6, 245, 365) ;//6
}
// 判断是否按下暂停和启动键
void keyPressed() {
// 判断是否按下暂停和启动键
if (key == 's' || key == 'S') {
flag = true;
} else if (key=='t' || key=='T') {
flag = false;
}
}
// 播放音乐
void playMusic(Time time) {
// 播放音乐:指定时间段内播放音乐。闹钟功能
if (time.currentSecond == 30 && time.currentMinute == 30 && time.currentHour == 22) {
player.play();
}
if (time.currentSecond == 40 && time.currentMinute == 30 && time.currentHour == 22) {
if (player.isPlaying()) {
player.pause();
}
}
// 播放秒针转动的音乐
if (flag) {
if (player1.position() == player1.length()) {
player1.rewind();
player1.play();
} else {
player1.play();
}
} else {
if (player1.isPlaying()) {
player1.pause();
}
}
}
// 右上角显示当前时间和日期
void showTimeAndDate(Time time) {
// 右上角显示当前时间。08:02:03,10:32:13
String secondBeatiful = time.currentSecond + "";
String minuteBeatiful = time.currentMinute + "";
String hourBeatiful = time.currentHour + "";
if (time.currentSecond < 10) {
secondBeatiful = "0" + time.currentSecond;
}
if (time.currentMinute < 10) {
minuteBeatiful = "0" + time.currentMinute;
}
if (time.currentHour < 10) {
hourBeatiful = "0" + time.currentHour;
}
String currentTime = hourBeatiful + ":" + minuteBeatiful + ":" + secondBeatiful;
textSize(50);
text(currentTime, width - 230, 50);
String currentDate = year() + "/" + month() + "/" + day();
textSize(25);
text(currentDate, width - 150, 100);
String author = "Author: Yuanhao Zheng";
textSize(20);
text(author, width - 250, height - 10);
}
// hour:时针
void hourPointer(Time time) {
// hour:时针
// 12个小时为360度,一个小时30度。
// 3点到12点的角度是0到270;0到3点的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleHour = radians(270);
if ((time.currentHourFloat >= 3 && time.currentHourFloat <= 12) || (time.currentHourFloat >= 15 && time.currentHourFloat <= 24)) {
angleHour = radians(30 * (time.currentHourFloat - 3));
} else {
angleHour = radians(30 * (time.currentHourFloat - 1) + 300);
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleHour);
} else {
rotate(radians(270));
}
stroke(255);
strokeWeight(7);
line(-10, 0, 50, 0);
popMatrix();
}
// minute:分针
void minutePointer(Time time) {
// minute:分针
// 60分钟为360度,一分钟为6度。
// 15分钟到60分钟的角度是0到270;0到15分钟的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleMinute = radians(270);
if ((time.currentMinuteFloat >= 0 && time.currentMinute <= 15)) {
angleMinute = radians(270 + 6 * time.currentMinuteFloat);
} else {
angleMinute = radians(6 * (time.currentMinuteFloat - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleMinute);
} else {
rotate(radians(0));
}
stroke(255);
strokeWeight(5);
line(-10, 0, 70, 0);
popMatrix();
}
// second and ellipse:秒针
void secondPointer(Time time) {
// second and ellipse:秒针
// 60秒为360度,一秒为6度。
// 15秒到60秒的角度是0到270;0到15秒的角度是270到360。
pushMatrix();
translate(width/2, height/2);
float angleSecond = radians(270);
if ((time.currentSecond >= 0 && time.currentSecond <= 15)) {
angleSecond = radians(270 + 6 * time.currentSecond);
} else {
angleSecond = radians(6 * (time.currentSecond - 15));
}
if (flag) { // 判断是否按下按键,停止转动
rotate(angleSecond);
} else {
rotate(radians(180));
}
stroke(255, 0, 0);
strokeWeight(3);
line(-15, 0, 90, 0);
fill(255, 0, 0);
ellipse(115, 0, 10, 10);
stroke(255);
popMatrix();
}