自機に弾を撃たせたいです。
自機に弾を撃たせたいです。
初めまして、崎島といいます。
今回、自分の趣味ということで、初めてのゲームを作りたいなと思い、東方二次創作でのゲームを作っています。物語等は考え済みです。
事前に、c言語の入門書は読み、DXライブラリの使い方も、見ながらではありますが何とかできます。
本題ですが、今、http://akaguro.jp/stg/stg_index.shtmlを参 ... て消してしまいました。
とりあえず、書いたコードはそのまま載せます。
code
#include "DxLib.h"
//プロトタイプ宣言//
void init_back_img(void);
void to_center(void);
void draw_back(void);
void draw_variable(void);
int get_key(void);
void init_player(void);
void move_player(void);
void draw_player(void);
struct PLAYER{
double x, y;
double draw_x, draw_y;
};
struct PLAYER p1;
int key[256];
int counter;
double back_img_y;
int back_img1;
int back_img2;
int gamecount;
int Color_White;
//こっから本文//
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
ChangeWindowMode(TRUE);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
init_player();
init_back_img();
while (ScreenFlip() == 0 && ProcessMessage() == 0
&& ClearDrawScreen() == 0 && get_key() == 0){
/*ここにプログラムを書く。主に関数呼び出し*/
to_center();
draw_back();
draw_player();
draw_variable();
move_player();
gamecount++;
back_img_y++;
}
DxLib_End();
return 0;
}
//以下、関数//
void init_back_img(){
back_img1 = LoadGraph("test.png");
back_img2 = LoadGraph("test.png");
back_img_y = 0;
Color_White = GetColor(255, 255, 255);
}
void init_player(){
p1.x = 0;
p1.y = -200;
p1.draw_x = 0;
p1.draw_y = 0;
}
void move_player(){
if (key[KEY_INPUT_RIGHT] >= 1){
p1.x = p1.x + 3;
if (p1.x < 0 && key[KEY_INPUT_A]) p1.x = 0;//瞬間移動っぽいもの
if (p1.x > 305)p1.x = 305;
}
if (key[KEY_INPUT_DOWN] >= 1){
p1.y = p1.y - 3;
if (p1.y < -220)p1.y = -220;
}
if (key[KEY_INPUT_LEFT] >= 1){
p1.x = p1.x - 3;
if (p1.x > 0 && key[KEY_INPUT_A])p1.x = 0;//瞬間移動っぽいもの
if (p1.x < -330)p1.x = -330;
}
if (key[KEY_INPUT_UP] >= 1){
p1.y = p1.y + 3;
if (p1.y > 240)p1.y = 240;
}
}
void draw_player(){
int Handle1;
int Handle2;
int Handle3;
Handle1 = LoadGraph("player_reimu1.png");
Handle2 = LoadGraph("player_reimu2.png");
Handle3 = LoadGraph("player_reimu3.png");
if (CheckHitKey(KEY_INPUT_LEFT) == 0 && CheckHitKey(KEY_INPUT_RIGHT) == 0)
{
// 右と左が押されていない(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else if (CheckHitKey(KEY_INPUT_LEFT) == 1 && CheckHitKey(KEY_INPUT_RIGHT) == 1){
// 右と左が押されている(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else{
// 右か左が押されている(通常グラ非表示)//
}
if (key[KEY_INPUT_RIGHT] >= 1 && key[KEY_INPUT_LEFT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle2, TRUE);
}//左靡きグラ表示//
if (key[KEY_INPUT_LEFT] >= 1 && key[KEY_INPUT_RIGHT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle3, TRUE);
}//右靡きグラ表示//
}
void to_center(){
p1.draw_x = p1.x + 320;
p1.draw_y = ((-1)*p1.y) + 240;
}
void draw_back(){
DrawGraph(0, back_img_y, back_img1, TRUE);
DrawGraph(0, back_img_y - 480, back_img2, TRUE);
DrawLine(0, 240, 640, 240, Color_White);
DrawLine(320, 0, 320, 480, Color_White);
DrawFormatString(320, 240, Color_White, "(0,0)");
if (back_img_y > 480){
back_img_y = 0;
}
}
void draw_variable(){
DrawFormatString(440, 440, Color_White, "gamecount=%d", gamecount);
}
int get_key(){
char keys[256];
GetHitKeyStateAll(keys);
for (int i = 0; i < 256; i++){
if (keys != 0){
key++;
}
else{
key = 0;
}
}
return 0;
}
/code
使用している環境は、
os:windows 8.1
コンパイラ名:Visual Studio 2013
今回、自分の趣味ということで、初めてのゲームを作りたいなと思い、東方二次創作でのゲームを作っています。物語等は考え済みです。
事前に、c言語の入門書は読み、DXライブラリの使い方も、見ながらではありますが何とかできます。
本題ですが、今、http://akaguro.jp/stg/stg_index.shtmlを参 ... て消してしまいました。
とりあえず、書いたコードはそのまま載せます。
code
#include "DxLib.h"
//プロトタイプ宣言//
void init_back_img(void);
void to_center(void);
void draw_back(void);
void draw_variable(void);
int get_key(void);
void init_player(void);
void move_player(void);
void draw_player(void);
struct PLAYER{
double x, y;
double draw_x, draw_y;
};
struct PLAYER p1;
int key[256];
int counter;
double back_img_y;
int back_img1;
int back_img2;
int gamecount;
int Color_White;
//こっから本文//
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
ChangeWindowMode(TRUE);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
init_player();
init_back_img();
while (ScreenFlip() == 0 && ProcessMessage() == 0
&& ClearDrawScreen() == 0 && get_key() == 0){
/*ここにプログラムを書く。主に関数呼び出し*/
to_center();
draw_back();
draw_player();
draw_variable();
move_player();
gamecount++;
back_img_y++;
}
DxLib_End();
return 0;
}
//以下、関数//
void init_back_img(){
back_img1 = LoadGraph("test.png");
back_img2 = LoadGraph("test.png");
back_img_y = 0;
Color_White = GetColor(255, 255, 255);
}
void init_player(){
p1.x = 0;
p1.y = -200;
p1.draw_x = 0;
p1.draw_y = 0;
}
void move_player(){
if (key[KEY_INPUT_RIGHT] >= 1){
p1.x = p1.x + 3;
if (p1.x < 0 && key[KEY_INPUT_A]) p1.x = 0;//瞬間移動っぽいもの
if (p1.x > 305)p1.x = 305;
}
if (key[KEY_INPUT_DOWN] >= 1){
p1.y = p1.y - 3;
if (p1.y < -220)p1.y = -220;
}
if (key[KEY_INPUT_LEFT] >= 1){
p1.x = p1.x - 3;
if (p1.x > 0 && key[KEY_INPUT_A])p1.x = 0;//瞬間移動っぽいもの
if (p1.x < -330)p1.x = -330;
}
if (key[KEY_INPUT_UP] >= 1){
p1.y = p1.y + 3;
if (p1.y > 240)p1.y = 240;
}
}
void draw_player(){
int Handle1;
int Handle2;
int Handle3;
Handle1 = LoadGraph("player_reimu1.png");
Handle2 = LoadGraph("player_reimu2.png");
Handle3 = LoadGraph("player_reimu3.png");
if (CheckHitKey(KEY_INPUT_LEFT) == 0 && CheckHitKey(KEY_INPUT_RIGHT) == 0)
{
// 右と左が押されていない(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else if (CheckHitKey(KEY_INPUT_LEFT) == 1 && CheckHitKey(KEY_INPUT_RIGHT) == 1){
// 右と左が押されている(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else{
// 右か左が押されている(通常グラ非表示)//
}
if (key[KEY_INPUT_RIGHT] >= 1 && key[KEY_INPUT_LEFT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle2, TRUE);
}//左靡きグラ表示//
if (key[KEY_INPUT_LEFT] >= 1 && key[KEY_INPUT_RIGHT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle3, TRUE);
}//右靡きグラ表示//
}
void to_center(){
p1.draw_x = p1.x + 320;
p1.draw_y = ((-1)*p1.y) + 240;
}
void draw_back(){
DrawGraph(0, back_img_y, back_img1, TRUE);
DrawGraph(0, back_img_y - 480, back_img2, TRUE);
DrawLine(0, 240, 640, 240, Color_White);
DrawLine(320, 0, 320, 480, Color_White);
DrawFormatString(320, 240, Color_White, "(0,0)");
if (back_img_y > 480){
back_img_y = 0;
}
}
void draw_variable(){
DrawFormatString(440, 440, Color_White, "gamecount=%d", gamecount);
}
int get_key(){
char keys[256];
GetHitKeyStateAll(keys);
for (int i = 0; i < 256; i++){
if (keys != 0){
key++;
}
else{
key = 0;
}
}
return 0;
}
/code
使用している環境は、
os:windows 8.1
コンパイラ名:Visual Studio 2013
Re: 自機に弾を撃たせたいです。
とりあえず、自機から弾幕を打つ条件(あるボタンが押されているなど)が成立していたら画面に「弾幕を打つ」と表示するプログラムを作れますか?崎島 さんが書きました:どうしても自機からの弾幕を打つことが出来ません。恥ずかしい話ではあるのですが、キレて消してしまいました。
とりあえず、書いたコードはそのまま載せます。
また、弾幕を打つには弾の位置の情報を格納する場所が必要だと思います。
このように毎フレーム画像のロードを行ってはいけません。
ロードは比較的重い上、リソース(ここでは画像ハンドル数)の枯渇を招いてしまいます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
- Dixq (管理人)
- 管理人
- 記事: 1662
- 登録日時: 14年前
- 住所: 北海道札幌市
- 連絡を取る:
Re: 自機に弾を撃たせたいです。
みけCATさん、返信ありがとうございます。
とても簡単に書きましたが、こういうことでしょうか?もうしわけありませんが、ご教授お願いします。
そして昨晩、自分でも新たに弾発射のコードを書いてみましたが、自機の下に弾が現れ消えるだけになってしまいました。
参考、引用元はhttp://bituse.info/game/shot/# プログラミング入門サイト bituse です。
画像のロードは、他にもやり方があるようなので、配布するまではこのままでいこうと思います。
なかなかわかりにくい質問になっているかもしれませんが、よろしくお願いします。
とても簡単に書きましたが、こういうことでしょうか?もうしわけありませんが、ご教授お願いします。
そして昨晩、自分でも新たに弾発射のコードを書いてみましたが、自機の下に弾が現れ消えるだけになってしまいました。
void draw_shot(){
for (int i = 0; i < 20; ++i){
if (tama[i].flag){
DrawGraph(p1.draw_x, p1.draw_y+1 , Handle4, TRUE);
}
}
}
void init_shot(){
if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){
for (int e = 0; e < 20; e++){
if (tama[e].flag == false){
tama[e].flag = true;
tama[e].xx = p1.x;
tama[e].yy = p1.y;
break;
}
}
}
for (int e = 0; e < 20; ++e){
if (tama[e].flag){
tama[e].yy = 14;
if (tama[e].yy < -240){
tama[e].flag = false;
}
}
}
}
画像のロードは、他にもやり方があるようなので、配布するまではこのままでいこうと思います。
なかなかわかりにくい質問になっているかもしれませんが、よろしくお願いします。
Re: 自機に弾を撃たせたいです。
DXライブラリのCheckHitKey関数は(多分)0以上の値しか返さないので、条件式が不適切です。
また、わざわざ条件が成立した時の処理を空にして、else以降に処理を書く意味もわかりません。
素直に!演算子などを用いて条件の真偽をひっくり返せばいいでしょう。
また、printf関数でも悪くないかもしれませんが、DrawString関数を使うことを想定していました。
崎島 さんが書きました:そして昨晩、自分でも新たに弾発射のコードを書いてみましたが、自機の下に弾が現れ消えるだけになってしまいました。
- draw_shot関数において、せっかくtamaに弾の位置の情報があるはずなのに、それを使わずにp1にアクセスするのは不自然です。
- 弾を移動させる処理が提示されたコードの中には無いようです。
- init_shot関数において、せっかくtama.yyを上のfor文の中で設定しているのに、下のfor文の中ですぐに固定値に上書きしてしまうのは不自然です。
- 消える原因はよくわかりません。コード全体はどうなっていますか?
崎島 さんが書きました:画像のロードは、他にもやり方があるようなので、配布するまではこのままでいこうと思います。
どうしてですか?
背景のロードはまともなのに、なぜ統一しないのですか?
「配布するまではこのままでいこうと思います」とのことですが、もしかして配布してからもこのままでいくつもりですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 自機に弾を撃たせたいです。
みけCATさん、返信ありがとうございます。
Zが押されたときに「弾幕を打つ」と白い文字で表示させるように書いたつもりですが、これでどうでしょうか?
コード全部です
tamaに弾の位置の情報があるということなので早速p1のところと入れ替えてみたところ
左上に弾画像が表示されるだけになりました。訳が分かりません。
弾を移動させる処理が無いとのことですが
二つ目のfor文からが弾の移動処理だと「プログラミング入門サイト bituse」というところには書いてあるのですが...
「•init_shot関数において、せっかくtama.yyを上のfor文の中で設定しているのに、下のfor文の中ですぐに固定値に上書きしてしまうのは不自然です。」
とのことで、早速固定値に上書きする部分を消してみました。
実行結果が変わっていない感じがします。
消える原因は僕もよくわかりません。動かせるときに動かすと消え、左上に出現し動かせないときには消えないようです。
画像のロードですが、
先ほども出しましたが、こんな風に全部一か所にまとめてみました。どうでしょうか?
Zが押されたときに「弾幕を打つ」と白い文字で表示させるように書いたつもりですが、これでどうでしょうか?
コード全部です
#include "DxLib.h"
//プロトタイプ宣言//
void init_back_img(void);
void to_center(void);
void draw_back(void);
void draw_variable(void);
void draw_shot(void);
bool life=true;
int get_key(void);
int count;
void init_shot(void);
struct shot{
double xx, yy;
int flag = false;
};
struct shot tama[100];
void move_player(void);
void draw_player(void);
struct PLAYER{
double x, y;
double draw_x, draw_y;
};
struct PLAYER p1;
int key[256];
int counter;
double back_img_y;
int back_img1;
int back_img2;
int Handle1;
int Handle2;
int Handle3;
int Handle4;
int gamecount;
int Color_White;
//こっから本文//
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
ChangeWindowMode(TRUE);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
init_back_img();
back_img1 = LoadGraph("test.png");
back_img2 = LoadGraph("test.png");
Handle1 = LoadGraph("player_reimu1.png");
Handle2 = LoadGraph("player_reimu2.png");
Handle3 = LoadGraph("player_reimu3.png");
Handle4 = LoadGraph("danmaku_reimu1.png");
while (ScreenFlip() == 0 && ProcessMessage() == 0
&& ClearDrawScreen() == 0 && get_key() == 0){
to_center();
draw_back();
draw_shot();
init_shot();
draw_player();
draw_variable();
move_player();
gamecount++;
back_img_y++;
++count;
}
DxLib_End();
return 0;
}
//以下,関数//
void draw_shot(){
for (int i = 0; i < 20; ++i){
if (tama[i].flag){
DrawGraph(p1.draw_x, p1.draw_y+1 , Handle4, TRUE);
}
}
}
void init_shot(){
if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){
for (int e = 0; e < 20; e++){
if (tama[e].flag == false){
tama[e].flag = true;
tama[e].xx = p1.x;
tama[e].yy = p1.y;
break;
}
}
}
for (int e = 0; e < 20; ++e){
if (tama[e].flag){
tama[e].yy = 14;
if (tama[e].yy < -240){
tama[e].flag = false;
}
}
}
}
void init_back_img(){
back_img_y = 0;
Color_White = GetColor(255, 255, 255);
}
void move_player(){
if (key[KEY_INPUT_RIGHT] >= 1){
p1.x = p1.x + 3;
if (p1.x < 0 && key[KEY_INPUT_A]) p1.x = 0;//瞬間移動っぽいやつ
if (p1.x > 305)p1.x = 305;
}
if (key[KEY_INPUT_DOWN] >= 1){
p1.y = p1.y - 3;
if (p1.y < -220)p1.y = -220;
}
if (key[KEY_INPUT_LEFT] >= 1){
p1.x = p1.x - 3;
if (p1.x > 0 && key[KEY_INPUT_A])p1.x = 0;//瞬間移動っぽいやつ
if (p1.x < -330)p1.x = -330;
}
if (key[KEY_INPUT_UP] >= 1){
p1.y = p1.y + 3;
if (p1.y > 240)p1.y = 240;
}
}
void draw_player(){
if (CheckHitKey(KEY_INPUT_LEFT) == 0 && CheckHitKey(KEY_INPUT_RIGHT) == 0)
{
// 右と左が押されていない(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else if (CheckHitKey(KEY_INPUT_LEFT) == 1 && CheckHitKey(KEY_INPUT_RIGHT) == 1){
// 右と左が押されている(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else{
// 右か左が押されている(通常グラ非表示)//
}
if (key[KEY_INPUT_RIGHT] >= 1 && key[KEY_INPUT_LEFT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle2, TRUE);
}//左靡きグラ表示//
if (key[KEY_INPUT_LEFT] >= 1 && key[KEY_INPUT_RIGHT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle3, TRUE);
}//右靡きグラ表示//
}
void to_center(){
p1.draw_x = p1.x+320;
p1.draw_y = ((-1)*p1.y) + 240;
}
void draw_back(){
DrawGraph(0, back_img_y, back_img1, TRUE);
DrawGraph(0, back_img_y - 480, back_img2, TRUE);
DrawLine(0, 240, 640, 240, Color_White);
DrawLine(320, 0, 320, 480, Color_White);
DrawFormatString(320, 240, Color_White, "(0,0)");
if (back_img_y > 480){
back_img_y = 0;
}
}
void draw_variable(){
DrawFormatString(440, 440, Color_White, "gamecount=%d", gamecount);
}
int get_key(){
char keys[256];
GetHitKeyStateAll(keys);
for (int i = 0; i < 256; i++){
if (keys[i] != 0){
key[i]++;
}
else{
key[i] = 0;
}
}
return 0;
}
void draw_shot(){
for (int i = 0; i < 20++i){
if (tama[i].flag){
DrawGraph(tama[i].xx,tama[i].yy, Handle4, TRUE);
}
}
}
弾を移動させる処理が無いとのことですが
void init_shot(){
if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){
for (int e = 0; e < 20; e++){
if (tama[e].flag == false){
tama[e].flag = true;
tama[e].xx = p1.x;
tama[e].yy = p1.y;
break;
}
}
}
for (int e = 0; e < 20; ++e){
if (tama[e].flag){
tama[e].yy = 14;
if (tama[e].yy < -240){
tama[e].flag = false;
}
}
}
}
「•init_shot関数において、せっかくtama.yyを上のfor文の中で設定しているのに、下のfor文の中ですぐに固定値に上書きしてしまうのは不自然です。」
とのことで、早速固定値に上書きする部分を消してみました。
void init_shot(){
if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){
for (int e = 0; e < 20; e++){
if (tama[e].flag == false){
tama[e].flag = true;
tama[e].xx = p1.x;
tama[e].yy = p1.y;
break;
}
}
}
for (int e = 0; e < 20; ++e){
if (tama[e].flag){
if (tama[e].yy < -240){
tama[e].flag = false;
}
}
}
}
消える原因は僕もよくわかりません。動かせるときに動かすと消え、左上に出現し動かせないときには消えないようです。
画像のロードですが、
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
ChangeWindowMode(TRUE);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
init_back_img();
back_img1 = LoadGraph("test.png");
back_img2 = LoadGraph("test.png");
Handle1 = LoadGraph("player_reimu1.png"); // 画像をロード
Handle2 = LoadGraph("player_reimu2.png");
Handle3 = LoadGraph("player_reimu3.png");
Handle4 = LoadGraph("danmaku_reimu1.png");
while (ScreenFlip() == 0 && ProcessMessage() == 0
&& ClearDrawScreen() == 0 && get_key() == 0){
to_center();
draw_back();
draw_shot();
init_shot();
draw_player();
draw_variable();
move_player();
gamecount++;
back_img_y++;
++count;
}
DxLib_End();
return 0;
}
Re: 自機に弾を撃たせたいです。
これ自体は悪くないと思います。
あとはどこに書くかですね。
自機の座標は変換されたdrawを用いているのに対し、弾の座標は生の座標を使用してしまっているので、
弾の座標も自機と同様に描画用に変換するべきです。
具体的にどこに書いてありますか?崎島 さんが書きました:弾を移動させる処理が無いとのことですが
二つ目のfor文からが弾の移動処理だと「プログラミング入門サイト bituse」というところには書いてあるのですが...void init_shot(){ if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){ for (int e = 0; e < 20; e++){ if (tama[e].flag == false){ tama[e].flag = true; tama[e].xx = p1.x; tama[e].yy = p1.y; break; } } } for (int e = 0; e < 20; ++e){ if (tama[e].flag){ tama[e].yy = 14; if (tama[e].yy < -240){ tama[e].flag = false; } } } }
少なくとも
操作キャラから弾を発射してみよう | シューティングゲーム作成入門~bituse~
には、似たfor文でyyを減算する処理はありますが、このような固定値を代入する処理は書かれていないようです。
draw_shot関数を変更していない場合、tama.yyは描画に反映されないため、実行結果は変わらないはずです。崎島 さんが書きました:「•init_shot関数において、せっかくtama.yyを上のfor文の中で設定しているのに、下のfor文の中ですぐに固定値に上書きしてしまうのは不自然です。」
とのことで、早速固定値に上書きする部分を消してみました。実行結果が変わっていない感じがします。void init_shot(){ if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){ for (int e = 0; e < 20; e++){ if (tama[e].flag == false){ tama[e].flag = true; tama[e].xx = p1.x; tama[e].yy = p1.y; break; } } } for (int e = 0; e < 20; ++e){ if (tama[e].flag){ if (tama[e].yy < -240){ tama[e].flag = false; } } } }
修正後のdraw_shot関数を使用した場合、きちんと弾のy位置が打った時の自機の位置を反映するようになりました。
悪くないと思います。崎島 さんが書きました:画像のロードですが、
先ほども出しましたが、こんな風に全部一か所にまとめてみました。どうでしょうか?int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){ ChangeWindowMode(TRUE); DxLib_Init(); SetDrawScreen(DX_SCREEN_BACK); init_back_img(); back_img1 = LoadGraph("test.png"); back_img2 = LoadGraph("test.png"); Handle1 = LoadGraph("player_reimu1.png"); // 画像をロード Handle2 = LoadGraph("player_reimu2.png"); Handle3 = LoadGraph("player_reimu3.png"); Handle4 = LoadGraph("danmaku_reimu1.png"); while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && get_key() == 0){ to_center(); draw_back(); draw_shot(); init_shot(); draw_player(); draw_variable(); move_player(); gamecount++; back_img_y++; ++count; } DxLib_End(); return 0; }
- 添付ファイル
-
- gazou.zip
- テスト用仮素材
- (6.49 KiB) ダウンロード数: 126 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 自機に弾を撃たせたいです。
みけCATさん、返信ありがとうございます。返信がかなり遅れてしまい、申し訳ございません。
描画用に変換ということは、簡単に言うともう一つ変数を用いるという解釈であっていますでしょうか?
説明不足でした。http://bituse.info/game/shot/8 ここには、PSHOT_NUMをヘッダーファイルに20と定義しているとあり、わざわざ私も同じように定義せずに20をそのままいれればいいのでは?と思い、20と入れました。やはりいけないことなのでしょうか?
質問が増えるばかりですが、ご教授よろしくお願いします。
描画用に変換ということは、簡単に言うともう一つ変数を用いるという解釈であっていますでしょうか?
void init_shot(){
if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){
for (int e = 0; e < 20; e++){
if (tama[e].flag == false){
tama[e].flag = true;
tama[e].xx = p1.x;
tama[e].yy = p1.y;
break;
}
}
}
for (int e = 0; e < 20; ++e){
if (tama[e].flag){
tama[e].yy = 14;
if (tama[e].yy < -240){
tama[e].flag = false;
}
}
}
}
質問が増えるばかりですが、ご教授よろしくお願いします。
Re: 自機に弾を撃たせたいです。
自機と同じようにもう二つメンバを追加するか、わざわざ個別に変換しなくてすむように描画関数のラッパを作るといいでしょう。崎島 さんが書きました:描画用に変換ということは、簡単に言うともう一つ変数を用いるという解釈であっていますでしょうか?
このような「マジックナンバー」を使うのは褒められたことではないですが、致命的な間違いではありません。崎島 さんが書きました:説明不足でした。http://bituse.info/game/shot/8 ここには、PSHOT_NUMをヘッダーファイルに20と定義しているとあり、わざわざ私も同じように定義せずに20をそのままいれればいいのでは?と思い、20と入れました。やはりいけないことなのでしょうか?void init_shot(){ if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){ for (int e = 0; e < 20; e++){ if (tama[e].flag == false){ tama[e].flag = true; tama[e].xx = p1.x; tama[e].yy = p1.y; break; } } } for (int e = 0; e < 20; ++e){ if (tama[e].flag){ tama[e].yy = 14; if (tama[e].yy < -240){ tama[e].flag = false; } } } }
サイトと同じように減算せずに、固定値の14を代入しているところが問題です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 自機に弾を撃たせたいです。
描画用に変換は描画用に変換ということです。崎島 さんが書きました:描画用に変換ということは、簡単に言うともう一つ変数を用いるという解釈であっていますでしょうか?
「もう一つ変数を用いるという解釈」は、その変数の使い道がわからないため、間違いだと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 自機に弾を撃たせたいです。
みけCATさん、返信ありがとうございます。
減算処理のために、以下のように文を追加しました。
それと、p1.xをp1.draw_xに、p1.yをp1.draw_yに、それぞれ変更したところ、自機から弾画像が描画(勿論、飛んでいくように)されるようになりました。
最終的に、以下のようなプログラムにしました。
このようにしたところ、自機画像からの弾画像発射が実現できました。
わざわざさまざまなことをご教授いただき、ありがとうございました。
今後ともつまずくことが多いかと思いますが、ぜひともよろしくおねがいいたします。
減算処理のために、以下のように文を追加しました。
それと、p1.xをp1.draw_xに、p1.yをp1.draw_yに、それぞれ変更したところ、自機から弾画像が描画(勿論、飛んでいくように)されるようになりました。
void init_shot(){
if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){
for (int e = 0; e < 20; e++){
if (tama[e].flag == false){
tama[e].flag = true;
tama[e].xx = p1.draw_x;
tama[e].yy = p1.draw_y;
break;
}
}
}
for (int e = 0; e < 20; ++e){
if (tama[e].flag){
tama[e].yy -= 14;//追加した文
if (tama[e].yy < -240){
tama[e].flag = false;
}
}
}
}
最終的に、以下のようなプログラムにしました。
#include "DxLib.h"
//プロトタイプ宣言//
void init_back_img(void);
void to_center(void);
void draw_back(void);
void draw_variable(void);
void draw_shot(void);
bool life=true;
int get_key(void);
int count;
void init_shot(void);
struct shot{
double xx, yy;
int flag = false;
};
struct shot tama[100];
void move_player(void);
void draw_player(void);
struct PLAYER{
double x, y;
double draw_x, draw_y;
};
struct PLAYER p1;
int key[256];
int counter;
double back_img_y;
int back_img1;
int back_img2;
int Handle1;
int Handle2;
int Handle3;
int Handle4;
int gamecount;
int Color_White;
//こっから本文//
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int){
ChangeWindowMode(TRUE);
DxLib_Init();
SetDrawScreen(DX_SCREEN_BACK);
init_back_img();
back_img1 = LoadGraph("test.png");//画像をロード
back_img2 = LoadGraph("test.png");
Handle1 = LoadGraph("player_reimu1.png");
Handle2 = LoadGraph("player_reimu2.png");
Handle3 = LoadGraph("player_reimu3.png");
Handle4 = LoadGraph("danmaku_reimu1.png");
while (ScreenFlip() == 0 && ProcessMessage() == 0
&& ClearDrawScreen() == 0 && get_key() == 0){
to_center();
draw_back();
draw_shot();
init_shot();
draw_player();
draw_variable();
move_player();
gamecount++;
back_img_y;
++count;
}
DxLib_End();
return 0;
}
//以下,関数//
void draw_shot(){
for (int i = 0; i < 20; ++i){
if (tama[i].flag){
DrawGraph(tama[i].xx,tama[i].yy, Handle4, TRUE);
}
}
}
void init_shot(){
if (CheckHitKey(KEY_INPUT_Z)>=1&&count%3==0){
for (int e = 0; e < 20; e++){
if (tama[e].flag == false){
tama[e].flag = true;
tama[e].xx = p1.draw_x;
tama[e].yy = p1.draw_y;
break;
}
}
}
for (int e = 0; e < 20; ++e){
if (tama[e].flag){
tama[e].yy -= 14;
if (tama[e].yy < -240){
tama[e].flag = false;
}
}
}
}
void init_back_img(){
back_img_y = 0;
Color_White = GetColor(255, 255, 255);
}
void move_player(){
if (key[KEY_INPUT_RIGHT] >= 1){
p1.x = p1.x + 3;
if (p1.x < 0 && key[KEY_INPUT_A]) p1.x = 0;//瞬間移動っぽいやつ
if (p1.x > 305)p1.x = 305;
}
if (key[KEY_INPUT_DOWN] >= 1){
p1.y = p1.y - 3;
if (p1.y < -220)p1.y = -220;
}
if (key[KEY_INPUT_LEFT] >= 1){
p1.x = p1.x - 3;
if (p1.x > 0 && key[KEY_INPUT_A])p1.x = 0;//瞬間移動っぽいやつ
if (p1.x < -330)p1.x = -330;
}
if (key[KEY_INPUT_UP] >= 1){
p1.y = p1.y + 3;
if (p1.y > 240)p1.y = 240;
}
}
void draw_player(){
if (CheckHitKey(KEY_INPUT_LEFT) == 0 && CheckHitKey(KEY_INPUT_RIGHT) == 0)
{
// 右と左が押されていない(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else if (CheckHitKey(KEY_INPUT_LEFT) == 1 && CheckHitKey(KEY_INPUT_RIGHT) == 1){
// 右と左が押されている(通常グラ表示)//
DrawGraph(p1.draw_x, p1.draw_y, Handle1, TRUE);
}
else{
// 右か左が押されている(通常グラ非表示)//
}
if (key[KEY_INPUT_RIGHT] >= 1 && key[KEY_INPUT_LEFT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle2, TRUE);
}//左靡きグラ表示//
if (key[KEY_INPUT_LEFT] >= 1 && key[KEY_INPUT_RIGHT] == 0){
DrawGraph(p1.draw_x, p1.draw_y, Handle3, TRUE);
}//右靡きグラ表示//
}
void to_center(){
p1.draw_x = p1.x+320;
p1.draw_y = ((-1)*p1.y) + 240;
}
void draw_back(){
DrawGraph(0, back_img_y, back_img1, TRUE);
DrawGraph(0, back_img_y - 480, back_img2, TRUE);
DrawLine(0, 240, 640, 240, Color_White);
DrawLine(320, 0, 320, 480, Color_White);
DrawFormatString(320, 240, Color_White, "(0,0)");
if (back_img_y > 480){
back_img_y = 0;
}
}
void draw_variable(){
DrawFormatString(440, 440, Color_White, "gamecount=%d", gamecount);
}
int get_key(){
char keys[256];
GetHitKeyStateAll(keys);
for (int i = 0; i < 256; i++){
if (keys[i] != 0){
key[i]++;
}
else{
key[i] = 0;
}
}
return 0;
}
わざわざさまざまなことをご教授いただき、ありがとうございました。
今後ともつまずくことが多いかと思いますが、ぜひともよろしくおねがいいたします。