#4
by 梅衣堂ひよ » 8年前
003系 さんが書きました:
「つまりこういうこと?」と思い、プロトタイプ宣言の方のコードを以下のように書き換えてみたりしましたがダメでした
コード:
void fSHOT1(int *shotx[10], int *shoty[10], int, int, int, int);
逆ですね。むしろ定義の方を宣言に合わせるべきでした。
配列というのは、添え字を付けなければ配列の先頭のポインタの扱いになります。
その為、渡した関数の中でも元の場所と同じように配列変数として扱えます。(1次元のみ。2次元以降は少し工夫が必要になります)
003系 さんが書きました:コード:
fSHOT1(&shot1[10].x, &shot1[10].y, player.x, player.y, windowWidth, windowHeight);
次にここ。
C++では、配列は0から数えます。そのため、これでは実在しないshot1の11番目のx、及びyのポインタを引数として渡すようになっています。
003系 さんが書きました:コード:
int count = 0, agility = 20, speed = 20;
int nowmx = 0, nowmy = 0, se = LoadSoundMem("shot1.ogg");
float angle;
struct iseries { int tax, tay, bux, buy, flag, velx, vely; };
struct iseries shot[10];
そしてfSHOTの中で定義されたローカル変数たち。
ローカル変数は、staticを付けないと定義されたブロックを抜けると存在を消されてしまい、次に入った時には新しく作られたものになります。
afillityやspeed、マウスの座標とangleはこのままでも一応問題ないですがcountとshotは中身がまっさらになり、seに至ってはここに入る度にファイルを追加読み込みしています。そしてseは解放されていないので、どんどんメモリを圧迫していきます。
おそらくはどこかのサイトからコピペしてきたりするのでしょうが、コピペするときはソースの意味を理解しないと危険ですので注意してください。
[hr]
オマケ。ソースを少し?改変いたしました。
► スポイラーを表示
コード:
#include "DxLib.h"
#define _USE_MATH_DEFINES
#include<math.h>
//変数定義
int windowWidth = 1280, windowHeight = 720;//ウインドウの縦横サイズ
struct battleman { int x, y, speed; };
struct shot { float x, y, velx, vely; int flag; };
//関数プロトタイプ宣言
void fPLAYERMOVE(int *x, int *y, int, int, int);
void fSHOT1(shot* _shot, int, int, int, int);
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
// ウィンドウモードに設定
ChangeWindowMode(TRUE);
SetOutApplicationLogValidFlag(false);
//DXライブラリを初期化
DxLib_Init();
//ウインドウタイトル設定
SetWindowText("playerShotStraight");
//マウスカーソルを描画
SetMouseDispFlag(true);
//構造体系
struct battleman player = { 0,0,20 };
struct shot shot1[10];
for (int i = 0; i < 10; i++) {
shot1[i].x = 0.0f;
shot1[i].y = 0.0f;
shot1[i].velx = 0.0f;
shot1[i].vely = 0.0f;
shot1[i].flag = 0;
}
//メインループ
while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) {
/*
更新処理
*/
//自機移動
fPLAYERMOVE(&player.x, &player.y, player.speed, windowWidth, windowHeight);
//直進弾発射
fSHOT1(shot1, player.x, player.y, windowWidth, windowHeight);
/*
描画処理
*/
DrawString(player.x, player.y, "●", GetColor(64, 64, 255));
for (int i = 0; i < 10; i++) {
if (shot1[i].flag == 0)
continue;
DrawString(shot1[i].x, shot1[i].y, "●", GetColor(255, 255, 255));
}
}
//DXライブラリを終了
DxLib_End();
return 0;
}
//関数定義
void fPLAYERMOVE(int *x, int *y, int speed, int width, int height) {
if (CheckHitKey(KEY_INPUT_W)) {
*y -= speed;
if (*y <= 0)*y = 0;
}
if (CheckHitKey(KEY_INPUT_A)) {
*x -= speed;
if (*x <= 0)*x = 0;
}
if (CheckHitKey(KEY_INPUT_S)) {
*y += speed;
if (*y >= height)*y = height;
}
if (CheckHitKey(KEY_INPUT_D)) {
*x += speed;
if (*x >= width)*x = width;
}
}
void fSHOT1(shot* _shot, int px, int py, int width, int height) {
static int count = 0; //待機時間用カウンター
const int agility = 5; //1発当たりの待機時間
const float speed = 20;
if (count < agility) {
count++;
}
else if (GetMouseInput()&MOUSE_INPUT_1) {
int nowmx = 0, nowmy = 0;
float angle = 0;
count = 0;
GetMousePoint(&nowmx, &nowmy);
//弾の発射処理
for (int i = 0; i < 10; i++) {
//発射中なら次へ(continue)
if (_shot[i].flag != 0) {
continue;
}
//発射用処理
_shot[i].flag = 1;
_shot[i].x = static_cast<float>(px);
_shot[i].y = static_cast<float>(py);
angle = atan2f((float)nowmy - (float)_shot[i].y, nowmx - (float)_shot[i].x);
_shot[i].velx = cosf(angle) * speed;
_shot[i].vely = sinf(angle) * speed;
break;
}
}
//弾の更新処理
for (int i = 0; i < 10; i++) {
if (_shot[i].flag == 1) {
_shot[i].x += _shot[i].velx;
_shot[i].y += _shot[i].vely;
if (_shot[i].x<0 || _shot[i].y<0 || _shot[i].x>width || _shot[i].y>height) {
_shot[i].flag = 0;
}
}
}
}
[quote="003系" id=3,19044,144570]
「つまりこういうこと?」と思い、プロトタイプ宣言の方のコードを以下のように書き換えてみたりしましたがダメでした
[code]void fSHOT1(int *shotx[10], int *shoty[10], int, int, int, int);[/code]
[/quote]
逆ですね。むしろ定義の方を宣言に合わせるべきでした。
配列というのは、添え字を付けなければ配列の先頭のポインタの扱いになります。
その為、渡した関数の中でも元の場所と同じように配列変数として扱えます。(1次元のみ。2次元以降は少し工夫が必要になります)
[quote="003系" id=3,19044,144565][code] fSHOT1(&shot1[10].x, &shot1[10].y, player.x, player.y, windowWidth, windowHeight);[/code][/quote]
次にここ。
C++では、配列は0から数えます。そのため、これでは実在しないshot1の11番目のx、及びyのポインタを引数として渡すようになっています。
[quote="003系" id=3,19044,144565][code] int count = 0, agility = 20, speed = 20;
int nowmx = 0, nowmy = 0, se = LoadSoundMem("shot1.ogg");
float angle;
struct iseries { int tax, tay, bux, buy, flag, velx, vely; };
struct iseries shot[10];[/code][/quote]
そしてfSHOTの中で定義されたローカル変数たち。
ローカル変数は、staticを付けないと定義されたブロックを抜けると存在を消されてしまい、次に入った時には新しく作られたものになります。
afillityやspeed、マウスの座標とangleはこのままでも一応問題ないですがcountとshotは中身がまっさらになり、seに至ってはここに入る度にファイルを追加読み込みしています。そしてseは解放されていないので、どんどんメモリを圧迫していきます。
おそらくはどこかのサイトからコピペしてきたりするのでしょうが、コピペするときはソースの意味を理解しないと危険ですので注意してください。
[hr]
オマケ。ソースを少し?改変いたしました。
[spoil][code]#include "DxLib.h"
#define _USE_MATH_DEFINES
#include<math.h>
//変数定義
int windowWidth = 1280, windowHeight = 720;//ウインドウの縦横サイズ
struct battleman { int x, y, speed; };
struct shot { float x, y, velx, vely; int flag; };
//関数プロトタイプ宣言
void fPLAYERMOVE(int *x, int *y, int, int, int);
void fSHOT1(shot* _shot, int, int, int, int);
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
// ウィンドウモードに設定
ChangeWindowMode(TRUE);
SetOutApplicationLogValidFlag(false);
//DXライブラリを初期化
DxLib_Init();
//ウインドウタイトル設定
SetWindowText("playerShotStraight");
//マウスカーソルを描画
SetMouseDispFlag(true);
//構造体系
struct battleman player = { 0,0,20 };
struct shot shot1[10];
for (int i = 0; i < 10; i++) {
shot1[i].x = 0.0f;
shot1[i].y = 0.0f;
shot1[i].velx = 0.0f;
shot1[i].vely = 0.0f;
shot1[i].flag = 0;
}
//メインループ
while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) {
/*
更新処理
*/
//自機移動
fPLAYERMOVE(&player.x, &player.y, player.speed, windowWidth, windowHeight);
//直進弾発射
fSHOT1(shot1, player.x, player.y, windowWidth, windowHeight);
/*
描画処理
*/
DrawString(player.x, player.y, "●", GetColor(64, 64, 255));
for (int i = 0; i < 10; i++) {
if (shot1[i].flag == 0)
continue;
DrawString(shot1[i].x, shot1[i].y, "●", GetColor(255, 255, 255));
}
}
//DXライブラリを終了
DxLib_End();
return 0;
}
//関数定義
void fPLAYERMOVE(int *x, int *y, int speed, int width, int height) {
if (CheckHitKey(KEY_INPUT_W)) {
*y -= speed;
if (*y <= 0)*y = 0;
}
if (CheckHitKey(KEY_INPUT_A)) {
*x -= speed;
if (*x <= 0)*x = 0;
}
if (CheckHitKey(KEY_INPUT_S)) {
*y += speed;
if (*y >= height)*y = height;
}
if (CheckHitKey(KEY_INPUT_D)) {
*x += speed;
if (*x >= width)*x = width;
}
}
void fSHOT1(shot* _shot, int px, int py, int width, int height) {
static int count = 0; //待機時間用カウンター
const int agility = 5; //1発当たりの待機時間
const float speed = 20;
if (count < agility) {
count++;
}
else if (GetMouseInput()&MOUSE_INPUT_1) {
int nowmx = 0, nowmy = 0;
float angle = 0;
count = 0;
GetMousePoint(&nowmx, &nowmy);
//弾の発射処理
for (int i = 0; i < 10; i++) {
//発射中なら次へ(continue)
if (_shot[i].flag != 0) {
continue;
}
//発射用処理
_shot[i].flag = 1;
_shot[i].x = static_cast<float>(px);
_shot[i].y = static_cast<float>(py);
angle = atan2f((float)nowmy - (float)_shot[i].y, nowmx - (float)_shot[i].x);
_shot[i].velx = cosf(angle) * speed;
_shot[i].vely = sinf(angle) * speed;
break;
}
}
//弾の更新処理
for (int i = 0; i < 10; i++) {
if (_shot[i].flag == 1) {
_shot[i].x += _shot[i].velx;
_shot[i].y += _shot[i].vely;
if (_shot[i].x<0 || _shot[i].y<0 || _shot[i].x>width || _shot[i].y>height) {
_shot[i].flag = 0;
}
}
}
}[/code][/spoil]