スムーズに複数画像をマウスで一緒に動かすには

解決


ゆたっぴー  2011-06-03 01:56:33  No: 40608

下記のプログラムは、複数の画像ファイルを動的なコンポーネントで作成し、少しづつ ずらしながら縦に重ねて並べておいて、マウスを左クリックした画像より上にある画像を一緒に動かすプログラムです
(プラグラムのパス\data\に 0.bmp〜9.bmpの画像ファイルが入ってます)

一応、目的の処理はできているようなのですが、どうしても動きが鈍く、動かす枚数が少ないうちはまだましなのですが、例えば、一番下から動かした場合、とてもカクカクしたした動きになってしまいます。もう少しスムーズに動かせないものでしょうか?

自作スパイダソリティタを作っておりまして、結構完成してきたのですが、この部分がうまくいかず困っております。どうぞよろしくお願い致します。
(前にも質問させていただきました。ありがとうございました。)
環境:WindowsXP SP3  Delphi7 professional

以下コードです。
  public
    { Public 宣言 }
   Orgpoint:Tpoint;
   Drawing: Boolean;
   IM:Array of TImage; //Imageの数
   procedure IMMouseDown(Sender:TObject; Button:TMouseButton; Shift:TShiftState; X,Y:Integer);
   procedure IMMouseMove(Sender:TObject; Shift:TShiftState; X,Y:Integer);
   procedure IMMouseUp(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 Form1.DoubleBuffered := True; //前にお教え頂きました!ちらつき防止
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 I:Integer;
 TPath:String;
begin
 TPath:=ExtractFilePath(Application.EXEName)+'data\'; //画像の入っているパス
 SetLength(IM,10); //動的イメージコンポーネント用配列作成

 For I:=0 to 9 do begin  //動的イメージを作成しながら並べていく
  IM[I]:=TImage.Create(Self); //Image作成
  IM[I].Parent:=Self; //Image作成
  IM[I].Picture.LoadFromFile(TPath+inttostr(I)+'.bmp');//画像読込

  IM[I].Visible:=True; //各種 設定
  IM[I].Width:=70;
  IM[I].Height:=100;
  IM[I].Left:=100;
  IM[I].Top:=I*20+10; //縦20づつ づらしながら画像を表示
  IM[I].Name:='I'+inttostr(I);

  IM[I].OnMouseDown:=IMMouseDown; //マウスを押した時の処理
  IM[I].OnMouseMove:=IMMouseMove;//マウスを動かした時の処理
  IM[I].OnMouseUp:=IMMouseUp;//マウスを離した時の処理
 end;
end;

//マウスを押した時の処理
procedure TForm1.IMMouseDown(Sender:TObject; Button:TMouseButton; Shift:TShiftState; X,Y:Integer);
var
 N,SX,SY:Integer;
 Han:Boolean;
begin
  Drawing:=True;
  OrgPoint:=Point(x,y);
end;

//マウスを動かした時の処理
procedure TForm1.IMMouseMove(Sender:TObject; Shift:TShiftState; X,Y:Integer);
var
 PN:Array of TPoint;
 S:String;
 I,J:Integer;
begin
 if Drawing=True then begin
  S:=TImage(Sender).Name; //押した画像の名前
  J:=StrToInt(Copy(S,2,1)); //押した画像の番号を取得

  SetLength(PN,10-J); //押した画像より上の画像を一緒に動かすための処理
  For I:=J to 9 do begin
   PN[I-J]:=TImage(IM[I]).Parent.ScreenToClient(TImage(IM[I]).ClientToScreen(Point(X, Y))) ;
   TImage(IM[I]).Left:=PN[I-J].X-Orgpoint.x;
   TImage(IM[I]).Top:=PN[I-J].Y-Orgpoint.y;
  end;

 end;
end;

//マウスを離した時の処理
procedure TForm1.IMMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 Drawing:=False;
end;


ささら  2011-06-04 17:59:05  No: 40609

SetLength(PN,10-J); //押した画像より上の画像を一緒に動かすための処理
  For I:=J to 9 do begin
   PN[I-J]:=TImage(IM[I]).Parent.ScreenToClient(TImage(IM[I]).ClientToScreen(Point(X, Y))) ;
   TImage(IM[I]).Left:=PN[I-J].X-Orgpoint.x;
   TImage(IM[I]).Top:=PN[I-J].Y-Orgpoint.y;
  end;

ここなんですが、1枚ごとに描画しているからでは?
一旦バックグラウンドに移動後の状態を描画して、
後で一気に表示すればマシになると思いますよ。


KHE00221  2011-06-05 01:07:50  No: 40610

>S:=TImage(Sender).Name; //押した画像の名前
>J:=StrToInt(Copy(S,2,1)); //押した画像の番号を取得

 押した画像  なので  Down で判断する
 Move で移動の度に  判断する必要なし

>SetLength(PN,10-J); //押した画像より上の画像を一緒に動かすための処理
>For I:=J to 9 do begin
>PN[I-J]:=TImage(IM[I]).Parent.ScreenToClient(TImage(IM[I]).ClientToScreen(Point(X, Y))) ;
>TImage(IM[I]).Left:=PN[I-J].X-Orgpoint.x;
>TImage(IM[I]).Top:=PN[I-J].Y-Orgpoint.y;

PN 配列にする必要ないだろ?

  For I:=J to 9 do 
  begin
   PN :=TImage(IM[I]).Parent.ScreenToClient(TImage(IM[I]).ClientToScreen(Point(X, Y))) ;
   TImage(IM[I]).Left := PN.X-Orgpoint.x;
   TImage(IM[I]).Top  := PN.Y-Orgpoint.y;

動的確保するなら Down で 

>マウスを左クリックした画像より上にある画像を一緒に動かすプログラムです

下の画像が一緒に動くのは内緒

そのまま動かしても  スムーズ  に動くけど・・・・・


KHE00221  2011-06-05 01:10:47  No: 40611

上って位置じゃなくて上に乗っているカードって事か・・・・


ゆたっぴー  2011-06-05 17:11:17  No: 40612

さらら様、KHE00221様  どうもありがとうございます

ご指摘を頂いた、IMMouseMoveのなかの処理を2回に一回処理をさせるようにした所、予想以上に効果がでて、かなり改善されました!

KHE00221さんのおっしゃる通り、PNは配列にする必要全くありませんでした・・・無駄な処理は省いた方がいいですね!

あきらめかけていましたが、うまく完成できそうです。心より御礼申し上げます。
PS.WindowsXP付属のスパイダソルティアはすごいですね。最初のカードを配る時点で処理のすスピード差を痛感してます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加