ゲームでキャラクターの周りを透明化するには?

解決


MASH  2004-05-12 07:31:22  No: 8891

背景の上に画像を重ね合わせてコピーしたいのですが、
画像の周りに黒い部分があって見栄えが良くありません。
そこを透明化して背景が見えるようにしたいのですがどうすれば良いですか?
まだ初心者なのでよろしくお願いします。


jok  2004-05-12 07:51:40  No: 8892

質問がよく分かりません。

> 背景の上に画像を重ね合わせてコピーしたいのですが、

コピーしたいって、どういうことですか?

> 画像の周りに黒い部分があって見栄えが良くありません。

どのようなコードで重ね合わせていますか?


shaki  2004-05-12 08:17:22  No: 8893

やりたいことはスプライトのことだと思います。
表示したい画像の透過したい部分を書いたマスク画像を用意します。

背景 and マスク
背景 or スプライト
と論理演算すると透過して描写できます。

マスク画像用意するのが面倒ならTImageを使うと楽です。
ビットマップの左下が透過色になりますのでそのまま背景上の表示すれば透過します。


MASH  2004-05-13 04:14:07  No: 8894

>マスク画像用意するのが面倒ならTImageを使うと楽です。
>ビットマップの左下が透過色になりますので
>そのまま背景上の表示すれば透過します。

レスありがとうございます。
背景上に表示するにはどうすればいいのですか?
CopyRectを使ってみましたがうまく行きませんでした。
よろしくお願いします。


jok  2004-05-13 04:42:55  No: 8895

> 背景上に表示するにはどうすればいいのですか?

背景を表示しているコンポーネントの上に目的の TImage を置くだけです。


MASH  2004-05-13 05:02:46  No: 8896

>背景を表示しているコンポーネントの上に目的の TImage を置くだけです。

ゲームを作るときには画像ファイル数を減らすために
一つの画像にいくつものキャラクターが描いてあったりしますよね?
その場合はどうすればいいのでしょうか?
何度もすみません。


jok  2004-05-13 05:09:45  No: 8897

特定のキャラクターが描かれている部分をTImage.Picture.Bitmap.Canvas.CopyRect() でコピーします。


MASH  2004-05-13 07:14:13  No: 8898

>特定のキャラクターが描かれている部分を>TImage.Picture.Bitmap.Canvas.CopyRect() でコピーします。

それだとやはりキャラの周りが黒く残ってしまいます。

>背景 and マスク
>背景 or スプライト
>と論理演算すると透過して描写できます。

非常にあつかましいと思うのですが、
このやり方を詳しく教えていただけませんか?
よろしくお願いいたします。


jok  2004-05-13 07:26:37  No: 8899

> それだとやはりキャラの周りが黒く残ってしまいます。

コードを示してくださいね。いつまでも堂々巡りです。


MASH  2004-05-13 07:42:45  No: 8900

>コードを示してくださいね。

すみませんでした。これです。
Image1には背景が、Image2には、キャラクター画像があります。
procedure TForm1.Button1Click(Sender: TObject);
begin
        Image1.Width:=Form1.Width;
        Image1.Height:=Form1.Height;
        Image1.Picture.Bitmap.Canvas.CopyRect(
        rect(100,100,164,132),Image2.Canvas,rect(0,0,64,32)
        );
end;

Delphi6 Personal


jok  2004-05-13 08:29:21  No: 8901

そのコードだと、背景の Image1 の中に描き込んでいるんですね。
そうではなく、Image1 の上に Image2 を <置く> のです。
そして、Image2 の中のビットマップにキャラクタのビットマップの特定の
矩形部分を CopyRect() するのです。

背景透過は、TImage ではなく TBitmap の機能です。もっとも簡単なコードを
示しますので新規で試してみてください。Form1 の右端のほうに Button1 と
Button2 を置きます。そして以下のようにします。ボタンを押すたびに二つの
図形の周りが透過されて表示されることが分かると思います。

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    CharaBmp,TargetBmp:TBitmap;// これらを手動で追加すること
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  CharaBmp := TBitmap.Create;
  CharaBmp.Width := 200;
  CharaBmp.Height := 100;

  with CharaBmp.Canvas do begin
    Brush.Color := clYellow;
    FillRect(Rect(0,0,100,100));
    Brush.Color := clLime;
    Pen.Width := 3;
    Pen.Color := clBlue;
    Rectangle(20,20,80,80);

    Brush.Color := clAqua;
    FillRect(Rect(100,0,200,100));
    Brush.Color := clYellow;
    Pen.Color := clRed;
    Ellipse(110,10,190,90);
  end;

  TargetBmp:= TBitmap.Create;
  TargetBmp.Width := 100;
  TargetBmp.Height := 100;
  TargetBmp.Transparent := true;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CharaBmp.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TargetBmp.Canvas.CopyRect(Rect(0,0,100,100),CharaBmp.Canvas,Rect(0,0,100,100));
  Refresh;
  Canvas.Draw(10,10,TargetBmp);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  TargetBmp.Canvas.CopyRect(Rect(0,0,100,100),CharaBmp.Canvas,Rect(100,0,200,100));
  Refresh;
  Canvas.Draw(10,10,TargetBmp);
end;

end.


jok  2004-05-13 08:32:39  No: 8902

Button3 を追加して以下のようにすると、CharaBmp の内容が見られます。

procedure TForm1.Button3Click(Sender: TObject);
begin
  Refresh;
  Canvas.Draw(10,10,CharaBmp);
end;


jok  2004-05-13 08:35:01  No: 8903

訂正です。すみません。

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CharaBmp.Free;
  TargetBmp.free; // これを追加する(汗
end;


MASH  2004-05-14 05:33:20  No: 8904

上のやり方でやってボタンを押すと
「ソースファイルが見つかりません。:Graphics.pas」
とエラーになります。
>CharaBmp,TargetBmp:TBitmap;// これらを手動で追加すること
というのは、
CharaBmp := TBitmap.Create;  の下に
CharaBmp.LoadFromFile('pic.bmp');
を追加するということで良いのですか?
TBitmapの使い方も良く分かりません。度々ですがよろしくお願いします。


jok  2004-05-14 07:13:34  No: 8905

> エラーになります。

そうですか? なんだか本題と違うかんじですね。

> 追加するということで良いのですか?

ちがいます。あの一行を手作業で書く、ということです。

ソースが完全に提示したものと一致してますか。これ以上説明できませんが。


jok  2004-05-14 07:21:51  No: 8906

念のため全ユニットのソースを示します。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    CharaBmp,TargetBmp:TBitmap;// これらを手動で追加すること
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  CharaBmp := TBitmap.Create;
  CharaBmp.Width := 200;
  CharaBmp.Height := 100;

  with CharaBmp.Canvas do begin
    Brush.Color := clYellow;
    FillRect(Rect(0,0,100,100));
    Brush.Color := clLime;
    Pen.Width := 3;
    Pen.Color := clBlue;
    Rectangle(20,20,80,80);

    Brush.Color := clAqua;
    FillRect(Rect(100,0,200,100));
    Brush.Color := clYellow;
    Pen.Color := clRed;
    Ellipse(110,10,190,90);
  end;

  TargetBmp:= TBitmap.Create;
  TargetBmp.Width := 100;
  TargetBmp.Height := 100;
  TargetBmp.Transparent := true;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CharaBmp.Free;
  TargetBmp.free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  TargetBmp.Canvas.CopyRect(Rect(0,0,100,100),CharaBmp.Canvas,Rect(0,0,100,100));
  Refresh;
  Canvas.Draw(10,10,TargetBmp);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  TargetBmp.Canvas.CopyRect(Rect(0,0,100,100),CharaBmp.Canvas,Rect(100,0,200,100));
  Refresh;
  Canvas.Draw(10,10,TargetBmp);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Refresh;
  Canvas.Draw(10,10,CharaBmp);
end;

end.


MASH  2004-05-14 07:43:11  No: 8907

>あの一行を手作業で書く

というのは、どういうことですか?
すでに書いてあるのとは違うのですか?
今度のもエラーになってしまいます。
もしよろしければメールにてプロジェクトごと送っては頂けないでしょうか?
本当にわからないので、すみません。


jok  2004-05-14 08:05:12  No: 8908

> もしよろしければメールにてプロジェクトごと送っては頂けないでしょうか?

すみませんがご希望には沿えません。
なぜエラーが出るのかわたしには分かりません。イベントハンドラがオブジェクト
インスペクタを使ってちゃんと関連づけされているかどうか、くらいですが。
どなたかのアドバイスがあればいいですね。


333  2004-05-14 09:26:05  No: 8909

delphiではマウスをぽちぽちクリック、ダブルクリックするだけで
ほとんどのGUI部分を作ることができます。
jokさんの例では各手続きのbegin〜endの間と
「これらを手動で追加すること」の行だけをキーボードから入力します。

書籍などで基礎を押さえてみればいかがでしょうか?
たぶんそのころには疑問も氷解していると思われます。

おせっかい失礼しました。


MASH  2004-05-14 15:41:42  No: 8910

そうですか、、お手数をかけました。


太郎衛門  2004-05-14 23:41:19  No: 8911

今更ですが、ちょっとだけ。。。
どうやら”裏画面”と”表画面”の関係がわかっていらっしゃらないようなので、
http://www.miyabi-vs.co.jp/~c-works/tips/Lafie/adv02.html
こちらが参考になると思われます。
ですが、333さんが仰るとおり、基礎を押さえておかなければ理解はできないでしょう。
もっとも、自分の基礎も怪しいところですが。。。


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

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






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