質問なんですが・・・
Posted: 2007年10月26日(金) 22:31
インベーダーゲームをつくりたいのですが、
敵の動きのプログラムが分からないです。
教えていただけませんか?
敵の動きのプログラムが分からないです。
教えていただけませんか?
まずゲームだと思わずにコンソール画面で処理出来るかどうか試してみてください。
int x,y;
の変数を用意し、増減フラグ
int flag;
を用意して、座標(x,y)を考えます。
(0,0)→(1,0)→(2,0)→(3,0)
↓
(1,1)←(2,1)←(3,1)←(4,1)
↓
(0,2)→(1,2)→(2,2)→(3,2)
このような動きをさせたいなら最初増減フラグはオンにしておきます。
増減フラグがオンの時はx座標が増加します。4まで来たら増減フラグはオフにします。
増減フラグが入れ替わる時、yが1増加します。
オフにしている最中はxは減少します。0まで来ると増減フラグはオンになります。
これを実装すればいいのではないでしょうか?
上記のような座標がコンソールで出せるかやってみてください。#include <stdio.h>
int main(){
int x=0,y=0,flag=1;
while(y<5){
printf("(%d,%d)\n",x,y);
x += flag; //x座標を増減
if(x>=4 || x<=0){ //範囲の外まで来たら
flag*=-1;//フラグを入れ替える
y++; //y座標増加
}
}
return 0;
} #include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int x=0,y=0,flag=1;
char Key[256];
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
SetDrawScreen( DX_SCREEN_BACK ); //裏画面に設定
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されていない
DrawBox(x*30,y*30,(x+1)*30,(y+1)*30,GetColor(255,255,255),TRUE);//四角形描画
x += flag;
if(x>=10 || x<=0){
flag*=-1;
y++;
}
if(y>10)break;
ScreenFlip(); //裏画面反映
WaitTimer(100);//0.1秒待つ
}
DxLib_End();
return 0;
} (0,0)→(1,0)→(2,0)→(3,0)
↓
(1,1)←(2,1)←(3,1)←(4,1)
↓
(0,2)→(1,2)→(2,2)→(3,2)
これを下のようにできませんか?
(0,0)→(1,0)→(2,0)→(3,0)→(4,0)
↓
(0,1)→(1,1)←(2,1)←(3,1)←(4,1)
↓
(0,2)→(1,2)→(2,2)→(3,2)→(4,2) #include"DxLib.h"
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
int x=320-16,y=240-16;//座標の変数
int x_flag=0,y_flag=0;//上下左右に動いているかのフラグ。
int grhandle; //グラフィックハンドル。
int begin; //最初の基準秒数を記録する変数。
ChangeWindowMode(TRUE);
SetMainWindowText("sample");
SetOutApplicationLogValidFlag(FALSE);
if(DxLib_Init()==-1)return -1;
SetDrawScreen(DX_SCREEN_BACK);
grhandle=LoadGraph("shikaku.bmp");
begin=GetNowCount();
while(ProcessMessage()!=-1){
DrawGraph(x,y,grhandle,FALSE);
DrawFormatString(0,0,GetColor(255,255,255),"(%d,%d)",x,y);
ScreenFlip();
ClearDrawScreen();
if(CheckHitKey(KEY_INPUT_ESCAPE))break;//エスケープキーが押されたら終了。
//動いてから1秒経ったら動く方向を乱数で取得。
if(GetNowCount()-begin>1000){
x_flag=GetRand(2)-1;
y_flag=GetRand(2)-1;
begin=GetNowCount();
}
//x_flagは上に動くなら-1、変化なしなら0、下へ動くなら1を指し示す。
x += x_flag*2;
//y_flagも右なら-1、動かないなら0、左なら1を指す。
y += y_flag*2;
if(x<0)x=0; //X座標が0より下ならば、見えないので強制的に0にする。
if(x>640-32)x=640-32;//X座標が640-32より上ならば、同じ理由で640-32にする。
//Y座標も同じように修正する。
if(y<0)y=0;
if(y>480-32)y=480-32;
}
DxLib_End();
return 0;
}
//基本的な部分の説明は省略させていただきました。
これはサンプルプログラムです、さっきのソースコードをこれに置き換えて、コンパイルしなおすと、さっきとは動きが変わります。#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int x=1,y=0,dir=0;
char Key[256];
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
SetDrawScreen( DX_SCREEN_BACK ); //裏画面に設定
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されていない
DrawBox(x*30,y*30,(x+1)*30,(y+1)*30,GetColor(255,255,255),TRUE);
if(x>=10 || x<=0)//外側まで来たら
dir = (dir+1)%4;//方向転換
if (dir==0)//右方向なら
x++;//右へ
else if(dir==1 || dir==3)//下方向なら
y++;//下へ
else if(dir==2)//左方向なら
x--;//左へ
if(y>10)break;
ScreenFlip();
WaitTimer(100);
}
DxLib_End();
return 0;
}#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int x=1,y=0,dir=0;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,1}; char Key[256];
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
SetDrawScreen( DX_SCREEN_BACK ); //裏画面に設定
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されていない
DrawBox(x*30,y*30,(x+1)*30,(y+1)*30,GetColor(255,255,255),TRUE);
if(x>=10 || x<=0)//外側まで来たら
dir = (dir+1)%4;//方向転換
x+=dx[di[/url]; y+=dy[di[/url];
if(y>10)break;
ScreenFlip();
WaitTimer(100);
}
DxLib_End();
return 0;
}ソースコードのように投稿するときれいに表示されると思います。
#include "DxLib.h"
typedef struct{
int x,y;
}xy_t;
int img;
xy_t xy[3][4];//敵の座標構造体
void set(){//左上の敵の座標[0][0]をもとに、敵の座標を決定
int i,j;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
xy[j].x=xy[0][0].x+j;
xy[j].y=xy[0][0].y+i;
}
}
}
void graph(){//描画
int i,j;
//四角形描画
for(i=0;i<10;i++)
for(j=0;j<10;j++)
DrawBox(j*20,i*20,(j+1)*20,(i+1)*20,GetColor(255,255,255),FALSE);
//敵描画
for(i=0;i<3;i++)
for(j=0;j<4;j++)
DrawGraph(xy[j].x*20,xy[j].y*20,img,FALSE);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int dir=0,dx[4]={1,0,-1,0},dy[4]={0,1,0,1};
char Key[256];
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //初期化処理
SetDrawScreen( DX_SCREEN_BACK ); //裏画面に設定
xy[0][0].x=1;
xy[0][0].y=0;
img = LoadGraph("img.PNG");
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されていない
set();
graph();
if(xy[0][0].x<=0 || xy[0][3].x>=9)//外側まで来たら
dir = (dir+1)%4;//方向転換
xy[0][0].x+=dx[di[/url]; xy[0][0].y+=dy[di[/url];
if(xy[0][0].y>7)break;
ScreenFlip();
WaitTimer(500);
}
DxLib_End();
return 0;
} #include <windows.h>
#include <stdio.h>
const char* szFileName = "conf.dat";
int CheckConf()
{
FILE* fp = NULL;
char ret = 0;
fp = fopen(szFileName, "rb");
if (fp != NULL) {
fread(&ret, 1, sizeof(char), fp);
fclose(fp);
}
return ret;
}
void SaveConf()
{
FILE* fp = NULL;
fp = fopen(szFileName, "wb");
if (fp != NULL) {
char flg = 1;
fwrite(&flg, 1, sizeof(char), fp);
fclose(fp);
}
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
if (CheckConf() == 0) {
int ret = MessageBox(NULL, "はい:通常起動\nいいえ:アプリ終了\nキャンセル:以降このメッセージボックスを表示しないに該当", "テスト", MB_YESNOCANCEL);
if (ret == IDNO) {
// いいえ
return 0;
} else if (ret == IDCANCEL) {
// キャンセル(以降表示しないに該当)
SaveConf();
}
}
// 通常のアプリプログラム
MessageBox(NULL, "通常のアプリ", "", MB_OK);
return 0;
}