人に聞けない痔の悩み、これでスッキリ >>

今までVisualC++.netでWinAPIを使ってアクションゲームを
作っていたのですが、最近DXライブラリを使い出しました。
今までは一定時間ごとにメインループとは別に自動的に行われる
処理はウィンドウプロシージャでSetTimerして
case WM_TIMER:に処理を書くことで実現していたのですが、
DXライブラリの場合それにあたる機能はあるのでしょうか。

たとえばメインループとは別に1秒おきにある変数をTRUEにしたり
FALSEにしたりしたい場合、ウィンドウプロシージャでやるしかないのでしょうか?

A 回答 (3件)

再度です。



流石にそこから先は、自分で考えてみてください。
どうやら私の認識違いも大きいようなので・・・・
私自身DirectXを使ったゲームの開発経験はありますが、DXライブラリ自体は
使ったことが無いので・・・・だから「経験者」の意味合いも、たぶん質問者様と
ズレがあるはずです。

一通り「DXライブラリ」のページを見ましたが、サンプルプログラムを全て見ていけば
解決できる問題のはずです。

全てのサンプルをまずは実行し、よーく見てください。移動とありますが、移動と、アニメーションの
計算を先にやってから、後でまとめて描画すれば、まあ解決できるはずです。

・・・もしくは

// 裏画面の内容を表画面にコピーする
ScreenFlip() ;

// Windows 特有の面倒な処理をDXライブラリにやらせる
ProcessMessage() ;

この2つをループ中に書くだけである程度は解決できるかも知れません。

まあ別の問題が出たらその時は、実際この2つで何をやっているかを調べればいいでしょう。
ソースも公開しているみたいですし・・・・

参考URL:http://homepage2.nifty.com/natupaji/DxLib/dxprog …
    • good
    • 0
この回答へのお礼

たびたびの解答ありがとうございます。
参考になりそうなサンプルまで見つけていただいて・・。
一応ダブルバッファリングは既にしていたのですが、
キー入力の同期とか課題がまだまだ多いです・・。
これをもとにがんばってみます。ありがとうございました!

お礼日時:2006/08/20 20:40

再度、No1です。

お礼について再度回答します。

while (1){
 タイム計測
   ↓
 足踏み用の変数の値を入れ替え
   ↓
 描画(足踏み変数を判定して左右のキャラを描画)
   ↓
 while (時間が前回計測時から1秒経過するまでループ){
  if (キー入力() == TRUE ){break;}
 }
}

の部分の

while (1){



 while (時間が前回計測時から1秒経過するまでループ){
  if (キー入力() == TRUE ){break;}

がいらない気がするんですよね。つまり

 タイム計測
   ↓
 足踏み用の変数の値を入れ替え
   ↓
 描画(足踏み変数を判定して左右のキャラを描画)

コレだけで十分かと・・・言い方正しいかは分かりませんが、基本的にゲームの描画とかアニメーションって
その時その時、瞬間の状態が描画できれば、まあ大体うまくいけます。そもそもゲームループって
1秒間に何回も実行しますよね??だから1回のループだけならコレで十分です。

後だんだん分かってくるとは思いますが、基本的に「描画」ってのは重い処理です。
質問者様の考えている、「キャラのアニメーションにあわせて描画」はありと言えばありですが、
キャラが10、20と増えるにしたがって必然的に追いつかなくなります。
なのでアニメーションの多さや、アクションが多いゲームで、その考え方はあまりオススメしません。
変に待ったりしないで、その瞬間が描画できれば良しとした方がいいです。

この回答への補足

すみません、アクションとは言いましたがどちらかというと
RPGに近いのかもしれません。キャラの動きに合わせて
描画するのではなく時間に合わせてキャラが描画されるといった
感じです。雰囲気としてはFFやドラクエの勇者や村人の
足踏みみたいな感じです。
ですのでキャラが増えても問題は無いタイプです。
その為while(1)はそれ自体がゲームループです。

後、

 タイム計測
   ↓
 足踏み用の変数の値を入れ替え
   ↓
 描画(足踏み変数を判定して左右のキャラを描画)

この仕様にした場合キー入力とかの判定がその場でできなくないですか?
キー入力があったらすぐに一歩移動したグラフィックを描画しないといけないので。。

補足日時:2006/08/20 17:06
    • good
    • 0

「DXライブラリ」で検索すると、そのままの名前のフリーライブラリがヒットしちゃうんですよね。


それのことを指しているのか、DirevtXそのものを指しているのかいまいち分かりませんので

>DXライブラリの場合それにあたる機能はあるのでしょうか

コレに関しては保留で。まあ「DXライブラリ」はウインドウプロシージャ周りはかなり内包されているみたいですね。
DirevtXには、その手の機能は無かったはずです。

>たとえばメインループとは別に1秒おきにある変数をTRUEにしたり
>FALSEにしたりしたい場合、ウィンドウプロシージャでやるしかないのでしょうか?

コレは私なら、そのつどそのつど時間を取得してその時の時間で計算しなおしますけどね。
無理にそういう実装にする必要も無いかと・・・
    • good
    • 0
この回答へのお礼

回答ありがとうございます。私が言っているのは
DirectXでなくDXライブラリです。
そのつど時間を取得するやり方は私も考えたのですが、
例えばキャラが1秒おきに自動的に足踏みをするように
したいのですが、
while (1){
 タイム計測
   ↓
 足踏み用の変数の値を入れ替え
   ↓
 描画(足踏み変数を判定して左右のキャラを描画)
   ↓
 while (時間が前回計測時から1秒経過するまでループ){
  if (キー入力() == TRUE ){break;}
 }
}
*但しキー入力は入力が無ければスルーされる

と、こんな感じに作ったのですが、while文をノーウェイト
で回しているためCPUに激しい負荷がかかります。
かといってSleepなどでとめると止めている間キー入力に
反応できなくなってしまうので、私としては
1秒おきに足踏み変数を入れ替えて自動的に再描画させる
サブループとキー入力があるまで何もしないメインループ
とを分離したかったのですが、何か解決策は無いものでしょうか・・?

お礼日時:2006/08/18 18:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QDXライブラリでの2Dの描画法[RPG作成]

VidualStudio.net C++ DXライブラリでRPGを初めて作成中なのですが、キャラ移動、マップ移動、マップスクロールなど実装したのはいいのですが、ゲームがとても重いです。

CPUの使用状況によってはスムーズな動きをするので、おそらくマップの描画に問題があるのだとおもいますが、マップは32x32ピクセルのものをゲームのスタート時に読み込み、2D配列に格納したintタイプのマップにあわせてDrawGraphイメージハンドルからひとつひとつ描いています。

これでは効率が悪すぎるのでしょうか?それとも初めからすべてマップ情報をメモリにロードするとメモリ不足で結局ディスクから読み込んでいるのでしょうか。(でもそれほどの量はテスト段階ですので扱っていないのですが。。。)
もっと効率のいいマップの描き方があれば教えていただきたいのでここに投稿させていただきました。

ちなみに、DXライブラリはここのものを使わせていただいています
http://homepage2.nifty.com/natupaji/DxLib/dxdload.html

VidualStudio.net C++ DXライブラリでRPGを初めて作成中なのですが、キャラ移動、マップ移動、マップスクロールなど実装したのはいいのですが、ゲームがとても重いです。

CPUの使用状況によってはスムーズな動きをするので、おそらくマップの描画に問題があるのだとおもいますが、マップは32x32ピクセルのものをゲームのスタート時に読み込み、2D配列に格納したintタイプのマップにあわせてDrawGraphイメージハンドルからひとつひとつ描いています。

これでは効率が悪すぎるのでしょ...続きを読む

Aベストアンサー

参考になりそうなQ&A:http://okwave.jp/qa4329951.html

要は「マップは予め一枚絵にしておけ」ってことですが。
#描画回数が増えれば増えるほどRAM→VRAMの転送にかかる時間が馬鹿にならなくなります

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

QC言語で簡単なゲームを作る方法

僕はC言語を学び始めた程度ですが、一番簡単に作れるゲームとその作り方(ソース)を教えて下さい。お願いします。

Aベストアンサー

★じゃんけんゲームのソースです。

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP_KATI : TYP_MAKE);
  case JKN_CHOKI:  return ((computer == JKN_PA) ? TYP_KATI : TYP_MAKE);
  case JKN_PA:  return ((computer == JKN_GOO) ? TYP_KATI : TYP_MAKE);
  default:   return -1;
 }
}

// じゃんけんゲーム
int main( void )
{
 // ゲーム変数
 int count;  // 勝負回数
 int kati = 0; // 勝ちカウンタ
 int make = 0; // 負けカウンタ
 // 一時変数
 int human;  // キー入力の一時変数(人間用)
 int computer; // 乱数発生の一時変数(コンピュータ用)
 
 // (6)じゃんけん勝負を10回行う
 printf( "★じゃんけんゲーム(10回勝負)\n\n" );
 for ( count = 1 ; count <= 10 ; count++ ){
  // (1)人間:3つの状態を入力
  printf( "%2d回目…[1]グー [2]チョキ [3]パー を入力して下さい:", count );
  do {
   // (2)キー入力
   switch ( getche() ){
    case '1': human = JKN_GOO; break;
    case '2': human = JKN_CHOKI; break;
    case '3': human = JKN_PA; break;
    default: human = -1; break;
   }
  } while ( human == -1 );
  
  // (3)コンピュータ:3つの状態を乱数で決める
  computer = (rand() % 3);
  // (4)人間vsコンピュータの勝負
  switch ( check(human,computer) ){
   case TYP_KATI:
    kati++;
    printf( "⇒勝ち。\n" );
    break;
   case TYP_MAKE:
    make++;
    printf( "⇒負け。\n" );
    break;
   case TYP_AIKO:
    printf( "⇒引き分け。\n" );
    break;
   default:
    printf( "⇒エラー。\n" );
    break;
  }
 }
 // (7)結果表示
 printf( "\n★じゃんけんゲームの結果\n" );
 printf( "人間    :%d 回勝ち\n", kati );
 printf( "コンピュータ:%d 回勝ち\n", make );
 printf( "※引き分け回数は %d 回でした。\n", (10 - kati - make) );
 return 0;
}

注意:全角空白をタブ文字に変換して下さい。

★じゃんけんゲームのソースです。

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

// じゃんけん定数
#define JKN_GOO  (0)
#define JKN_CHOKI (1)
#define JKN_PA  (2)

// 勝敗の定数
#define TYP_KATI (0)
#define TYP_MAKE (1)
#define TYP_AIKO (2)

// じゃんけんの判定関数
int check( int human, int computer )
{
 if ( human == computer ){
  return TYP_AIKO;
 }
 switch ( human ){
  case JKN_GOO:  return ((computer == JKN_CHOKI) ? TYP...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qマップチップの当たり判定の出し方

キャラの座標をposx、posyとして宣言し、キー入力でその値をプラスやマイナスをして動かせるようにし、またマップをint map[16][16]として宣言し、for文でmap[x][y]として回して絵画しているのですが、キャラの移動変数と連動して当たり判定を作ろうとすると、「キャラの移動変数が配列になっていない」というエラーが出ます。
しかし、キャラ座標を配列にする訳にもいかないのでどうすればいいのか困っています。

Aベストアンサー

追記。

もし「キャラの座標」と「マップ配列の要素の番号」が1対1に対応していない場合は
switch (map[new_posx][new_posy]にある場所のタイプ) {
の部分を
switch (map[new_posxからmapの要素に対応させる変換式][new_posyからmapの要素に対応させる変換式]にある場所のタイプ) {
に変えて下さい。

例えば
new_xposが  ~102⇒mapを飛び出すのでNG
new_xposが103~113⇒map[0][???]
new_xposが114~124⇒map[1][???]
new_xposが125~135⇒map[2][???]
new_xposが136~146⇒map[3][???]
new_xposが147~157⇒map[4][???]
new_xposが158~168⇒map[5][???]
(以下略)
new_xposが268~278⇒map[15][???]
new_xposが279~  ⇒mapを飛び出すのでNG
のようにに対応しているなら「103を引いて、11で割る」と0~15になります。

なので、上記の例であれば
switch (map[((int)new_posx-103)/11][new_posyからmapの要素に対応させる変換式]にある場所のタイプ) {
と書けばOKです(もちろん、NG範囲を除外した上で)

y方向も、同じように変換式にして下さい。

引いたり(場合によっては足したり)、割ったりする数値は「質問者さんが書いているプログラムに合う数値」に合わせて、適切な値に変えて下さい。

追記。

もし「キャラの座標」と「マップ配列の要素の番号」が1対1に対応していない場合は
switch (map[new_posx][new_posy]にある場所のタイプ) {
の部分を
switch (map[new_posxからmapの要素に対応させる変換式][new_posyからmapの要素に対応させる変換式]にある場所のタイプ) {
に変えて下さい。

例えば
new_xposが  ~102⇒mapを飛び出すのでNG
new_xposが103~113⇒map[0][???]
new_xposが114~124⇒map[1][???]
new_xposが125~135⇒map[2][???]
new_xposが136~146⇒map[3][???]
new_xpos...続きを読む

Q横スクロールアクションのステージ製作方法

DXライブラリで http://www.youtube.com/watch?v=k2cKhuD2NF0
こちらのゲームのような横スクロールアクションを作ろうと思ってます。

ステージの製作方法なんですがどのようにすればよろしいでしょうか?
PhotoshopやIllustratorは持ってはいるのですが、それでステージ全体をデザインし
http://dixq.net/g/26.html  (ゲームプログラミングの館)
こちらのように 0と1で足場を組むのが一般的でしょうか?

また、そういった事を解説しているWebページがありましたら
是非とも教えていただきたいです。

回答よろしくお願いします。

Aベストアンサー

汎用マッチエディタを使うとか自分で作るとかでしょうね。
「Platinum」
http://www.hyperdevice.net/
「WIN用ソフト紹介 MapEditor5」
http://www.moreread.net/mario/Any/win/index.php?id=16


人気Q&Aランキング