//=============================================================================
//【Player.cpp】
//Playerポリゴンを管理する関数を扱うクラス
//=============================================================================
//*****************************************************************************
//インクルード・ヘッダーファイル
//*****************************************************************************
#include "input.h" //入力処理用ヘッダー
#include "Player.h" //Playerポリゴンのヘッダー
//*****************************************************************************
//ライブラリのリンク
//*****************************************************************************
//*****************************************************************************
//マクロ定義
//*****************************************************************************
//#define PLAYER_TEXTURENAME "DATA/TEXTURE/Player.png" //テクスチャファイル名
#define PLAYER_INITPOS_X (SCREEN_CENTER_X) //初期位置X
#define PLAYER_INITPOS_Y (SCREEN_CENTER_Y) //初期位置Y
#define PLAYER_SIZE_X (50) //横幅
#define PLAYER_SIZE_Y (50) //縦幅
#define PLAYER_SPEED (3.0f) //速度
#define PLAYER_INITIALVELOCITYJUMP (15.0f) //飛び幅初速
#define PLAYER_MAXJUMP (250.0f) //最大飛び幅度
#define PLAYER_GRAVITY (0.98) //重力
#define PLAYER_MAXGRAVITY (50.0) //最大重力
//*****************************************************************************
//イーナム定義
//*****************************************************************************
//*****************************************************************************
//構造体定義
//*****************************************************************************
//*****************************************************************************
//プロトタイプ宣言
//*****************************************************************************
void MakeFormatPlayer (LPDIRECT3DDEVICE9 pDevice); //Playerポリゴンフォーマット情報作成関数
void PosChangePlayer (float moveX, float moveY, float moveZ, float zoomX, float zoomY, float zoomZ, float angle); //Playerポリゴン座標変更関数
//*****************************************************************************
//グローバル変数:
//*****************************************************************************
CUSTOMVERTEX g_pFormatPlayer [NUM_VERTEX]; //フォーマット情報格納用変数
LPDIRECT3DVERTEXBUFFER9 g_pVertexPlayer = NULL; //頂点バッファコンポーネントへのポインタ
LPDIRECT3DTEXTURE9 g_pTexturePlayer = NULL; //テクスチャオブジェクト格納用変数
D3DXMATRIX g_pBasePosMATRIXPlayer [NUM_VERTEX]; //ベース座標格納マトリックス
D3DXVECTOR3 g_Pos = D3DXVECTOR3(PLAYER_INITPOS_X, PLAYER_INITPOS_Y, 0.0f); //原点位置格納用変数
D3DXVECTOR3 g_Zoom = D3DXVECTOR3(1.0f, 1.0f, 1.0f); //拡張量格納用変数
float g_Angle = 0.0f; //回転量格納用変数
float g_nSideIertia = 0.0f; //横軸慣性格納用変数
float g_nSideLength = 0.0f; //縦軸慣性格納用変数
float g_nJumpAxis = 0.0f; //ジャンプ前の縦軸格納用変数
bool g_bJump = false; //ジャンプ判定確認用変数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン初期化関数】
//Playerポリゴンの初期化処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
HRESULT InitPlayer(
LPDIRECT3D9 pD3D, //Direct3Dへアクセスするためのポインタ
LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//フォーマット情報を作成する
MakeFormatPlayer(pDevice);
//頂点バッファの作成をする
if (FAILED(pDevice->CreateVertexBuffer(
sizeof(CUSTOMVERTEX) * 4, //確保する頂点バッファのサイズ
D3DUSAGE_WRITEONLY, //リソースの使用法を定義するフラグ
FVF_CUSTOM, //頂点フォーマットの型の指定
D3DPOOL_MANAGED, //どの種類のメモリに頂点バッファを置くかの指定
&g_pVertexPlayer, //頂点バッファコンポーネントへのポインタのアドレス
NULL))) //特に使用されていない為NULL
{
pDevice->Release();
pD3D->Release();
return E_FAIL;
}
return S_OK;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン終了処理関数】
//Playerポリゴンの終了処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UninitPlayer(void)
{
if (g_pVertexPlayer != NULL) {
g_pVertexPlayer->Release();
g_pVertexPlayer = NULL;
}
if (g_pTexturePlayer != NULL) {
g_pTexturePlayer->Release();
g_pTexturePlayer = NULL;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン更新処理関数】
//Playeポリゴンrの更新処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void UpdataPlayer(LPDIRECT3DDEVICE9 pDevice)
{
//Dを押した場合右移動処理を行う
if (GetKeyboardPress(DIK_D)) {
//左Siftを押した場合ダッシュ処理を行う
if (GetKeyboardPress(DIK_LSHIFT)) {
if (g_nSideIertia < PLAYER_SPEED * 2) g_nSideIertia += 0.2f; //走り速度よりも小さい場合は横慣性を0.2増やす
}
//左Siftを押していない場合は歩き処理を行う
else {
if (g_nSideIertia < PLAYER_SPEED) g_nSideIertia += 0.1f; //歩き速度よりも小さい場合は横慣性を0.1増やす
}
}
//Aを押した場合左移動処理を行う
if (GetKeyboardPress(DIK_A)) {
//左Siftを押した場合ダッシュ処理を行う
if (GetKeyboardPress(DIK_LSHIFT)) {
if (-PLAYER_SPEED * 2 < g_nSideIertia) g_nSideIertia -= 0.2f; //走り速度よりも大きい場合は横慣性を0.2増やす
}
//左Siftを押していない場合は歩き処理を行う
else {
if (-PLAYER_SPEED < g_nSideIertia) g_nSideIertia -= 0.1f; //歩き速度よりも大きい場合は横慣性を0.2増やす
}
}
//DとAを押していない場合横慣性処理を行う
if (!GetKeyboardPress(DIK_D) && !GetKeyboardPress(DIK_A)) {
//0よりも横慣性が高い場合左に横慣性を加える
if (0.0f < g_nSideIertia) {
if (PLAYER_SPEED < g_nSideIertia) g_nSideIertia -= 0.10f; //歩き速度よりも大きい場合は横慣性を0.10減らす
else g_nSideIertia -= 0.5f; //上記じゃない場合は横慣性を0.5減らす
if (g_nSideIertia < 0.0f) g_nSideIertia = 0.0f; //横慣性が0より小さい場合は横慣性を0にする
}
//0よりも横慣性が低い場合右に横慣性を加える
if (g_nSideIertia < 0.0f) {
if (g_nSideIertia < -PLAYER_SPEED) g_nSideIertia += 0.10f; //歩き速度よりも小さい場合は横慣性を0.10増やす
else g_nSideIertia += 0.5f; //上記じゃない場合は横慣性を0.5増やす
if (0.0f < g_nSideIertia) g_nSideIertia = 0.0f; //横慣性が0より大きい場合は横慣性を0にする
}
}
g_Pos.x += g_nSideIertia;
if (GetKeyboardTrigger(DIK_SPACE) && g_bJump) {
g_nSideLength = -PLAYER_INITIALVELOCITYJUMP;
g_bJump = false;
}
if (!g_bJump) {
g_nSideLength += PLAYER_GRAVITY;
}
g_Pos.y += g_nSideLength;
//変わった横慣性分移動値を変える
//画面外判定の下準備
float originX = NULL; //移動前の中心X
float originY = NULL; //移動前の中心Y
float minX = NULL; //移動前のX頂点最低値
float minY = NULL; //移動前のY頂点最低値
float maxX = NULL; //移動前のX頂点最大値
float maxY = NULL; //移動前のY頂点最大値
//上記の変数に数値を入れる
for (int i = 0; i < NUM_VERTEX; i++) {
if (originX != NULL) originX += g_pFormatPlayer[i].pos.x;
else originX = g_pFormatPlayer[i].pos.x;
if (originY != NULL) originY += g_pFormatPlayer[i].pos.y;
else originY = g_pFormatPlayer[i].pos.y;
if (minX == NULL) minX = g_pFormatPlayer[i].pos.x;
else if (g_pFormatPlayer[i].pos.x < minX) minX = g_pFormatPlayer[i].pos.x;
if (minY == NULL) minY = g_pFormatPlayer[i].pos.y;
else if (g_pFormatPlayer[i].pos.y < minY) minY = g_pFormatPlayer[i].pos.y;
if (maxX == NULL) maxX = g_pFormatPlayer[i].pos.x;
else if (maxX < g_pFormatPlayer[i].pos.x) maxX = g_pFormatPlayer[i].pos.x;
if (maxY == NULL) maxY = g_pFormatPlayer[i].pos.y;
else if (maxY < g_pFormatPlayer[i].pos.y) maxY = g_pFormatPlayer[i].pos.y;
}
//頂点の数分割って重点を求める
originX = originX / (float)NUM_VERTEX;
originY = originY / (float)NUM_VERTEX;
//左画面外判定
if (minX + (g_Pos.x - originX) < 0) {
g_Pos.x += 0 - (minX + (g_Pos.x - originX));
g_nSideIertia = 0;
}
//右画面外判定
if (SCREEN_WIDTH < maxX + (g_Pos.x - originX)) {
g_Pos.x += SCREEN_WIDTH - (maxX + (g_Pos.x - originX));
g_nSideIertia = 0;
}
//上画面判定
if (minY + (g_Pos.y - originY) < 0) {
g_Pos.y += 0 - (minY + (g_Pos.y - originY));
g_bJump = false;
g_nSideLength = 0;
}
//下画面判定
if (SCREEN_HEIGHT < maxY + (g_Pos.y - originY)) {
g_Pos.y += SCREEN_HEIGHT - (maxY + (g_Pos.y - originY));
g_bJump = true;
g_nSideLength = 0;
}
//位置更新処理
PosChangePlayer(g_Pos.x, g_Pos.y, g_Pos.z, g_Zoom.x, g_Zoom.y, g_Zoom.z, g_Angle);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン描画処理関数】
//Playerポリゴンの描画処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void DrawPlayer(LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//頂点バッファを書き込むためにメモリをロックする
void *pData;
if (SUCCEEDED(g_pVertexPlayer->Lock(
0, //全体にロックをするため0
sizeof(CUSTOMVERTEX) * 4, //ロックしたいメモリサイズ
(void**)&pData, //ロックされたメモリ範囲の先頭アドレスへのポインタ
0))) //ロック時の動作を定義するフラグ
{
memcpy(pData, g_pFormatPlayer, sizeof(CUSTOMVERTEX) * 4);
g_pVertexPlayer->Unlock();
}
//ストリームソースという頂点処理の流れに頂点バッファを実際にセットする
pDevice->SetStreamSource(
0, //ストリームの番号
g_pVertexPlayer, //頂点バッファコンポーネントへのポインタ
0, //頂点データの書き始めを示すオフセット
sizeof(CUSTOMVERTEX)); //1頂点のサイズ
//ストリームに頂点バッファの型を教える
pDevice->SetFVF(FVF_CUSTOM);
//テクスチャをデバイスのステージに割り当てる
pDevice->SetTexture(0, g_pTexturePlayer);
//頂点の結び方とポリゴンの描画枚数を指定
pDevice->DrawPrimitive(
D3DPT_TRIANGLESTRIP, //頂点をどう結びポリゴンにするかのフラグ
0, //描画を開始する最初の頂点番号
2); //描画するポリゴンの数
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴンフォーマット情報作成関数】
//Playerポリゴンのフォーマット情報作成処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void MakeFormatPlayer(LPDIRECT3DDEVICE9 pDevice) //ビデオカードへアクセスするためのポインタ
{
//頂点座標設定
g_pFormatPlayer[0].pos = //左上
D3DXVECTOR3(-PLAYER_SIZE_X / 2, -PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[1].pos = //右上
D3DXVECTOR3(+ PLAYER_SIZE_X / 2, - PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[2].pos = //左下
D3DXVECTOR3( - PLAYER_SIZE_X / 2, + PLAYER_SIZE_Y / 2, 0.0f);
g_pFormatPlayer[3].pos = //右下
D3DXVECTOR3( + PLAYER_SIZE_X / 2, + PLAYER_SIZE_Y / 2, 0.0f);
D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[0], g_pFormatPlayer[0].pos.x, g_pFormatPlayer[0].pos.y, g_pFormatPlayer[0].pos.z);
D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[1], g_pFormatPlayer[1].pos.x, g_pFormatPlayer[1].pos.y, g_pFormatPlayer[0].pos.z);
D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[2], g_pFormatPlayer[2].pos.x, g_pFormatPlayer[2].pos.y, g_pFormatPlayer[0].pos.z);
D3DXMatrixTranslation(&g_pBasePosMATRIXPlayer[3], g_pFormatPlayer[3].pos.x, g_pFormatPlayer[3].pos.y, g_pFormatPlayer[0].pos.z);
//除算数設定
g_pFormatPlayer[0].rhw = 1.0f;
g_pFormatPlayer[1].rhw = 1.0f;
g_pFormatPlayer[2].rhw = 1.0f;
g_pFormatPlayer[3].rhw = 1.0f;
//頂点カラー設定
g_pFormatPlayer[0].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[1].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[2].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
g_pFormatPlayer[3].col =
D3DCOLOR_RGBA(255, 255, 255, 255);
//テクスチャ座標設定
g_pFormatPlayer[0].tex =
D3DXVECTOR2(0.0f, 0.0f); //左上
g_pFormatPlayer[1].tex =
D3DXVECTOR2(1.0f, 0.0f); //右上
g_pFormatPlayer[2].tex =
D3DXVECTOR2(0.0f, 1.0f); //左下
g_pFormatPlayer[3].tex =
D3DXVECTOR2(1.0f, 1.0f); //右下
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//【Playerポリゴン座標変更関数】
//Playerポリゴンの座標の変更処理を行う関数
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void PosChangePlayer(
float moveX, //X移動量
float moveY, //Y移動量
float moveZ, //Z移動量
float zoomX, //X拡張量
float zoomY, //Y拡張量
float zoomZ, //Z拡張量
float angle) //回転量
{
D3DXMATRIX PosMatrix; //Playerポリゴンの現在位置格納用単位行列
D3DXMATRIX MoveMatrix; //Playerポリゴンの移動量格納用単位行列
D3DXMATRIX ZoomMatrix; //Playerポリゴンの拡張量格納用単位行列
D3DXMATRIX RotationMatrix; //Playerポリゴンの回転量格納用単位行列
//行列初期化
D3DXMatrixIdentity(&MoveMatrix);
D3DXMatrixIdentity(&PosMatrix);
D3DXMatrixIdentity(&ZoomMatrix);
D3DXMatrixIdentity(&RotationMatrix);
//D3DXMatrixTranslation関数を使用してMoveMatrixに移動量を格納する
D3DXMatrixTranslation(
&MoveMatrix,
moveX,
moveY,
moveZ);
//D3DXMatrixScaling関数を使用してZoomMatrixに拡張量を格納する
D3DXMatrixScaling(
&ZoomMatrix,
zoomX,
zoomY,
zoomZ);
//D3DXMatrixRotationZ関数を使用してRotationMatrixに回転量を格納する
D3DXMatrixRotationZ(
&RotationMatrix,
D3DXToRadian(angle));
for (int i = 0; i < NUM_VERTEX; i++) {
PosMatrix = g_pBasePosMATRIXPlayer[i] * ZoomMatrix * RotationMatrix * MoveMatrix; //現在地の行列に計算した今までの行列を加算して格納する
g_pFormatPlayer[i].pos.x = PosMatrix._41; //演算結果をポリゴンのX座標に格納する
g_pFormatPlayer[i].pos.y = PosMatrix._42; //演算結果をポリゴンのY座標に格納する
g_pFormatPlayer[i].pos.z = PosMatrix._43; //演算結果をポリゴンのZ座標に格納する
}
}
実際に動作は確認できる
bool GetKeyboardPress(int nKey); //押している間true
bool GetKeyboardTrigger(int nKey); //押した瞬間true
bool GetKeyboardRepeat(int nKey); //押している間true(Trigger時には反応せず、Pressと違ってTrigger判定の後少しラグがある)
bool GetKeyboardRelease(int nKey); //離した瞬間true
押している間に調整が効き、一定の高さ(指定)までしかジャンプできないといったシステムを作るにはどうすればいいでしょうか?