アニメーションと画面スクロールがうまくいってません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ケイン
記事: 7
登録日時: 6年前

アニメーションと画面スクロールがうまくいってません

#1

投稿記事 by ケイン » 6年前

初めまして、ケインです。DXライブラリでゲームを作っている途中ですけれどアニメーションと画面スクロールのところでうまくいってません。
初心者ですが、新・ゲームプログラミングの館などのサイトを参考に書いてみました。

コード:

#include "DxLib.h"
#include <math.h>
#define chip_size (32)							//一つのチップサイズ
#define screen_widht (640)						//画面の横幅
#define screen_height (480)						//画面の縦幅
#define MAP_WIDTH (1280/chip_size)				//マップの横幅
#define map_height (screen_height/chip_size)	//マップの縦幅
#define map_widht_pixel (1280)					//マップのピクセルサイズ


typedef struct {
	int plx, ply, plimg, plmuki, kogeki,sesshoku,ycount,xcount;
}ch_t;

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,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,0,0,0,0,0,0,0,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,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 },
	{ 1,1,1,1,1,1,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 },
	{ 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
	{ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,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 },
	{ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,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 },
	{ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,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 },
	{ 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 },
	{ 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 },
	{ 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 },
	{ 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 },
	
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

	int image[18];//主人公の歩行アニメーション
	int kimage[30];//主人公の攻撃アニメーション
	char Key[256];
	ch_t ch;

	if (ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1) return -1; //ウィンドウ化と初期化処理

	ch.plx = 0; //主人公のx座標
	ch.ply = 150; //主人公のy座標
	ch.plmuki = 3;//主人公の初期グラフィック
	int ix=0, iy=0;
	ch.ycount = 0;
	ch.xcount = 0;
	int sayu=0;//左右のどっちを向いているか
	int houkou=0;
	int kogekicounter=0;//攻撃カウンタ
	int kogekigra=0;//主人公の攻撃グラフィック
	ch.sesshoku=0;//敵に接触してるか
	ch.kogeki=false;//攻撃してるか
	int eimage[18];//敵のグラフィック
	int enemygra = 0;
	int enemyx = 400;//敵のx座標
	int enemyy = 160;//敵のy座標
	int enewcounter=0;
	int waimage[18];//主人公のグラフィック
	int wai = 0;
	int wax = ch.plx;
	int way = ch.ply;
	int wacounter = 0;
	int t1rimage[15];
	int t1r = 0;
	int t1rcounter = 0;
	int bw, bh, sw, sh;
	double enesx, enesy;
	int damage;//ダメージ判定
	int i, j;
	int haikei;
	int hai;
	int mapend= 1280;
	int camerax ;
	int cameray = 0;
	int ncamera;
	int scrolloffset;
	int gamenx;

	
	SetDrawScreen(DX_SCREEN_BACK); //描画先を裏画面に設定
	LoadDivGraph("t1.png", 18, 3, 6, 250, 250, eimage);//画像を分割してeimage配列に保存
	LoadDivGraph("aruki.png", 18, 3, 6, 200, 200, image);//画像を分割してimage配列に保存
	LoadDivGraph("鉈3段.png", 30, 3, 10, 250, 250, kimage);//画像を分割してkimage配列に保存
	LoadDivGraph("pose.png", 18, 3, 6, 200, 200, waimage);//画像を分割してwaimage配列に保存
	LoadDivGraph("tre.png", 15, 3, 5, 250, 250, t1rimage);//画像を分割してt1rimage配列に保存
	while (!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll(Key) && !Key[KEY_INPUT_ESCAPE])
	{
		
		gamenx = ch.plx;

		//haikei = LoadGraph("BACK1.png");
		//for (i = 0; i<20; i++)
		//	for (j = 0; j<40; j++)
		//		if (hantei[i][j] == 1)
		//			DrawGraph(j * 32, i * 32, haikei, TRUE);

		hai = LoadGraph("douro.png");
		camerax = gamenx-screen_widht/2;
		if (camerax < 0)
		{
			camerax = 0;
		}
		if (camerax >1280)
		{
			camerax = 1280;
		}
		//画面スクロール
		if (ch.plx >mapend)
		{
			scrolloffset = ch.plx - mapend;

			ncamera = camerax + scrolloffset;

			if (ncamera > (map_widht_pixel - screen_widht))
			{
				scrolloffset = (map_widht_pixel - screen_widht) - camerax;
			}

			if (scrolloffset > 0)
			{
				camerax += scrolloffset;

				ch.plx -= scrolloffset;
				enemyx -= scrolloffset;
				wax -= scrolloffset;
			}

			
		}
		//背景の描画
		{
			for (i = 0; i < map_height; i++)
			{
				for (j = 0; j < MAP_WIDTH; j++)
				{
					if (mapdata[i][j] == 0)
					{	

						DrawGraph((int)(j * chip_size)-(camerax), (int)(i * chip_size), hai, TRUE);		
						}
					}
				}
			}
		
		


		
		//主人公の動き
		{
			

			if (CheckHitKey(KEY_INPUT_RIGHT) == 1 || CheckHitKey(KEY_INPUT_LEFT) == 1) { //キーボードの方向キーの右か左を押しているとch.xカウンタが増えていく
				ch.xcount++;

			}
			if (CheckHitKey(KEY_INPUT_UP) == 1 || CheckHitKey(KEY_INPUT_DOWN) == 1) { //キーボードの方向キーの上か下を押しているとch.yカウンタが増えていく
				ch.ycount++;
			}




			if (CheckHitKey(KEY_INPUT_RIGHT) > 0) {//方向キーの右を押している時、右向きの主人公の歩行アニメーションをする

				ch.plmuki = 0 + (ch.xcount % 64) / 8;
				ch.plx += 3;
				wax += 3;
				sayu = 0;

			}

			if (CheckHitKey(KEY_INPUT_LEFT) > 0) {//方向キーの左を押している時、左向きの主人公の歩行アニメーションをする

				ch.plmuki = 9 + (ch.xcount % 64) / 8;
				ch.plx -= 3;
				wax -= 3;
				sayu = 1;

			}


			if (CheckHitKey(KEY_INPUT_UP) > 0) {//主人公が左右のどちらかを向いてて方向キーの上を押している時、その向きのままの主人公の歩行アニメーションをする

				if (houkou == 0) {
					ch.plmuki = 0 + (ch.ycount % 64) / 8;

				}
				else if (houkou == 1) {
					ch.plmuki = 9 + (ch.ycount % 64) / 8;
				}

				ch.ply -= 3;
				way -= 3;
			}

			if (CheckHitKey(KEY_INPUT_DOWN) > 0) {//主人公が左右のどちらかを向いてて方向キーの下を押している時、その向きのままの主人公の歩行アニメーションをする

				if (houkou == 0) {
					ch.plmuki = 0 + (ch.ycount % 64) / 8;
				}
				else if (houkou == 1) {
					ch.plmuki = 9 + (ch.ycount % 64) / 8;
				}
				ch.ply += 3;
				way += 3;
			}

			//方向キーを押していない時は、ch.xカウンタ、ch.yカウンタを0にする
			if (Key[KEY_INPUT_LEFT] == 0) {

				if (Key[KEY_INPUT_RIGHT] == 0) {

					if (Key[KEY_INPUT_UP] == 0) {

						if (Key[KEY_INPUT_DOWN] == 0) {

							ch.xcount = 0;
							ch.ycount = 0;

						}
					}
				}
			}

			if (sayu == 0)
			{
				if (ch.xcount == 0) 
				{
					if (ch.ycount == 0)
					{
						//ch.plmuki = 4;
				}
				}
			}

			if (sayu == 1)
			{
				if (ch.xcount == 0)
				{
					if (ch.ycount == 0)
					{
						//ch.plmuki = 10;
					}
				}
			}

			if (ch.plmuki == 0 || ch.plmuki == 1 || ch.plmuki == 2)//主人公の右向きの画像がある時、右方向を向いてるとする
			{

				houkou = 0;//右向き
			}


			if (ch.plmuki == 9 || ch.plmuki == 10 || ch.plmuki == 11) //主人公の左向きの画像がある時、左方向を向いてるとする
			{

				houkou = 1;//左向き
			}

			if (CheckHitKey(KEY_INPUT_UP) && CheckHitKey(KEY_INPUT_DOWN))
			{
				ch.ycount = 28;
			}

			if (CheckHitKey(KEY_INPUT_RIGHT) && CheckHitKey(KEY_INPUT_LEFT))
			{
				ch.xcount = 28;
			}
			//画面外に出ないようにするための壁
			if (ch.plx < 0&&wax<0)
			{
				ch.plx = 0;
				wax = 0;
			}
			if (ch.plx > 1080&&wax>1080)
			{
				ch.plx = 1080;
				wax = 1080;
			}
			if (ch.ply < 0 && way < 0)
			{
				ch.ply = 0;
				way = 0;
			}
			if (ch.ply > 280 && way > 280)
			{
				ch.ply = 280;
				way = 280;
			}

			if (CheckHitKey(KEY_INPUT_UP) || CheckHitKey(KEY_INPUT_DOWN) || CheckHitKey(KEY_INPUT_RIGHT) || CheckHitKey(KEY_INPUT_LEFT))
			{
				DrawGraph(ch.plx, ch.ply, image[ch.plmuki], TRUE);//主人公の描画
			}

		}
		
		//敵の追跡
		{
			double sb, sbx, sby, bx, by, sx, sy;

			sx = enemyx / 2;
			sy = enemyy / 2;

			bx = ch.plx / 2;
			by = ch.ply / 2;

			sbx = bx - sx;
			sby = by - sy;

			sb = sqrt(sbx*sbx + sby*sby);

			enesx = sbx / sb * 2;
			enesy = sby / sb * 2;
 
				if ((ch.plx - 30 < enemyx && ch.plx + 90 > enemyx &&//主人公がダメージを受ける範囲内にいない場合、主人公を追いかけ、敵の歩行アニメーションをする
					ch.ply + 90 > enemyy && ch.ply - 70 < enemyy) == 0)
				{
					enemyx += enesx;
					enemyy += enesy;
					DrawGraph(enemyx, enemyy, eimage[enemygra], TRUE);//敵の歩行アニメーション
					enewcounter++;
					

				}
				if (enemyx > ch.plx + 90 )
				{
					enemygra = 1 + (enewcounter % 128) / 16;
				}
				if (enemyx < ch.plx - 30)
				{
					enemygra = 10 + (enewcounter % 128) / 16;
				}
			
		}
		
		//攻撃
		{
		if (CheckHitKey(KEY_INPUT_Z) == 1) { //Zキーを押してる時は攻撃していると判定
			ch.kogeki = true;
		}
		else if (CheckHitKey(KEY_INPUT_Z) == 0&&kogekicounter==0)//Zキーが押されていなく、攻撃カウンタが0の場合は攻撃していないとする
		{
			ch.kogeki = false;
		}

		if (ch.kogeki == true) { //攻撃してると判定されたら攻撃カウンタを増やしていく
			kogekicounter++;
		}
		if(ch.kogeki== true){//攻撃をしてると判定されている時は攻撃1のアニメーションをさせる
			kogekigra = 0+(kogekicounter%32)/8;
			DrawGraph(ch.plx, ch.ply, kimage[kogekigra], TRUE);
		}

		 if (ch.kogeki == true && 64>kogekicounter&&kogekicounter>32)//攻撃1のアニメーションの後にZキーを押すと攻撃2のアニメーションをさせる←実現できていない
			{

		 kogekigra = 5 + (kogekicounter % 64) / 16;
		 DrawGraph(ch.plx, ch.ply, kimage[kogekigra], TRUE);
		}

		
		 if ( 32<kogekicounter&&64>kogekicounter&&CheckHitKey(KEY_INPUT_Z) != 1)//攻撃カウンタが32と64の中間にある時にZキーを押さなかったら攻撃カウンタが0になる←攻撃2に移れない原因?
		 {
			 
			 kogekicounter = 0;

		 }
		 //何も操作していない時は主人公の立ってる時のアニメーションをする
			if(sayu==0&&ch.kogeki==false&&kogekicounter==0&&
				CheckHitKey(KEY_INPUT_UP)==0&& CheckHitKey(KEY_INPUT_DOWN) ==0&& CheckHitKey(KEY_INPUT_RIGHT) ==0&& CheckHitKey(KEY_INPUT_LEFT)==0) 
			{
				DrawGraph(wax, way, waimage[wai], TRUE);//主人公の立ちアニメーション(右向き)
				wacounter++;
				wai = 0 + (wacounter % 65) / 13;
			}
			if (sayu==1&&ch.kogeki == false && kogekicounter == 0 &&
				CheckHitKey(KEY_INPUT_UP) == 0 && CheckHitKey(KEY_INPUT_DOWN) == 0 && CheckHitKey(KEY_INPUT_RIGHT) == 0 && CheckHitKey(KEY_INPUT_LEFT) == 0)
			{
				DrawGraph(wax, way, waimage[wai], TRUE);//主人公の立ちアニメーション(左向き)
				wacounter++;
				wai = 6 + (wacounter % 65) / 13;
			}
			
		}
		//攻撃の当たり判定
		
			if (ch.kogeki == true)//主人公が攻撃をしており、範囲内に敵がいた場合は敵のダメージ判定をする
			{
				if (ch.plx - 30 < enemyx && ch.plx + 90 > enemyx &&
					ch.ply + 90 > enemyy && ch.ply - 70 < enemyy)
				{
					damage = 1;

				}
			}

			if (damage == 1)//敵がダメージを受けたとき時、ダメージを受ける時のアニメーションをする
			{
				DrawGraph(enemyx, enemyy, t1rimage[t1r], TRUE);
				t1rcounter++;
				t1r = 0 + (t1rcounter % 36) / 12;
			}
		    if (ch.kogeki==false)
			{
				damage = 0;
				t1rcounter = 0;
			}
		//接触領域←これから先使用する予定
		{
			if (ch.plx - 30 < enemyx && ch.plx + 90 > enemyx &&
				ch.ply + 90 > enemyy && ch.ply - 70 < enemyy)
			{
				//enemyx = ch.plx-enemyx;
				//enemyy = ch.ply-enemyy;
				}
			}
		
		ScreenFlip();//裏画面を表画面に反映
	}

	DxLib_End();
	return 0;
}
①画面スクロールの問題は、主人公をうまく追いかけていないところです。右に進めば進むほど、主人公が画面の外に埋もれてしまいます。
②Zキーを押した時に攻撃のアニメーションをするようにしてありますが、1つ目の攻撃アニメーションが終わった後にまたZキーを押すと2つ目の攻撃アニメーションに
映るようにしておきたいです。しかし、1つ目の攻撃アニメーションが終わった後にまたZキーを押してもそのまま終わってしまいます。攻撃カウンタが32を超えた時に
0にするようにしてあるのが原因だとは分かっていますけれど、どなたかいい方法を教えていただけないのでしょうか?
よろしくお願いします。

“C言語何でも質問掲示板” へ戻る