Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.1 ) |
- 名前:管理人 日時:2019/09/22 02:49
if (count <= 41 && ++count <= 50)
こちらを
if (count < 50) ++count;
このようにすれば良いのではないでしょうか?
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.2 ) |
- 名前:マーク42 日時:2019/09/22 06:41
素晴らしいです!本当にどうもありがとうございます!
実は連続攻撃というものがありまして、Rキーの後、キーAを押して攻撃が成功すると、キーAのみを連打すれば追加攻撃(連続攻撃)ができるというものです。
早速コードを以下のように編集して、if (count < 50) ++count;を入れました。すると何時間も悩んでいたことがあっという間に実現できました。
管理人様には感謝しかありません。本当にどうもありがとうございます!!
以下が全体のコードです。
#include "DxLib.h"
int Key [ 256 ] ;
int gpUpdateKey ()
{
char tmpKey [ 256 ] ;
GetHitKeyStateAll ( tmpKey );
for (int i = 0 ; i < 256 ; i ++ )
( tmpKey [ i ] == 0 ) ? ( Key [ i ] = 0 ) : Key [ i ] ++;
0を返します。
}
intステージ[ 4 ] [ 7 ] [ 2 ] ; //盤上のマスの格子点の座標
int pos [ 3 ] [ 6 ] [ 2 ] ; //キャラ描画座標
void init_stage () // stageとposを初期化する
{
for (int j = 0 ; j < 7 ; j ++ ) {
int w = ( j - 3 ) * 100 、 h = 300 ;
用 (int型 I = 4 ; - I > = 0 ; ) {
stage [ i ] [ j ] [ 0 ] = w + 400 、 stage [ i ] [ j ] [ 1 ] = h - 100 ;
W = W * 9 / 10 、 H = H * 9 / 10 。
}
}
for (int i = 0 ; i < 3 ; i ++ )
for (int j = 0 ; j < 6 ; j ++ ) {
POS [ I ] [ J ] [ 0 ] = (ステージ[ I ] [ J ] [ 0 ] +ステージ[ I + 1 ] [ J + 1 ] [ 0 ] ) / 2 - 25 。
POS [ I ] [ J ] [ 1 ] = (ステージ[ I ] [ J ] [ 1 ] +ステージ[ I + 1 ] [ J + 1 ] [ 1 ] ) / 2 - 65 。
}
}
int White ;
int function_status ; //戦闘画面中は1とするための変数function_statusの定義
int WINAPI WinMain ( HINSTANCE 、 HINSTANCE 、 LPSTR 、 int )
{
SetGraphMode (780 、 680 、 32 )。 //ウィンドウの大きさを指定
ChangeWindowMode ( TRUE ); //全画面ではなくウインドウを使用
if ( DxLib_Init () == - 1 ) return - 1 ; // DXライブラリ初期化処理
SetDrawScreen ( DX_SCREEN_BACK ); //裏画面を使用する設定
init_stage (); //ステージ、posの初期化
int enemyX = 4 、 enemyY = 1 ; //敵の位置
int playerX = 1 、 playerY = 1 ; //俺の位置
int enemyMove = 0 ; //敵の移動状態
//俺の移動状態// 1〜21で右に振り向きのプログラム@が終わり、22になったら足踏みするAを実行するようにする。
int playerMove = 1 ;
int lockonMove = 0 ;
int lockonHandle [ 3 ] ;
function_status = 1 ; //最初は1にして戦闘画面状態にする。
int lock = 0 ; //ロック状態
int enemyGHandle [ 12 ] ; //敵のグラフィックハンドル格納用配列
int playerGHandle [ 12 ] ; //俺のグラフィックハンドル格納用配列
// 0-2:後ろ向き、3-5:右向き、6-8:前向き、9-11:左向き
LoadDivGraph ("charall.png" 、 12 、 3 、 4 、 49 、 66 、 enemyGHandle )。
LoadDivGraph ("charall.png" 、 12 、 3 、 4 、 49 、 66 、 playerGHandle )。
LoadDivGraph ("lockon.bmp" 、 3 、 3 、 1 、 23 、 23 、 lockonHandle )。
int enemyImage = enemyGHandle [ 11 ] ; //敵左向き
int playerImage = playerGHandle [ 4 ] ; //俺右向き
int lockImge = lockonHandle [ 3 ] ;
int preplayerX ;
int after = 0 ;
符号なし 整数カウント= 50 ;
int count2 = 50 ;
unsigned int count3 = 50 ;
const int MOVE_INTERVAL = 1000 ; //何ミリ秒ごとに移動処理をするか
int nextMoveTime = GetNowCount () + MOVE_INTERVAL ; //次回移動処理をする時刻
int stopCount = 0 ; //動かないのがあと何回か
while ( ProcessMessage () == 0 ) {
gpUpdateKey (); //キーの入力状態を取得
if ( Key [ KEY_INPUT_X ] == 1 ) { //キーXを押すとfunction_statusは0になる
function_status = 0 ;
}
if ( Key [ KEY_INPUT_Y ] == 1 ) { //キーYを押すとfunction_statusは1になる
function_status = 1 ; //戦闘画面に戻す
}
else { //戦闘画面中は1とする
// gpUpdateKey(); //キーの入力状態を取得上のifで既にgpUpdateKey();があり、elseはif以外の情報は引き継ぐので再びgpUpdateKey();書く必要はなかった。
//俺の移動
if ( Key [ KEY_INPUT_RIGHT ] == 1 && playerX < 2 ) { //キーを入力する以外にも押した後に早く画像を切り替えるて足踏みするようにするために初期値にも1はあるがキーにもplayerMove = 1を書いたり、キーを押したらどうしたいかをするためにplayerX ++を書いている。
playerMove = 1 ; playerX ++; playerImage = playerGHandle [ 2 ] ;
} // playerMove = 1;があると下に書いたplayerMoveより足踏みするplayerMoveが無いと初期値の1でそのまま足踏みするので遅く反応するのでは?
if ( Key [ KEY_INPUT_LEFT ] == 1 && playerX > 0 ) { //キーにplayerMove = 1を書くと初期値の1よりも早くキーに書いたplayerMoveの1が行くため早く足踏みに行くため、止まってから足踏みに行くまでの間にある向きを変える画像playerGHandle [2]が一瞬であるため、向きを変えるのが早く見えるのでは?足踏みを速く来るようにしたため。
playerMove = 1 ; playerX- ; playerImage = playerGHandle [ 9 ] ; //まあ、足踏みさせなくても、ただ書くだけでも方向を十分早く変えれる
}
if ( Key [ KEY_INPUT_UP ] == 1 && playerY > 0 ) {
playerMove = 1 ; playerY- ; playerImage = playerGHandle [ 2 ] ;
}
if ( Key [ KEY_INPUT_DOWN ] == 1 && playerY < 2 ) {
playerMove = 1 ; playerY ++; playerImage = playerGHandle [ 8 ] ;
}
// Rが一度押された上でフレームを利用してループさせるためにif文を新しく外に書いたのだ。
if ( Key [ KEY_INPUT_R ] == 1 && playerY == enemyY ) {
DrawGraph ( pos [敵Y ] [敵X ] [ 0 ] 、 pos [敵Y ] [敵X ] [ 1 ] 、//多分ここはいらない下に描画するための関数を書くため
lockImge 、 FALSE ); //ロックマークの描画
ロック= 1 ; // Key [KEY_INPUT_R] == 1 && playerY == enemyYの時、lockを1にする。lockを「何フレーム目の時」でも値を1として置いたため、条件式lockの入力キーAに話すせる。
lockonMove = 1 ;
}
if ( lockonMove > 0 ) { // lockonMoveが0以上であれば++ lockonMoveをする、
++ lockonMove ;
}
if ( lockonMove == 10 ) {
lockImge = lockonHandle [ 0 ] ; //情報lockonMove == 10やlockonHandle [0]を引き継いで下に書いた描画関数に入るため、ここには関数に入れる情報だけ入るのだ。
//その時の情報lockonMove == 10やlockonHandle [0]以外の引き継がれたとうかその時の敵の座標なども関数に入る。関数が求めるものが入るので、関数に必要なものを揃える。
}
else if ( lockonMove == 20 ) {
lockImge = lockonHandle [ 1 ] ;
}
else if ( lockonMove == 30 ) {
lockImge = lockonHandle [ 2 ] ;
}
else if ( lockonMove == 40 ) {
lockImge = lockonHandle [ 1 ] ;
lockonMove = 1 ;
}
if ( playerY != enemyY ) {
ロック= 0 ;
lockonMove = 0 ; //敵が移動した場合ロックオンの画像が消えるようにlockonMoveを0にする。
}
// playerY!= enemyYよりY座標が異なる場合を表す、Y座標が異なる場合はlockの値は0になる。要はロックが解除されてしまう。
if ( lock ) {
if ( Key [ KEY_INPUT_A ] == 1 && count <= 50 ) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
// count ++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX-1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
// if(count> = 0 && ++ count> 40){// countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++ count> 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
ロック= 0 ; // lock = 1の時の「lock !!」の描画を消すためにlockの値を0に変更。
lockonMove = 0 ; //アタックする時ロックオンの画像が消えるように値を0にする。
preplayerX = playerX ; //元の位置を保持
playerX = enemyX - 1 ; //俺は敵の眼前へ
後= 1 ; //アタック状態ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle [ 5 ] ; //攻撃を食らうと右向きになるようにする
count = count - 10 ; //キーAを押すたびに10だけ引く
}
}
if ( Key [ KEY_INPUT_A ] == 1 && enemyImage == enemyGHandle [ 5 ] )//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle [5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10 ;
playerX = enemyX - 1 ; //俺は敵の眼前へ
後= 1 ; //アタック状態ここまでをアタックとしてafter = 1と置いた。
}
if (カウント< 50 ) ++カウント; //これにより連続で攻撃してもif(Key [KEY_INPUT_A] == 1 && enemyImage == enemyGHandle [5])を考慮して連続攻撃ができる!
if ( after > 0 && ++ after > 15 ) { // afterが1より大きい時++ afterが働き15より大きくなったら、
/// ifの中にifを書いてしまうとその前のifを否定してしまうためデータが引き継げない。なので別のif文として書いた。←多分違う
playerX = preplayerX ; // preplayerXの座標をplayerXに代入する。
playerImage = playerGHandle [ 4 ] ;
after = 0 ; //アタック解除
}
//敵の移動
int t = GetNowCount ();
if ( t > = nextMoveTime ) { //指定の時間が経ったら(1sごとに)
nextMoveTime = t + MOVE_INTERVAL ; //次回移動処理をする時刻
if ( stopCount > 0 ) { //停止中のとき
stopCount- ; //止まっている残り時間(回数)を減らす
}
else { //普通の状態のとき
if ( GetRand (99 ) < 10 ) { //たまに(10%の確率で)
stopCount = GetRand (4 ); //数秒間(1〜5秒間)その場に止まる
}
else { // 9マス上のいずれかのパネルに移動させる
int cy = enemyY 、 cx = enemyX ;
やります {
enemyY = GetRand (2 );
enemyX = GetRand (2 ) + 3 ;
} while ( enemyX == cx && enemyY == cy ||
enemyX == playerX && enemyY == playerY );
enemyImage = enemyGHandle [ 10 ] ;
enemyMove = 1 ;
}
}
}
if ( playerMove > 0 ) { // 1フレームで処理を終わらせるためifの後はelse ifを使った。//フレームがあってもplayerMove ++を書かないと1ずつ上がらない。playerMove++をフレームの60回ループするするところに書くことで以下のように書いて足踏みしている画像が描けた。
playerMove ++; // 60フレームの中で、このifで条件(playerMove> 0)が真であるためplayerMove ++を「フレーム」と「条件式」により繰り返しplayerMove ++して、
if ( playerMove == 10 )//以前の文を否定しないelse ifが次にあるためplayerMoveの情報を引き継ぎplayerMove == 20となるまで繰り返しplayerMove ++をした。次にもelse ifがあるので同様、、 、
{
playerImage = playerGHandle [ 4 ] ;
}
else if ( playerMove == 20 )//条件式として書くため=は==と書いた。//elseifによりplayerMoveが20を超えて(20の場合を否定し)30の場合を表す。
{
playerImage = playerGHandle [ 5 ] ;
}
else if ( playerMove == 40 )// 30まで上がったものが40に上がった時、playerGHandle [4]になる。if文の連続では文法のルールで前の文を否定するため連続的に画像が流れず足踏みできない、なのでelse ifにしたのだ。
{
playerImage = playerGHandle [ 4 ] ;
}
else if ( playerMove == 60 * 4 ) { //下に書いているように60フレームないに納めないといけないため、50まで上がったところで終わっている。
playerImage = playerGHandle [ 3 ] ; //上に書いてることには誤りがある、60フレームで1sなだけ、超えてもいい。
playerMove = 1 ; //
}
}
//ループ内に書いたenemyMoveについてenemyMoveが0より大きくて40を超えたら{}の中身を実行。
if ( enemyMove > 0 && ++ enemyMove > 40 ) { // pcが60フレームで一周するためenemyMoveが61以上だとenemyGHandle [8]が反映されず元のままで移動が終わる。以来enemyMoveは60以下でなくてはならない
enemyMove = 0 ; enemyImage = enemyGHandle [ 11 ] ; // 60になる前に画像11を描画するようにしなければならないため、60リクエスト40フレームにした。
}
}
//これより以下は描画するためのプログラム
ClearDrawScreen (); //裏画面を
// if(function_status == 0){// function_status = 0の時はメニュー画面でfunction_statusが1の時は戦闘画面とした。
//キーXを押すとfunction_statusを0とするように書いた
if ( function_status == 0 ) {
ホワイト= GETCOLOR (255 、 255 、 255 ); //色の取得
DrawString (100 、 140 、 "メニュー画面(Xをプッシュ)" 、白)。
//攻撃手段を選んでいる最中は0とする
ScreenFlip (); //裏画面を表画面に反映
}
else { //ステージの描画
INT stageColor = GETCOLOR (160 、 64 、 64 )。
for (int i = 0 ; i < 4 ; i ++ )
DrawLine (ステージ[ i ] [ 0 ] [ 0 ] 、ステージ[ i ] [ 0 ] [ 1 ] 、
stage [ i ] [ 6 ] [ 0 ] 、 stage [ i ] [ 6 ] [ 1 ] 、 stageColor 、 5 );
for (int j = 0 ; j < 7 ; j ++ )
DrawLine (ステージ[ 0 ] [ j ] [ 0 ] 、ステージ[ 0 ] [ j ] [ 1 ] 、
stage [ 3 ] [ j ] [ 0 ] 、 stage [ 3 ] [ j ] [ 1 ] 、 stageColor 、 5 );
DrawGraph ( pos [ enemyY ] [ enemyX ] [ 0 ] 、 pos [ enemyY ] [ enemyX ] [ 1 ] 、
enemyImage 、 true ); //敵キャラの描画
DrawGraph ( pos [ playerY ] [ playerX ] [ 0 ] 、 pos [ playerY ] [ playerX ] [ 1 ] 、
playerImage 、 true ); //俺キャラの描画
if ( lock == 1 ) {
DrawGraph ( pos [ enemyY ] [ enemyX ] [ 0 ] 、 pos [ enemyY ] [ enemyX ] [ 1 ] 、
lockImge 、 FALSE ); //ロックマーク中だけ描画するようにした。
} //ロックマークの描画
もし (ロック) DrawFormatString (100 、 200 、 GETCOLOR (255 、 255 、 255 )、 "LOCK" )。 //ループ内に書くと条件式lockのによりlockの値を0にしてもずっと表示されるため、必要な時に表示するようにここに書いた
DrawFormatString (50 、 300 、 GETCOLORを(255 、 0 、 0 )、 "%D /%D" 、カウント、 COUNT2 )。//殴った回数をカウントを表示するための関数
}
ScreenFlip (); //裏画面を表画面に反映
}
DxLib_End (); // DXライブラリ使用の終了処理
0を返します。 //ソフトの終了
}
こんなシンプルに解決してしまうなんて、恐れ入ります。
ただ欲を言うと連続攻撃を行えるのは大変ありがたいのですが、すぐに0になっても50になってしまうため、制限のようなものがありません。
なのでゆっくり+1されて50になるようにできないでしょうか。
私が考えたのは時間の関数を使い0.5秒ごとに+1されるなど考えました。
あるいは、あえて時間をかけて+1されるようにダミーのデータを挟むなども良いと思いました(実装の仕方はまだわかりませんが)
フレームは利用するにしては速いため多分使えないと考えました。
ちなみに、管理人様はツイッターや講師の方ですか?管理人様が有料で講師などされているならば是非受講したいです!
 |
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.3 ) |
- 名前:マーク42 日時:2019/09/22 15:25
あの後、ゆっくり+1ずつcountが増えるように書いたのですが、実行したとたんにものすごい勢いでcountの値が上がっていきます。原因がわかりません。
編集した部分です。
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}
}
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
if (count < 50)++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 10 == 0) { ++count<50; }//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
以下は全体のプログラムです。
#include "DxLib.h"
int Key[256];
int gpUpdateKey()
{
char tmpKey[256];
GetHitKeyStateAll(tmpKey);
for (int i = 0; i < 256; i++)
(tmpKey[i] == 0) ? (Key[i] = 0) : Key[i]++;
return 0;
}
int stage[4][7][2]; // 盤上のマスの格子点の座標
int pos[3][6][2]; // キャラ描画座標
void init_stage() // stage と pos を初期化する
{
for (int j = 0; j < 7; j++) {
int w = (j - 3) * 100, h = 300;
for (int i = 4; --i >= 0; ) {
stage[i][j][0] = w + 400, stage[i][j][1] = h - 100;
w = w * 9 / 10, h = h * 9 / 10;
}
}
for (int i = 0; i < 3; i++)
for (int j = 0; j < 6; j++) {
pos[i][j][0] = (stage[i][j][0] + stage[i + 1][j + 1][0]) / 2 - 25;
pos[i][j][1] = (stage[i][j][1] + stage[i + 1][j + 1][1]) / 2 - 65;
}
}
int White;
int function_status;//戦闘画面中は1とするための変数function_statusの定義
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
SetGraphMode(780, 680, 32); // ウィンドウの大きさを指定
ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用
if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理
SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定
init_stage(); // stage, pos の初期化
int enemyX = 4, enemyY = 1; // 敵の位置
int playerX = 1, playerY = 1; // 俺の位置
int enemyMove = 0; // 敵の移動状態
// 俺の移動状態//1〜21で右に振り向きのプログラム@が終わり、22になったら足踏みするAを実行するようにする。
int playerMove = 1;
int lockonMove = 0;
int lockonHandle[3];
function_status = 1;//最初は1にして戦闘画面状態にする。
int lock = 0; // ロック状態
int enemyGHandle[12]; // 敵のグラフィックハンドル格納用配列
int playerGHandle[12]; // 俺のグラフィックハンドル格納用配列
// 0-2:後ろ向き、3-5:右向き、6-8:前向き、9-11:左向き
LoadDivGraph("charall.png", 12, 3, 4, 49, 66, enemyGHandle);
LoadDivGraph("charall.png", 12, 3, 4, 49, 66, playerGHandle);
LoadDivGraph("lockon.bmp", 3, 3, 1, 23, 23, lockonHandle);
int enemyImage = enemyGHandle[11]; // 敵 左向き
int playerImage = playerGHandle[4]; // 俺 右向き
int lockImge = lockonHandle[3];
int preplayerX;
int after = 0;
unsigned int count = 50;
int count2 = 50;
unsigned int count3 = 50;
int count4 = 0;
int frames = 0; // フレーム数
const int MOVE_INTERVAL = 1000; // 何ミリ秒ごとに移動処理をするか
int nextMoveTime = GetNowCount() + MOVE_INTERVAL; // 次回移動処理をする時刻
int stopCount = 0; // 動かないのがあと何回か
while (ProcessMessage() == 0) {
gpUpdateKey(); // キーの入力状態を取得
if (Key[KEY_INPUT_X] == 1) { //キーXを押すとfunction_statusは0になる
function_status = 0;
}
if (Key[KEY_INPUT_Y] == 1) { //キーYを押すとfunction_statusは1になる
function_status = 1;//戦闘画面に戻す
}
else {//戦闘画面中は1とする
//gpUpdateKey(); // キーの入力状態を取得 上のifで既にgpUpdateKey();があり、elseはif以外の情報は引き継ぐので再びgpUpdateKey();書く必要はなかった。
// 俺の移動
if (Key[KEY_INPUT_RIGHT] == 1 && playerX < 2) { //キーを入力する以外にも押した後に早く画像を切り替えて足踏みするようにするために初期値にも1はあるがキーにもplayerMove=1を書いたり、キーを押したらどうしたいかをするためにplayerX++を書いている。
playerMove = 1; playerX++; playerImage = playerGHandle[2];
} //playerMove = 1;があると下に書いたplayerMoveより足踏みするplayerMoveが無いと初期値の1でそのまま足踏みするので遅く反応するのでは?
if (Key[KEY_INPUT_LEFT] == 1 && playerX > 0) {//キーにplayerMove=1を書くと初期値の1よりも早くキーに書いたplayerMoveの1が行くため早く足踏みに行くため、止まってから足踏みに行くまでの間にある向きを変える画像playerGHandle[2]が一瞬であるため、向きを変えるのが早く見えるのでは?足踏みを速く来るようにしたため。
playerMove = 1; playerX--; playerImage = playerGHandle[9];//まあ、足踏みさせなくても、ただ書くだけでも方向を十分早く変えれる
}
if (Key[KEY_INPUT_UP] == 1 && playerY > 0) {
playerMove = 1; playerY--; playerImage = playerGHandle[2];
}
if (Key[KEY_INPUT_DOWN] == 1 && playerY < 2) {
playerMove = 1; playerY++; playerImage = playerGHandle[8];
}
//Rが一度押された上でフレームを利用してループさせるためにif文を新しく外に書いたのだ。
if (Key[KEY_INPUT_R] == 1 && playerY == enemyY) {
DrawGraph(pos[enemyY][enemyX][0], pos[enemyY][enemyX][1],//多分ここはいらない下に描画するための関数を書くため
lockImge, FALSE); // ロックマークの描画
lock = 1;//Key[KEY_INPUT_R] == 1 && playerY == enemyYの時、lockを1にする。lockを「何フレーム目の時」でも値を1として置いたため、条件式lockの入力キーAに呼び出せる。
lockonMove = 1;
}
if (lockonMove > 0) {//lockonMoveが0より大きいならば++lockonMoveをする、
++lockonMove;
}
if (lockonMove == 10) {
lockImge = lockonHandle[0];//情報lockonMove == 10やlockonHandle[0]を引き継いで下に書いた描画関数に入るため、ここには関数に入れる情報だけ入るのだ。
//その時の情報lockonMove == 10やlockonHandle[0]以外の引き継がれたとうかその時の敵の座標なども関数に入る。関数が求めるものが入るので、関数に必要なものを揃える。
}
else if (lockonMove == 20) {
lockImge = lockonHandle[1];
}
else if (lockonMove == 30) {
lockImge = lockonHandle[2];
}
else if (lockonMove == 40) {
lockImge = lockonHandle[1];
lockonMove = 1;
}
if (playerY != enemyY) {
lock = 0;
lockonMove = 0;//敵が移動した場合ロックオンの画像が消えるようにlockonMoveを0にする。
}
//playerY != enemyYよりY座標が異なる場合を表す、Y座標が異なる場合はlockの値は0になる。要はロックが解除されてしまう。
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}
}
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
if (count < 50)++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 10 == 0) { ++count<50; }//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
if (after > 0 && ++after > 15) {//afterが1より大きい時++afterが働き15より大きくなったら、
///ifの中にifを書いてしまうとその前のifを否定してしまうためデータが引き継げない。なので別のif文として書いた。←多分違う
playerX = preplayerX;//preplayerXの座標をplayerXに代入する。
playerImage = playerGHandle[4];
after = 0;//アタック解除
}
// 敵の移動
int t = GetNowCount();
if (t >= nextMoveTime) { // 指定の時間が経ったら(1sごとに)
nextMoveTime = t + MOVE_INTERVAL; // 次回移動処理をする時刻
if (stopCount > 0) { // 停止中のとき
stopCount--; // 止まっている残り時間(回数)を減らす
}
else { // 普通の状態のとき
if (GetRand(99) < 10) { // たまに(10%の確率で)
stopCount = GetRand(4); // 数秒間(1〜5秒間)その場に止まる
}
else { // 9マス上のいずれかのパネルに移動させる
int cy = enemyY, cx = enemyX;
do {
enemyY = GetRand(2);
enemyX = GetRand(2) + 3;
} while (enemyX == cx && enemyY == cy ||
enemyX == playerX && enemyY == playerY);
enemyImage = enemyGHandle[10];
enemyMove = 1;
}
}
}
if (playerMove > 0) {//1フレームで処理を終わらせるためifの後はelse ifを使った。//フレームがあってもplayerMove++を書かないと1ずつ上がらない。playerMove++をフレームの60回ループするするところに書くことで以下のように書いて足踏みしている画像が描けた。
playerMove++;//60フレームの中で、このifで条件(playerMove > 0)が真であるためplayerMove++を「フレーム」と「条件式」により繰り返しplayerMove++して、
if (playerMove == 10)//以前の文を否定しないelse ifが次にあるためplayerMoveの情報を引き継ぎplayerMove == 20となるまで繰り返しplayerMove++をした。次にもelse ifがあるので同様、、、
{
playerImage = playerGHandle[4];
}
else if (playerMove == 20)//条件式として書くため=は==と書いた。//else ifによりplayerMoveが20を超えて(20の場合を否定し)30の場合を表す。
{
playerImage = playerGHandle[5];
}
else if (playerMove == 40)//30まで上がったものが40に上がった時、playerGHandle[4]になる。if文の連続では文法のルールで前の文を否定するため連続的に画像が流れず足踏みできない、なのでelse ifにしたのだ。
{
playerImage = playerGHandle[4];
}
else if (playerMove == 60 * 4) {//下に書いているように60フレームないに納めないといけないため、50まで上がったところで終わっている。
playerImage = playerGHandle[3];//上に書いてることには誤りがある、60フレームで1sなだけ、超えてもいい。
playerMove = 1;//
}
}
//ループ内に書いたenemyMoveについてenemyMoveが0より大きくて40を超えたら{}の中身を実行。
if (enemyMove > 0 && ++enemyMove > 40) {//pcが60フレームで一周するためenemyMoveが61以上だとenemyGHandle[8]が反映されず元のままで移動が終わる。なのでenemyMoveは60以下でなくてはならない
enemyMove = 0; enemyImage = enemyGHandle[11];//60になる前に画像11を描画するようにしなければならないため、60より小さい40フレームにした。
}
}
//これより以下は描画するためのプログラム
ClearDrawScreen(); // 裏画面を
//if (function_status == 0) {//function_status = 0の時はメニュー画面でfunction_statusが1の時は戦闘画面とした。
//キーXを押すとfunction_statusを0とするように書いた
if (function_status == 0) {
White = GetColor(255, 255, 255); //色の取得
DrawString(100, 140, "メニュー画面 (xをプッシュ)", White);
//攻撃手段を選んでいる最中は0とする
ScreenFlip(); // 裏画面を表画面に反映
}
else {// ステージの描画
int stageColor = GetColor(160, 64, 64);
for (int i = 0; i < 4; i++)
DrawLine(stage[i][0][0], stage[i][0][1],
stage[i][6][0], stage[i][6][1], stageColor, 5);
for (int j = 0; j < 7; j++)
DrawLine(stage[0][j][0], stage[0][j][1],
stage[3][j][0], stage[3][j][1], stageColor, 5);
DrawGraph(pos[enemyY][enemyX][0], pos[enemyY][enemyX][1],
enemyImage, true); // 敵キャラの描画
DrawGraph(pos[playerY][playerX][0], pos[playerY][playerX][1],
playerImage, true); // 俺キャラの描画
if (lock == 1) {
DrawGraph(pos[enemyY][enemyX][0], pos[enemyY][enemyX][1],
lockImge, FALSE);//ロックマーク中だけ描画するようにした。
}//ロックマークの描画
if (lock) DrawFormatString(100, 200, GetColor(255, 255, 255), "LOCK");//ループ内に書くと条件式lockのによりlockの値を0にしてもずっと表示されるため、必要な時に表示するようにここに書いた
DrawFormatString(50, 300, GetColor(255, 0, 0), "%d/%d", count, count2);//殴った回数をカウントを表示するための関数
}
ScreenFlip(); // 裏画面を表画面に反映
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}
 |
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.4 ) |
- 名前:マーク42 日時:2019/09/22 16:31
解決できましたが、他の問題が発生しました。
編集した部分です。
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}
}
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
if (count < 50)++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 10 == 0) { ++count; if (count > 50) { count = 50; }
}//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
以下は全体のプログラムです。
#include "DxLib.h"
int Key[256];
int gpUpdateKey()
{
char tmpKey[256];
GetHitKeyStateAll(tmpKey);
for (int i = 0; i < 256; i++)
(tmpKey[i] == 0) ? (Key[i] = 0) : Key[i]++;
return 0;
}
int stage[4][7][2]; // 盤上のマスの格子点の座標
int pos[3][6][2]; // キャラ描画座標
void init_stage() // stage と pos を初期化する
{
for (int j = 0; j < 7; j++) {
int w = (j - 3) * 100, h = 300;
for (int i = 4; --i >= 0; ) {
stage[i][j][0] = w + 400, stage[i][j][1] = h - 100;
w = w * 9 / 10, h = h * 9 / 10;
}
}
for (int i = 0; i < 3; i++)
for (int j = 0; j < 6; j++) {
pos[i][j][0] = (stage[i][j][0] + stage[i + 1][j + 1][0]) / 2 - 25;
pos[i][j][1] = (stage[i][j][1] + stage[i + 1][j + 1][1]) / 2 - 65;
}
}
int White;
int function_status;//戦闘画面中は1とするための変数function_statusの定義
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
SetGraphMode(780, 680, 32); // ウィンドウの大きさを指定
ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用
if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理
SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定
init_stage(); // stage, pos の初期化
int enemyX = 4, enemyY = 1; // 敵の位置
int playerX = 1, playerY = 1; // 俺の位置
int enemyMove = 0; // 敵の移動状態
// 俺の移動状態//1〜21で右に振り向きのプログラム@が終わり、22になったら足踏みするAを実行するようにする。
int playerMove = 1;
int lockonMove = 0;
int lockonHandle[3];
function_status = 1;//最初は1にして戦闘画面状態にする。
int lock = 0; // ロック状態
int enemyGHandle[12]; // 敵のグラフィックハンドル格納用配列
int playerGHandle[12]; // 俺のグラフィックハンドル格納用配列
// 0-2:後ろ向き、3-5:右向き、6-8:前向き、9-11:左向き
LoadDivGraph("charall.png", 12, 3, 4, 49, 66, enemyGHandle);
LoadDivGraph("charall.png", 12, 3, 4, 49, 66, playerGHandle);
LoadDivGraph("lockon.bmp", 3, 3, 1, 23, 23, lockonHandle);
int enemyImage = enemyGHandle[11]; // 敵 左向き
int playerImage = playerGHandle[4]; // 俺 右向き
int lockImge = lockonHandle[3];
int preplayerX;
int after = 0;
unsigned int count = 50;
int count2 = 50;
unsigned int count3 = 50;
int count4 = 0;
int frames = 0; // フレーム数
const int MOVE_INTERVAL = 1000; // 何ミリ秒ごとに移動処理をするか
int nextMoveTime = GetNowCount() + MOVE_INTERVAL; // 次回移動処理をする時刻
int stopCount = 0; // 動かないのがあと何回か
while (ProcessMessage() == 0) {
gpUpdateKey(); // キーの入力状態を取得
if (Key[KEY_INPUT_X] == 1) { //キーXを押すとfunction_statusは0になる
function_status = 0;
}
if (Key[KEY_INPUT_Y] == 1) { //キーYを押すとfunction_statusは1になる
function_status = 1;//戦闘画面に戻す
}
else {//戦闘画面中は1とする
//gpUpdateKey(); // キーの入力状態を取得 上のifで既にgpUpdateKey();があり、elseはif以外の情報は引き継ぐので再びgpUpdateKey();書く必要はなかった。
// 俺の移動
if (Key[KEY_INPUT_RIGHT] == 1 && playerX < 2) { //キーを入力する以外にも押した後に早く画像を切り替えて足踏みするようにするために初期値にも1はあるがキーにもplayerMove=1を書いたり、キーを押したらどうしたいかをするためにplayerX++を書いている。
playerMove = 1; playerX++; playerImage = playerGHandle[2];
} //playerMove = 1;があると下に書いたplayerMoveより足踏みするplayerMoveが無いと初期値の1でそのまま足踏みするので遅く反応するのでは?
if (Key[KEY_INPUT_LEFT] == 1 && playerX > 0) {//キーにplayerMove=1を書くと初期値の1よりも早くキーに書いたplayerMoveの1が行くため早く足踏みに行くため、止まってから足踏みに行くまでの間にある向きを変える画像playerGHandle[2]が一瞬であるため、向きを変えるのが早く見えるのでは?足踏みを速く来るようにしたため。
playerMove = 1; playerX--; playerImage = playerGHandle[9];//まあ、足踏みさせなくても、ただ書くだけでも方向を十分早く変えれる
}
if (Key[KEY_INPUT_UP] == 1 && playerY > 0) {
playerMove = 1; playerY--; playerImage = playerGHandle[2];
}
if (Key[KEY_INPUT_DOWN] == 1 && playerY < 2) {
playerMove = 1; playerY++; playerImage = playerGHandle[8];
}
//Rが一度押された上でフレームを利用してループさせるためにif文を新しく外に書いたのだ。
if (Key[KEY_INPUT_R] == 1 && playerY == enemyY) {
DrawGraph(pos[enemyY][enemyX][0], pos[enemyY][enemyX][1],//多分ここはいらない下に描画するための関数を書くため
lockImge, FALSE); // ロックマークの描画
lock = 1;//Key[KEY_INPUT_R] == 1 && playerY == enemyYの時、lockを1にする。lockを「何フレーム目の時」でも値を1として置いたため、条件式lockの入力キーAに呼び出せる。
lockonMove = 1;
}
if (lockonMove > 0) {//lockonMoveが0より大きいならば++lockonMoveをする、
++lockonMove;
}
if (lockonMove == 10) {
lockImge = lockonHandle[0];//情報lockonMove == 10やlockonHandle[0]を引き継いで下に書いた描画関数に入るため、ここには関数に入れる情報だけ入るのだ。
//その時の情報lockonMove == 10やlockonHandle[0]以外の引き継がれたとうかその時の敵の座標なども関数に入る。関数が求めるものが入るので、関数に必要なものを揃える。
}
else if (lockonMove == 20) {
lockImge = lockonHandle[1];
}
else if (lockonMove == 30) {
lockImge = lockonHandle[2];
}
else if (lockonMove == 40) {
lockImge = lockonHandle[1];
lockonMove = 1;
}
if (playerY != enemyY) {
lock = 0;
lockonMove = 0;//敵が移動した場合ロックオンの画像が消えるようにlockonMoveを0にする。
}
//playerY != enemyYよりY座標が異なる場合を表す、Y座標が異なる場合はlockの値は0になる。要はロックが解除されてしまう。
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}
}
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
if (count < 50)++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 10 == 0) { ++count; if (count > 50) { count = 50; }
}//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
//★あるフレームが進んでから画像がを動くまでを遅くした、ならば、あるフレームが進んだら数字も次の数字に移るまで遅くできるのは?と考えた。
if (after > 0 && ++after > 15) {//afterが1より大きい時++afterが働き15より大きくなったら、
///ifの中にifを書いてしまうとその前のifを否定してしまうためデータが引き継げない。なので別のif文として書いた。←多分違う
playerX = preplayerX;//preplayerXの座標をplayerXに代入する。
playerImage = playerGHandle[4];
after = 0;//アタック解除
}
// 敵の移動
int t = GetNowCount();
if (t >= nextMoveTime) { // 指定の時間が経ったら(1sごとに)
nextMoveTime = t + MOVE_INTERVAL; // 次回移動処理をする時刻
if (stopCount > 0) { // 停止中のとき
stopCount--; // 止まっている残り時間(回数)を減らす
}
else { // 普通の状態のとき
if (GetRand(99) < 10) { // たまに(10%の確率で)
stopCount = GetRand(4); // 数秒間(1〜5秒間)その場に止まる
}
else { // 9マス上のいずれかのパネルに移動させる
int cy = enemyY, cx = enemyX;
do {
enemyY = GetRand(2);
enemyX = GetRand(2) + 3;
} while (enemyX == cx && enemyY == cy ||
enemyX == playerX && enemyY == playerY);
enemyImage = enemyGHandle[10];
enemyMove = 1;
}
}
}
//足踏みをすべてifにすると前の条件を満たしてしまい次のifに進まないため、前の条件以外の残り物playerMove == 10などの条件を継続させないために、その条件を省くためにelse ifとした。
if (playerMove > 0) {//1フレームで処理を終わらせるためifの後はelse ifを使った。//フレームがあってもplayerMove++を書かないと1ずつ上がらない。playerMove++をフレームの60回ループするするところに書くことで以下のように書いて足踏みしている画像が描けた。
playerMove++;//60フレームの中で、このifで条件(playerMove > 0)が真であるためplayerMove++を「フレーム」と「条件式」により繰り返しplayerMove++して、
if (playerMove == 10)//以前の文を否定しないelse ifが次にあるためplayerMoveの情報を引き継ぎplayerMove == 20となるまで繰り返しplayerMove++をした。次にもelse ifがあるので同様、、、
{
playerImage = playerGHandle[4];
}
else if (playerMove == 20)//条件式として書くため=は==と書いた。//else ifによりplayerMoveが20を超えて(20の場合を否定し)30の場合を表す。
{
playerImage = playerGHandle[5];
}
else if (playerMove == 40)//30まで上がったものが40に上がった時、playerGHandle[4]になる。if文の連続では文法のルールで前の文を否定するため連続的に画像が流れず足踏みできない、なのでelse ifにしたのだ。
{
playerImage = playerGHandle[4];
}
else if (playerMove == 60 * 4) {//下に書いているように60フレームないに納めないといけないため、50まで上がったところで終わっている。
playerImage = playerGHandle[3];//上に書いてることには誤りがある、60フレームで1sなだけ、超えてもいい。
playerMove = 1;//
}
}
//ループ内に書いたenemyMoveについてenemyMoveが0より大きくて40を超えたら{}の中身を実行。
if (enemyMove > 0 && ++enemyMove > 40) {//pcが60フレームで一周するためenemyMoveが61以上だとenemyGHandle[8]が反映されず元のままで移動が終わる。なのでenemyMoveは60以下でなくてはならない
enemyMove = 0; enemyImage = enemyGHandle[11];//60になる前に画像11を描画するようにしなければならないため、60より小さい40フレームにした。
}
}
//これより以下は描画するためのプログラム
ClearDrawScreen(); // 裏画面を
//if (function_status == 0) {//function_status = 0の時はメニュー画面でfunction_statusが1の時は戦闘画面とした。
//キーXを押すとfunction_statusを0とするように書いた
if (function_status == 0) {
White = GetColor(255, 255, 255); //色の取得
DrawString(100, 140, "メニュー画面 (xをプッシュ)", White);
//攻撃手段を選んでいる最中は0とする
ScreenFlip(); // 裏画面を表画面に反映
}
else {// ステージの描画
int stageColor = GetColor(160, 64, 64);
for (int i = 0; i < 4; i++)
DrawLine(stage[i][0][0], stage[i][0][1],
stage[i][6][0], stage[i][6][1], stageColor, 5);
for (int j = 0; j < 7; j++)
DrawLine(stage[0][j][0], stage[0][j][1],
stage[3][j][0], stage[3][j][1], stageColor, 5);
DrawGraph(pos[enemyY][enemyX][0], pos[enemyY][enemyX][1],
enemyImage, true); // 敵キャラの描画
DrawGraph(pos[playerY][playerX][0], pos[playerY][playerX][1],
playerImage, true); // 俺キャラの描画
if (lock == 1) {
DrawGraph(pos[enemyY][enemyX][0], pos[enemyY][enemyX][1],
lockImge, FALSE);//ロックマーク中だけ描画するようにした。
}//ロックマークの描画
if (lock) DrawFormatString(100, 200, GetColor(255, 255, 255), "LOCK");//ループ内に書くと条件式lockのによりlockの値を0にしてもずっと表示されるため、必要な時に表示するようにここに書いた
DrawFormatString(50, 300, GetColor(255, 0, 0), "%d/%d", count, count2);//殴った回数をカウントを表示するための関数
}
ScreenFlip(); // 裏画面を表画面に反映
}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了
}
 |
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.5 ) |
- 名前:管理人 日時:2019/09/22 23:30
> 解決できましたが
問題が解決したようで何よりです
> 他の問題が発生しました。
コメントを拝見する限りでは他の問題は無さそうですが、他にも何か問題が発生したのでしょうか?
> ちなみに、管理人様はツイッターや講師の方ですか?管理人様が有料で講師などされているならば是非受講したいです!
いえ、DXライブラリ関連( DXライブラリの開発・掲示板対応 )以外の活動は特にしていません
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.6 ) |
- 名前:マーク42 日時:2019/09/23 06:46
すいません、新たな問題の内容を書き忘れていました。
[発生した問題]
Rキーを押して敵をロックオンしてAを押すと攻撃するので50から10引かれて40になるところがなぜか30になってしまいます。
どこかで条件が被っていて変な計算になっているのか、探しても他のですが、構文的に問題がないため、問題点が見つかりませんでした。
[行いたいこと]
Rキーを押して敵をロックオンしてAを押すと攻撃して50から10を引いて、さらにAを押すと連続攻撃できるため40からさらに10を減らすようにしたいです。
条件なしになら作れたのですが
if (count < 50)++frames;
if (frames % 10 == 0) { ++count; if (count > 50) { count = 50; }}
の条件付きで書こうとすると今回の問題が起きて詰みました。
余談ですが、
管理人様はたった一人でこの質問サイトの問題を解決していますが、何者なのでしょうか?というか何をなされている方なのでしょうか?
DXライブラリを用いてゲーム作製などに携わっている方なのでしょうか?
質問が多くなりすいません。
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.7 ) |
- 名前:マーク42 日時:2019/09/23 08:30
できれば、なぜ今回のような問題が起こってしまったのか教えて頂けると勉強になります。
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.8 ) |
- 名前:管理人 日時:2019/09/23 22:28
> [発生した問題]
> Rキーを押して敵をロックオンしてAを押すと攻撃するので50から10引かれて40になるところがなぜか30になってしまいます。
> どこかで条件が被っていて変な計算になっているのか、探しても他のですが、構文的に問題がないため、問題点が見つかりませんでした。
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}
}
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
こちらの部分で Aキーを押すと『count = count - 10;//キーAを押すたびに10だけ引く』の行で count から 10 引かれ
その直後の『if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])』の条件も真となる
( Aキーが押されている & enemyImage にも enemyGHandle[5] が代入されているので )
ので、if文の中の『count = count - 10;』が実行されて count から合計 20 引かれる、という状態になっています
直し方ですが、後半の if文は lock が 1 ではないときのみ実行されるように変更すると良い気がします
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}
}
else
{
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
}
> 余談ですが、
> 管理人様はたった一人でこの質問サイトの問題を解決していますが、何者なのでしょうか?というか何をなされている方なのでしょうか?
ゲーム会社でゲームのプログラムを書く仕事をしています
> DXライブラリを用いてゲーム作製などに携わっている方なのでしょうか?
仕事で製作するゲームにDXライブラリは使われていません
( 仕事でDXライブラリを使ってゲーム製作ができたらDXライブラリの開発やメンテナンスも一緒にできて最高なのですが… )
なのでDXライブラリ関連の作業や掲示板のご返信は、仕事が終わって帰宅した後や休日に行っています
 |
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.9 ) |
- 名前:マーク42 日時:2019/09/24 01:14
いつもどうもありがとうございます!
納得です(;'∀')なんでこんなミスが気が付かなったのか、、、まだまだ未熟です。
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}
}
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
最初のif文でenemyImage = enemyGHandle[5]がセットされしまい、かつキーAを押すため次のif文も真になる、すなわち働いてしまうため
if文の中の『count = count - 10;』が実行されて count から合計 20 引かれる、という状態になるのですね!
わかりやすい解説感謝します。
あの今更で申し訳ないのですが、最初の質問のif (count <= 41 && ++count <= 50)に関して改めてデバッグして疑問が出たのですが、
「count = count - 10;//キーAを押すたびに10だけ引く」よりcountは40になるのでcount <= 41の条件を満たし
繰り上がると思ったのですが繰り上がりませんでした。
なぜでしょうか。
 |
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.10 ) |
- 名前:管理人 日時:2019/09/25 00:27
> あの今更で申し訳ないのですが、最初の質問のif (count <= 41 && ++count <= 50)に関して改めてデバッグして疑問が出たのですが、
> 「count = count - 10;//キーAを押すたびに10だけ引く」よりcountは40になるのでcount <= 41の条件を満たし
> 繰り上がると思ったのですが繰り上がりませんでした。
すみません、『繰り上がる』とは具体的にはどのような動作を指しているのでしょうか?
1増える、という意味でしたらたしかにその通りで、countは40から41に増えるはずです
42まで増えるとcount <= 41の条件を満たさなくなるので、countは42以上には増えないはずです
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.11 ) |
- 名前:マーク42 日時:2019/09/25 01:47
返信ありがとうございます!
伝え方が下手ですいません。
countは50なのでcount - 10は40になります。
そして、if文のcount <= 41よりcountが40より小さい数値あるいは41の時にcountは50まで+1されていきます。
countは40でifの条件に入るはずなのにと思っていましたが。
++count <= 50よりcountが42になったらcount <= 41の条件に背くので42からは+1されずで止まってしまうわけですね。
正しいでしょうか。
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.12 ) |
- 名前:管理人 日時:2019/09/25 23:57
> ++count <= 50よりcountが42になったらcount <= 41の条件に背くので42からは+1されずで止まってしまうわけですね。
>
> 正しいでしょうか。
はい、その通りです
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.13 ) |
- 名前:マーク42 日時:2019/09/26 02:14
管理人様、確認ありがとうございます。
最後に以下のプログラムで連続で攻撃するとどうしてもcountが負の値になってしまいます。
試したことはif (Key[KEY_INPUT_A] == 1 && count <= 50 && count>=0)と書いてcountは0以上で負の数値ではないと書いてもうまくいかず
どうすれば負の値に突入しないで済むかわかりません。
if (lock) {
if (Key[KEY_INPUT_A] == 1 && count <= 50) { //殴る//(lock){}の中に書くとロックする度にcountが0になるので意味がない
//count++; ここにcount書くとifの条件よりcountが0の時の下のlockやplayerX = enemyX - 1など条件になるため、++でcountが1になったらロックできても攻撃できないんだ
//ここのcountの情報がそのまま下の描画関数に渡されるだけ。
//if (count >= 0 && ++count > 40) {//countが0から15になるまでを一フレームで表しただけでは?ようはcountを0〜1にするのに15フレームかかっただけでは?いや、単純にここにフレームは働いていないなので++count > 40と書いて39回行うはずがフレームが働かないので1しか上がっていないので一回しか攻撃が出来ないのだ
lock = 0;//lock = 1の時の「lock!!」の描画を消すためにlockの値を0に変更。
lockonMove = 0;//アタックする時 ロックオンの画像が消えるように値を0にする。
preplayerX = playerX; // 元の位置を保持
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
enemyImage = enemyGHandle[5];//攻撃を食らうと右向きになるようにする
count = count - 10;//キーAを押すたびに10だけ引く
}//★if (Key[KEY_INPUT_A] == 1 && count <= 50 && count>=0)としてもcountが0以上で4とかの場合、10引かれてマイナスになるので意味がない。
}
else
{
if (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])//敵が右向きの時に続けてAを押すと連続攻撃ができる//相手がenemyImage == enemyGHandle[5]状態の時に他の攻撃もできるように他のキーも&&すればいい
{
count = count - 10;
playerX = enemyX - 1; // 俺は敵の眼前へ
after = 1;//アタック状態 ここまでをアタックとしてafter = 1と置いた。
}
}
if (count < 50)++frames;//framesが5で割りきれる時に+countが+1されいく。//countが50より小さい時、framesがフレームにより+1ずつされていき、10で割り切れる際にcountが50になるまで+1される、++により最初+1が追加され49かい+1されるので結果的にcountは50になる。
if (frames % 10 == 0) {
++count; if (count > 50) { count = 50; }
}//これにより連続で攻撃してもif (Key[KEY_INPUT_A] == 1 && enemyImage == enemyGHandle[5])を考慮して連続攻撃ができる!
 |
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.14 ) |
- 名前:管理人 日時:2019/09/27 00:36
> 試したことはif (Key[KEY_INPUT_A] == 1 && count <= 50 && count>=0)と書いてcountは0以上で負の数値ではないと書いてもうまくいかず
> どうすれば負の値に突入しないで済むかわかりません。
count が 10 未満のときに 10 引いたら負の数値になってしまいますので、
count を負の数値にしない為には
if (Key[KEY_INPUT_A] == 1 && count <= 50 && count>=10)
とする必要があります
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.15 ) |
- 名前:マーク42 日時:2019/09/27 03:33
いつも大変お世話になっております。
爪が甘かったです。
最初から条件文にいれれば良かったのですね。
どうもありがとうございます!
|
Re: 50から10ずつ減っていき、ゆっくり1ずつ戻り50になる。 ( No.16 ) |
- 名前:マーク42 日時:2019/09/27 16:35
追加攻撃の方にも&& count >= 10を付け足すことでマイナスに突入することはなくなりました。
どうもありがとうございます!
|
|