Компьютерная графика
Взаимодействие
Jordi Linares i Pellicer
Escola Politècnica Superior d’Alcoi
Dep. de Sistemes Informàtics i Computació
jlinares@dsic.upv.es
http://www.dsic.upv.es/~jlinares
Взаимодействие
•

В processing есть два способа реализации взаимодействия
с пользователем:
Использовать набор системных переменных
Определить набор функций-обработчиков, которые
вызываются как ответ на определённое событие.
Какой метод лучше использовать — зависит от конкретной
задачи; их можно даже комбинировать.
Обычно смотрим системные переменные внутри
функции draw(). Хотя она постоянно запускается,
обнаружение всех событий через этот механизм
не гарантировано.
Использование функций-обработчиков гарантирует
обнаружение всех событий благодаря тому, что они
обрабатываются как очередь.

•
•

•

•
•
Взаимодействие
mouseX, mouseY

•

В них всегда хранится текущее местоположение курсора:
mouseX => координата по x
mouseY => координата по y

•
•
Взаимодействие
// Мячик, который следует за мышью
void setup()
{
size(500, 500);
noStroke();
// Фон
background(0);
}
void draw()
{
// След
fill(0, 1);
rect(0, 0, width, height);
// Рисуем мячик, следующий
// за местоположением мыши
fill(255);
ellipse(mouseX, mouseY, 50, 50);
}
Взаимодействие
pmouseX, pmouseY

•

В них хранятся координаты мыши в предыдущем кадре:
pmouseX => координата по x
pmouseY => координата по y

•
•
Взаимодействие
// Свободное рисование
void setup()
{
size(500, 500);
background(0);
stroke(255);
strokeWeight(2);
smooth(); // Использовать технологию antialiasing
}
void draw()
{
line(pmouseX, pmouseY, mouseX, mouseY);
}
Взаимодействие
mousePressed

•

Будет TRUE, если любая кнопка мыши нажата, и
FALSE иначе
Взаимодействие
// Свободное рисование
void setup()
{
size(500, 500);
background(0);
stroke(255);
strokeWeight(2);
smooth(); // Использовать технологию antialiasing
}
void draw()
{
if (mousePressed)
line(pmouseX, pmouseY, mouseX, mouseY);
}
Взаимодействие
mouseButton

•
•

Принимает значения LEFT, RIGHT или CENTER в
зависимости от того, какая клавиша мыши нажата
Должна использоваться вместе с mousePressed
Взаимодействие
// Свободное рисование
void setup()
{
size(500, 500);
background(0);
strokeWeight(2);
smooth(); // Использовать технологию antialiasing
}
void draw()
{
if (mousePressed) {
if (mouseButton == LEFT) { // Рисовать
stroke(255);
strokeWeight(2);
}
else {
// Стирать
stroke(0);
strokeWeight(4);
}
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
Взаимодействие
keyPressed

•

Будет TRUE, если нажата клавиша
key

•
•
•
•

В ней хранится символ нажатой клавиши
Может также иметь значения: BACKSPACE,
TAB, ENTER, RETURN, ESC и DELETE.
Если значение равно константе CODED, то из системной
переменной keyCode ясно, какая специальная клавиша
нажата: UP,DOWN,LEFT,RIGHT,ALT,CONTROL,SHIFT
Использоваться эта переменная должна совместно с
KeyPressed.
Взаимодействие
Определение функций-обработчиков как
ответов на событие

•
•
•

Добавляются новые функции (callback functions),
которые вызываются, когда возникает ассоциированное
с ними событие.
У этих функций специальные имена, они не имеют
параметров и возвращают void
В их теле может быть полезным обратиться к
вышеописанным системные переменные.
Взаимодействие
void mousePressed()

•
•
•

Всегда вызывается, когда нажата кнопка мыши
Через mouseButton можно узнать, какая именно кнопка
нажата.
Определяет именно нажатие (первый клик, перед
тем, как отпустить)
void mouseReleased()

•
•

Всегда вызывается после того, как клавиша мыши
отпущена - второй клик, после нажатия.
Через mouseButton можно узнать, какая именно кнопка
отпущена
Взаимодействие
void mouseClicked()

•
•
•

Всегда вызывается после полного клика, когда
кнопка нажата и затем отпущена.
Через mouseButton можно узнать соответствующую
кнопку
До этого события произойдут mousePressed() и
mouseReleased()
Взаимодействие
void mouseMoved()

•
•

Всегда вызывается после перемещения мыши, когда
клавиши не нажаты.
Обычно внутри обращаются к mouseX и mouseY , чтобы
узнать координаты курсора
void mouseDragged()

•
•

Вызывается после перемещения мыши, когда нажата хоть
одна клавиша (из mouseButton можно узнать, какая)
Обычно внутри обращаются к mouseX и mouseY , чтобы
узнать координаты курсора
Взаимодействие
void keyPressed()

•
•

Всегда вызывается, когда нажата клавиша на клавиатуре
Обычно используют key, чтобы узнать, какая клавиша
нажата (keyCode тоже можно использовать)
void keyReleased()

•
•

Всегда вызывается, когда отпущена клавиша на клавиатуре
Обычно используют key, чтобы узнать, какая клавиша
нажата (keyCode тоже можно использовать)
Взаимодействие
void keyTyped()

•
•
•
•

Всегда вызывается после того, как символ напечатан
(после того, как клавиша нажата и отпущена)
До этого события произойдут keyPressed()и
keyReleased()
Долгое удерживание кнопки будет создавать
повторяющиеся события keyTyped(), что будет дальше
— зависит от настроек операционной системы
Клавиши Control, Alt и Shift игнорируются этим событием
Взаимодействие
// Свободное рисование
color colorStroke = color(255, 0, 0);
void setup()
{
size(500, 500);
background(0);
strokeWeight(2);
smooth(); // Использовать технологию antialiasing
}
void draw()
{
if (mousePressed) {
if (mouseButton == LEFT) { // Рисовать
stroke(colorStroke);
strokeWeight(2);
}
else {
stroke(0);
// Стереть
strokeWeight(4);
}
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
void keyPressed()
{
switch (key) {
case 'r':
case 'R':
colorStroke = color(255,0,0);
break;
case 'g':
case 'G':
colorStroke = color(0,255,0);
break;
case 'b':
case 'B':
colorStroke = color(0,0,255);
break;
}
}
Практика 6-1
•

Запрограммируйте игру ‘Посадка на Луну’

Двигатель (r)
F = m· (g + r)

a=r+g
v(t+1) = v(t) + a
e(t+1) = e(t) + v(t+1)

Сила притяжения (g)
Практика 6-1
•
•
•
•
•

Корабль изначально должен находиться вверху окна
в случайной по горизонтали точке
Внизу нарисуйте лунную поверхность просто как
прямоугольник, а посередине — посадочную площадку.
На корабль влияет сила притяжения (как это было в
прошлых примерах на прошлом занятии)
Когда игрок нажимает UP, и только в этом случае,
результирующая сила будет: сила притяжения и
противоположная ей сила двигателя (только вкл/выкл
двигателя, без промежуточных уровней)
По нажатию LEFT и RIGHT корабль будет перемещаться
влево или вправо (простой перенос, ничего больше не
нужно)
Практика 6-1
•
•
•
•
•
•
•

Посадка считается удачной, если:
Корабль приземлился на посадочную полосу
Его скорость в этот момент ниже некоторого порога.
Если этот порог превышен, то считается, что корабль
Разбился.
После удачной или неудачной посадки игра будет
запущена заново, а корабль помещён в стартовую точку
Нарисуйте корабль, как хотите (совет: используйте
операцию переноса, чтобы поместить его на экран)
Если двигатель включён, можно нарисовать огонь
Эффект катастрофы тоже можно нарисовать
Настройте значения силы притяжения, мощности двигателя,
и движений по горизонтали, чтобы добавить играбельности
Всё взаимодействие с игроком может быть сделано внутри
функции draw() через проверку подходящих системных
переменных

•
•
Практика 6-1

Компьютерная графика в Processing, часть 6. Взаимодействие.

  • 1.
    Компьютерная графика Взаимодействие Jordi Linaresi Pellicer Escola Politècnica Superior d’Alcoi Dep. de Sistemes Informàtics i Computació jlinares@dsic.upv.es http://www.dsic.upv.es/~jlinares
  • 2.
    Взаимодействие • В processing естьдва способа реализации взаимодействия с пользователем: Использовать набор системных переменных Определить набор функций-обработчиков, которые вызываются как ответ на определённое событие. Какой метод лучше использовать — зависит от конкретной задачи; их можно даже комбинировать. Обычно смотрим системные переменные внутри функции draw(). Хотя она постоянно запускается, обнаружение всех событий через этот механизм не гарантировано. Использование функций-обработчиков гарантирует обнаружение всех событий благодаря тому, что они обрабатываются как очередь. • • • • •
  • 3.
    Взаимодействие mouseX, mouseY • В нихвсегда хранится текущее местоположение курсора: mouseX => координата по x mouseY => координата по y • •
  • 4.
    Взаимодействие // Мячик, которыйследует за мышью void setup() { size(500, 500); noStroke(); // Фон background(0); } void draw() { // След fill(0, 1); rect(0, 0, width, height); // Рисуем мячик, следующий // за местоположением мыши fill(255); ellipse(mouseX, mouseY, 50, 50); }
  • 5.
    Взаимодействие pmouseX, pmouseY • В ниххранятся координаты мыши в предыдущем кадре: pmouseX => координата по x pmouseY => координата по y • •
  • 6.
    Взаимодействие // Свободное рисование voidsetup() { size(500, 500); background(0); stroke(255); strokeWeight(2); smooth(); // Использовать технологию antialiasing } void draw() { line(pmouseX, pmouseY, mouseX, mouseY); }
  • 7.
    Взаимодействие mousePressed • Будет TRUE, еслилюбая кнопка мыши нажата, и FALSE иначе
  • 8.
    Взаимодействие // Свободное рисование voidsetup() { size(500, 500); background(0); stroke(255); strokeWeight(2); smooth(); // Использовать технологию antialiasing } void draw() { if (mousePressed) line(pmouseX, pmouseY, mouseX, mouseY); }
  • 9.
    Взаимодействие mouseButton • • Принимает значения LEFT,RIGHT или CENTER в зависимости от того, какая клавиша мыши нажата Должна использоваться вместе с mousePressed
  • 10.
    Взаимодействие // Свободное рисование voidsetup() { size(500, 500); background(0); strokeWeight(2); smooth(); // Использовать технологию antialiasing } void draw() { if (mousePressed) { if (mouseButton == LEFT) { // Рисовать stroke(255); strokeWeight(2); } else { // Стирать stroke(0); strokeWeight(4); } line(mouseX, mouseY, pmouseX, pmouseY); } }
  • 11.
    Взаимодействие keyPressed • Будет TRUE, еслинажата клавиша key • • • • В ней хранится символ нажатой клавиши Может также иметь значения: BACKSPACE, TAB, ENTER, RETURN, ESC и DELETE. Если значение равно константе CODED, то из системной переменной keyCode ясно, какая специальная клавиша нажата: UP,DOWN,LEFT,RIGHT,ALT,CONTROL,SHIFT Использоваться эта переменная должна совместно с KeyPressed.
  • 12.
    Взаимодействие Определение функций-обработчиков как ответовна событие • • • Добавляются новые функции (callback functions), которые вызываются, когда возникает ассоциированное с ними событие. У этих функций специальные имена, они не имеют параметров и возвращают void В их теле может быть полезным обратиться к вышеописанным системные переменные.
  • 13.
    Взаимодействие void mousePressed() • • • Всегда вызывается,когда нажата кнопка мыши Через mouseButton можно узнать, какая именно кнопка нажата. Определяет именно нажатие (первый клик, перед тем, как отпустить) void mouseReleased() • • Всегда вызывается после того, как клавиша мыши отпущена - второй клик, после нажатия. Через mouseButton можно узнать, какая именно кнопка отпущена
  • 14.
    Взаимодействие void mouseClicked() • • • Всегда вызываетсяпосле полного клика, когда кнопка нажата и затем отпущена. Через mouseButton можно узнать соответствующую кнопку До этого события произойдут mousePressed() и mouseReleased()
  • 15.
    Взаимодействие void mouseMoved() • • Всегда вызываетсяпосле перемещения мыши, когда клавиши не нажаты. Обычно внутри обращаются к mouseX и mouseY , чтобы узнать координаты курсора void mouseDragged() • • Вызывается после перемещения мыши, когда нажата хоть одна клавиша (из mouseButton можно узнать, какая) Обычно внутри обращаются к mouseX и mouseY , чтобы узнать координаты курсора
  • 16.
    Взаимодействие void keyPressed() • • Всегда вызывается,когда нажата клавиша на клавиатуре Обычно используют key, чтобы узнать, какая клавиша нажата (keyCode тоже можно использовать) void keyReleased() • • Всегда вызывается, когда отпущена клавиша на клавиатуре Обычно используют key, чтобы узнать, какая клавиша нажата (keyCode тоже можно использовать)
  • 17.
    Взаимодействие void keyTyped() • • • • Всегда вызываетсяпосле того, как символ напечатан (после того, как клавиша нажата и отпущена) До этого события произойдут keyPressed()и keyReleased() Долгое удерживание кнопки будет создавать повторяющиеся события keyTyped(), что будет дальше — зависит от настроек операционной системы Клавиши Control, Alt и Shift игнорируются этим событием
  • 18.
    Взаимодействие // Свободное рисование colorcolorStroke = color(255, 0, 0); void setup() { size(500, 500); background(0); strokeWeight(2); smooth(); // Использовать технологию antialiasing } void draw() { if (mousePressed) { if (mouseButton == LEFT) { // Рисовать stroke(colorStroke); strokeWeight(2); } else { stroke(0); // Стереть strokeWeight(4); } line(mouseX, mouseY, pmouseX, pmouseY); } } void keyPressed() { switch (key) { case 'r': case 'R': colorStroke = color(255,0,0); break; case 'g': case 'G': colorStroke = color(0,255,0); break; case 'b': case 'B': colorStroke = color(0,0,255); break; } }
  • 19.
    Практика 6-1 • Запрограммируйте игру‘Посадка на Луну’ Двигатель (r) F = m· (g + r) a=r+g v(t+1) = v(t) + a e(t+1) = e(t) + v(t+1) Сила притяжения (g)
  • 20.
    Практика 6-1 • • • • • Корабль изначальнодолжен находиться вверху окна в случайной по горизонтали точке Внизу нарисуйте лунную поверхность просто как прямоугольник, а посередине — посадочную площадку. На корабль влияет сила притяжения (как это было в прошлых примерах на прошлом занятии) Когда игрок нажимает UP, и только в этом случае, результирующая сила будет: сила притяжения и противоположная ей сила двигателя (только вкл/выкл двигателя, без промежуточных уровней) По нажатию LEFT и RIGHT корабль будет перемещаться влево или вправо (простой перенос, ничего больше не нужно)
  • 21.
    Практика 6-1 • • • • • • • Посадка считаетсяудачной, если: Корабль приземлился на посадочную полосу Его скорость в этот момент ниже некоторого порога. Если этот порог превышен, то считается, что корабль Разбился. После удачной или неудачной посадки игра будет запущена заново, а корабль помещён в стартовую точку Нарисуйте корабль, как хотите (совет: используйте операцию переноса, чтобы поместить его на экран) Если двигатель включён, можно нарисовать огонь Эффект катастрофы тоже можно нарисовать Настройте значения силы притяжения, мощности двигателя, и движений по горизонтали, чтобы добавить играбельности Всё взаимодействие с игроком может быть сделано внутри функции draw() через проверку подходящих системных переменных • •
  • 22.