![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
初投稿です。C#のコンソールアプリケーションでゲーム作りをしているC#初心者です。
GraphicsExというフォームを作ってそこに壁を描画するところまではできたのですが、画像を自キャラとして動かせるとよいのですが、できないので今はとりあえず丸を描画して動かしています。
質問なのですが、自キャラを丸で描画して動かすと、壁の当たり判定が分からないので、キャラ(ただの丸ですが)が壁をすり抜けてしまいます。壁にぶつかった時にそれ以上進めないようにするために壁の当たり判定をどなたか教えてほしいです。
あとGraphicsを使っているからか、プログラムがおかしいのか分かりませんが(おそらく後者(汗)キャラの移動はキー入力でやっていて、数秒は意図した通りに移動できるのですが何故かキャラを移動しても、しなくても数秒後にフォームがとまってしまい動かなくなります。どのようにプログラムを記述をするとうまく自キャラの操作をできるのかも教えていただけるとすごく嬉しいです。
重ね重ね恐縮ですが、できればソース付でお願いします。
そもそも、コンソールアプリケーションでゲームを作るべきではない、DirectXを使うべきだ、とかあると加えてアドバイスほしいです。
(ウインドウズフォームもDirectXもあまり詳しくないですが。。。orz)
一応いままでのおおまかなプログラムを載せておきます。長文失礼しました。
No.2ベストアンサー
- 回答日時:
>一応いままでのおおまかなプログラムを載せておきます。
プログラムが見当たらないようですが、添付忘れでしょうか?
>質問なのですが、自キャラを丸で描画して動かすと、壁の当たり判定が分からないので、キャラ(ただの丸ですが)が壁をすり抜けてしまいます。壁にぶつかった時にそれ以上進めないようにするために壁の当たり判定をどなたか教えてほしいです。
壁というのが、画面の端なのか、画面上に存在する障害物なのかでソースの複雑さが変わってきます。
基本的な考え方としては点AB間の距離から衝突してるか判定していく感じです。
(この場合は壁A、自機Bの距離)
以下は障害物に対する矩形判定の処理を書いておきます。画面端の判定にも使えます。
最近C#に触ってないので、C++ライクなソースになってますがこんな感じです。
//矩形(四角形)
struct square{
int x,y,w,h; //中央の点xyとその点からの横、縦の長さwh(=矩形の幅、高さの半分)
};
//衝突判定 衝突したらtrueを返す
bool Collision(square a, square b){
int r = a.w + b.w;
if( (a.x - b.x + r) < 0 ) return false;
if( (a.x - b.x) > r ) return false;
r = a.h + b.h;
if( (a.y - b.y + r) < 0 ) return false;
if( (a.y - b.y) > r ) return false;
return true;
}
void main(){
square wall, player; //壁と自機のそれぞれの当たり判定
bool b = Collision(wall, player);
if(b){ ... } //衝突した
else { ... } //衝突していない
}
>やっぱりDirectXは難しいですかorz
C++で使われるのがDirectXで、C#はManaged DirectX(以下mdと表記)というものを使います。現在開発は停止されていて、mdの後継としてXNAがあります。
私はC++のDirectX経験者ですが、C#のmdはC++に比べて遥かに簡単ですよ。
C++での経験があるとはいえ、C#に手を出して3日で簡単なゲームが作れた時は感動しました。
MDXの参考はこちら。
http://www.clks.jp/csg/dx001.html
C#全般に関する参考はこちら。
http://homepage3.nifty.com/midori_no_bike/CS/
この回答への補足
回答ありがとうございました。
プログラムの添付を忘れていました。すみません。
壁は画面の範囲と範囲内の四角形(障害物)を壁として壁がないところを進んでいく迷路、あるいはイライラ棒みたいにした感じです。実際には迷路の中に敵を出現させますが。
おおまかなプログラムはこんな感じです。無駄が多いですが(汗
namespace question
{
class GraphicsEx : Form
{
int size = 40; //キャラのサイズ
static void Main(string[] args)
{
Console.WriteLine("マップを表示");
Application.Run(new GraphicsEx());
}
public GraphicsEx()
{
int max, may;
max = 900;
may = 600;
Text = "GraphicsEx";
BackColor = Color.SkyBlue;
ClientSize = new Size(max, may);
}
protected override void OnPaint(PaintEventArgs pea)
{
Graphics g = pea.Graphics;
Pen pen = new Pen(Color.White, 2);
Pen extent = new Pen(Color.Black, 5); //外側の壁
SolidBrush brush = new SolidBrush(Color.DeepPink);
SolidBrush backbrush3 = new SolidBrush(Color.SkyBlue); //描画を消す背景色です
int space, x1, y1,oldx,oldy; //x1とy1が自キャラの座標ですが変える分には問題ありません
space = 40;
x1 = space ; //自キャラの座標をスタート位置にもって行きます
y1 = space ;
oldx = oldy = 0; //描画の軌跡を消す変数です
//画面の範囲
g.DrawRectangle(extent, space, space, 720, 520);
//マップ作成
g.FillRectangle(brush, 81, 81, 38, 78); //1 壁
g.FillRectangle(brush, 80, 200, 80, 80); //2 壁
g.FillRectangle(brush, 40, 320, 40, 80); //3 壁
g.FillRectangle(brush, 80, 440, 40, 80); //4 壁
g.FillRectangle(brush, 160, 40, 40, 80); // 壁 //5
g.FillRectangle(brush, 120, 320, 40, 80); // 壁 //6
次に続きを書きます。
No.4
- 回答日時:
ソース拝見いたしました。
max,mayが画面のサイズという事でよろしいでしょうか? 以下そのつもりで話を進めます。
画面端と自機の衝突判定について。
障害物との判定に比べたら分かりやすいと思います。
//左
if(a.x-a.w < 0) { /* 左端にぶつかった */ }
//右
if(max < a.x+a.w) { /* 右端にぶつかった */ }
//上
if(a.y - a.h < 0) { /* 上端にぶつかった */ }
//下
if(may < a.y + a.h) { /* 下端にぶつかった */ }
こうやって4箇所判定していけばいいわけです。
障害物と自機の衝突判定についてはNo.2で回答した通りです。
>数秒は意図した通りに移動できるのですが何故かキャラを移動しても、しなくても数秒後にフォームがとまってしまい動かなくなります。
申し訳ありませんがC#の作法をほとんど忘れてしまったため、具体的な指摘が出来ない状態です。
>class GraphicsEx : Form
>Application.Run(new GraphicsEx());
ただ一つ言えるのはkinoshita_garyuさんはコンソールアプリと書かれてますが、これは間違いなくフォームアプリです。
あとOnPaintメソッドは、ウィンドウが移動されるなどして再描画が必要になったら呼び出されるイベント系の関数です。この関数内でループ処理をするのはバグ要因に成り得ると思います。
正しいループ処理する場所については、こちらを参考に。
http://www.clks.jp/csg/gt001.html
画面端の判定まで回答いただきありがとうございます。
>ただ一つ言えるのはkinoshita_garyuさんはコンソールアプリと書かれてますが、これは間違いなくフォームアプリです。
出力先をコンソールにしていたので気にせず普通に勘違いしていましたorz恥ずかしい話ですが。
正しくループ処理するのははじめから不安だったので助かりました。参考にさせていただきます。
No.3
- 回答日時:
すみません、誤植です。
MDXの参考はこちら。
↓
mdの参考はこちら。
この回答への補足
g.FillRectangle(brush, 160, 360, 40, 40); // 壁 //7
g.FillRectangle(brush, 200, 280, 120, 40); // 壁 //8
(brush, 160, 480, 40, 40); // 壁 //9
(brush, 240, 80, 40, 80); // 壁 //10
(brush, 240, 200, 40, 80); // 壁 //11
(brush, 200, 360, 80, 80); // 壁 //12
(brush, 240, 480, 40, 80); // 壁 //13
(brush, 320, 40, 80, 80); // 壁 //14
while (true)
{
g.FillEllipse(backbrush3, oldx, oldy, size, size);
oldx = x1;
oldy = y1;
brush.Color = Color.LightSeaGreen;
g.FillEllipse(brush, x1, y1, size, size);
Thread.Sleep(100);
ConsoleKeyInfo c = Console.ReadKey();
switch (c.Key)
{
case ConsoleKey.UpArrow:
y1 -= width;
break;
case ConsoleKey.DownArrow:
y1 += width;
break;
case ConsoleKey.LeftArrow:
x1 -= height;
break;
case ConsoleKey.RightArrow:
x1 += height;
break;
case ConsoleKey.Escape:
Application.Exit();
break;
}
}
}
}
}
壁をすべて書くとすごい文字数になったので、略して書きます。
壁を略して書かずにそのままプログラムを実行するとできるとは思いますが、キャラの移動するしないにかかわらず、プログラム実行後数秒ほどで止まると思いますorz
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_08.png?e8efa67)
No.1
- 回答日時:
「ゲームプログラマになる前に覚えておきたい技術」(秀和システム、平山 尚)
衝突判定に関する章(8章)を読んでください。まずはこの本を買うことです。
上記の書籍はC++ユーザー向けですが、C#が多少なりとも使えるのであれば、C++のロジック部分はそれなりに理解できるはず。
DirectXはC++中級者以上でないと使いこなすのが難しいため、C#ユーザーであればまずXNAを使ったゲーム開発にチャレンジしてみては?
ちなみに「コンソール アプリケーション」というのはコマンド プロンプト上で動作するような文字ベースのプログラムのことですが、「Windowsフォーム アプリケーション」と勘違いしていませんか?
用語を間違えると回答者の皆さんも混乱するので。
回答ありがとうございました。
やっぱりDirectXは難しいですかorz
Windowsフォームアプリケーションはあんまり使ったことないので分かりませんが、コンソールアプリケーションよりゲーム作りに向いてるのかな?って思って書きました。紛らわしい書きかたしてすみません。
紹介していただいた本に関しては検討します。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ListBoxで改行したい
-
for文の実行速度を遅くしたいの...
-
PowerPoint の VBA
-
ポリゴン 球体を三角形パッチ...
-
c言語 ちらつき
-
C#で壁の当たり判定と自キャラ...
-
立方体をくるくる回転させるプ...
-
N88BASICでシューティングゲー...
-
delphi 画面のちらつき
-
C#(.net) ドロー系ソフト作成 ...
-
VB.NETでグラフィックを描くと...
-
給紙トレイをダイアログを使わ...
-
DrawLineで引いた線が消えてし...
-
VB 6.0 PictureBox のプロパテ...
-
線の描画速度
-
Visual C++ MaskedTextBoxの右...
-
iPhone開発にて 透過PNGを表示...
-
VB.NETでphotoshopのレイヤーの...
-
VBA(エクセル)で自動的にボタン...
-
VBA シートのボタン名を変更し...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ListBoxで改行したい
-
for文の実行速度を遅くしたいの...
-
PowerPoint の VBA
-
c言語 ちらつき
-
VB.NETでグラフィックを描くと...
-
C#を用いて描画する四角形の角...
-
win32api複数のタイマーを同時...
-
画面に絵を出す方法
-
給紙トレイをダイアログを使わ...
-
C#で壁の当たり判定と自キャラ...
-
花火のアルゴリズム
-
円の頂点の求め方を知りたいです。
-
C# DrawImage 物理サイズでな...
-
VB.netで図形描画ができません^^;
-
画面の再描画について
-
エクセルのレーダーチャート 0...
-
リアルタイムで再描画
-
.NETのPictureBoxでウインドウ...
-
Word 描画オブジェクトを削除...
-
vb6のTEXTBOX
おすすめ情報