質問なんですが・・・
-
tk-xleader
Re:質問なんですが・・・
>リクさん
とりあえず、ある画像をウィンドウ内で下に動かすようなプログラムは組めますか?
敵の動きというのは、アニメーションの考え方になります。そこで、画像の描画位置を少しずつ動かしていく事で表現できます。
ということは、座標を少しずつ変化させていく事で、画像を動かせます。
とりあえず、ある画像をウィンドウ内で下に動かすようなプログラムは組めますか?
敵の動きというのは、アニメーションの考え方になります。そこで、画像の描画位置を少しずつ動かしていく事で表現できます。
ということは、座標を少しずつ変化させていく事で、画像を動かせます。
-
リク
Re:質問なんですが・・・
回答ありがとうございます。
画像を右なら右、左なら左みたいに
一方通行ならプログラムはできるんですが、
インベーダーゲームみたいに
→→→→→↓
↓←←←←←
みたいなプログラムができないのです。
画像を右なら右、左なら左みたいに
一方通行ならプログラムはできるんですが、
インベーダーゲームみたいに
→→→→→↓
↓←←←←←
みたいなプログラムができないのです。
-
管理人
Re:質問なんですが・・・
まずゲームだと思わずにコンソール画面で処理出来るかどうか試してみてください。
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まで来ると増減フラグはオンになります。
これを実装すればいいのではないでしょうか?
上記のような座標がコンソールで出せるかやってみてください。-
管理人
Re:質問なんですが・・・
もし言っている意味がわからなければ以下のサンプルを参考にしてください。
アルゴリズムは上のものをそのまま実装しただけです。
アルゴリズムは上のものをそのまま実装しただけです。
#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;
} -
管理人
Re:質問なんですが・・・
DXライブラリをお使いでしたら以下のサンプルもどうぞ。
#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;
} -
リク
Re:質問なんですが・・・
回答ありがとうございます。
DXライブラリをつかっているので、下のプログラムを実行してみました。
思っているような動きをしたのはしたのですが、
さきほど管理人さんがおっしゃられたものなのですが、
DXライブラリをつかっているので、下のプログラムを実行してみました。
思っているような動きをしたのはしたのですが、
さきほど管理人さんがおっしゃられたものなのですが、
(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) -
tk-xleader
Re:質問なんですが・・・
Dxライブラリ使用だとしたら、画面の座標は左上を(0,0)として、右に行くほどx座標がが増加し、下に行くほどy座標が増加します。
つまり、int型変数で上下左右の動きを制御する変数を用意し、その変数の値によって、座標を動かすという考え方になります。
とりあえず、サンプルプログラムを作ってみましたのでlzhで添付します。
つまり、int型変数で上下左右の動きを制御する変数を用意し、その変数の値によって、座標を動かすという考え方になります。
とりあえず、サンプルプログラムを作ってみましたのでlzhで添付します。
-
リク
Re:質問なんですが・・・
管理人さんのとtkmakwins15のを両方を合体させて自分なりにプログラムを書いてみました。
こんな感じでいいでしょうか?
#include"DxLib.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int x=0,y=0;//座標の変数
int x_flag=0,y_flag=0;//上下左右に動いているかのフラグ。
int grhandle; //グラフィックハンドル。
int flg = 3;
if(ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init()==-1) return -1;
SetDrawScreen(DX_SCREEN_BACK);
grhandle=LoadGraph("shikaku.bmp");
while(ProcessMessage()!=-1){
DrawGraph(x,y,grhandle,FALSE);
ScreenFlip();
ClearDrawScreen();
x += flg;
if(x==0 || x==300){
flg *= -1;
y += 5;
}
}
DxLib_End();
return 0;
}
こんな感じでいいでしょうか?
#include"DxLib.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int x=0,y=0;//座標の変数
int x_flag=0,y_flag=0;//上下左右に動いているかのフラグ。
int grhandle; //グラフィックハンドル。
int flg = 3;
if(ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init()==-1) return -1;
SetDrawScreen(DX_SCREEN_BACK);
grhandle=LoadGraph("shikaku.bmp");
while(ProcessMessage()!=-1){
DrawGraph(x,y,grhandle,FALSE);
ScreenFlip();
ClearDrawScreen();
x += flg;
if(x==0 || x==300){
flg *= -1;
y += 5;
}
}
DxLib_End();
return 0;
}
-
tk-xleader
Re:質問なんですが・・・
方向を勝手に変えるには、乱数を使うとよいでしょう。
考え方は、X座標が右に変化する時は-、左に動く時は+、動かなければ0とすると、それに1フレームで動かしたいドット数をかけると、その方向に変化するということです。
#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;
}
//基本的な部分の説明は省略させていただきました。
これはサンプルプログラムです、さっきのソースコードをこれに置き換えて、コンパイルしなおすと、さっきとは動きが変わります。考え方は、X座標が右に変化する時は-、左に動く時は+、動かなければ0とすると、それに1フレームで動かしたいドット数をかけると、その方向に変化するということです。
-
管理人
Re:質問なんですが・・・
それなら方向を決める変数を用意して、if文で制御してもいいのではないでしょうか?
方向を示す
int dir=0;
を用意します。
dir=0 は右方向に進む
dir=1 は下方向に進む
dir=2 は左方向に進む
dir=3 は下方向に進む
これを繰り返したらいいですよね?これを繰り返すには
dir = (dir+1)%4;
でOKです。
この変数に格納されている指示通り動かせばいいでしょう。
方向を示す
int dir=0;
を用意します。
dir=0 は右方向に進む
dir=1 は下方向に進む
dir=2 は左方向に進む
dir=3 は下方向に進む
これを繰り返したらいいですよね?これを繰り返すには
dir = (dir+1)%4;
でOKです。
この変数に格納されている指示通り動かせばいいでしょう。
#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;
}-
管理人
Re:質問なんですが・・・
ifを並べるのがいやならこんな風にスマートにも出来ます。
黄色の部分が変更点です。
黄色の部分が変更点です。
#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;
}-
リク
Re:質問なんですが・・・
回答ありがとうございます。
プログラムはとても分かりやすかったです。
続けて質問したいのですが、
縦に3匹、横4匹、計12匹いるようなものを
全部まとめてさきほどと同じように動かすにはどうすればいいですか?
プログラムはとても分かりやすかったです。
続けて質問したいのですが、
縦に3匹、横4匹、計12匹いるようなものを
全部まとめてさきほどと同じように動かすにはどうすればいいですか?
-
管理人
Re:質問なんですが・・・
全部聞いてしまったらプログラムを作る楽しみが減りませんか??
リクさんがよいのでしたらサンプル作りますが、一応基礎があるので、はってんさせてみてはいかがでしょうか?
上記サンプルを応用するとすれば、12匹のどれかが端にさしかかったら方向転換すればいいんですよね。
xy座標は12匹全部違うはずですが、端にくる敵はかわらないはずですから、その敵を判定材料にすればよいでしょう。
緑が左端、黄色が右端にさしかかったことを判定させればいいでしょう。
□■■■■□□
□■■■■□□
□■■■■□□
□□□□□□□
□□■■■■□
□□■■■■□
□□■■■■□
□□□□□□□
□□□■■■■
□□□■■■■
□□□■■■■
□□□□□□□
□□□□□□□
□□□■■■■
□□□■■■■
□□□■■■■
□□□□□□□
□□■■■■□
□□■■■■□
□□■■■■□
□□□□□□□
□■■■■□□
□■■■■□□
□■■■■□□
□□□□□□□
■■■■□□□
■■■■□□□
■■■■□□□
リクさんがよいのでしたらサンプル作りますが、一応基礎があるので、はってんさせてみてはいかがでしょうか?
上記サンプルを応用するとすれば、12匹のどれかが端にさしかかったら方向転換すればいいんですよね。
xy座標は12匹全部違うはずですが、端にくる敵はかわらないはずですから、その敵を判定材料にすればよいでしょう。
緑が左端、黄色が右端にさしかかったことを判定させればいいでしょう。
□■■■■□□
□■■■■□□
□■■■■□□
□□□□□□□
□□■■■■□
□□■■■■□
□□■■■■□
□□□□□□□
□□□■■■■
□□□■■■■
□□□■■■■
□□□□□□□
□□□□□□□
□□□■■■■
□□□■■■■
□□□■■■■
□□□□□□□
□□■■■■□
□□■■■■□
□□■■■■□
□□□□□□□
□■■■■□□
□■■■■□□
□■■■■□□
□□□□□□□
■■■■□□□
■■■■□□□
■■■■□□□
-
tk-xleader
Re:質問なんですが・・・
長方形型なのであれば、その長方形ひとつで考えるという方法もあります。描画は別として、
後、余談ですが、リクさん。ソースコード投稿時はそれらを
後、余談ですが、リクさん。ソースコード投稿時はそれらを
ソースコードのように投稿するときれいに表示されると思います。
-
リク
Re:質問なんですが・・・
回答ありがとうございます。
勉強のつもりでやっているので、サンプルプログラムを載せていただいてもかまわないです。
一応今、自分で作っているプログラムでは32ピクセルの画像を2つ使って、
動かしているところです。
敵を配列にいれると簡単だと聞いたのですが
配列をつかってするにはどうすればよいですか?
勉強のつもりでやっているので、サンプルプログラムを載せていただいてもかまわないです。
一応今、自分で作っているプログラムでは32ピクセルの画像を2つ使って、
動かしているところです。
敵を配列にいれると簡単だと聞いたのですが
配列をつかってするにはどうすればよいですか?
-
管理人
Re:質問なんですが・・・
一番左上の敵のみ座標を移動させています。
敵の間隔は常に等間隔で、決まったフォーマットなので、一匹敵の座標が決まるだけで全ての
座標が決められる事を利用しました。
プロジェクトファイルに
http://dixq.net/img/img.PNG
を保存して以下のプログラムを実行してください。
なお、ソースコードを投稿する時や、半角空白を使って文字で図を表したい時は
プレタグと言うものを利用してください。
これは<pre>というタグと</pre>というタグで囲む事で文字が等間隔、空白も表示されるようになります。
<>これは半角で入力してください。タグは記事には表示されません。
敵の間隔は常に等間隔で、決まったフォーマットなので、一匹敵の座標が決まるだけで全ての
座標が決められる事を利用しました。
プロジェクトファイルに
http://dixq.net/img/img.PNG
を保存して以下のプログラムを実行してください。
なお、ソースコードを投稿する時や、半角空白を使って文字で図を表したい時は
プレタグと言うものを利用してください。
これは<pre>というタグと</pre>というタグで囲む事で文字が等間隔、空白も表示されるようになります。
<>これは半角で入力してください。タグは記事には表示されません。
#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;
} -
リク
Re:質問なんですが・・・
回答ありがとうございます。
ご返事送れてすいません。
自機は自分でがんばりたいと思います。
でも当たり判定は悩みそうなので
分からなかったら、また質問させてください。
ご返事送れてすいません。
自機は自分でがんばりたいと思います。
でも当たり判定は悩みそうなので
分からなかったら、また質問させてください。
-
リク
Re:質問なんですが・・・
一つ前の質問は解決しました。すいません。
当たり判定もできたのですが、
敵にあたって存在フラグを0にして、
敵を画面から消すことまでできたのですが、
その画面から消した敵のところに
弾を打つとそこで弾が消えてしまいます。
画面から消えても敵がいるみたいな感じになっています。
どうやって直せばいいでしょうか?
当たり判定もできたのですが、
敵にあたって存在フラグを0にして、
敵を画面から消すことまでできたのですが、
その画面から消した敵のところに
弾を打つとそこで弾が消えてしまいます。
画面から消えても敵がいるみたいな感じになっています。
どうやって直せばいいでしょうか?
-
リク
Re:質問なんですが・・・
質問なんですが、
インベーダーの敵がランダムに1発ずつ攻撃してくる
方法が分からないです。
教えていただけませんか?
GetRandで乱数を発生させてやったのですが、
処理が早すぎて一瞬だけしか画面に表示されないのです。
インベーダーの敵がランダムに1発ずつ攻撃してくる
方法が分からないです。
教えていただけませんか?
GetRandで乱数を発生させてやったのですが、
処理が早すぎて一瞬だけしか画面に表示されないのです。
-
たまー
Re:画面の操作にて、
ダイアログボックスというのは分かってるのですが、
それで、一度決定するともう表示しなくなるようにするには
どうすればいいかと思い書きました。その場合だと、
アプリを落とした時、「もう表示しない」を選択しておくと
アプリ終了後もどこかにそのデータを残しとかなければいけないし、
立ちあげたときにはダイアログBOXより先にそっちを見に行って、
チェックの確認と、このようになると思うのですがその
やり方をしりたかったのです^^
よろしくお願いします。
それで、一度決定するともう表示しなくなるようにするには
どうすればいいかと思い書きました。その場合だと、
アプリを落とした時、「もう表示しない」を選択しておくと
アプリ終了後もどこかにそのデータを残しとかなければいけないし、
立ちあげたときにはダイアログBOXより先にそっちを見に行って、
チェックの確認と、このようになると思うのですがその
やり方をしりたかったのです^^
よろしくお願いします。
-
GPGA
Re:画面の操作にて、
普通にセーブファイルを作ってフラグを書き込めばいいと思います。
以下サンプル。
以下サンプル。
#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;
} -
たまー
Re:画面の操作にて、
回答ありがとうございます^^
GPGAさんのかかれたものを参考にさせていただきます^^
まだできていませんが、解決できそうなので助かりました~
ありがとうございます。
GPGAさんのかかれたものを参考にさせていただきます^^
まだできていませんが、解決できそうなので助かりました~
ありがとうございます。