Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Создание GUI


Автор: awilum 9.5.2009, 13:58
Пишу GUI к своему движку. Сделал класс кнопки. 

Код

type
  TButton = class
    constructor Create;
    destructor  Destroy;
  public
    procedure Draw(x,y,w,h: uint;texture: uint; aC: integer; r,g,b,a: Byte);
    procedure OnClick();
    procedure OnMouse();
  private
    ButtonX,
    ButtonY,
    ButtonWidth,
    ButtonHeight: uint;
    aCount,aFrame: integer;
  public
    onClickF:Boolean;
  end;

constructor TButton.Create;
begin
end;

destructor TButton.Destroy;
begin
end;

procedure TButton.Draw(x,y,w,h: uint;texture: uint; aC: integer; r,g,b,a: Byte);
begin
  ButtonX := x;
  ButtonY := y;
  ButtonWidth := w;
  ButtonHeight:= h;
  aCount := 2;
  ac:= aCount;
  age.sprite.DrawAnimStatic(x,y,w,h,aC,aFrame,texture,r,g,b,a);
end;

procedure TButton.OnClick();
begin
  OnClickF:= false;
  if age.input.But[0] then
  begin
    age.input.But[0] := false;
    if age.collision.PointCollision(ButtonX, ButtonY, ButtonWidth, ButtonHeight, age.input.X, age.input.Y, 1, 1 ) then
     OnClickF := true
  end;
end;

procedure TButton.OnMouse();
begin
 if age.collision.PointCollision(ButtonX, ButtonY, ButtonWidth, ButtonHeight, age.input.X, age.input.Y, 1, 1 ) then
    begin
    aFrame := 2;
    end
    else
    aFrame := 1; 
end;


в программе создаю несколько кнопочек при инициализации

Код

var
Btn1,Btn2,Btn3:TButton;



в таймере(он у меня на WINAPI) проверяются все обновления программы.
вот там я вызываю проверки для каждой кнопки


Код

 if BTN1.OnClickF then begin
  i:=random(600);
 end;

 if BTN2.OnClickF then begin
   age.Quit;
 end;

 if BTN3.OnClickF then begin
   age.Quit;
 end;

  BTN1.OnClick;
  BTN2.OnClick;
  BTN3.OnClick;

  BTN1.OnMouse;
  BTN2.OnMouse;
  BTN3.OnMouse;


рисую кнопки в отдельной процедуре Render

Код

  Btn1.Draw(10,300,200,50,butTex,3,255,255,255,255);
  Btn2.Draw(10,249,200,50,butTex,3,255,255,255,255);
  Btn3.Draw(10,198,200,50,butTex,3,255,255,255,255);


Значит при наведении курсора на кнопки срабатывает OnMouse; для каждой кнопки и кнопка меняет вид, как и должно быть.
А вот почему то OnClick; срабатывает только для первой кнопки, для остальных ноль реакции. В чем может быть проблема ?





Автор: Louken 10.5.2009, 23:49
awilum
Потому что:
Код

procedure TButton.OnClick();
begin
  OnClickF:= false;
  if age.input.But[0] then
  begin
    age.input.But[0] := false;
    if age.collision.PointCollision(ButtonX, ButtonY, ButtonWidth, ButtonHeight, age.input.X, age.input.Y, 1, 1 ) then
     OnClickF := true
  end;
end;

В момент проверки для других кнопок, 0-ая кнопка мышки перестает быть нажатой.

Будь внимателен.

Автор: pseud 11.5.2009, 10:06
код нечитабелен:
Код

  private
    ButtonX,
    ButtonY,
    ButtonWidth,
    ButtonHeight: uint;
    aCount,aFrame: integer;

пиши так:
Код

  private
    ButtonX: UINT;
    ButtonY: UINT;
    ButtonWidth: UINT;
    ButtonHeight: UINT;
    Count: Integer;
    Frame: integer;

Автор: awilum 11.5.2009, 12:38
ChekBox не работает. Работает только то то что картинка только меняется. Нажал картинка поменялась на зачеркнутый квадратик еще раз нажал картинка без крестика, как и должно быть в CheckBox
Но реакции на включен CheckBox или не включен нет.

Код

procedure TCheckBox.OnCheck();
begin
  OnCheckF := false;
  if age.collision.PointCollision(ButtonX, ButtonY, ButtonWidth, ButtonHeight, age.input.X, age.input.Y, 1, 1 ) then
  begin
  OnCheckF := true;
  aFrame := aFrame + 1;
  if aFrame = 1 then begin   aFrame := 1;  OnCheckF := false; end;
  if aFrame = 2 then begin   aFrame := 2;  OnCheckF := true; end;
  if aFrame > 2  then
  begin
  aFrame := 1;
  OnCheckF := false;
  end;
  end;
end;


.....
Код


var
 Chk1: TCheckBox;



таймер

Код

 if BTN1.OnClickF then
   i:=random(600)
   else
 if BTN2.OnClickF then
   age.Quit
   else
 if BTN3.OnClickF then
   age.Quit;

 if chk1.onCheckF then
   i:=600
   else
   i:=0;


 BTN1.OnClickF:= false;
 BTN2.OnClickF:= false;
 BTN3.OnClickF:= false;
 chk1.onCheckF := false;

 if age.input.But[0] then
 begin
   age.input.But[0] := false;
   BTN1.OnClick;
   BTN2.OnClick;
   BTN3.OnClick;
   chk1.OnCheck;
 end;

 BTN1.OnMouse;
 BTN2.OnMouse;
 BTN3.OnMouse;







Автор: Louken 11.5.2009, 17:05
awilum
Какой ужас
Код

procedure TCheckBox.OnCheck();
begin
  OnCheckF := false;
  if age.collision.PointCollision(ButtonX, ButtonY, ButtonWidth, ButtonHeight, age.input.X, age.input.Y, 1, 1 ) then
  begin
  OnCheckF := true;
  aFrame := aFrame + 1;
  if aFrame = 1 then begin   aFrame := 1;  OnCheckF := false; end;
  if aFrame = 2 then begin   aFrame := 2;  OnCheckF := true; end;
  if aFrame > 2  then
  begin
  aFrame := 1;
  OnCheckF := false;
  end;
  end;
end;

Не проще ли
Код

procedure TCheckBox.OnCheck();
begin  
  if age.collision.PointCollision(ButtonX, ButtonY, ButtonWidth, ButtonHeight, age.input.X, age.input.Y, 1, 1 ) then
    OnCheckF := not OnCheckF;
end;

А рисовать
Код

procedure TCheckBox.Paint();
begin
  if OnCheckF then {Рисуем крестик}
  else {Не рисуем крестик}
end;

И тут что за бред
Код

if age.input.But[0] then
 begin
   age.input.But[0] := false;
   BTN1.OnClick;
   BTN2.OnClick;
   BTN3.OnClick;
   chk1.OnCheck;
 end;

Снова наступаешь на теже грабли, что и в нулевом посте
Научись уже наконец сам проверять свой код, банально можно пробежаться и в уме прикинуть, что должно происходить, после исполнения каждой строчки, тогда и не будешь допускать таких нелепостей.
Или ты думаешь, что тебе весь твой "движок" будут так исправлять.

Автор: awilum 11.5.2009, 18:22
Я всегда раньше писал и кнопки и чекбоксы прям в самой игре. Но вот сейчас переписываю движок на котором делал свои игры и решил, что лучше будет все эти кнопки, чекбоксы и тд.. разместить в отдельном модуле GUI engine. что бы игру не засорять  повторяющемся кодом тем самым повысить удобство в использовании и читабильность кода.
Всегда писал в играх вот так

if age.input.But[0] then
  begin
    age.input.But[0] := false;

  ///----- обработка ----------------////

end;

Код

if age.input.But[0] then
  begin
    age.input.But[0] := false;

  //////////////////////////////////////////////////////  кнопки

  if PointCollision( 296, 289, 25, 25, fge.inp.X, fge.inp.Y, 1, 1 ) then
  begin
     // любой код
   end;

   if PointCollision( 475, 289, 25, 25, fge.inp.X, fge.inp.Y, 1, 1 ) then
   begin
      // любой код
   end;

  //////////////////////////////////////////////////////  Чекбоксы

  // Переход в полноекраный режим с помощью чекбокса
  if PointCollision(  475,414,25,25, fge.inp.X, fge.inp.Y, 1, 1 ) then
    begin
             click := click + 1;
             if click = 0 then optFullScreen := 0;
             if click = 1 then optFullScreen := 1;
             if click > 1  then
             begin
               optFullScreen := 0;
               click := 0;
             end;
     if optFullScreen = 1 then click := 1
       else
       click := 0;
  end;


end;



И это нормально работает

А в модуле GUI который сейчас пишу , почему то это все не работает 

Автор: Qu1nt 11.5.2009, 19:10
Сам подход неверен.
Правильней - запрограммировать коллекцию, которая будет обрабатывать всякие разные графические компоненты. Кликательные и нажимательные эвенты реализовать через события. 

Автор: Louken 11.5.2009, 21:38
awilum
Сам посуди, нестыковочка какая то
Код

procedure TButton.OnClick();
begin
  OnClickF:= false;
  if age.input.But[0] then
  begin
    age.input.But[0] := false;
    if age.collision.PointCollision(ButtonX, ButtonY, ButtonWidth, ButtonHeight, age.input.X, age.input.Y, 1, 1 ) then
     OnClickF := true
  end;
end;

if age.input.But[0] then
 begin
   age.input.But[0] := false;
   BTN1.OnClick;

   BTN2.OnClick;
   BTN3.OnClick;
   chk1.OnCheck;
 end;

Соотнеси те строчки кода, которые я выделил, так у тебя ни для кнопок ни для чекбоксов клики мышки обрабатываться не должны вообще.

Цитата

И это нормально работает
А в модуле GUI который сейчас пишу , почему то это все не работает 

Почему не работает смотри чуть выше

Qu1nt
Цитата

Сам подход неверен.

+1

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)