ゲームスピードを一定にするには?

解決


MASH  2004-06-17 07:35:35  No: 9468

シューティングゲームを作っているのですが、
Delphi開発環境で(F9でコンパイル+実行)実行すると上手くいくのですが、
生成した実行ファイルを直接ダブルクリックなどで起動するとゲームスピードが
ありえないくらいに遅くなっていることが良くあります。
メインループは、http://delphi.nce.buttobi.net/mainroutine/index.html
で説明されているやり方でやっています。
どうしてでしょうか、回避するいい方法を教えてください。


MASH  2004-06-17 07:40:42  No: 9469

ちょっとリンクが上手くいかないようなので、
http://delphi.nce.buttobi.net/
の「メインルーチン」というところを参考にしました。


スタテツ  2004-06-18 00:49:19  No: 9470

レスが無いようなので。
サンプルソースを見てみました。
これといってデバッグ環境とそうで無い場合で違いが現れるようには思えませんし、私の環境では違いは現れません。(数十回テストしただけですが)
多分他の箇所に原因があると思います。


MASH  2004-06-18 02:09:53  No: 9471

>多分他の箇所に原因があると思います。

レスありがとうございます。
他にどんな可能性が考えられますか?
ちなみに、ゲームスピードが遅くなるときはマウスがスムーズに動かなかったりして、
パソコン全体が重くなるような気がします。
デスクトップに置いてやると特に頻度が高くなるので、
深めのディレクトリや全角文字が入っていたりすると良くないのでしょうか?


スタテツ  2004-06-18 05:21:43  No: 9472

よく分からんですが、
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=046977
からすると、やはり単純な画像の描画だけでは不安定になる要素は考えづらいです。可能性はあげればキリが無いですが、
●非常に重い処理をしている
●変なメッセージをやたら飛ばしている
●実はアプリケーションが終了していない
とかあるかもしれません。っていうかソース無しで可能性をあげてくれといわれてもそりゃ私には無理です。他の方よろしくお願いします。
原因を究明するには
○再現する最小コードを示す
これに尽きます。長いとだれも読んでくれませんし。


MASH  2004-06-19 03:04:03  No: 9473

>○再現する最小コードを示す

最小コードを作ろうと思ってソースを削っていて、
{$J+}のところを削除しましたら、
今のところ一度も重くなっていません。
これは何か関係があるのでしょうか?


ふぐちゃん  2004-06-19 03:26:01  No: 9474

横から失礼します。

> {$J+}
これは型付き定数を変更できるようにするスイッチです。
Delphi6以上のデフォルトは {$J-} です。
{$J+} は推奨されていませんので、できれば使わない方がよろしいかと思います。


MASH  2004-06-19 07:14:59  No: 9475

その後何回か試して見たところ、やっぱりダメでした。
なので、ソースを出させていただきます。よろしくお願いします。
開発環境で(F9)でなくても、起動させていて直接EXEを実行でもスムーズに動きます。

const
  jikiy=30;

type
  Tjiki = record                //自機
    x: Integer;
    zanki: Integer;
  end;
  
  TForm1 = class(TForm)
    Ura: TImage;
    Back: TImage;
    Event: TApplicationEvents;
    procedure FormCreate(Sender: TObject);
    procedure gameplay;
    procedure key;
    procedure FormDestroy(Sender: TObject);
    procedure EventIdle(Sender: TObject; var Done: Boolean);
  private
    { Private 宣言 }
    jiki: Tjiki;
    char,mchar,exp,mexp: TBitmap;
    Nowtime, Beforetime: DWORD;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
        Form1.DoubleBuffered :=True;
        TimeBeginPeriod(1);
        Form1.ClientHeight:=480;
        Form1.ClientWidth:=640;
        Ura.Height:=Form1.ClientHeight;
        Ura.Width:=Form1.ClientWidth;
        jiki.x:=280;
        //キャラクター
        char:= TBitmap.Create;
        char.LoadFromFile('picture\pic.bmp');
        mchar:= TBitmap.Create;
        mchar.LoadFromFile('picture\pic.bmp');
        mchar.Mask($00000000);
end;

procedure TForm1.gameplay;
begin
        //背景を裏画面にコピー
        BitBlt(Ura.Canvas.Handle,0,0,640,480,
        Back.Picture.Bitmap.Canvas.Handle,0,0,srccopy);
        key;            //プレイヤーのキー操作
        //裏画面を表示
        BitBlt(Form1.Canvas.Handle,0,0,640,480,
        Ura.Canvas.Handle,0,0,srccopy);
end;

//自機の操作
procedure TForm1.key;
begin
        if GetKeyState(VK_LEFT)<0 then Dec(jiki.x);
        if GetKeyState(VK_RIGHT)<0 then Inc(jiki.x);
        //自機操作限定
        if jiki.x<0 then jiki.x:=0;
        if jiki.x>Form1.ClientWidth-64 then  jiki.x:=Form1.ClientWidth-64;
        //自機を裏画面に表示
        BitBlt(Ura.Canvas.Handle,jiki.x,jikiy,64,32,
        mchar.Canvas.Handle,0,0,srcand);
        BitBlt(Ura.Canvas.Handle,jiki.x,jikiy,64,32,
        char.Canvas.Handle,0,0,srcinvert);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
        char.Free;
        mchar.Free;
        TimeEndPeriod(1);
end;

procedure TForm1.EventIdle(Sender: TObject; var Done: Boolean);
begin
        NowTime:=timeGetTime;
        if (NowTime-BeforeTime) < 17 then
        begin
          Sleep(1);
          Done:=False;
          Exit;
        end;
        gameplay;
        BeforeTime:=NowTime;
        Done:=False;
end;

end.


スタテツ  2004-06-19 11:13:15  No: 9476

お疲れ様です
あれ??
試す前に確認したいのですが。
問題点は
>生成した実行ファイルを直接ダブルクリックなどで起動するとゲームスピードが
>ありえないくらいに遅くなっている
ですよね?
>直接EXEを実行でもスムーズに動きます
これじゃ問題点が無いですよね??


MASH  2004-06-20 04:24:30  No: 9477

>>直接EXEを実行でもスムーズに動きます
>これじゃ問題点が無いですよね??

開発環境を起動させている間にEXEを直接実行ということです。
これは別に、何回かしかやってないのであまり信用できるものではありませんが。
ちなみに、Private 宣言で"char,mchar,exp,mexp: TBitmap;"の"exp,mexp"を消し忘れていました。


スタテツ  2004-06-20 05:50:44  No: 9478

再現しません。
開発環境に依存しているのかもしれません。
当方「WindowsXp+sp1 Delphi7 pro」です。


MASH  2004-06-20 07:01:17  No: 9479

そうですか…。とするとどうしようもありませんね。
こちらは、「WindowsXP+SP1 Delphi6 Personal」です。


スタテツ  2004-06-21 05:13:09  No: 9480

WinXP+Delphi6 Personal
でも試しましたがやはり再現しません。
試した方式は
Delphi6→F9
Delphi6を立ち上げたまま、project1.exeをダブルクリック
Delphi6を終了して、project1.exeをダブルクリック
デスクトップにコピーして、project1.exeをダブルクリック
全て数十回試行しましたが動作に変化はありませんでした。
てか、本当に提示されたソースで再現します??
あと、時々発生するとのことですが、
マシンのメモリ、CPU時間は十分にあるのでしょうか?


MASH  2004-06-21 07:23:13  No: 9481

パソコンの性能は、こんなでそんなに悪いものではないと思います。
Duron 900MHz
256MB RAM

確かに、ソースを削っていくと再現しにくくはなりますが、しなくなるわけではありません。
多分、たまたまパソコンが不安定なときに起動したものがそうなってしまうのかと思います。

別件で失礼ですが、このソースで実行時にカーソルを
ウィンドウの外に移動させると動きがカクカクするのは、どうしてですか?
また、どうすれば直りますか?


スタテツ  2004-06-21 08:21:49  No: 9482

タスクマネージャでCPU使用率を確認してください。
そもそもサンプルソースの方法でメインルーチンを作成しますと17msecを超える処理をさせようとすると動きがカクカクします。
原因は恐らくこのためです。
しかもこの処理はWindowsのCPUを独占しているわけじゃないので、他のアプリケーションの動作に左右されます。
それと、提示されたソースは高速に動作させるゲームには不向きな操作が多数使われています。これらを回避するにはもうちょっとスキルUPが必要です。
Form1.DoubleBuffered :=True;
TImage;
とかは結構時間を使います。
ゲーム用ルーチンならDirectXを用いるとかなり本格的なものが作れますし
サンプルも今なら結構出回ってると思います。
非DirectXであればなるべく省エネ設計しないとこのカクカクは避けることができませんし、それでもだめな場合は処理をスキップするような処理を作成する必要があります。

>ウィンドウの外に移動させると動きがカクカクするのは、どうしてですか?
主語が無いです^^;
マウスカーソルorアプリケーション
どちらであっても、他のアプリケーションの影響で、ゲームの処理が遅くなっているのが原因かと思われます。


MASH  2004-06-21 22:47:29  No: 9483

それなら、DirectXを使うことにします。
ありがとうございました。


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

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






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