Skip to content

OOP_button_zh

aaaven edited this page Mar 7, 2018 · 1 revision

按钮:面向对象编程练习。

1. 要想编写一个按钮应该从哪里开始?

要点:

  • 画出按钮:一个长方形或者圆形
//draw
fill(buttonColor);
rect(bx, by, w, h);
  • 检查按钮状态:鼠标是否在按钮图形内
// hover
if (mouseX > bx && mouseX < bx+w &&
    mouseY > by && mouseY < by+h) {
    buttonColor = color(255, 0, 0);
  } else {
    buttonColor = color(100);
  }
// click
if (mouseX > bx && mouseX < bx+w &&
    mouseY > by && mouseY < by+h) {//hover
    buttonColor = color(255, 0, 0);
    if(mousePressed){//click
         buttonColor = color(random(255), random(255), random(255));
    }
  } else {
    buttonColor = color(100);
  }
  • 填入processing基本框架
void setup(){
//run only once
}

void draw(){
//always loop
}
  • 完成按钮编写后,请思考变量以及起作用域在这段代码中的作用,如果不使用变量会如何?

如何编写一个圆形的按钮呢?

  • 要点在于如何做鼠标位置与按钮关系的判断
//circle, check

  float distance = dist(x, y, mouseX, mouseY);
  if ( distance < size/2) { //mouse hover
    buttonColor = color(255, 0, 0);
    if (mousePressed) {
      buttonColor = color(random(255), random(255), random(255));
    }
  } else {
    buttonColor = color(100);
  }

2.怎么去写两个或者更多的按钮呢?

  • Of course, copy and paste always come in handy. Give it a try for 2 buttons.
  fill(button1Color);
  ellipse(x1, y1, size1, size1);
  fill(button2Color);
  ellipse(x2, y2, size2, size2);

  float distance1 = dist(x1, y1, mouseX, mouseY);
  if ( distance1 < size1/2) { //mouse hover
    button1Color = color(255, 0, 0);
    if (mousePressed) {
      button1Color = color(random(255), random(255), random(255));
    }
  } else {
    button1Color = color(100);
  }
  float distance2 = dist(x2, y2, mouseX, mouseY);
  if ( distance2 < size2/2) { //mouse hover
    button2Color = color(255, 0, 0);
    if (mousePressed) {
      button2Color = color(random(255), random(255), random(255));
    }
  } else {
    button2Color = color(100);
  }
  • 如果是十个按钮甚至更多呢?
//function
int checkDistance(float _x, float _y, float _size) {
  int result = 0;
  float distance = dist(_x, _y, mouseX, mouseY);
  if ( distance < _size/2) { //mouse hover
    result = 1;
    if (mousePressed) {
      result = 2;
    }
  } else {
    result = 0;
  }
  return result;
}
  //call the function in draw()

  //draw
  fill(button1Color);
  ellipse(x1, y1, size1, size1);

  //check
  int check = checkDistance(x1, y1, size1);
  switch(check) {
  case 0:
    button1Color = color(100);
    break;
  case 1:
    button1Color = color(255, 0, 0);
    break;
  case 2:
        button1Color = color(random(255),random(255),random(255));
    break;
  }
  • 这样对于写一个按钮而言,看起来可能并没有省多少事儿,但是如果加上循环的话:
y = height/2;
btn_size = 100;

for (int x = btn_size/2; x < width; x+=btn_size) {
    println(x);
    int check = checkDistance(x, y, btn_size);
    switch(check) {
    case 0:
      buttonColor = color(x/10);
      break;
    case 1:
      buttonColor = color(255, 0, 0);
      break;
    case 2:
      buttonColor = color(random(255), random(255), random(255));
      break;
    }

    fill(buttonColor);
    ellipse(x, y, btn_size, btn_size);
  }
  • 或者循环嵌套:
  for (int y = btn_size/2; y < height; y += btn_size) {
    for (int x = btn_size/2; x < width; x += btn_size) {
		//check
		//draw
}
}

3.如何用面向对象编程去编写一个按钮呢?

  • OOP "framework":
Class Button{
//declare fields(variable)
float x,y,size;
//construction function
Button(float _x, float _y, float _size){
    x = _x;
    y = _y;
    size = _size;
}
//method a(function) eg. checkDistance()
void checkDistance(){
}
//method b(function) eg.drawButton() or display()
void display(){
}
//method c(function) eg.update()
void update(){
}
}
  • 代码示例
class Button {
  float x, y, size;
  int result = 0;
  color buttonColor = color(100);
  Button(float _x, float _y, float _size) {
    x = _x;
    y = _y;
    size = _size;
  }
  void checkDistance() {
    float distance = dist(x, y, mouseX, mouseY);
    if ( distance < size/2) { //mouse hover
      result = 1;
      if (mousePressed) {
        result = 2;
      }
    } else {
      result = 0;
    }
  }
  void updateColor() {
    switch(result) {
    case 0:
      buttonColor = color(100);
      break;
    case 1:
      buttonColor = color(255, 0, 0);
      break;
    case 2:
      buttonColor = color(random(255), random(255), random(255));
      break;
    }
  }
  void display() {
    fill(buttonColor);
    ellipse(x, y, size, size);
  }
}
// declare
Button button1, button2;
void setup() {
  size(400, 400);
  noStroke();
  //init
  button1 = new Button(width/2,height/3,100);
  button2 = new Button(width/2,2*height/3,50);
}
void draw() {
  background(100);
  //run btn1
  button1.checkDistance();
  button1.updateColor();
  button1.display();
  //run btn2
  button2.checkDistance();
  button2.updateColor();
  button2.display();
}
  • 这样看起来还是不够简洁,如何去优化一下呢?(提示:可以在一个函数中调用别的函数)
//in button class
  void run(){
    check();
    update();
    display();
  }
//in draw()
  button1.run();
  button2.run();
  • 另外一个小建议:使用多标签管理代码