• 締切済み

DXライブラリによるパズルゲーム制作について

 今、私はDXライブラリによるパズルゲーム制作に取り掛かっています。 そこで、画像をランダムに表示する際のプログラムの書き方に詰まってしまったので、教えていただければと思い投稿しました。 LoadDivGraph( "BLOCK.png" , 16 , 4 , 4 , 32 , 32 , Block ); for(int i=0;i<15;i++) {     for(int j=0;j<20;j++)     {         int n =GetRand(14);   if(i==0||i==14||j==0||j==19)   { DrawGraph( j*32, i*32 , Block[7], TRUE );   }   else   { DrawGraph( j*32, i*32 , Block[n], TRUE );   }     } } ※インデントに関してはご容赦ください。 かなり端折っていますが、上記のような感じで打ってしまうと、(ここには書いていませんが)while文があるおかげで、一秒間に60回のペースでBlock[n]の中身が変化してしまいます。 これを解消したいのですが、かといって、いちいち変数を用意してコピーするのでは効率が悪いですよね。あと、パズルゲームですので、この先、表示した画像を入れ替えたり消したりといった処理があることを念頭に入れたうえでのベストな書き方を教えていただければと思います。 ちなみに、C言語・C++の書き方でお願いします。

みんなの回答

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

書き方を含めてアドバイスを受けたいなら「C言語何でも質問掲示板」をおすすめします。「ゲームプログラミングの館」と同じサイトにある掲示板です。 ソースコードを、ちゃんとしたインデントで貼れるのがなんといってもメリットです。 ちなみに初期化をwhileループ内に書いてはいけません。

_Purple_
質問者

補足

追記 http://dixq.net/forum/viewtopic.php?f=3&t=11346 //マルチポスト相互リンク

関連するQ&A

  • DXライブラリの透過処理について

    #include "DxLib.h" int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) { ChangeWindowMode(TRUE); SetDrawScreen(DX_SCREEN_BACK); if(DxLib_Init()==1) { return -1; } char key[256]; // int haikei; int mapchip[2][152]; int i,j; //int x = 0, y = 0; //haikei = LoadGraph("haikei/草原.jpg"); LoadDivGraph("03.png",5,1,5,32,32,mapchip[0]); LoadDivGraph("mura.png",1,1,1,32,32,mapchip[1]); while(ScreenFlip()==0 && ProcessMessage() == 0 && GetHitKeyStateAll(key)==0) { // ClearDrawScreen(); // DrawGraph(x,y,haikei,FALSE); for(i = 0; i<15;i++) { for(j=0;j<20;j++) { DrawGraph(j*32,i*32,mapchip[0][4],FALSE); } } DrawGraph(32,32,mapchip[1][0],TRUE); /* if(CheckHitKey(KEY_INPUT_RIGHT) == 1) x+=10; if(CheckHitKey(KEY_INPUT_LEFT) == 1) x-=10; if(CheckHitKey(KEY_INPUT_UP) == 1) y-=10; if(CheckHitKey(KEY_INPUT_DOWN) == 1) y+=10; */ if(key[KEY_INPUT_ESCAPE] == 1) { DxLib_End(); return 0; } } } 「DrawGraph(32,32,mapchip[1][0],TRUE);」という処理でmura.pngの左上のカラーキーで透過するはずですがしません。 Win10のペイントで作ったpngファイル形式に対応してないかと思うのですが、よくわかりまえん。 なぜ?

  • DXライブラリでマップが作れません・・・。

    今DXライブラリとVisualC++2008を使ってゲーム(アクション)を作っているのですがマップが作れません・・・、構造体?をつかってマップの描写は成功したのですが、0のところに判定を持たせることができません・・・。どのようにすればいいのでしょうか?色々試してみてもできず困っています。 ソースの一部 #include"DxLib.h" #define MAP_SIZE 64 // マップチップ一つのドットサイズ #define MAP_WIDTH 10 // マップの幅 #define MAP_HEIGHT 8 // マップの縦長さ int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } , } ; void HYOUZI(void); void SYOKIKA(void); struct dousa{ int power; int flag; }; struct dousa jump; struct zahyou { int x,y; int img; int flag; int muki_y; int muki_x; int x1; int x2; int x3; int x4; int y1; int y2; int y3; int y4; }; struct zahyou haikei; struct charcter { int x,y; int img; int flag; }; struct charcter ziki; struct map; //初期化 void SYOKIKA(void){ jump.flag=0; ziki.x=100; ziki.y=100; ziki.img=LoadGraph("red_player.bmp"); } //背景 void HYOUZI(void){ int i,j; for( i = 0 ; i < MAP_HEIGHT ; i ++ ) { for( j = 0 ; j < MAP_WIDTH ; j ++ ) { if( MapData[ i ][ j ] == 0 ) { DrawBox( j * MAP_SIZE , i * MAP_SIZE , j * MAP_SIZE + MAP_SIZE , i * MAP_SIZE + MAP_SIZE , GetColor( 255 , 0 , 0 ) , TRUE ) ; } } } DrawGraph(ziki.x,ziki.y,ziki.img,TRUE); ScreenFlip(); } //動き void ugoki(void){ int OldX , OldY ; OldX = ziki.x ; OldY = ziki.y ; if (CheckHitKey(KEY_INPUT_RIGHT) == 1){ ziki.x=ziki.x+4; } if (CheckHitKey(KEY_INPUT_RIGHT) == 1) if (CheckHitKey(KEY_INPUT_Z) == 1) { ziki.x=ziki.x+8; } if (CheckHitKey(KEY_INPUT_LEFT) == 1){ ziki.x=ziki.x-4; } if (CheckHitKey(KEY_INPUT_LEFT) == 1) if (CheckHitKey(KEY_INPUT_Z) == 1) { ziki.x=ziki.x-8; } if(ziki.x>640){ ziki.x=-10; } if(ziki.x<-10){ ziki.x=640; } //ジャンプ jump.power-=1; ziki.y -=jump.power; if(ziki.y>400){ jump.power=0; ziki.y=400; jump.flag=0; } if (CheckHitKey(KEY_INPUT_DOWN) == 1 && jump.flag == 0){ jump.power=30; jump.flag=1; } if (CheckHitKey(KEY_INPUT_UP) == 1 && jump.flag == 0){ jump.power=20; jump.flag=1; } if( MapData[ ziki.x ][ ziki.y ] == 0 ) { ziki.x = OldX ; ziki.y = OldY ; } } int WINAPI WinMain ( HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { ChangeWindowMode(TRUE); if(DxLib_Init()==-1) { return -1; } SYOKIKA(); SetDrawScreen(DX_SCREEN_BACK); while(ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0){ HYOUZI(); ugoki(); ClearDrawScreen(); } DxLib_End(); return(0); } 分かる人がいたらぜひ教えてください(o_ _)o

  • 8パズル

    C++のプログラミングの勉強をしています。 ネットなどを利用して勉強してるところなんですが、わからないところがあります。 8パズルの探索プログラムなんですがネットで見つけたものは初期値が最初から入ってるものでした。 自分で入力して実行したいのですがそれがうまくいきません。 読み込んでるつもりなのですがメモリに記憶されてないみたいです。 変数がメイン文の中にない場合の入力がわかってないからできないのだと思います。 どなたか下のプログラムを最初に自分で値を入力する方法を教えていただけないでしょうか?? #include <stdio.h> #include <string.h> #include <time.h> #define TRUE 1 #define FALSE 0 #define GOAL 2 #define SIZE 9 /* 状態数 (9! / 2) */ #define MAX_STATE 181440 /* 隣接リスト */ const char adjacent[SIZE][5] = { 1, 3,-1,-1,-1, 0, 4, 2,-1,-1, 1, 5,-1,-1,-1, 0, 4, 6,-1,-1, 1, 3, 5, 7,-1, 2, 4, 8,-1,-1, 3, 7,-1,-1,-1, 4, 6, 8,-1,-1, 5, 7,-1,-1,-1, }; /* キュー */ char state[MAX_STATE + 1][SIZE]; /* +1 はワーク領域 */ char space_postion[MAX_STATE]; int prev_state[MAX_STATE]; /* 同一局面チェックテーブル */ char check_table[MAX_STATE * 2]; /* 初期状態 */ char init_state[SIZE] = { 8, 6, 7, 2, 5, 4, 3, 0, 1 }; char final_state[SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 0 }; /* 結果を出力 */ void print_answer( int n ) { int i, j; if( n != 0 ) print_answer( prev_state[n] ); for( i = 0; i < 3; i++ ){ for( j = 0; j < 3; j++ ){ printf("%d ", state[n][i * 3 + j] ); } printf("\n"); } printf("\n"); } /* 番号に変換 */ int change_number( char *board ) { char work[SIZE]; static int fact_table[SIZE] = { 40320, 5040, 720, 120, 24, 6, 2, 1, 0, }; int j, k, value = 0; memcpy( work, board, SIZE ); for( j = 0; j < SIZE - 1; j++ ){ value += fact_table[j] * work[j]; for( k = j + 1; k < SIZE; k++ ){ if( work[j] < work[k] ) work[k]--; } } return value; } /* 探索 */ void search( void ) { int front = 0, rear = 1; /* 初期化 */ memcpy( state[0], init_state, SIZE ); space_postion[0] = 7; prev_state[0] = -1; check_table[ change_number( init_state ) ] = TRUE; check_table[ change_number( final_state ) ] = GOAL; /* キューにデータがある間繰り返す */ while( front < rear ){ int s = space_postion[front]; int i, k, n; for( i = 0; (n = adjacent[s][i]) != -1; i++ ){ /* 状態をコピー */ memcpy( state[rear], state[front], SIZE ); /* 移動 */ state[rear][s] = state[rear][n]; state[rear][n] = 0; space_postion[rear] = n; prev_state[rear] = front; k = change_number( state[rear] ); if( check_table[k] == GOAL ){ /* 発見 */ print_answer( rear ); printf("状態数 %d 個\n", rear ); return; } else if( !check_table[k] ){ /* キューに登録 */ check_table[k] = TRUE; rear++; } } front++; } } int main() { int start, end; /* * 静的変数が 0 に初期化される場合は不用だが * 初期化することは悪いことではない。 */ memset( check_table, 0 , MAX_STATE * 2 ); start = clock(); search(); end = clock(); printf("時間 %d \n", end - start ); return 0; }

  • C言語 DXライブラリ

    #include <math.h> #include "DxLib.h" #define PI 3.1415926f int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); int Handle[3]; LoadDivGraph( "画像/弾01.png", 3, 3, 1, 14, 16, Handle ); float x=320,y=240,angle=0,speed=1; while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){ x += cos( angle ) * speed; DrawRotaGraph( x, y, 1.0, angle+PI/2, Handle[0], TRUE ); } DxLib_End(); return 0; } これを実行すると画像が右に動いていくのですが、なぜ動くのかわかりません。 x += cos( angle ) * speed; の部分はx=320+0*1という事だと思っているのですが、これだとxはずっと320のままで画像が右に動いて行かないと思います。 教えてくださいm(_ _ )m

  • 15パズルの作り方が分かりません!

    ご閲覧ありがとうございます。 実は大学で、「15パズル」のプログラムを作れという課題が出たのですが、上手く動きません。プログラミングに関してはほぼ初心者で、どこがどうまちがっているのか、どのように直したらきちんと動くのかが全く分かりません・・・。!il||li(っω-`。)il||li 助けて下さい!お願いします(´;ω;`) 以下が私がいじっていたプログラムです <html> <head> <title>15パズル</title> <script type="text/javascript"> // 初期盤面を生成するプロシージャ function gstart() { var checked=new Array(15); // 「使用済み」のチェック用 var i, j; // カウンタ var n; // パネル番号 var p; // パリティ計算用 var parity = false; // 奇順列の状態 var flag; // その数が使用済みかどうか while(parity==false){ // 奇順列の間は繰り返す for(i=0;i<16;i++) checked[i]=false; // すべて未使用状態化 for(i=0;i<16;i++){ // パネル番号を順に決める flag = false; // 最初はパネル番号未決定とする while(flag==false){ // 未使用状態の間は繰り返す n = Math.floor(Math.random()*16); // nに0~8の乱数を設定 if(checked[n]==false){ // nが未使用なら pnum[i] = n; // i番目のパネルのパネル番号をn checked[n] = true; // nを使用済みにする flag = true; // パネル番号決定 } } } p = 0; // 偶順列か奇順列かの計算 for(i=0;i<15;i++){ for(j=i+1;j<16;j++){ if(pnum[i]!=0 && pnum[j]!=0){ if(pnum[i]>pnum[j]) p++; // 互換の数を勘定 } } } if((p%2)==0) parity=true; // 互換の数が偶数なら偶順列 } for(i=0;i<16;i++){ if(pnum[i]==0) document.forms[0].elements[i].value= ""; else document.forms[0].elements[i].value= pnum[i]; } } function move(obj) { var i,j,k; for(j=0;j<16;j++) if(obj.value==pnum[j]) i=j; // objのパネル位置を調べる for(j=-4;j<2;j=j+3){ // 上下左右の隣接パネルの調査 k = i+j; if((k>=0&&k<16) && ((Math.floor(i/2)==Math.floor(k/2))||(i%2==k%2))){ if(pnum[k]==0){ // 隣が空なら入れ替え pnum[k] = pnum[i]; document.forms[0].elements[k].value= pnum[k]; pnum[i] = 0; document.forms[0].elements[i].value= ""; } } } } </script> </head> <body> <h1>15パズル</h1> [開始]ボタンクリックでスタート。 <form id="Form1"> <script type="text/javascript"> var i; var s; var pnum=new Array(16); // パネル番号記憶用 for(i=0;i<16;i++){ document.write("<input style='width:30px; height:30px;' type='button' value='"+(i+1)+"' onClick='move(this)'>"); if((i+1)%4==0) document.write("<br />"); } document.forms[0].elements[15].value= ""; </script> <br /> <input style="width:60px; height:30px;" type="button" value="開始" onClick="gstart()"><br /> </form> </body> </html>

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }

  • DXライブラリでの画像表示

    ゲームプログラミング初心者です。 DXライブラリを用いて画像を表示させようと以下のプログラムを組んで実行してみたのですが、ウィンドウは表示されるのに画像が表示されません。 使用しているのはBorland C++ 5.5.,BCC Developer,DXライブラリです。 ちゃんと画像もプロジェクトファイルの中に入っていると思います。 OSはwindows8です。 考えられる原因を教えてもらえないでしょうか。 #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode(TRUE); if( DxLib_Init() == -1 ) { return -1; } LoadGraphScreen(0,0,"image.png",TRUE); WaitKey(); DxLib_End(); return 0; }

  • 画素数の計算について

    現在BMPで640×480の画像の左右両端の80画素ずつ切り取り480×480の画像を作って さらに、8×8のブロックに分けて各ブロックごとの光の強度をだすプログラミングをつくっているのですが、 (各ブロックはそれぞれ[1][1]~[8][8]となづけています) [1][8]、[2][8]、[3][8]…と8がつくブロックの強度がすべて0になってしまいます。 いろいろと考えてみたのですが、どうにもうまくいかずに悩んでおります。 助けていただけませんでしょうか? よろしくおねがいします。 おそらく、ここらへんがおかしいと思う部分をのせておきます。 /* 640側の左右80ずつ切り取り、480×480の正方形の画像にする */ int bunkatsu(BMP *rp,RESULT *res){ int x,y; int a=0; for(y = 0;y < rp->Bmpi.biHeight; y++){ for(x = 80;x < rp->Bmpi.biWidth - 80; x++){ res->data[a] = rp->blue[y * rp->Bmpi.biWidth + x] + rp->green[y * rp->Bmpi.biWidth + x] + rp->red[y * rp->Bmpi.biWidth + x]; a++; } } return 0; } /* 480×480を8×8のブロックに分け(60×60が64ブロック) 、各ブロックの明るさを計算する */ int keisan(BMP *rp,RESULT *res){ int b,c; int i=0,j=0; int x,y; for(y = 0;(y+60) < rp->Bmpi.biHeight;y+=60){ for(x = 0;(x + 60) < (rp->Bmpi.biWidth - 160);x+=60){ for(b = 0;b < 60;b++){ for(c = 0; c < 60;c++){ res->akarusa[i][j]+=res->data[(y + b) * rp->Bmpi.biWidth +(x + c)]; } } j++; } j=0; i++; } max(res); return 0; } /* 一番明るいブロックの特定 */ RESULT *max(RESULT *res){ int MAX1=0; int MAX2=0; int i=0; int j=0; for(i = 0;i < 8;i++){ for(j = 0;j < 8;j++){ printf("[%d][%d]=%d ",i+1,j+1,res->akarusa[i][j]); if(MAX1 < res->akarusa[i][j]){ MAX1 = res->akarusa[i][j]; res->maxi=i; res->maxj=j; } } printf("\n"); } printf("一番明るいブロックは[%d][%d]です\n",res->maxi + 1,res->maxj + 1); return 0; } です。よろしくおねがいします。

  • 携帯用パズルのシャッフルについて

    こんにちは。 携帯用のパズルゲームを作っているのですが、シャッフルがうまくできません。 私の持っている本(フラッシュ8用)を読むと、ランダムな数字を先に作ってからピースに置き換えて ステージに配置すると書いてあります。 携帯用に書き換えなければいけないのですがさっぱり見当もつきません。。 ランダムは for(i = 0; i < 16; i++){ while(1){ eval("p" add i) = random(16); flag = 0; for(j = 0; j < i; j++){ if(eval("p" add i) == eval("p" add j)) flag = 1; } if(flag == 0) break; } } このように書きました。 パズルのピースにはそれぞれMC0~MC15というインスタンス名がつけてあります。 ステージには各マスにp0~p15とつけてあります。 パズルピースは縦40ピクセル横40ピクセルの正方形で 縦に4枚横に4枚ならんでいるようなステージです。 全くの初心者なので、参考になるサイトなどもあれば 教えていただけると助かります。 よろしくお願いします。

  • Javaで美術館パズルを作ろうとしたのですが、、、

    Java言語(eclipse)を使い美術館パズル(http://www.nikoli.com/ja/puzzles/bijutsukan/)を作成しようと思い作っていき、柱や番号をframeやbuttonとしておき、クリックしたらそこにランプが置けるか判定し、可能ならば緑のランプを点灯させるところまでは何とかプログラミングできました。しかしその後、その置いたランプから十字方向に(柱にぶつかるまで)黄色いランプを点灯させる良いプログラミングが思い浮かびません。1から作り直すようなアイディアでも構いませんので、何かいい方法があれば、ぜひ教えてください。以下に自分の悩んでいる部分を載せておきます。↓ class MuseumGame extends JFrame implements ActionListener { JPanel panel; MyButton[][] button; MyButton[] lamp; MyButton[][] lamp2; int lamp_count; MuseumGame(GameData data) { setTitle("美術館パズル"); setSize(500,500); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); panel = new JPanel(); add(panel); panel.setLayout(new GridLayout(data.w,data.h)); button = new MyButton[data.h][data.w]; for(int i=0; i<data.h; i++) { for(int j=0; j<data.w; j++) { button[i][j] = new MyButton(i,j); button[i][j].addActionListener(this); panel.add(button[i][j]); } } for(int i=0; i<data.n; i++) { int h = data.wall[i][0]; int w = data.wall[i][1]; int c = data.wall[i][2]; button[h][w].setWall(c); } lamp = new MyButton[data.h*data.w]; lamp_count = 0; } public void actionPerformed(ActionEvent ae) { MyButton button = (MyButton) ae.getSource(); if( button.isWall ) return; if( button.getText() == "■" ) { button.setText(""); } else { if( button.getBackground() == Color.WHITE ) { lampAdd(button); } else { lampDelete(button); } } } void lampAdd(MyButton button) { // 本当にそこにランプが置けるか判定する lamp[lamp_count++] = button; button.setBackground(Color.GREEN); // 柱の数値をチェックして影響を表示する // 四方の通路を黄色にする // 上を解決するいいアイディアをお願いします、、、

    • ベストアンサー
    • Java