TImage&TImageListの使い方


プレアデスⅢ世  2013-07-26 22:49:18  No: 44932

www.geocities.jp/my_ultraseven/mozart/image/reidesu.gif
  ゴチャゴチャ説明するより画像を見てもらえばわかると思うのですが、クリックしないでマウスを動かすとき、現在位置を強調するために以下のようなコーディングをしました。現在位置には透過画像を重ね、現在位置に隣接するマスは元の画像のままという方針でコーディングしています。マウスをゆっくり動かすと期待通りの動作になるものの、素早く動かすと画像の通り現在位置以外のマスも強調されてしまいます(笑)。
  PutKabeEmpha が見るからに初心者レベルの遅いコードになっているのが原因だと思います。何かいい方法はないでしょうか?
const
  X_CNT  = 19; //ボードの縦の数 0〜19 でアクセスするので20個
  Y_CNT  = 14; //ボードの横の数 0〜14 でアクセスするので15個
  DOT = 32;    //1マスのドット数
  PNL_X = 640; // パネル横 32*20 = 640
  PNL_Y = 480; // パネル縦 32*16 = 480
  KABE = 0; //壁
  YUKA = 1; //床
  TOKA = 10;//透過

    BlockList: TImageList;
    omoteImage: TImage;
    FBord: array[0..X_CNT, 0..Y_CNT] of Integer; //メインの盤面
    FuraBmp: TBitmap;

procedure TForm1.BordPaint;
var
 i,j :Integer;
begin  //床タイル背景に敷き詰め
  for j := 0 to Y_CNT do
    for i := 0 to X_CNT do
      BlockList.Draw(FuraBmp.Canvas,i*DOT,j*DOT,FBord[i,j]);
  omoteGa.Canvas.Draw(0,0,FuraBmp);
end;

//クリックしないでムーブするとき、現在位置を強調する
procedure TForm1.PutKabeEmpha(mx,my:Integer);
var
  i,j:Integer;
begin
  i := mx div DOT;
  j := my div DOT;
  FBord[i,j] := TOKA;

  if j = 0 then //ボード最上段
  begin
    if i = 0 then //ボード左端
    begin
      FBord[i+1,j]   := YUKA;      FBord[i,j+1]   := YUKA;      FBord[i+1,j+1] := YUKA;
    end else
    if i =X_CNT then //ボード右端
    begin
      FBord[i-1,j]   := YUKA;      FBord[i-1,j+1] := YUKA;      FBord[i,j+1]   := YUKA;
    end else
    begin
      FBord[i-1,j]   := YUKA;      FBord[i+1,j]   := YUKA;      FBord[i-1,j+1] := YUKA;
      FBord[i,j+1]   := YUKA;      FBord[i+1,j+1] := YUKA;
    end
  end else if j = Y_CNT then //ボード最下段
  begin
    if i = 0 then //ボード左端
    begin
      FBord[i,j-1]   := YUKA;      FBord[i+1,j-1] := YUKA;      FBord[i+1,j]   := YUKA;
    end else
    if i =X_CNT then //ボード右端
    begin
      FBord[i-1,j-1] := YUKA;      FBord[i-1,j]   := YUKA;      FBord[i,j-1]   := YUKA;
    end else
    begin
      FBord[i-1,j-1] := YUKA;      FBord[i-1,j]   := YUKA;      FBord[i,j-1]   := YUKA;
      FBord[i+1,j-1] := YUKA;      FBord[i+1,j]   := YUKA;
    end
  end else //ボード中央
  begin
    if i = 0 then //ボード左端
    begin
      FBord[i,j-1]   := YUKA;      FBord[i+1,j-1] := YUKA;      FBord[i+1,j]   := YUKA;
      FBord[i,j+1]   := YUKA;      FBord[i+1,j+1] := YUKA;
    end else
    if i =X_CNT then //ボード右端
    begin
      FBord[i-1,j-1] := YUKA;      FBord[i,j-1]   := YUKA;      FBord[i-1,j]   := YUKA;
      FBord[i-1,j+1] := YUKA;      FBord[i,j+1]   := YUKA;
    end else
    begin
      FBord[i-1,j-1] := YUKA;      FBord[i,j-1]   := YUKA;      FBord[i+1,j-1] := YUKA;
      FBord[i-1,j]   := YUKA;      FBord[i+1,j]   := YUKA;      FBord[i-1,j+1] := YUKA;
      FBord[i,j+1]   := YUKA;      FBord[i+1,j+1] := YUKA;
    end
  end;
  BordPaint;
end;

procedure TForm1.omoteImageMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if ssLeft in Shift then PutKabe(X,Y)
  else                    PutKabeEmpha(X,Y);
end;


take  2013-07-26 23:23:48  No: 44933

FBordの二次元配列に
マウス位置を示す中心を透過の「10」
その周りは床を示す「1」にしたいけど
ソースがグチャグチャになるので簡単な方法はありませんか?
(※ややこしいから透過を「2」で示すと2を中心とした)

0000000
0000000
0011100
0012100
0011100
0000000
0000000

というように「1」の床を代入したいけど
FBord配列の端っこでエラーが出るから
それを避けるif文を書くと複雑になるなら
最初からエラーにならない範囲

[0..X_CNT, 0..Y_CNT] →[-1..X_CNT+1, -1..Y_CNT+1] 

にするというのはダメですか?

それと上記内容と
「素早く動かすと現在位置以外のマスも強調されてしまいます」
は別問題です。

そのソースだとXやYが2マス以上動くと床「1」で
消えないです。
遅いのも関係ありません。
(この処理遅くないけど)

前に「2」にしていたところを次の移動のタイミングで「1」にする
という処理にすれば解決するでしょう


プレアデスⅢ世  2013-07-27 03:36:42  No: 44934

> そのソースだとXやYが2マス以上動くと床「1」で
> 消えないです。
  ああ! なるほど。
  助言いただいた方法でもう一度じゃレンジしてみます。ありがとうございました。


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

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






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