//******************************************************************************
//
//
// プレイヤー
//
//
//******************************************************************************
//--------------------------------
// インクルード
//--------------------------------
#include "All.h"
//--------------------------------
// 定数
//--------------------------------
#define PL_SPEED (5) //プレイヤーのスピード
#define PL_SCR_MERGIN (36) //プレイヤーの移動範囲制限用
#define PL_JUMP_PWR (1.98f)
#define Ground (9.8067)
#define PL_SCALE (1.0f) //プレイヤーのスケール
#define PL_TEX_LEFT (0) //プレイヤー画像の位置x
#define PL_TEX_TOP (0) //プレイヤー画像の位置y
#define PL_TEX_W (128) //プレイヤー画像の幅
#define PL_TEX_H (128) //プレイヤー画像の高さ
#define PL_TEX_CX (64) //プレイヤー画像の中心x
#define PL_TEX_CY (64) //プレイヤー画像の中心y
#define PL_SHOT_CNT_MAX (32)
#define PL_DEFAULT_POS_Y (10)
#define PL_ANIM_CNT_PER_FRAME (12)
#define PL_ANIM_FRAME_NUM (6)
#define PL_ANIM_CNT_PER_FRAME_MOVE_LEFT (5) //プレイヤーの動きのフレーム
#define PL_ANIM_FRAME_NUM_MOVE_LEFT (4) //プレイヤーの動きの数
#define PL_ANIM_CNT_PER_FRAME_MOVE_RIGHT (5) //プレイヤーの動きのフレーム
#define PL_ANIM_FRAME_NUM_MOVE_RIGHT (4) //プレイヤーの動きの数
#define PL_ANIM_CNT_PER_FRAME_STAY (5) //待機のフレーム
#define PL_ANIM_FRAME_NUM_STAY (4) //待機の数
#define PL_ANIM_CNT_PER_FRAME_ATACK (7) //攻撃のフレーム
#define PL_ANIM_FRAME_NUM_ATACK (2) //攻撃の数
#define PL_ANIM_CNT_PER_FRAME_JUMP (5)
#define PL_ANIM_FRAME_NUM_JUMP (4)
//------------------------------------
// プロトタイプ宣言
//------------------------------------
VECTOR2 *Vector2Normalize(VECTOR2 *out, const VECTOR2 *v);
//--------------------------------
// 構造体
//--------------------------------
int img_ch[30];
int y_temp; //ジャンプしたときのy座標
int y_prev;
bool Jump_flag;
int DIR;
//--------------------------------
// 変数
//--------------------------------
OBJ2D player;
static bool prev_Z = kb.Z;
bool PL_Stop_flag = 0;//バグ止め
//--------------------------------
// 初期化
//--------------------------------
void Player_Init()
{
//OBJ2DのワークエリアをPLAYER_WORKを指すポイントにキャスト
PLAYER_WORK *work = (PLAYER_WORK *)player.work;
//初期座標を設定
player.data = player_spr;
player.pos.x = SCREEN_WIDTH * 0.3;//スクリーン横方向中心
player.pos.y = SCREEN_HEIGHT * 0.8;//スクリーン下の方
player.scale.x = PL_SCALE;
player.scale.y = PL_SCALE;
work->shot_Lv = 1;
player.radius = 16;//当たり判定を行うので、半径を入れておく
player.exist = true;//プレイヤーが点滅するようになるので、存在フラグを設定しておく
work->hp = PLAYER_HP;//プレイヤーのヒットポイント
work->dCnt = 0;//ダメージカウンタ(初期値0)
player.color = VECTOR4(1, 1, 1, 1);//白で不透明にしておく
// player.shot_Lv = 1;
}
//--------------------------------
// 更新
//--------------------------------
void Player_Update()
{
if (!player.exist)return;
//OBJ2DのワークエリアをPLAYER_WORKを指すポイントにキャスト
PLAYER_WORK *work = (PLAYER_WORK *)player.work;
//プレイヤー移動
player.speed.x = player.speed.y = 0;
if (kb.Left) {
player.speed.x += -1;
work->jCnt++;
work->jFrame = (work->jCnt / PL_ANIM_CNT_PER_FRAME_MOVE_LEFT) % PL_ANIM_FRAME_NUM_MOVE_LEFT;
if (work->jCnt >= PL_ANIM_CNT_PER_FRAME_MOVE_LEFT) {
work->jFrame++;
if (work->jFrame >= PL_ANIM_FRAME_NUM_MOVE_LEFT) {
work->jFrame = 0;
work->jCnt = 0;
}
}
DIR = 0;
}
if (kb.Right) {
player.speed.x += 1;
work->sCnt++;
work->sFrame = (work->sCnt / PL_ANIM_CNT_PER_FRAME_MOVE_RIGHT) % PL_ANIM_FRAME_NUM_MOVE_RIGHT;
if (work->sCnt >= PL_ANIM_CNT_PER_FRAME_MOVE_RIGHT) {
work->sFrame++;
if (work->sFrame >= PL_ANIM_FRAME_NUM_MOVE_RIGHT) {
work->sFrame = 0;
work->sCnt = 0;
}
}
DIR = 1;
}
if (kb.Z)
{
player.speed.x = player.speed.y = 0;
if (DIR == 1)
{
work->tCnt++;
work->tFrame = (work->tCnt / PL_ANIM_CNT_PER_FRAME_ATACK) % PL_ANIM_FRAME_NUM_ATACK;
if (work->tCnt >= PL_ANIM_CNT_PER_FRAME_ATACK)
{
work->tFrame++;
if (work->tFrame >= PL_ANIM_FRAME_NUM_ATACK)
{
work->tFrame = 0;
work->tCnt = 0;
}
}
}
if (DIR == 0)
{
work->tCnt++;
work->tFrame = (work->tCnt / PL_ANIM_CNT_PER_FRAME_ATACK) % PL_ANIM_FRAME_NUM_ATACK;
if (work->tCnt >= PL_ANIM_CNT_PER_FRAME_ATACK)
{
work->tFrame++;
if (work->tFrame >= PL_ANIM_FRAME_NUM_ATACK)
{
work->tFrame = 0;
work->tCnt = 0;
}
}
}
}
if (kb.Up) {
if (DIR == 1)
{
work->tCnt++;
work->tFrame = (work->tCnt / PL_ANIM_CNT_PER_FRAME_JUMP) % PL_ANIM_FRAME_NUM_ATACK;
if (work->tCnt >= PL_ANIM_CNT_PER_FRAME_JUMP)
{
work->tFrame++;
if (work->tFrame >= PL_ANIM_FRAME_NUM_ATACK)
{
work->tFrame = 0;
work->tCnt = 0;
}
}
}
if (DIR == 0)
{
work->tCnt++;
work->tFrame = (work->tCnt / PL_ANIM_CNT_PER_FRAME_JUMP) % PL_ANIM_FRAME_NUM_JUMP;
if (work->tCnt >= PL_ANIM_CNT_PER_FRAME_JUMP)
{
work->tFrame++;
if (work->tFrame >= PL_ANIM_FRAME_NUM_JUMP)
{
work->tFrame = 0;
work->tCnt = 0;
}
}
}
}
//********************************
// ジャンプフラグ
//********************************
if (Jump_flag == true)
{
y_temp = player.pos.y;
player.pos.y += (player.pos.y - y_prev) + 0.4;
y_prev = y_temp;
if (player.pos.y >= PL_DEFAULT_POS_Y)
{
player.pos.y = PL_DEFAULT_POS_Y;
Jump_flag = false;
}
}
if (kb.Space && !kb_prev.Space && Jump_flag == false)
{
y_prev = player.pos.y;
player.pos.y = player.pos.y - PL_JUMP_PWR;
Jump_flag = true;
}
Vector2Normalize(&player.speed, &player.speed);
player.speed *= PL_SPEED;
player.pos += player.speed;
//プレイヤー範囲制限
if (player.pos.x < PL_SCR_MERGIN) player.pos.x = PL_SCR_MERGIN;//左方向
if (player.pos.x > SCREEN_WIDTH - PL_SCR_MERGIN) player.pos.x = SCREEN_WIDTH - PL_SCR_MERGIN;//右方向
if (player.pos.y < PL_SCR_MERGIN) player.pos.y = PL_SCR_MERGIN;//上方向
if (player.pos.y > SCREEN_HEIGHT - PL_SCR_MERGIN) player.pos.y = SCREEN_HEIGHT - PL_SCR_MERGIN;//下方向
//ダメージカウンタ処理
/*if (work->dCnt > 0)work->dCnt--;
if (work->aCnt >= PL_ANIM_CNT_PER_FRAME) {
work->aFrame++;
if (work->aFrame >= PL_ANIM_FRAME_NUM) {
work->aFrame = 0;
work->aCnt = 0;
}
}*/
//デバッグ文字列表示
debug->SetString("player_x:%.2f player_y:%.2f", player.pos.x, player.pos.y);
//debug->SetString("shot_cnt:%d", shot_cnt);
//debug->SetString("player.shot_Lv:%d", work->shot_Lv);
}
//--------------------------------
// 描画
//--------------------------------
void Player_Draw()
{
if (!player.exist)return;
//OBJ2DのワークエリアをPLAYER_WORKを指すポイントにキャスト
PLAYER_WORK *work = (PLAYER_WORK *)player.work;
//プレイヤーの描画色の設定
VECTOR4 col = player.color;
if (work->dCnt > 0)col = VECTOR4(1, 0.2f, 0.2f, 1);//ダメージ中なら赤く
//DIR = 0; //向き
if (kb.Right)
{
Sprite_Render(Player_Move_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->sFrame * PL_TEX_W), PL_TEX_TOP,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
if (kb.Left)
{
Sprite_Render(Player_Move_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->jFrame * PL_TEX_W), PL_TEX_TOP + 128,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
if (player.speed.x < 0.5f && player.speed.x > -0.5f)
{
if (DIR == 1)
{
Sprite_Render(Player_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->aFrame * PL_TEX_W), PL_TEX_TOP,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
else if (DIR == 0)
{
Sprite_Render(Player_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->aFrame * PL_TEX_W), PL_TEX_TOP + 128,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
}
if (kb.Z)
{
if (DIR == 1) {
Sprite_Render(Player_Atack_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->tFrame * PL_TEX_W), PL_TEX_TOP,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
else if (DIR == 0)
{
Sprite_Render(Player_Atack_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->tFrame * PL_TEX_W), PL_TEX_TOP + 128,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
}
if (kb.Space) {
if (DIR == 1) {
Sprite_Render(Player_Jump_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->tFrame * PL_TEX_W), PL_TEX_TOP,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
else if (DIR == 0)
{
Sprite_Render(Player_Jump_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
(float)(PL_TEX_LEFT + work->tFrame * PL_TEX_W), PL_TEX_TOP + 128,
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
}
}
}
アニメーションについて
アニメーションについて
Re: アニメーションについて
表示させたいキャラの状態をstateという変数で表すことにして、
表示させたい画像の描画出発点(言い方はこれでつたわりますか?)のx,y座標は
sx[],sy[]みたいな配列で用意すると
Sprite_Render(Player_Jump_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
sx[state],sy[state],
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
この一回だけで短くかけると思います。
sxとsyは例えばですが、画像が
____________
↑ | ↓ |→|←|
____________
みたいに並んでいたとしたら
for(i=0;i<4;i++){
sx = PL_TEX_W * i, sy = 0;
}
のようにして
stateには
if(kb.up)state = 0;
else if(kb.down)state = 1;
・・・
みたいな感じにしてあげることで
それぞれの状態にあった画像へのアクセスができるわけです
攻撃とかジャンプとかも左右移動と同じように実装できると思います。
表示させたい画像の描画出発点(言い方はこれでつたわりますか?)のx,y座標は
sx[],sy[]みたいな配列で用意すると
Sprite_Render(Player_Jump_Image, player.pos.x, player.pos.y,
PL_SCALE, PL_SCALE,
sx[state],sy[state],
PL_TEX_W, PL_TEX_H,
PL_TEX_CX, PL_TEX_CY,
0
);
この一回だけで短くかけると思います。
sxとsyは例えばですが、画像が
____________
↑ | ↓ |→|←|
____________
みたいに並んでいたとしたら
for(i=0;i<4;i++){
sx = PL_TEX_W * i, sy = 0;
}
のようにして
stateには
if(kb.up)state = 0;
else if(kb.down)state = 1;
・・・
みたいな感じにしてあげることで
それぞれの状態にあった画像へのアクセスができるわけです
攻撃とかジャンプとかも左右移動と同じように実装できると思います。