今自分が悩んでいることは
1.アニメーションのスピードが速いので自然に描画できるよう改善したい。
2.左クリック長押ししているとアニメーションが止まるので長押し状態でもアニメーションを動かしたい。
3.腕が360°回るので腕の回る上限を決めたい。
1.について
WaitTimer関数を用いて改善しようと思ったのですが、Waitが他の処理にも影響してしまい
描画の挙動がおかしいです。
2.について
今作っているゲームは左クリックで弾を撃ちます。長押しでなければ問題ないのですが長押し状態だと
アニメーションが止まってしまいます。
3.について
今作っているゲームはマウスで狙いを付ける仕様です。その為[身体の画像]と[腕の画像]を組み合わせ、[腕の画像]をマウスカーソルの方向に回転させています。しかし腕が360°回転してしまうので人間の可動範囲に上限を決めたいと思っています。
ソースはこちらです。
#include "DxLib.h"
#include <math.h>
void Player(void);
//キー取得用配列
char key[256];
//ジャンプしてるかのフラグ。
bool jflag = false;
//プレイヤー用配列
//player[0~6]=左に走るグラフィック [7,8]=左向き停止中グラフィック
//[9~13]=なし [14~20]=右に走るグラフィック [21,22]=右向き停止中グラフィック
//[23~27]=なし [28]=右向きジャンプ中グラフィック [29]=左向きジャンプ中グラフィック [30~34]=なし
int player[35],playerx = 100, playery = 260, playerw, playerh;
//手用配列
//te[0]=左向き用の腕 te[1]=右向き用の腕
int te[2], tex = 100, tey = 240, tew , teh ;
// マウスと中心点との角度格納用変数
float angle=0;
//エイム、弾道用【弾道は使用してないです】
int AIM, Dandou=0;
//弾丸用変数
int Tama, Tamax=0, Tamay=0, Tamaw, Tamah;
//弾丸用計算変数
double sx, sy ,sbx, sby, sb, Tamasx, Tamasy;
//マウス用変数
int mx, my, mxx=0, myy=0;
//ショットフラグ
int ShotFlag = 0;
//身体の向き【0=左向き 1=右向き】
muki = 1;
//その他変数
int i = 35, j;
// プレイヤーがジャンプ中か、のフラグ
char JumpFlag = FALSE;
int JumpPower = 0;
// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//Windowモードで起動
ChangeWindowMode(TRUE);
// DXライブラリ初期化処理
if (DxLib_Init() == -1)
{
// エラーが起きたら直ちに終了
return -1;
}
/* 画像の読み込みです */
//歩行グラフィック & 幅と高さを取得
LoadDivGraph("hokougraph.png", 35, 7, 5, 96, 96, player);
GetGraphSize( player[0] , &playerw , &playerh ) ;
//手グラフィック
LoadDivGraph("hand.png", 2, 2, 1, 96, 96, te);
//エイム(クロスヘア)グラフィック
AIM = LoadGraph("aim.png");
//弾道グラフィック ボツ処理
//Dandou = LoadGraph("dandou.png");
//弾丸グラフィク & 幅と高さを取得
Tama = LoadGraph("tama.png");
GetGraphSize( Tama , &Tamaw , &Tamah ) ;
//マウスカーソルを表示
SetMouseDispFlag( TRUE ) ;
/* ここからループ処理の開始です */
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && GetHitKeyStateAll(key) == 0 || key[KEY_INPUT_ESCAPE] >= 1)
{
// 画面を初期化
ClearDrawScreen();
// 描画先画面を裏にする
SetDrawScreen(DX_SCREEN_BACK);
/* プレイヤー関数へ */
Player();
}
// DXライブラリ使用の終了処理
DxLib_End();
// ソフトの終了
return 0;
}
/* プレイヤー関数 */
void Player(void)
{
/* ここからプレイヤーのジャンプ処理です */
//ジャンプキーが押されている かつ 地面に接地している場合
if (key[KEY_INPUT_UP] >= 1 && playery == 260)
{
//ジャンプフラグのON
JumpFlag = TRUE;
JumpPower = 12;
}
//ジャンプフラグがONの場合
if (JumpFlag == TRUE)
{
if (muki == 1)
{
i = 28;
}
if (muki == 0)
{
i = 29;
}
if (key[KEY_INPUT_RIGHT] >= 1)
{
muki = 1;
playerx += 10;
}
if (key[KEY_INPUT_LEFT] >= 1)
{
muki = 0;
playerx -= 10;
}
playery -= JumpPower;
// 落下加速度を加える
JumpPower -= 1;
// もし地面についていたら止まる
if (playery > 260)
{
playery = 260;
JumpPower = 0;
JumpFlag = FALSE;
}
}
/* ここからプレイヤーの移動処理です */
//移動キーが押された場合
if (key[KEY_INPUT_RIGHT] >= 1 || key[KEY_INPUT_LEFT] >= 1)
{
//右キーが押されている かつ ジャンプしていない 場合
if (key[KEY_INPUT_RIGHT] >= 1 && JumpFlag == FALSE)
{
playerx += 10;
muki = 1;
if (i >= 0 && i <= 13 || i >= 20)
{
i = 14;
}
else if (i >= 14 && i <= 19)
{
i++;
}
}
//左キーが押されている かつ ジャンプしていない 場合
if (key[KEY_INPUT_LEFT] >= 1 && JumpFlag == FALSE)
{
playerx -= 10;
muki = 0;
if (i >= 6)
{
i = 0;
}
else if (i >= 0)
{
i++;
}
}
WaitTimer(0);
}
//何もしていない場合(キーが何も押されていない かつ ジャンプしていない)
if (CheckHitKeyAll() == 0 && JumpFlag == FALSE)
{
if (muki == 0)
{
if (i != 7)
{
i = 7;
}
else if (i != 8)
{
i = 8;
}
}
if (muki == 1)
{
if (i != 21)
{
i = 21;
}
else if (i != 22)
{
i = 22;
}
}
WaitTimer(0);
}
/* ここからマウス処理です */
// マウスの座標を取得(mx,my)
GetMousePoint(&mx, &my);
if (muki == 1)
{
// 中心点とマウスの座標から角度を計算( 動かしたい画像(手)の中心座標 と マウス座標 を使用している)
angle = (float)atan2(my - (float)playery-48, mx - (float)playerx-48);
}
else if (muki == 0)
{
// 中心点とマウスの座標から角度を計算(〃)
angle = (float)atan2((float)playery+48 - my, (float)playerx+48 - mx);
}
//マウス左クリックのボタンが押された場合
if ((GetMouseInput() & MOUSE_INPUT_LEFT) != 0)
{
//マウス座標を新たに取得(mxx,myy)
GetMousePoint(&mxx, &myy);
if(muki == 1)
{
Tamax = tex;
Tamay = tey;
//腕の反動
angle = (-90);
}
else if(muki == 0)
{
Tamax = tex;
Tamay = tey;
// 〃
angle = (90);
}
//ショットフラグON
ShotFlag = 1;
}
if(muki == 1)
{
//新たに取得したマウス座標(mxx,myy)のxより Tamax が大きい場合
if(Tamax > mxx-5 )
{
//ショットフラグOFF
ShotFlag = 0;
}
}
else if(muki == 0)
{
//新たに取得したマウス座標(mxx,myy)のxより Tamax が小さい場合
if(Tamax < mxx+5)
{
//ショットフラグOFF
ShotFlag = 0;
}
}
/* ここからTama(弾)の移動処理です */
// Tama が (mxx,myy) へ移動するときの計算
sx = Tamax + Tamaw / 8;
sy = Tamay + Tamah / 8;
sbx = mxx - sx;
sby = myy - sy;
sb = sqrt(sbx * sbx + sby * sby);
Tamasx = sbx / sb * 80;
Tamasy = sby / sb * 80;
//ショットフラグがONの場合
if (ShotFlag == 1)
{
Tamax += Tamasx;
Tamay += Tamasy;
DrawGraph(Tamax, Tamay, Tama, TRUE);
}
//if(ShotFlag == 1) ボツ処理 もしかしたら使うかも
//{
// DrawRotaGraph3( tex, tey, 0, 0, 300, 1.0, angle, Dandou, TRUE ) ;
// ShotFlag = 0;
//}
//手の画像をプレイヤーにくっつけるための処理
tex = playerx+48;
tey = playery+46;
//描画します
DrawGraph(mx-15, my-15, AIM, TRUE);
DrawGraph(playerx, playery, player[i], TRUE);
DrawRotaGraph(tex, tey, 1.0, angle, te[muki], TRUE);
// 裏画面の内容を表画面に反映します
ScreenFlip();
}
質問ではありませんが今後のためにも、見やすいプログラムの書き方・無駄な処理・こういう処理の仕方もあるなど是非アドバイスもよろしくお願いします。