Зеленое счастье и никаких наркотиков!

воскресенье, ноября 21, 2010

Один урок в неделю: Эффектная арифметика

      Никогда не дружил с арифметикой, постоянно ошибался в школе с вычислениями, даже самыми простыми, такими как сложение и вычитание... наверно потому что не учил таблицу умножения.
      Вот и здесь, голые вычисления заняли у меня полторы недели... Когда еще только рисовал дизайн, подумал о том, как будут двигаться значки на панельке... я хотел скопировать эффект "пузыря" с rocketdock. Честно признаюсь что это уже третья попытка была :), первые две закончились неудачей, но в целом другими довольно красивыми эффектами. На этот раз я решил не отступать, и бился несколько дней над задачей, но окончилось все тем же... потом я впал в депрессию, из который меня вытащил товарищ Ang3l за что ему человеческое спасибо, и новая попытка увенчалась Успехом. Пусть мой Успех занимает приблизительно 70 строк, но он был достигнут кровью и потом. Далее я опишу, какие нужно внести изменения в проект, чтобы получить красивую панельку инструментов.
В событие objMain.Create добавляем такие строки:
panelWidth = ds_list_create();
var i;
for(i=0;i<ds_list_size(panel);i+=1)
{
   ds_list_add(panelWidth,1);
} 
room_speed = 60;
Мы создаем список ширины каждого значка на панели, затем наполняем его пустыми значениями с помощью цикла for. Последняя строка сделана для того, чтобы анимация стала плавной.
Заменяем событие objMain.Draw на это:
var i,size,scale,sprw,X,Y,width;
// Делаем некоторые оптимизационные вычисления 
size = ds_list_size(panel);
sprw = sprite_get_width(panelSprite);
 
scale = size*34/sprw;
// Вычисляем точку, где у нас находится панель в спокойном состоянии
X = room_width / 2 - size*17 - sprw*2; 
Y = 16;
 
var A,B,W,WW
// Собственно есть у меня дурная привычка, называть
// временные переменные большими буковками...
width = 0;
A = 0;
B = -1;
W = -17;
WW = 34*size;
select = -1;

// Если курсор в области взаимодействия с панелью
if (mouse_x>X-16 && mouse_y>Y && mouse_x<X+WW+32 && mouse_y < Y+72)
for(i=0;i<size;i+=1)
{
  A = 2-(min(abs(mouse_x-X-34*i-34),96) / 96); // Рассчитываем размер значка
  ds_list_replace(panelWidth,i,A);
  if (A > B) // Ищем самый близки к курсору значок
  {
     B = A;
     select = i; // По умолчанию выделяем его
  }
  width += A * 34; // Подсчитываем фактическую величину
}
else // Если курсор за пределами панели
for(i=0;i<size;i+=1)
{
  A = max(ds_list_find_value(panelWidth,i)-0.05,1); // Уменьшаем размер значков
  ds_list_replace(panelWidth,i,A);
  width += A * 34; // Опять же, просчитываем фактическую ширину панели
}
B = X+WW/2-width/2 -17; // Небольшая оптимизация вычислений
A = B+ds_list_find_value(panelWidth,0)*26;
// Рисуем подложку панели
draw_sprite(panelSprite,0,A,Y); draw_sprite_ext(panelSprite,1,A+sprw,Y,width/sprw,1,0,-1,1); draw_sprite(panelSprite,2,A+sprw+width,Y);  
// Сдвигаем точку рисования значков на ширину рамки панели
B += sprw + 8;
Y += sprw + 8;
W = 0;
for(i=0;i<size;i+=1)
{
  // Собственно рисуем иконку
  A = ds_list_find_value(panelWidth,i);
  W+= A*34;
  tmp = ds_list_find_value(panel,i);
  draw_sprite_ext(ds_list_find_value(tmp,1),0,B+W,Y+A*8,A*.25,A*.25,0,-1,1);
  if (i = select) // Отображаем подпись выделенного значка
    draw_text_ol(B+W-string_width(ds_list_find_value(tmp,0)) /2,
          Y+A*24,ds_list_find_value(tmp,0),c_white,c_black);
}
draw_text(10,10,TOOL); // Временное отображение выделенного инструмента
Теперь, у самых любопытных (ну или просто внимательных) компилятор будет ругаться на draw_text_ol, собственно эту функцию вы можете взять в интернете с помощью Google - первая же ссылка (привет DeatHSoul и Stasundr ;) ). А можете взять мой, слегка оптимизированный вариант:



argument0 = round(argument0);
argument1 = round(argument1); 
    draw_set_color(argument4) 
    draw_text(argument0-1,argument1,argument2)
    draw_text(argument0,argument1-1,argument2)
    draw_text(argument0+1,argument1,argument2)
    draw_text(argument0,argument1+1,argument2)
    //draw_set_blend_mode(bm_zero)
    //draw_text_transformed_color(argument0,argument1+string_height(argument2)*2,argument2,1,-1,0,c_white,c_white,c_black,c_black,1);
    //draw_set_blend_mode(bm_normal)
    draw_set_color(argument3)
    draw_text(argument0,argument1,argument2)
Специально оставил комментарии для любопытных :).
Ну что, теперь осталось научиться выделять иконки с помощью мышки, и панель готова! Но я, все таки вас огорчу, выделять инструменты нужно с умом... это тема для нашего следующего урока. (исходника пока не дам, ждем до следующего урока).

2 комментария: