下記のプログラムは、複数の画像ファイルを動的なコンポーネントで作成し、少しづつ ずらしながら縦に重ねて並べておいて、マウスを左クリックした画像より上にある画像を一緒に動かすプログラムです
(プラグラムのパス\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;
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枚ごとに描画しているからでは?
一旦バックグラウンドに移動後の状態を描画して、
後で一気に表示すればマシになると思いますよ。
>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様 どうもありがとうございます
ご指摘を頂いた、IMMouseMoveのなかの処理を2回に一回処理をさせるようにした所、予想以上に効果がでて、かなり改善されました!
KHE00221さんのおっしゃる通り、PNは配列にする必要全くありませんでした・・・無駄な処理は省いた方がいいですね!
あきらめかけていましたが、うまく完成できそうです。心より御礼申し上げます。
PS.WindowsXP付属のスパイダソルティアはすごいですね。最初のカードを配る時点で処理のすスピード差を痛感してます。
ツイート | ![]() |