初投稿です。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
No.1
- 回答日時:
「ゲームプログラマになる前に覚えておきたい技術」(秀和システム、平山 尚)
衝突判定に関する章(8章)を読んでください。まずはこの本を買うことです。
上記の書籍はC++ユーザー向けですが、C#が多少なりとも使えるのであれば、C++のロジック部分はそれなりに理解できるはず。
DirectXはC++中級者以上でないと使いこなすのが難しいため、C#ユーザーであればまずXNAを使ったゲーム開発にチャレンジしてみては?
ちなみに「コンソール アプリケーション」というのはコマンド プロンプト上で動作するような文字ベースのプログラムのことですが、「Windowsフォーム アプリケーション」と勘違いしていませんか?
用語を間違えると回答者の皆さんも混乱するので。
回答ありがとうございました。
やっぱりDirectXは難しいですかorz
Windowsフォームアプリケーションはあんまり使ったことないので分かりませんが、コンソールアプリケーションよりゲーム作りに向いてるのかな?って思って書きました。紛らわしい書きかたしてすみません。
紹介していただいた本に関しては検討します。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(動画サービス) TikTokでとある動画の絵師さんを探しています。今の所、動画も見つからなくてその絵師さんの垢も見つ 1 2023/03/13 01:24
- レトロゲーム ファミコンのインベーダの質問その3 背景にインベーダーを描画したとしても、なぜ動けるのか? 3 2022/07/08 16:58
- その他(アニメ・マンガ・特撮) 作画が綺麗でキャラの表情が魅力的なおすすめ漫画を教えてください。 絵を描く人間です。男性キャラの表情 1 2023/04/18 00:49
- モニター・ディスプレイ マルチモニタでのカーソルの動き方 1 2022/06/15 14:59
- デザイン ちびキャラを上手に描く方法 1 2022/09/13 18:28
- 楽器・演奏 ★この考え方 どう思われますかぁ? 5 2023/06/08 16:44
- その他(動画サービス) OBSで質問です ①HyperX Cloud Alpha ゲーミング ヘッドセット インライン音量コ 1 2022/11/21 22:10
- ゲーム ゲームトレードでのトラブルについて 1 2023/06/30 21:50
- Visual Basic(VBA) エクセルマクロでアニメを作る方法を教えてください。 1 2023/02/07 14:27
- 画像編集・動画編集・音楽編集 ボカロの架空窓口の閉鎖という曲で動画を作りたい者です。 1 2022/06/13 18:12
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ListBoxで改行したい
-
[続編] pictureBoxそのものの...
-
for文の実行速度を遅くしたいの...
-
C#を用いて描画する四角形の角...
-
VC++ MFCチェックボックスの色...
-
MFCでのコンボボックスについて
-
Visual C++ MaskedTextBoxの右...
-
円の頂点の求め方を知りたいです。
-
画面に絵を出す方法
-
PowerPoint の VBA
-
C# DrawImage 物理サイズでな...
-
VBA シートのボタン名を変更し...
-
VBA(エクセル)で自動的にボタン...
-
worksheetFunctionクラスのVloo...
-
実行時エラー 438になった時の...
-
【C#/Java?】try-catchでcatch...
-
「Columns("A:C")」の列文字を...
-
eclipseのデバッグ中に変数の値...
-
フォームの再読み込み
-
クリックイベントなのに、2回ク...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ListBoxで改行したい
-
for文の実行速度を遅くしたいの...
-
PowerPoint の VBA
-
給紙トレイをダイアログを使わ...
-
Word 描画オブジェクトを削除...
-
画面に絵を出す方法
-
C#を用いて描画する四角形の角...
-
C#でPictureBox内での図形移動...
-
VB.NETでグラフィックを描くと...
-
ビットマップに描画をしてピク...
-
VB.netで図形描画ができません^^;
-
C# DrawImage 物理サイズでな...
-
Excel VBA:コントロールボタン...
-
MFCでのコンボボックスについて
-
OpenGLでのオブジェクトの描画上限
-
円の頂点の求め方を知りたいです。
-
コンボボックスのテキストを消...
-
VB.NETでphotoshopのレイヤーの...
-
DrawLineで引いた線が消えてし...
-
水平線の描画
おすすめ情報