DXライブラリ置き場 http://homepage2.nifty.com/natupaji/DxLib/dxprogram.html#N4
こちらの「マップスクロール」(スクロールが滑らかになる方)でマップを作りました。
質問なのですが、マップ上に敵がいます。
移動処理、当たり判定はなんとなく検討がついているので多分大丈夫なのですが、
自キャラが移動すると、モンスターもその方向に動き、また初期位置に戻る行動を繰り返してしまいます。
画面スクロールしても、敵をその場所に記憶させる事はできました。
例:自キャラが左へ移動→敵も一瞬左へ移動→すぐに初期位置に戻る
それと、マップスクロールを使っているため、ch.x、ch.yが機能しておらず、
キャラクターのアニメーションが向きしか機能していません。
(キャラの動きは旧ゲームプログラミング館19~22章)
どうすればマップスクロールに対応したアニメーションを行えるでしょうか。
ちなみに226~232行がキャラ、モンスター画像処理です。
コード張ります。
- コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269#include "DxLib.h"
#include "def.h"
#include "Hit.h"
#include "Key.h"
// モンスター、プレイヤーの位置
int PlayerX , PlayerY;
int MonsterX,MonsterY;
// 移動しているかどうかのフラグ( 0:停止中 1:移動中 )
int Move;
// 各方向に移動する量
int MoveX, MoveY;
// 移動し始めてから何フレーム経過したかを保持する変数
int MoveCounter;
int hp = 1000,hp_max = 1000; //初期HP
int ep = 0,ep_max = 1000; //初期MP
int exp = 0,exp_max = 1000; //初期EXP
int lvl = 1;
int MapDrawPointX , MapDrawPointY , MapDrawPointMonsX; // 描画するマップ座標値
int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
int idou = 0; //移動中の向きフラグ防止
int Key[256]; // キーが押されているフレーム数を格納する
int Stats_1 = OFF; //Item画面スイッチ処理
int ItemBox = OFF; //Item画面処理
int GameTime = 0;
ch_t ch;
mons_t mons;
extern int MapData[ MAP_HEIGHT ][ MAP_WIDTH ];
// マップとプレイヤーの描画関数
void GraphDraw( int ScrollX, int ScrollY )
{
int j , i ;
// 描画するマップチップの数をセット
DrawMapChipNumX = 800 / MAP_SIZE + 2 ;
DrawMapChipNumY = 600 / MAP_SIZE + 2 ;
// 画面左上に描画するマップ座標をセット
MapDrawPointX = PlayerX - ( DrawMapChipNumX / 2 - 1 ) ;
MapDrawPointY = PlayerY - ( DrawMapChipNumY / 2 - 1 ) ;
MapDrawPointMonsX = MonsterX - ( DrawMapChipNumX / 2 - 1 ) ;
// マップを描く
for( i = -1 ; i < DrawMapChipNumY ; i ++ )
{
for( j = -1 ; j < DrawMapChipNumX ; j ++ )
{
// 画面からはみ出た位置なら描画しない
if( j + MapDrawPointX < 0 || i + MapDrawPointY < 0 ||
j + MapDrawPointX >= MAP_WIDTH || i + MapDrawPointY >= MAP_HEIGHT ) continue ;
// マップデータが0だったら四角を描画する
if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 0 )
{
DrawBox(j * MAP_SIZE + ScrollX, i * MAP_SIZE + ScrollY,
j * MAP_SIZE + MAP_SIZE + ScrollX, i * MAP_SIZE + MAP_SIZE + ScrollY,
GetColor( 0 , 200 , 200 ) , TRUE ) ;
}
// マップデータが0だったら四角を描画する
if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 1 )
{
DrawBox(j * MAP_SIZE + ScrollX, i * MAP_SIZE + ScrollY,
j * MAP_SIZE + MAP_SIZE + ScrollX, i * MAP_SIZE + MAP_SIZE + ScrollY,
GetColor( 0 , 100 , 0 ) , TRUE ) ;
}
}
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int image[16];
int ScrollX, ScrollY ;
//画面サイズ
SetGraphMode( 800 , 600 , 32 ) ;
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
ch.x =320;
ch.y =160;
ch.walking_flag=0;
ch.muki=3;
// プレイヤーの初期位置をセット
PlayerX = 5 ;
PlayerY = 5 ;
MonsterX = 2;
MonsterY = 2;
// 最初は停止中(0)にしておく
Move = 0 ;
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
//画像読み込み
LoadDivGraph( "画像/char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
while(!ProcessMessage() && !ClearDrawScreen() && gpUpdateKey()==0 && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
// 移動中ではない場合キー入力を受け付ける
if( Move == 0 )
{
// キー入力を得る
// Key[0] = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ;
// キー入力に応じてプレイヤーの座標を移動
if( (Key[ KEY_INPUT_LEFT] >= 1) && PAD_INPUT_LEFT && ch.muki == 1)
{
Move = 1 ;
MoveX = -1 ;
MoveY = 0 ;
}
if( (Key[ KEY_INPUT_RIGHT] >= 1) && PAD_INPUT_RIGHT && ch.muki == 3)
{
Move = 1 ;
MoveX = 1 ;
MoveY = 0 ;
}
if( (Key[ KEY_INPUT_UP] >= 1) && PAD_INPUT_UP && ch.muki == 0)
{
Move = 1 ;
MoveX = 0 ;
MoveY = -1 ;
}
if( (Key[ KEY_INPUT_DOWN] >= 1) && PAD_INPUT_DOWN && ch.muki == 2)
{
Move = 1 ;
MoveX = 0 ;
MoveY = 1 ;
}
// 進入不可能なマップだった場合は移動できない
if( Move == 1 )
{
if( MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 0 ||
MapData[ PlayerY + MoveY ][ PlayerX + MoveX ] == 2)
{
Move = 0 ;
}
else
{
MoveCounter = 0 ;
}
}
// 停止中は画面のスクロールは行わない
ScrollX = 0 ;
ScrollY = 0 ;
}
// 移動中の場合は移動処理を行う
if( Move == 1 )
{
MoveCounter +=4 ;
idou = 1;
// 移動処理が終了したら停止中にする
if( MoveCounter == MOVE_FRAME )
{
Move = 0 ;
idou = 0;
// プレイヤーの位置を変更する
PlayerX += MoveX ;
PlayerY += MoveY ;
// 停止中は画面のスクロールは行わない
ScrollX = 0 ;
ScrollY = 0 ;
}
else
{
// 経過時間からスクロール量を算出する
ScrollX = -( MoveX * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
ScrollY = -( MoveY * MAP_SIZE * MoveCounter / MOVE_FRAME ) ;
}
}
// マップとプレイヤーを描画
GraphDraw( ScrollX, ScrollY ) ;
if(ch.x%32==0 && ch.y%32==0){ //座標が32で割り切れたら入力可能
ch.walking_flag=1; //歩くフラグを立てる。
if ( (Key[ KEY_INPUT_UP ] >= 1)
&& Key[ KEY_INPUT_LEFT ] == 0
&& Key[ KEY_INPUT_DOWN ] == 0
&& Key[ KEY_INPUT_RIGHT] == 0
&& idou == 0) //上ボタンが押されたら(それ以外を押されていなかったら)
ch.muki=0; //上向きフラグを立てる
else if( Key[ KEY_INPUT_LEFT ] >= 1
&& Key[ KEY_INPUT_UP ] == 0
&& Key[ KEY_INPUT_DOWN ] == 0
&& Key[ KEY_INPUT_RIGHT] == 0
&& idou == 0) //左ボタンが押されたら
ch.muki=1; //左向きフラグを立てる
else if( Key[ KEY_INPUT_DOWN ] >= 1
&& Key[ KEY_INPUT_UP ] == 0
&& Key[ KEY_INPUT_LEFT ] == 0
&& Key[ KEY_INPUT_RIGHT] == 0
&& idou == 0) //下ボタンが押されたら
ch.muki=2; //下向きフラグを立てる
else if( Key[ KEY_INPUT_RIGHT] >= 1
&& Key[ KEY_INPUT_UP ] == 0
&& Key[ KEY_INPUT_LEFT ] == 0
&& Key[ KEY_INPUT_DOWN] == 0
&& idou == 0) //右ボタンが押されたら
ch.muki=3; //右向きフラグを立てる
else //何のボタンも押されてなかったら
ch.walking_flag=0; //歩かないフラグを立てる
}
//当たり判定
MonsterHit();
//描画処理
//キャラクター
ch.img=image[ch.muki*4]; //画像をセット
DrawGraph( ( PlayerX - MapDrawPointX ) * MAP_SIZE , ( PlayerY - MapDrawPointY ) * MAP_SIZE, ch.img , TRUE ) ;//画像を描画
//モンスター
mons.img=image[(mons.x%32+mons.y%32)/8 + mons.muki*4]; //画像をセット
DrawGraph( ( MonsterX - MapDrawPointMonsX ) * MAP_SIZE , ( MonsterY - MapDrawPointY ) * MAP_SIZE, mons.img , TRUE ) ;//画像を描画
//ステータス背景
DrawBox(0,544,800,600,GetColor(0,125,120),TRUE );
//HP表示
DrawBox(89,555,91+WD ,571,GetColor(0,0,0),FALSE);//メーターの枠を描画
DrawBox(90,556,90+WD*hp/hp_max,570,GetColor(255,0,0),TRUE );//メーターの中身を描画
//EP表示
DrawBox(89,575,91+WD ,591,GetColor(0,0,0),FALSE);//メーターの枠を描画
DrawBox(90,576,90+WD*ep/ep_max,590,GetColor(0,200,120),TRUE );//メーターの中身を描画
if(ep<ep_max) ep+=1;
//EXP表示
DrawBox(249,555,351+WD ,591,GetColor(0,0,0),FALSE);//メーターの枠を描画
DrawBox(250,556,250+(WD+100)*exp/exp_max,590,GetColor(0,255,0),TRUE );//メーターの中身を描画
//文字表示
DrawString(65,555,"HP",GetColor(0,0,0));
DrawString(65,575,"EP",GetColor(0,0,0));
DrawString(215,565,"EXP",GetColor(0,0,0));
DrawFormatString(15,565, GetColor(0,0,0), "LV %d",lvl);
DrawString(475,565,"Equip",GetColor(0,0,0));
if(Key[ KEY_INPUT_A] == 1 && ItemBox == OFF){
ItemBox = ON;
Stats_1 = OFF;
} else if(Key[ KEY_INPUT_A] == 2 && Stats_1 == ON){
ItemBox = OFF;
}
if(ItemBox == ON){
DrawBox(20,50,120,200,GetColor(0,125,120),TRUE );
DrawString(30,60,"Item",GetColor(0,0,0));
if(Key[ KEY_INPUT_A] == 0)Stats_1 = ON;
}
ScreenFlip();
}
DxLib_End();
return 0;
}
よろしくお願いします。