横スクロールアクションで敵が振動してしまいます。
Posted: 2011年3月06日(日) 22:30
どうもはじめまして
現在龍神録と本家のアクションサンプルを参考に横スクロールアクションを作っているのですが、
敵キャラが地面に着いていると振動してしまいます。下のソースでは自機とほぼ同じsourceをつかっているのですが、自機は振動せず敵のみ振動します。今のところわかっている原因は enemy.downsp が1以下(小数点)になると振動しはじめます。
どうすれば小数点でも振動しないようにできるでしょうか?
全部書き込むと量がおおいので、原因と思われる箇所を書いてます
codeタグをご利用下さい。 softya(ソフト屋)
現在龍神録と本家のアクションサンプルを参考に横スクロールアクションを作っているのですが、
敵キャラが地面に着いていると振動してしまいます。下のソースでは自機とほぼ同じsourceをつかっているのですが、自機は振動せず敵のみ振動します。今のところわかっている原因は enemy.downsp が1以下(小数点)になると振動しはじめます。
どうすれば小数点でも振動しないようにできるでしょうか?
全部書き込むと量がおおいので、原因と思われる箇所を書いてます
codeタグをご利用下さい。 softya(ソフト屋)
--enemy_act_pattern--
void enemy_pattern0(int i){
int t=enemy[i].cnt;
float vx, vy ;
// 移動量の初期化
vx = 0.0F ;
vy = 0.0F ;
ch.cnt++;
ch.img=(ch.cnt%24)/6;
if(CheckStatePad(configpad.left)>0)//左が押されていたら
vx-=SPEED;//座標を左に
if(CheckStatePad(configpad.right)>0)//右が押されていたら
vx+=SPEED;//座標を右に
// 地に足が着いている場合のみジャンプボタン(ボタン1 or Zキー)を見る
if( enemy[i].jumpflag == FALSE && CheckStatePad(configpad.jump)>0 )
{
enemy[i].downsp = -JUMP_POWER ;
enemy[i].jumpflag = TRUE ;
}
// 落下処理
enemy[i].downsp += 0.01; ←ココ
// 落下速度を移動量に加える
vy = enemy[i].downsp ;
// 移動量に基づいてキャラクタの座標を移動
CharMove( &enemy[i].x, &enemy[i].y, &enemy[i].downsp, vx, vy, CHAR_SIZE, &enemy[i].jumpflag ) ;
}
--enemy.cpp--
void enemy_enter(){//敵の行動を登録・制御する関数
int i,j,t;
for(t=0;t<ENEMY_ORDER_MAX;t++){
if(enemy_order[t].cnt){//現在の瞬間がオーダーの瞬間なら
if((i=enemy_num_search())!=-1){
enemy[i].flag =1;//フラグ
enemy[i].cnt =0;//カウンタ
enemy[i].pattern=enemy_order[t].pattern;//移動パターン
enemy[i].muki =1;//向き
enemy[i].knd =enemy_order[t].knd;//敵の種類
enemy[i].x =enemy_order[t].x;//座標
enemy[i].y =enemy_order[t].y;
enemy[i].sp =enemy_order[t].sp;//スピード
enemy[i].bltime =enemy_order[t].bltime;//弾の発射時間
enemy[i].blknd =enemy_order[t].blknd;//弾幕の種類
enemy[i].blknd2 =enemy_order[t].blknd2;//弾の種類
enemy[i].col =enemy_order[t].col;//色
enemy[i].wait =enemy_order[t].wait;//停滞時間
enemy[i].hp =enemy_order[t].hp;//体力
enemy[i].hp_max =enemy[i].hp;//体力最大値
enemy[i].vx =0;//水平成分の速度
enemy[i].vy =0;//鉛直成分の速度
enemy[i].ang =0;//角度
for(j=0;j<6;j++)
enemy[i].item_n[j]=enemy_order[t].item_n[j];//落とすアイテム
}
}
}
}
//敵の行動制御
void enemy_act(){
int i;
for(i=0;i<ENEMY_MAX;i++){
if(enemy[i].flag==1){
if(0<=enemy[i].pattern && enemy[i].pattern<ENEMY_PATTERN_MAX){
enemy_pattern[enemy[i].pattern](i);
enemy[i].x+=cos(enemy[i].ang)*enemy[i].sp;
enemy[i].y+=sin(enemy[i].ang)*enemy[i].sp;
enemy[i].x+=enemy[i].vx;
enemy[i].y+=enemy[i].vy;
enemy[i].cnt++;
enemy[i].img=enemy[i].muki*3+(enemy[i].cnt%18)/6;
//敵が画面から外れたら消す
if(enemy[i].x<-20 || MAP_PIXEL_WIDTH+20<enemy[i].x || enemy[i].y<-20 || MAP_PIXEL_HEIGHT+20<enemy[i].y)
enemy[i].flag=0;
}
else
printfDx("enemy[i].patternの%d値が不正です。",enemy[i].pattern);
}
}
}
void enemy_main(){
enemy_enter();
enemy_act();
}
--wall.cpp--
int CharMove( float *X, float *Y, float *DownSP,
float vx, float vy, float Size, char *JumpFlag )
{
float Dummy = 0.0F ;
float hsize ;
// キャラクタの左上、右上、左下、右下部分が当たり判定のある
// マップに衝突しているか調べ、衝突していたら補正する
// 半分のサイズを算出
hsize = Size * 0.5F ;
// 先ず上下移動成分だけでチェック
{
// 左下のチェック、もしブロックの上辺に着いていたら落下を止める
if( MapHitCheck( *X - hsize, *Y + hsize, &Dummy, &vy ) == 3 ) *DownSP = 0.0F ;
// 右下のチェック、もしブロックの上辺に着いていたら落下を止める
if( MapHitCheck( *X + hsize, *Y + hsize, &Dummy, &vy ) == 3 ) *DownSP = 0.0F ;
// 左上のチェック、もしブロックの下辺に当たっていたら落下させる
if( MapHitCheck( *X - hsize, *Y - hsize, &Dummy, &vy ) == 4 ) *DownSP *= 0.0F ;
// 右上のチェック、もしブロックの下辺に当たっていたら落下させる
if( MapHitCheck( *X + hsize, *Y - hsize, &Dummy, &vy ) == 4 ) *DownSP *= 0.0F ;
// 上下移動成分を加算
*Y += vy ;
}
// 後に左右移動成分だけでチェック
{
// 左下のチェック
MapHitCheck( *X - hsize, *Y + hsize, &vx, &Dummy );
// 右下のチェック
MapHitCheck( *X + hsize, *Y + hsize, &vx, &Dummy );
// 左上のチェック
MapHitCheck( *X - hsize, *Y - hsize, &vx, &Dummy );
// 右上のチェック
MapHitCheck( *X + hsize, *Y - hsize, &vx, &Dummy );
// 左右移動成分を加算
*X += vx ;
}
// 接地判定
{
// キャラクタの左下と右下の下に地面があるか調べる
if( GetChipParam( *X - Size * 0.5F, *Y + Size * 0.5F + 1.0F ) == 0 &&
GetChipParam( *X + Size * 0.5F, *Y + Size * 0.5F + 1.0F ) == 0 )
{
// 足場が無かったらジャンプ中にする
*JumpFlag = TRUE ;
}
else
{
// 足場が在ったら接地中にする
*JumpFlag = FALSE ;
}
}
// 終了
return 0 ;
}
// マップとの当たり判定( 戻り値 0:当たらなかった 1:左辺に当たった 2:右辺に当たった
// 3:上辺に当たった 4:下辺に当たった
// 注意:vx と vy 、どっちか片方が0じゃないとまともに動作しません(爆)
int MapHitCheck( float X, float Y,
float *vx, float *vy )
{
float afX, afY ;
// 移動量を足す
afX = X + *vx ;
afY = Y + *vy ;
// 当たり判定のあるブロックに当たっているかチェック
if( GetChipParam( afX, afY ) == 1 )
{
float blx, bty, brx, bby ;
// 当たっていたら壁から離す処理を行う
// ブロックの上下左右の座標を算出
blx = (float)( (int)afX / CHIP_SIZE ) * CHIP_SIZE ; // 左辺の X 座標
brx = (float)( (int)afX / CHIP_SIZE + 1 ) * CHIP_SIZE ; // 右辺の X 座標
bty = (float)( (int)afY / CHIP_SIZE ) * CHIP_SIZE ; // 上辺の Y 座標
bby = (float)( (int)afY / CHIP_SIZE + 1 ) * CHIP_SIZE ; // 下辺の Y 座標
// 上辺に当たっていた場合
if( *vy > 0.0F )
{
// 移動量を補正する
*vy = bty - Y - 1.0F ;
// 上辺に当たったと返す
return 3 ;
}
// 下辺に当たっていた場合
if( *vy < 0.0F )
{
// 移動量を補正する
*vy = bby - Y + 1.0F ;
// 下辺に当たったと返す
return 4 ;
}
// 左辺に当たっていた場合
if( *vx > 0.0F )
{
// 移動量を補正する
*vx = blx - X - 1.0F ;
// 左辺に当たったと返す
return 1 ;
}
// 右辺に当たっていた場合
if( *vx < 0.0F )
{
// 移動量を補正する
*vx = brx - X + 1.0F ;
// 右辺に当たったと返す
return 2 ;
}
// ここに来たら適当な値を返す
return 4 ;
}
// どこにも当たらなかったと返す
return 0 ;
}
// マップチップの値を取得する関数
int GetChipParam( float X, float Y )
{
int x, y ;
// 整数値へ変換
x = (int)X / CHIP_SIZE ;
y = (int)Y / CHIP_SIZE ;
// マップからはみ出ていたら 0 を返す
if( x >= MAP_WIDTH || y >= MAP_HEIGHT || x < 0 || y < 0 ) return 0 ;
// 指定の座標に該当するマップの情報を返す
return MapData[ y ][ x ] ;
}