C#とDXライブラリを使用して,ゲームを作成しているのですが,LoadDivGraphで画像を正しく分割読み込み出来ず困っています.
龍神録のプログラミングの館にて公開されている自機画像0.pngを描画する処理(http://dixq.net/rp/4.html)をC#で行おうと,LoadDivGraphを使用して自機画像0.pngを分割した結果,配列の0番目には正しく画像が格納されているのに対して,1番目~11番目には画像が格納されておらず,正しくアニメーションできませんでした.
確認のため,次のようなプログラムを作成して,自機画像のアニメーションをしてみた結果,やはり,配列GrHandleの0番目は正しく描画されており,1番目から11番目には画像が描画されていませんでした.
同じような問題を抱えている人がいたのですが,自分の場合,0番目には正しく画像の情報が格納されているのに次以降の配列に情報が格納されておらず,どうしてこのような現象になったのかわからなかったので質問させていただきました.
何かご存じでしたら,教えていただきたいです.
------------------------------------------------------------------------------------------------------------------------------
using DxLibDLL;
using System;
class Ryu
{
[STAThread]
static void Main()
{
int[] GrHandle=new int [12];
int GNum = 0;
int loopcnt = 0;
// ウインドウモードで起動
DX.ChangeWindowMode(DX.TRUE);
// 初期化
if (DX.DxLib_Init() == -1) return;
// 画像の読み込み
DX.LoadDivGraph("../dat/img/char/0.png", 12, 4, 3, 73, 73, out GrHandle[0]);
// 描画対象を裏画面に
DX.SetDrawScreen(DX.DX_SCREEN_BACK);
// 閉じられるか、何かキーが押されるまでループ
while (DX.ProcessMessage() == 0 && DX.CheckHitKeyAll() == 0 )
{
loopcnt++;
if (GNum < 11 & loopcnt % 40 == 39)
{
GNum++; //画像ナンバーを変更
}
// 画面の初期化
DX.ClearDrawScreen();
// 画像の描画
DX.DrawGraph(200, 200, GrHandle[GNum], DX.TRUE);
//文字の表示
DX.DrawString(100, 80, "loopcnt = " + loopcnt, DX.GetColor(255, 255, 255));
DX.DrawString(100, 100, "GNum = " + GNum, DX.GetColor(255, 255, 255));
// 裏画面の内容を表画面に反映
DX.ScreenFlip();
}
// 後始末
DX.DxLib_End();
}
}
------------------------------------------------------------------------------------------------------------------------------
使用言語:C#,DXライブラリ
開発環境:Visual Stdio 2008 express edition
C#とDXLibでLoadDivGraph関数を使用して分割読み込みできない
Re: C#とDXLibでLoadDivGraph関数を使用して分割読み込みできない
ざっと見out intなあたりがおかしいのでDxLibのダウンロードページ見て納得。
機械変換がおかしい。
int *がout intやref intに変わるのは,C++のint &の代わりに使っている場合のみで,配列を扱う場合はそのまま配列にする,
マーシャリングする場合はMarshalAs属性をつける形にする必要があります。
# 単体/配列両方ならば,オーバーロードで解決する。
というわけで,DxLibDotNet.dllを自分で(コードを修正した上で)ビルドする必要があります。
今回に関する場所について書くなら,DxDLL.csの7190行目からの,とします。
DXクラス下にある大量の構造体とか,enum化されていないconst intとか,突っ込み所は満載ですが……。
機械変換がおかしい。
int *がout intやref intに変わるのは,C++のint &の代わりに使っている場合のみで,配列を扱う場合はそのまま配列にする,
マーシャリングする場合はMarshalAs属性をつける形にする必要があります。
# 単体/配列両方ならば,オーバーロードで解決する。
というわけで,DxLibDotNet.dllを自分で(コードを修正した上で)ビルドする必要があります。
今回に関する場所について書くなら,DxDLL.csの7190行目からの,
は,私がやるならせめて[DllImport("DxLib.dll", EntryPoint="dx_LoadDivGraph")] extern static int dx_LoadDivGraph_x86( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, out int HandleBuf, int NotUse3DFlag); [DllImport("DxLib_x64.dll", EntryPoint="dx_LoadDivGraph")] extern static int dx_LoadDivGraph_x64( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, out int HandleBuf, int NotUse3DFlag); public static int LoadDivGraph( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, out int HandleBuf) { if( System.IntPtr.Size == 4 ) { return dx_LoadDivGraph_x86( FileName , AllNum , XNum , YNum , XSize , YSize , out HandleBuf , FALSE ); } else { return dx_LoadDivGraph_x64( FileName , AllNum , XNum , YNum , XSize , YSize , out HandleBuf , FALSE ); } } public static int LoadDivGraph( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, out int HandleBuf, int NotUse3DFlag) { if( System.IntPtr.Size == 4 ) { return dx_LoadDivGraph_x86( FileName , AllNum , XNum , YNum , XSize , YSize , out HandleBuf , NotUse3DFlag ); } else { return dx_LoadDivGraph_x64( FileName , AllNum , XNum , YNum , XSize , YSize , out HandleBuf , NotUse3DFlag ); } }
[DllImport("DxLib.dll", EntryPoint="dx_LoadDivGraph", CharSet=CharSet.Ansi)]
extern static int dx_LoadDivGraph_x86( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] int[] HandleBuf, [MarshalAs(UnmanagedType.Bool)] bool NotUse3DFlag);
[DllImport("DxLib_x64.dll", EntryPoint="dx_LoadDivGraph", CharSet=CharSet.Ansi)]
extern static int dx_LoadDivGraph_x64( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] int[] HandleBuf, [MarshalAs(UnmanagedType.Bool)] bool NotUse3DFlag);
public static int LoadDivGraph( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, int[] HandleBuf)
{
return LoadDivGpaph(FileName, AllNum, XNum, YNum, XSize, YSize, HandleBuf, false);
}
public static int LoadDivGraph( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, int[] HandleBuf, bool NotUse3DFlag)
{
if( System.IntPtr.Size == 4 ) // .NET 4以降なら !Environment.Is64BitProcess を利用
{
return dx_LoadDivGraph_x86( FileName , AllNum , XNum , YNum , XSize , YSize , HandleBuf , NotUse3DFlag );
}
else
{
return dx_LoadDivGraph_x64( FileName , AllNum , XNum , YNum , XSize , YSize , HandleBuf , NotUse3DFlag );
}
}
DXクラス下にある大量の構造体とか,enum化されていないconst intとか,突っ込み所は満載ですが……。
Re: C#とDXLibでLoadDivGraph関数を使用して分割読み込みできない
仕事の関係により,返信がおくれてしまって申し訳ございませんでした.
>バグさま
見落としていました. ここの&は&&でした.
ただそのコードを直しても,問題は解決しませんでした.当たり前ですが….
>YuOさま
指定された個所のライブラリファイルを変更して,再ビルド行ったのですが,
次のようなエラーが発生しました.
エラー1:'DxLibDLL.DX.LoadDivGraph(string, int, int, int, int, int, int[])' に最も適しているオーバーロード メソッドには無効な引数がいくつか含まれています。
エラー2:引数 '7': 'out int' から 'int[]' に変換できません。
エラー3:名前 'LoadDivGpaph' は現在のコンテキスト内に存在しません。
エラー1とエラー2に関しては,関数に渡す引数をout GrHandle[0]からGrHandleに変更することで改善することができました.
改善前:DX.LoadDivGraph("../dat/img/char/0.png", 12, 4, 3, 73, 73, out GrHandle[0]);
改善後:DX.LoadDivGraph("../dat/img/char/0.png", 12, 4, 3, 73, 73, GrHandle);
しかしエラー3のエラーのみ,再ビルドを行っても解決できませんでした.
とよくよくソースコードを見ていたところ,LoadDivGraphのスペルが間違っていたようですね.
記載されていたコードの7行目:LoadDivGpaphは正しくはLoadDivGraphでした.
DxLibのライブラリファイルを変更した結果,サンプルコードで正しくアニメーションできていました.ありがとうございました.
後で解決したコードを記述しておきます.
C#で開発している人のためにも,管理人さんに報告しておいたほうがいいかもしれませんね…
>バグさま
見落としていました. ここの&は&&でした.
ただそのコードを直しても,問題は解決しませんでした.当たり前ですが….
>YuOさま
指定された個所のライブラリファイルを変更して,再ビルド行ったのですが,
次のようなエラーが発生しました.
エラー1:'DxLibDLL.DX.LoadDivGraph(string, int, int, int, int, int, int[])' に最も適しているオーバーロード メソッドには無効な引数がいくつか含まれています。
エラー2:引数 '7': 'out int' から 'int[]' に変換できません。
エラー3:名前 'LoadDivGpaph' は現在のコンテキスト内に存在しません。
エラー1とエラー2に関しては,関数に渡す引数をout GrHandle[0]からGrHandleに変更することで改善することができました.
改善前:DX.LoadDivGraph("../dat/img/char/0.png", 12, 4, 3, 73, 73, out GrHandle[0]);
改善後:DX.LoadDivGraph("../dat/img/char/0.png", 12, 4, 3, 73, 73, GrHandle);
しかしエラー3のエラーのみ,再ビルドを行っても解決できませんでした.
とよくよくソースコードを見ていたところ,LoadDivGraphのスペルが間違っていたようですね.
記載されていたコードの7行目:LoadDivGpaphは正しくはLoadDivGraphでした.
DxLibのライブラリファイルを変更した結果,サンプルコードで正しくアニメーションできていました.ありがとうございました.
後で解決したコードを記述しておきます.
C#で開発している人のためにも,管理人さんに報告しておいたほうがいいかもしれませんね…
Re: C#とDXLibでLoadDivGraph関数を使用して分割読み込みできない
自分なりにまとめました
問題:C#とDXLibでLoadDivGraph関数を使用して分割読み込みできない.
現象:C#でDxLibのLoadDivGraph関数を使用すると,画像を正しく分割読み込み出来ない.具体的には,
LoadDivGraph関数を利用すると配列の0番目の画像しか読み込めない.
解決策:DxDLL.csファイルの7190行目に記述されているLoadDivGraphを次のように変更.プロジェクトを再ビルドする.
以下正しく動いているかを判定するためのプログラム(C#)
問題:C#とDXLibでLoadDivGraph関数を使用して分割読み込みできない.
現象:C#でDxLibのLoadDivGraph関数を使用すると,画像を正しく分割読み込み出来ない.具体的には,
LoadDivGraph関数を利用すると配列の0番目の画像しか読み込めない.
解決策:DxDLL.csファイルの7190行目に記述されているLoadDivGraphを次のように変更.プロジェクトを再ビルドする.
[DllImport("DxLib.dll", EntryPoint="dx_LoadDivGraph", CharSet=CharSet.Ansi)]
extern static int dx_LoadDivGraph_x86( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] int[] HandleBuf, [MarshalAs(UnmanagedType.Bool)] bool NotUse3DFlag);
[DllImport("DxLib_x64.dll", EntryPoint="dx_LoadDivGraph", CharSet=CharSet.Ansi)]
extern static int dx_LoadDivGraph_x64( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1), Out] int[] HandleBuf, [MarshalAs(UnmanagedType.Bool)] bool NotUse3DFlag);
public static int LoadDivGraph( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, int[] HandleBuf)
{
return LoadDivGpaph(FileName, AllNum, XNum, YNum, XSize, YSize, HandleBuf, false);
}
public static int LoadDivGraph( string FileName, int AllNum, int XNum, int YNum, int XSize, int YSize, int[] HandleBuf, bool NotUse3DFlag)
{
if( System.IntPtr.Size == 4 )
{
return dx_LoadDivGraph_x86( FileName , AllNum , XNum , YNum , XSize , YSize , HandleBuf , NotUse3DFlag );
}
else
{
return dx_LoadDivGraph_x64( FileName , AllNum , XNum , YNum , XSize , YSize , HandleBuf , NotUse3DFlag );
}
}
using DxLibDLL;
using System;
class Ryu
{
[STAThread]
static void Main()
{
int[] GrHandle=new int [12];
int GNum = 0;
int loopcnt = 0;
// ウインドウモードで起動
DX.ChangeWindowMode(DX.TRUE);
// 初期化
if (DX.DxLib_Init() == -1) return;
// 画像の読み込み
DX.LoadDivGraph("../dat/img/char/0.png", 12, 4, 3, 73, 73, GrHandle);
// 描画対象を裏画面に
DX.SetDrawScreen(DX.DX_SCREEN_BACK);
// 閉じられるか、何かキーが押されるまでループ
while (DX.ProcessMessage() == 0 && DX.CheckHitKeyAll() == 0 )
{
loopcnt++;
if (GNum < 11 && loopcnt % 40 == 39)
{
GNum++; //画像ナンバーを変更
}
// 画面の初期化
DX.ClearDrawScreen();
// 画像の描画
DX.DrawGraph(200, 200, GrHandle[GNum], DX.TRUE);
//文字の表示
DX.DrawString(100, 80, "loopcnt = " + loopcnt, DX.GetColor(255, 255, 255));
DX.DrawString(100, 100, "GNum = " + GNum, DX.GetColor(255, 255, 255));
// 裏画面の内容を表画面に反映
DX.ScreenFlip();
}
// 後始末
DX.DxLib_End();
}
}