そのコードは以下の質問で
クォーターの当たり判定とスクロール
http://dixq.net/forum/viewtopic.php?t=12822
質問に回答してくれたソフト屋さんにif文だらけで汚いと言われたもので、
以下がそのコードになります。
if( checkkey(KEY_INPUT_LEFT)>0 && checkkey(KEY_INPUT_UP)>0 ){//押されたキーによって
p.muki=5; //向きを指定。これは左上
p.walkflag=true;//歩きフラグをたてる
}else if( checkkey(KEY_INPUT_LEFT)>0 && checkkey(KEY_INPUT_DOWN)>0 ){
p.muki=6; //左下
p.walkflag=true;
}else if( checkkey(KEY_INPUT_RIGHT)>0 && checkkey(KEY_INPUT_UP)>0 ){
p.muki=7; //右上
p.walkflag=true;
}else if( checkkey(KEY_INPUT_RIGHT)>0 && checkkey(KEY_INPUT_DOWN)>0 ){
p.muki=8; //右下
p.walkflag=true;
}else if( checkkey(KEY_INPUT_LEFT)>0 ){
p.muki=1; //左向きで
p.walkflag=true; //フラグが建つよ
}else if( checkkey(KEY_INPUT_RIGHT)>0 ){
p.muki=2; //右
p.walkflag=true;
}else if( checkkey(KEY_INPUT_UP)>0 ){
p.muki=3; //右
p.walkflag=true;
}else if( checkkey(KEY_INPUT_DOWN)>0 ){
p.muki=4;
p.walkflag=true;
}else{ //それ以外
p.walkflag=false; //フラグ建ってないよ
}
//歩きフラグの分岐
if(p.walkflag==true){//フラグがたってる時
if(p.muki==1){ //左へ
p.x-=4; //走る
p.y+=4; /*クォータの座標に変えたため、X座標だけ変動しても斜めに移動するため
y座標も変えた*/
p.img=10+(p.cnt/5)%8;
}if(p.muki==2){ //右へ
p.x+=4; //走る
p.y-=4;
p.img=19+(p.cnt/5)%8;//それのアニメーション
}if(p.muki==3){ //上へ
p.y-=6;
p.x-=6;
p.img=28+(p.cnt/5)%8;
}if(p.muki==4){ //下へ
p.y+=6;
p.x+=6;
p.img=1+(p.cnt/5)%8;
}
if(p.muki==5){ //左上
p.x-=6;
p.img=37+(p.cnt/5)%8;
}if(p.muki==6){ //左下
p.y+=6;
p.img=55+(p.cnt/5)%8;
}if(p.muki==7){ //右上
p.y-=6;
p.img=46+(p.cnt/5)%8;
}if(p.muki==8){
p.x+=6;
p.img=64+(p.cnt/5)%8;
}
}if(p.walkflag==false){//フラグが建ってない時
//それぞれの向きの立っている絵にする
if(p.muki==1) p.img=9;
if(p.muki==2) p.img=18;
if(p.muki==3) p.img=27;
if(p.muki==4) p.img=0;
if(p.muki==5) p.img=36;
if(p.muki==6) p.img=54;
if(p.muki==7) p.img=45;
if(p.muki==8) p.img=63;
}
そこで上記の質問でソフト屋さんが配列を使えばきれいにできるとのヒントをくれたので
それをもとに自分なりきれいにしてみました。
ソフト屋さん、せっかくアドバイスくれたのに遅くなってすいません!
以下がそのコードになります。
//キー入力配列
p.muki[0]=CheckKey(KEY_INPUT_LEFT); p.muki[1]=CheckKey(KEY_INPUT_RIGHT);
p.muki[2]=CheckKey(KEY_INPUT_DOWN); p.muki[3]=CheckKey(KEY_INPUT_UP);
for(int i=0; i<4; i++){
if(p.muki[i]>0){
switch(i){
case 0://左へ
p.x-=p.speed;//走る
p.y+=p.speed;
p.img=10+(p.cnt/5)%8;//それのアニメーション
break;
case 1://右へ
p.x+=p.speed;
p.y-=p.speed;
p.img=19+(p.cnt/5)%8;
break;
case 2://下へ
p.x+=p.speed;
p.y+=p.speed;
p.img=1+(p.cnt/5)%8;
break;
case 3://上へ
p.x-=p.speed;
p.y-=p.speed;
p.img=28+(p.cnt/5)%8;
break;
}
}
}
どうでしょうか?我ながらなかなか綺麗になったと思うのですが……
まだ歩きフラグなど入れてないため移動をやめると走ってる途中の画像で止まりますが、ベースはこんな感じでいいかなーと。
ソフト屋さんのもう一つのヒントの構造体配列はいまいち扱い方が思いつかなかったのでそれはまだ実装できておりません。
できればcheckkeyの配列化、構造体配列を使うをやってから質問したかったんですが、ごめんなさいわからんかったです……
よろしければ感想とアドバイスください。
いらぬ誤解を招かないよう、一応、コードの全体はっておきますね。
#include"DxLib.h"
#include"Key.h"//新c言語と同じupdateとcheckkeyが書かれてる
#include <math.h>//ルート使おうかなと思いインクルード
//画面の大きさ
#define SCREEN_WIDTH 640;
#define SCREEN_HEIGHT 480;
//チップの枚数
#define CHIP_NUMBER_X 10
#define CHIP_NUMBER_Y 8
#define MAP_PARTS_HSIZEX 32 /*マップパーツの横サイズ(半分)*/
#define MAP_PARTS_HSIZEY 16 /*マップパーツの縦サイズ(半分)*/
#define VTOP_PARTS_SIZEX 64 /*仮想トップビューのマップパーツの横サイズ*/
#define VTOP_PARTS_SIZEY 64 /*仮想トップビューのマップパーツの縦サイズ*/
#define CHAR_PARTS_SIZEX 64
#define CHAR_PARTS_SIZEY 48
#define MAP_VIEW_OFFSET 32
//プレイヤー構造体
typedef struct{
bool walkflag,jumpflag;//歩きフラグ
int img,cnt,jcnt,muki[8];//画像、カウンタ、向き
double x,y,speed,naname,oldx,oldy;//座標
}PLAY;
//マップデータ
int MapData[ CHIP_NUMBER_Y ][ CHIP_NUMBER_X ] =
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ,
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } ,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
/*AllocConsole();
freopen("CONOUT$", "w", stdout); //標準出力をコンソールにする
// printf( "これでprintfが使えます\n" ); //←お試し用*/
//構造体宣言
PLAY p;
//画像変数
int player[81];
int map;
//画像の読み込み
map = LoadGraph("img/mapchip01.bmp");
LoadDivGraph("img/player1.png",81,9,9,64,64,player);
//構造体要素の初期化
memset(&p,0,sizeof(PLAY));
//プレイヤー座標の初期化
p.x=160;
p.y=160;
p.speed=4.0;//移動スピード
p.naname=sqrt(2.0);//とりあえず斜め移動の速度制御のために用意。まだ使ってない。
while(ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && updatekey()==0 ){
//プレイヤー移動アニメーションのためのカウント
p.cnt++;
//座標を記録
p.oldx=p.x;
p.oldy=p.y;
//キー入力配列
p.muki[0]=CheckKey(KEY_INPUT_LEFT); p.muki[1]=CheckKey(KEY_INPUT_RIGHT);
p.muki[2]=CheckKey(KEY_INPUT_DOWN); p.muki[3]=CheckKey(KEY_INPUT_UP);
for(int i=0; i<4; i++){
if(p.muki[i]>0){
switch(i){
case 0://左へ
p.x-=p.speed;//走る
p.y+=p.speed;
p.img=10+(p.cnt/5)%8;//それのアニメーション
break;
case 1://右へ
p.x+=p.speed;
p.y-=p.speed;
p.img=19+(p.cnt/5)%8;
break;
case 2://下へ
p.x+=p.speed;
p.y+=p.speed;
p.img=1+(p.cnt/5)%8;
break;
case 3://上へ
p.x-=p.speed;
p.y-=p.speed;
p.img=28+(p.cnt/5)%8;
break;
}
}
}
//いけない所だったら
if( MapData[(int)p.y/64][(int)p.x/64]==0 ){
p.x=p.oldx; //移動前の座標を代入
p.y=p.oldy;
}
//マップ描画
for(int y=0;y<CHIP_NUMBER_Y;y++){
for(int x=0;x<CHIP_NUMBER_X;x++){
if(MapData[y][x]==1){
DrawGraph(MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX*(x-y), MAP_PARTS_HSIZEY*(x+y), map,TRUE);
}
}
}
//プレイヤー描画
DrawGraph((MAP_VIEW_OFFSET+MAP_PARTS_HSIZEX)+(p.x-p.y)*MAP_PARTS_HSIZEX/VTOP_PARTS_SIZEX - CHAR_PARTS_SIZEX/2
,(p.x+p.y)*MAP_PARTS_HSIZEY/VTOP_PARTS_SIZEY - CHAR_PARTS_SIZEY
,player[p.img],TRUE);
}
DxLib_End();
return 0;
}