Как сделать (движущийся) эллипс кликабельным? Обработка

Итак, я начал изучать обработку с недели назад, и я пытаюсь сделать движущийся эллипс интерактивным. Я следил за API обработки, но не могу понять. Я удалил весь код, относящийся к интерактивному эллипсу, потому что это был беспорядок.

В разделе, где я объявляю все свои вары, вы можете увидеть, как я использую:

int breedte = 600;
int hoogte = 600;

Предположительно это:

int breedte = width;
int hoogte = height;

Но по какой-то причине ширина и высота не выводят ширину и высоту, объявленные в:

size(600,600) 

Я спрашиваю:

  1. Как сделать (подвижный) эллипс интерактивным?

  2. Почему я не могу использовать ширину и высоту для int hoogte и int blendte?

Заранее спасибо.

Основной файл:

int x = 0;
int leftSide = 0;
int rightSide = width;
int bottomSide = height;

int totalHits = 0;
int totalMiss = 0;

boolean start = false;

int circelSize = 100;
int circelRings = 24;
int circelSpeed = 1;
int circelPositionY = 0;

int breedte = 600;
int hoogte = 600;

String[] buttonText = {"Start","Stop"};
String buttonTextActive = buttonText[0];
int[] buttonColor = {0,90};
int buttonColorActive = buttonColor[0];
int buttonHighlight = 50;
int buttonSize = 80;  
int buttonY = breedte - (buttonSize /2);
int buttonX = hoogte / 2 - 40;

void setup() {
  size(600, 600);
  smooth();
  noStroke();
}

void draw() {
  if (start) {
    circelPositionY = circelPositionY + circelSpeed;
    drawCircel(circelPositionY);
    if (circelPositionY == (width + circelSize)) {
      circelPositionY = 0;
    }
  }
  drawButton();
}

Файл событий:

void mousePressed() {
  // Start or Stop button
  if(mouseX > buttonX & mouseX < buttonX  + buttonSize & mouseY > buttonY & mouseY < buttonY + (buttonSize / 2)){
    if(start) {
      start = false;
      buttonColorActive = buttonColor[0];
      buttonTextActive = buttonText[0];
      println("Game stoped");
    } else {
      start = true;
      buttonColorActive = buttonColor[1];
      buttonTextActive = buttonText[1];
      println("Game started");
    }
  }
//HERE SHOULD GO THE CLICKABLE ELLPISE
}

Файл функций:

void drawCircel(int circelPositionY) {
  background(204);
  for (int i = 0; i < circelRings; i = i+1) {
    int even = i % 2;
    if (even == 0) {
      fill(255,0,0);
      ellipse(-(circelSize / 2) + circelPositionY, height / 2 - (circelSize / 2), circelSize - (i * (circelSize / circelRings)), circelSize - (i * (circelSize / circelRings)));
    } else {
      fill(255);
      ellipse(-(circelSize / 2) + circelPositionY, height / 2 - (circelSize / 2), circelSize - (i * (circelSize / circelRings)), circelSize - (i * (circelSize / circelRings)));
    }
  }
}

void drawButton() {
  fill(buttonColorActive);
  rect(buttonX,buttonY, buttonSize, buttonSize / 2);
  fill(255);
  textAlign(CENTER, CENTER);
  text(buttonTextActive, buttonX + (buttonSize / 2),buttonY + (buttonSize / 4));
}

person Thomas Beumer    schedule 13.09.2017    source источник


Ответы (2)


В будущем попробуйте опубликовать MCVE вместо нескольких отдельных фрагментов или всего проекта. Также, пожалуйста, задавайте только один вопрос для каждого сообщения.

Чтобы сделать круг интерактивным, вам нужно будет написать код, который проверяет, нажимается ли круг. На самом деле это две отдельные проверки. Сначала вы должны определить, когда мышь нажата. Один из способов сделать это - определить функцию mousePressed():

void mousePressed(){
  // mouse is pressed
}

Затем вам нужно проверить, находится ли в данный момент мышь внутри круга. Для этого вы можете использовать функцию dist(): если расстояние между мышью и центром круга меньше, чем радиус круга, то мышь находится внутри круга. Это может выглядеть так:

void mousePressed(){
  if(dist(mouseX, mouseY, circleX, circleY) < circleRadius){
    // mouse is pressed inside the circle
  }
}

Бесстыдная самореклама: я написал учебник по обнаружению столкновений в Processing, включая столкновение точка-круг, доступный здесь.

Что касается того, почему вы не можете использовать width и height в верхней части скетча, это потому, что код в верхней части скетча выполняется до срабатывания функции setup(), а переменные width и height не устанавливаются до тех пор, пока вы не вызовете size() из функции setup(). Поэтому вам нужно переместить этот код в после, когда вы позвоните size().

Если у вас есть дополнительные вопросы, опубликуйте обновленный MCVE в новом вопросе, и мы продолжим работу. Удачи.

person Kevin Workman    schedule 13.09.2017
comment
Привет, Кевин, сегодня ты мой герой. Ваш ответ не может быть более ясным! Самореклама - это именно то, что я хотел добавить в свой проект, не стыдно :). Я прочитал MCVE, и мой следующий пост будет лучше. Спасибо, мой друг - person Thomas Beumer; 14.09.2017

Обработка не предоставляет API для обнаружения попаданий, поэтому вам нужно реализовать это самостоятельно, что, на мой взгляд, является отличным обучающим упражнением. Вы можете изучить математику эллипса здесь.

Но общий подход заключается в использовании функции, подобной приведенной ниже, чтобы убедиться, что точка, на которую вы щелкнули, действительно находилась внутри предоставленного вами эллипса.

boolean InsideEllipse(
    float x, float y, 
    float xc, float yc, 
    float width, float height
) { 

    // First half the width and height to get the ellipse parameters
    float a = width / 2;
    float b = height / 2;

    // Now calculate the deltas:
    float xd = x - xc;
    float yd = y - yd;

    // Now the equation of an ellipse is given by 
    //      x^2 / a ^ 2 + y^2 / b ^ 2 = 1
    // So if we are inside the ellipse, we would expect the left hand
    // side of this expression to be less than one
    boolean inside = xd * xd / (a * a) + yd * yd / (b * b) <= 1.0
    return inside
}
person user2662833    schedule 13.09.2017
comment
Я очень ценю ваш ответ, но я не знаю, как применить этот код к уже написанному мной коду. Я ошибаюсь в последних двух правилах. - person Thomas Beumer; 13.09.2017
comment
Последние две строки отсутствуют ; - person JeremyDouglass; 30.09.2017
comment
О, спасибо, в последних двух строках отсутствует точка с запятой. Извините за поздний ответ. Но этот код должен работать с эллипсами, которые не обязательно являются кругами :) Если вы объедините то, что я имею, с ответом Кевина Воркмана, вы сможете заставить это работать для не кругов - person user2662833; 01.10.2017