東方ProjectのMusic Roomの再現について
Posted: 2013年6月29日(土) 17:47
この間はお世話になりました。3Dです。
今回も前回と同じ様な質問です。
前回、CSVファイル(最終的に独自フォーマット(?)のテキストファイル)からパス、曲名、コメントを読みとって
表示するプログラムに関して教えて頂きました。この場をお借りしてお礼申し上げます。今回は、読みとり部では無く、
表示部に関する質問です。
となっております。
自分で実装したい事は、
No.1からNo.10までを表示。(表示中の曲番号 : No.1 ~ No.10)
↓
もし、No.10選択中に下キーが押されたら、項目を一つずらして表示(表示中の曲番号 : No.2 ~ No.11)このとき、座標は固定で、項目だけを移動させたいです。
↓
上同様に、たとえば、n曲~n+9曲表示中、選択されている項目がn+9曲の時に下キーが押されたら、表示中の項目はn+1曲~n+10曲となります。(伝えづらい...)
↓
もし、No.17選択中に下キーが押されたら、最初の表示に戻す(表示中の曲番号 : No.1 ~ No.10)
としたいです。自分なりに書いてみましたが、うまくスクロール(?)しません。文字の色も変わりません。また、座標は変えずに項目を動かしたいのですが、全体的に動いてしまいます。(flag == 1の時)
自分の説明不足や質問で不明な点が有れば書いて頂けるとうれしいです。
[開発環境]
Visual C++ 2008 Express Edition
Dxlib
windows XP
[追記]
#タイトルを変更しました
今回も前回と同じ様な質問です。
前回、CSVファイル(最終的に独自フォーマット(?)のテキストファイル)からパス、曲名、コメントを読みとって
表示するプログラムに関して教えて頂きました。この場をお借りしてお礼申し上げます。今回は、読みとり部では無く、
表示部に関する質問です。
#define _CRT_SECURE_NO_WARNINGS 1
#include "DxLib.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MUSIC_MAX 17 // 17曲あります
#define DRAW_MAX 10 // 一度に表示する項目は10です
typedef struct{
int color;
char name[256];
}test_t;
// テスト用の構造体です
static int Key[256]; // キーが押されているフレーム数を格納する
// キーの入力状態を更新する
int gpUpdateKey(){
char tmpKey[256]; // 現在のキーの入力状態を格納する
GetHitKeyStateAll( tmpKey );//全てのキーの入力状態を得る
for( int i=0; i<256; i++ ){
if( tmpKey[i] != 0 )//i番のキーコードに対応するキーが押されていたら
Key[i]++; //加算
else //押されていなければ
Key[i] = 0; //0にする
}
return 0;
}
int ProcessLoop() // 毎回行う重要なループ
{
if( ProcessMessage() != 0 ) return 1;
if( ClearDrawScreen() != 0 ) return 1;
if( gpUpdateKey() != 0 ) return 1;
return 0;
}
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int)
{
AllocConsole(); // DOS窓を使う為の処理?
freopen( "CONOUT$", "w", stdout ); // 上同様
ChangeWindowMode( TRUE ),SetAlwaysRunFlag( TRUE ),DxLib_Init(),SetDrawScreen( DX_SCREEN_BACK ); // いつもの処理
int i; // forで使用
int SelectNum = 0; // 現在選択中
int SelectMusicCmt = 0; // 現在表示している曲のコメント
int SelectedMusicNo= 0; // コメントを表示する曲の番号を保持
int Start = 0; // 開始位置
int End = 0; // 描写終了位置
int flag = 0; // 選択している項目が10より大きい時のフラグ
test_t music[17] = { // 構造体
{ GetColor(240,210,210), "曲1~kyoku 1.", },
{ GetColor(130,105,105), "曲2~kyoku 2.", },
{ GetColor(130,105,105), "曲3~kyoku 3.", },
{ GetColor(130,105,105), "曲4~kyoku 4.", },
{ GetColor(130,105,105), "曲5~kyoku 5.", },
{ GetColor(130,105,105), "曲6~kyoku 6.", },
{ GetColor(130,105,105), "曲7~kyoku 7.", },
{ GetColor(130,105,105), "曲8~kyoku 8.", },
{ GetColor(130,105,105), "曲9~kyoku 9.", },
{ GetColor(130,105,105), "曲10~kyoku 10.", },
{ GetColor(130,105,105), "曲11~kyoku 11.", },
{ GetColor(130,105,105), "曲12~kyoku 12.", },
{ GetColor(130,105,105), "曲13~kyoku 13.", },
{ GetColor(130,105,105), "曲14~kyoku 14.", },
{ GetColor(130,105,105), "曲15~kyoku 15.", },
{ GetColor(130,105,105), "曲16~kyoku 16.", },
{ GetColor(130,105,105), "曲17~kyoku 17.", },
};
printf( "Start == %d, End == %d\n", Start, End ); // 初期値を出力
while( !ProcessLoop() ){ // メインループ
/* ------------------------------計算------------------------------ */
End = Start + 10;
if( Key[ KEY_INPUT_DOWN ] == 1 ){ // 下キーが押されたら
SelectNum = ( SelectNum + 1 ) % MUSIC_MAX;
if( flag == 1 ){
Start++; // 開始位置を移動する
flag = 2; // フラグの値を変えて毎回行わないようにする
}
}
if( Key[ KEY_INPUT_UP ] == 1 ){ // 上キーが押されたら
SelectNum = ( SelectNum + ( MUSIC_MAX - 1 ) ) % MUSIC_MAX;
if( flag == 1 ){
Start--; // 開始位置を下げる
flag = 2; // フラグの値を変えて毎回行わないようにする
}
}
if( Key[ KEY_INPUT_UP ] == 1 || Key[ KEY_INPUT_DOWN ] == 1 ){ // 上下どちらかのキーが押されたら
for(i=0 ; i<MUSIC_MAX ; i++ ){
if( i == SelectNum ){ // もし、現在処理している物が選択番号と同じなら
music[i].color = GetColor(240,210,210); // 色を変える
} else { // そうでなければ
music[i].color = GetColor(130,105,105); // 色を変える
}
}
if( SelectNum > DRAW_MAX ){ // もし、始まりが10曲より大きくなったら
flag = 1; // フラグを立てる
} else { // そうじゃ無ければ
Start = 0; // 始まりを0に
flag = 0; // フラグを消す
}
printf( "Start == %d, End == %d, \n", Start, End ); // デバッグ用
}
if( Key[ KEY_INPUT_Z ] == 1 || Key[ KEY_INPUT_RETURN ] == 1 ){ // もし、エンターキーかZキーが押されたら
SelectedMusicNo = SelectNum; // その時のSelectNumを保存
}
/* ------------------------------描写------------------------------ */
for(i=Start ; i<End ; i++ ){ // No.~の部分
if( i == SelectNum ){ // もし選択中なら
DrawFormatString( 60, 100+16*i, music[i].color, "%s", music[i].name );
} else { // そうで無ければ
DrawFormatString( 65, 100+16*i, music[i].color, "%s", music[i].name );
}
}
// コメント描写
DrawFormatString( 80, 350, GetColor( 255, 255, 255 ), "%s", music[ SelectedMusicNo ].name ); //name なのは無視してください
ScreenFlip();
}
DxLib_End();
return 0;
}
自分で実装したい事は、
No.1からNo.10までを表示。(表示中の曲番号 : No.1 ~ No.10)
↓
もし、No.10選択中に下キーが押されたら、項目を一つずらして表示(表示中の曲番号 : No.2 ~ No.11)このとき、座標は固定で、項目だけを移動させたいです。
↓
上同様に、たとえば、n曲~n+9曲表示中、選択されている項目がn+9曲の時に下キーが押されたら、表示中の項目はn+1曲~n+10曲となります。(伝えづらい...)
↓
もし、No.17選択中に下キーが押されたら、最初の表示に戻す(表示中の曲番号 : No.1 ~ No.10)
としたいです。自分なりに書いてみましたが、うまくスクロール(?)しません。文字の色も変わりません。また、座標は変えずに項目を動かしたいのですが、全体的に動いてしまいます。(flag == 1の時)
自分の説明不足や質問で不明な点が有れば書いて頂けるとうれしいです。
[開発環境]
Visual C++ 2008 Express Edition
Dxlib
windows XP
[追記]
#タイトルを変更しました