マップチップで画面をを左右にスクロールさせる
Posted: 2011年6月21日(火) 23:25
ものすごい初歩的なことなのかもしれませんが…
DXライブラリ置き場のサンプル、マップのスクロールを参考にさせていただき、
マップチップを使ったアクションゲームでの左右へのスクロールを作ろうと思い、
とりあえず横40マス(2画面分)、縦15マス分の画面を作ってみました。
サンプルの仕組みは理解したつもりですが、
自分であらかじめ組んでいたプログラムに取り付けるようにスクロール処理をつけたせいか間違っているようで、
キャラは中心から表示できたもののマップが表示されなく、さらにキャラごと高速移動するような結果になってしまいました…
サンプルひとつひとつが理解できてもこんがらがってくるのでちょっと困っているところです…
おかしいところがいくつかあると思うのですが…まず考え方が違ったのでしょうか…
DXライブラリ置き場のサンプル、マップのスクロールを参考にさせていただき、
マップチップを使ったアクションゲームでの左右へのスクロールを作ろうと思い、
とりあえず横40マス(2画面分)、縦15マス分の画面を作ってみました。
サンプルの仕組みは理解したつもりですが、
自分であらかじめ組んでいたプログラムに取り付けるようにスクロール処理をつけたせいか間違っているようで、
キャラは中心から表示できたもののマップが表示されなく、さらにキャラごと高速移動するような結果になってしまいました…
サンプルひとつひとつが理解できてもこんがらがってくるのでちょっと困っているところです…
おかしいところがいくつかあると思うのですが…まず考え方が違ったのでしょうか…
#include "DxLib.h"
//構造体
//プレイヤー構造体
struct Playerdata{
int X, Y, img;
}Player;
////
int Key[256];
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
else GetHitKeyStateAll_InputKey[i]=0;
}
return 0;
}
#define MAP_SIZE 32 // マップチップ一つのドットサイズ
#define MAP_WIDTH 40 // マップの幅
#define MAP_HEIGHT 15 // マップの縦長さ
// マップのデータ
int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] =
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } ,
{ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ,
} ;
/////
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
// 画像をロード
//マップ
int lenga1 = LoadGraph( "image/map/lenga1.png" );
int statesbar = LoadGraph( "image/statesbar.png" );
int haikei1 = LoadGraph( "image/haikei1.png" );
int testimg = LoadGraph( "image/testimg.png" );
//キャラ関係
int chara[24]; //キャラ画像
int HPgazou[11]; //HPの画像
LoadDivGraph( "image/chara.png" , 24 , 6 , 4 , 64 , 64 , chara );//プレイヤー
LoadDivGraph( "image/HP.png" , 11 , 1 , 11 , 224 , 32 , HPgazou );//体力
//関数
Player.X = 32 , Player.Y = 288 ; //プレイヤー座標
int JumpPower = 0 ; //ジャンプパワー
int Jump = 0 ; //ジャンプ状態か
int walkdirection = 1 ; //歩く向き
int walkanime = 0 ; //歩くアニメーション用
int HP = 10 ; //HP
int HPimg ; //HP画像
int i , j ; //座標用
int MapDrawPointX , MapDrawPointY ; // 描画するマップ座標値
int DrawMapChipNumX , DrawMapChipNumY ; // 描画するマップチップの数
// 描画するマップチップの数をセット
DrawMapChipNumX = 640 / MAP_SIZE + 1 ;
DrawMapChipNumY = 480 / MAP_SIZE + 1 ;
// 画面左上に描画するマップ座標をセット
MapDrawPointX = Player.X - DrawMapChipNumX / 2 ;
MapDrawPointY = Player.Y - DrawMapChipNumY / 2 ;
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
//ココから
//背景を描画
DrawGraph( 0, 0, haikei1, FALSE ); // 背景
// マップを描画
for( i = 0 ; i < DrawMapChipNumY ; i ++ )
{
for( j = 0 ; j < DrawMapChipNumX ; j ++ )
{
// 画面からはみ出た位置なら描画しない
if( j + MapDrawPointX < 0 || i + MapDrawPointY < 0 ||
j + MapDrawPointX >= MAP_WIDTH || i + MapDrawPointY >= MAP_HEIGHT ) continue ;
//1のとき壁を描画
if( MapData[ i + MapDrawPointY ][ j + MapDrawPointX ] == 1 )
{
DrawGraph( j * MAP_SIZE , i * MAP_SIZE , lenga1 , FALSE ) ;
}
}
}
// ジャンプ状態じゃなく、ジャンプボタンを押して地面についていたらジャンプ
if ( Jump==0 && (Key[KEY_INPUT_SPACE] >=1 ) && JumpPower <= 0)
if(MapData[(Player.Y+64)/32][(Player.X + 16)/32] != 0
||MapData[(Player.Y+64)/32][(Player.X + 47)/32] != 0)
{
JumpPower = 16 ;
Jump = 1 ;
}
//ジャンプ状態で右向きなら右ジャンプの画像
if ( walkdirection == 1 && Jump == 1 ){
Player.img=chara[5];
}
//ジャンプ状態で左向きなら左ジャンプの画像
if ( walkdirection == 0 && Jump == 1 ){
Player.img=chara[11];
}
if( Key[ KEY_INPUT_RIGHT ] >= 1 ) { //右キーが押されて
if(MapData[(Player.Y)/32][(Player.X + 48)/32] == 0 //右が壁じゃなかったら
&&MapData[(Player.Y+31)/32][(Player.X + 48)/32] == 0
&&MapData[(Player.Y+32)/32][(Player.X + 48)/32] == 0
&&MapData[(Player.Y+63)/32][(Player.X + 48)/32] == 0)
Player.X+=3 ; //右に動く
walkdirection = 1 ;
}
if( Key[ KEY_INPUT_RIGHT ] >= 1 && Jump== 0 ){ // 右キーが押されていてジャンプ状態じゃなかったら
walkanime++;
Player.img=chara[(walkanime/10)%4 +1];//右に歩くアニメ
}
if( walkdirection == 1 && ( Key[ KEY_INPUT_RIGHT ] == 0 )&& Jump== 0 )// 右キーが離されてジャンプ状態じゃなかったら
Player.img=chara[0]; //右を向く
if( Key[ KEY_INPUT_LEFT ] >= 1 ){// 左キーが押されて
if(MapData[(Player.Y)/32][(Player.X+15)/32] == 0
&&MapData[(Player.Y+31)/32][(Player.X+15)/32] == 0
&&MapData[(Player.Y+32)/32][(Player.X+15)/32] == 0
&&MapData[(Player.Y+63)/32][(Player.X+15)/32] == 0) //左が壁じゃなかったら
Player.X-=3 ; //左に動く
walkdirection = 0 ;
}
if( Key[ KEY_INPUT_LEFT ] >= 1 && Jump== 0 ){ // 左キーが押されていてジャンプ状態じゃなかったら
walkanime++;
Player.img=chara[(walkanime/10)%4 +7];//右に歩くアニメ
}
if( walkdirection == 0 && ( Key[ KEY_INPUT_LEFT ] == 0 ) && Jump== 0 ) // 左キーが離されてジャンプ状態じゃなかったら
Player.img=chara[6]; //左を向く
if( Key[ KEY_INPUT_RIGHT ] >= 1 && Key[ KEY_INPUT_LEFT ] >= 1)//左右両方押されてたら右向く
Player.img=chara[0];
// ジャンプ中ならキャラの落下処理
if(Jump == 1){
Player.Y -= JumpPower ;
JumpPower -= 1 ;
}
//補正//
//床にめりこんだら上に補正
if(JumpPower < 0)
if(MapData[(Player.Y+64)/32][(Player.X + 16)/32] != 0
||MapData[(Player.Y+64)/32][(Player.X + 47)/32] != 0)
{
Player.Y = ((Player.Y+65)/32) * 32 - 65 + 1 ;
}
//天井にめりこんだら下に補正
if(JumpPower > 0)
if(MapData[(Player.Y-1)/32][(Player.X + 16)/32] != 0
||MapData[(Player.Y-1)/32][(Player.X + 47)/32] != 0)
{
Player.Y = ((Player.Y+65)/32) * 32 - 65 + 32 + 1 ;
JumpPower = 0 ;
}
//右の壁にめりこんだら左に補正
if(MapData[(Player.Y)/32][(Player.X + 48)/32] != 0
||MapData[(Player.Y+63)/32][(Player.X + 48)/32] != 0)
{
Player.X = ((Player.X+65)/32) * 32 - 65 + 16 + 1 ;
}
//左の壁にめりこんだら右に補正
if(MapData[(Player.Y)/32][(Player.X+15)/32] != 0
||MapData[(Player.Y+63)/32][(Player.X+15)/32] != 0)
{
Player.X = ((Player.X+65)/32) * 32 - 65 + 16 + 1 ;
}
// ジャンプ中にキャラが地面についたら落下をやめる
if(Jump == 1 && JumpPower < 0 )
if(MapData[(Player.Y+64)/32][(Player.X + 16)/32] != 0
||MapData[(Player.Y+64)/32][(Player.X + 47)/32] != 0)
{
JumpPower = 0 ;
Jump = 0 ;
}
//歩いているときに踏み外したらジャンプ状態にする
if(Jump == 0)
if(MapData[(Player.Y+64)/32][(Player.X + 16)/32] == 0
&&MapData[(Player.Y+64)/32][(Player.X + 47)/32] == 0)
{
Jump = 1 ;
}
DrawGraph( ( Player.X - MapDrawPointX ) * MAP_SIZE,( Player.Y - MapDrawPointY ) * MAP_SIZE, Player.img, TRUE ); // キャラを描画
//HP
if( HP==10 )
HPimg = HPgazou[10];
//画像
//ステータスバー背景
for(int y=0 ; y<1 ; y++){
for(int x=0 ; x<20 ; x++){
DrawGraph(x*32+0,y*32+418,statesbar,FALSE);
}
}
DrawGraph( 0, 420, HPimg, TRUE ); // HPバー
DrawGraph( 0, 0, testimg, FALSE ); // テストイメージ
ScreenFlip();
}
DxLib_End();
return 0;
}