現在地: メニュー >> 実践編08 >> 実践編08::1人称視点 >> 実践編08::まとめコード1

問題


「→」「←」「↑」「↓」キーを押す事で1人称視点での移動を行え。

答え


#include <iostream>
#include <cmath>
#include <GL/glut.h>


//------------ 各種データ構造 ------------//
class WalkInfo
{
public:
	float HeadAngle;//カメラの回転(Y軸中心)
	float PosX;//x
	float PosY;//y
	float PosZ;//z
	float WalkBias;//縦揺れ用バイアス値
	float weight;
	//コンストラクタ
	WalkInfo():HeadAngle(0),PosX(0),PosY(0),PosZ(0),WalkBias(0),weight(0.05){}

};


//------------- プロトタイプ宣言 ------------------//
void display();
void reshape(int w, int h);
void specialkey(int key, int x, int y);
void DrawXYZ();
void DrawField();

//--------- 各種外部変数 ---------//
WalkInfo CurrentPos;
const float PI_OVER_180 = 0.0174532925;


//---------- OpenGLの初期設定 ------------//
void GLUT_CALL_FUNCs()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutSpecialFunc(specialkey);
}


void MyOtherGLInit()
{
	glClearColor(1.0, 1.0, 1.0, 1.0);
	glEnable(GL_DEPTH_TEST);

	//材質はglColorで設定する
	glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
	glEnable(GL_COLOR_MATERIAL);

	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);



}


void GLUT_INITs(int *argcp,char**argvp)
{
	glutInit(argcp,argvp);
	glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH);
	glutInitWindowSize(640,480);
	glutCreateWindow("Basic Walking Around");
	
	GLUT_CALL_FUNCs();
	MyOtherGLInit();

}



//------------- メイン関数 ------------//
int main(int argc ,char **argv)
{

	GLUT_INITs(&argc, argv);
	
	glutMainLoop();

	return 0;
}


//------------- ここから各種コールバック --------------//
void display()
{
	static float LightPos[]= {10,10,10,0};

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();
	
	
	glRotatef(360 - CurrentPos.HeadAngle,0,1.0,0);
	glTranslatef(-CurrentPos.PosX, -CurrentPos.PosY - 0.25, -CurrentPos.PosZ);
	glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
	
	DrawXYZ();

	DrawField();


	glutSwapBuffers();

}



void reshape(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(30.0, (double)w / (double)h, 0.1, 1000.0);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
}


//---  特殊キーによる制御  ----//
void specialkey(int key, int x, int y)
{

	static int Sign;
	Sign = 1;
	switch (key) 
	{
	case GLUT_KEY_UP:
		Sign = -1;
	case GLUT_KEY_DOWN:
		CurrentPos.PosX += Sign * sin(CurrentPos.HeadAngle * PI_OVER_180) * CurrentPos.weight;
		CurrentPos.PosZ += Sign * cos(CurrentPos.HeadAngle * PI_OVER_180) * CurrentPos.weight;

		if ((Sign == -1)&&(CurrentPos.WalkBias >= 359.0f))
		{
			CurrentPos.WalkBias = 0.0;
		}
		else if((Sign == 1)&&(CurrentPos.WalkBias <= 1.0))
		{
			CurrentPos.WalkBias = 359.0;
		}else{
			CurrentPos.WalkBias -= Sign*10;
		}

		CurrentPos.PosY= sin(CurrentPos.WalkBias*PI_OVER_180) / 20.0;
	break;


	case GLUT_KEY_RIGHT:
		Sign = -1;
	case GLUT_KEY_LEFT:
		CurrentPos.HeadAngle += Sign*2;
		break;


	default:
	break;



	}

	glutPostRedisplay();

}


//------------- ここから各種関数 ----------------//
void DrawXYZ()
{
	glBegin(GL_LINES);

	glColor3f(0,1,0);//x
	glVertex2f(-1000,0);
	glVertex2f(1000, 0);

	glColor3f(1,0,0);//y
	glVertex2f(0,0);
	glVertex2f(0,1000);

	glColor3f(0,0,1);//z
	glVertex3f(0,0,-1000);
	glVertex3f(0,0, 1000);
	glEnd();

}

void DrawField()
{
	glColor3f(0,1,0);
	glPushMatrix();
	glTranslatef(1,0,-3);
	glutSolidCube(0.5);
	glPopMatrix();

	glColor3f(1,1,0);
	glPushMatrix();
	glTranslatef(-1,0,-3);
	glutSolidCube(0.5);
	glPopMatrix();


	glColor3f(1,0,0);
	glPushMatrix();
	glTranslatef(1,0,5);
	glutSolidTeapot(0.3);
	glPopMatrix();

	glColor3f(1,0,1);
	glPushMatrix();
	glTranslatef(-1,0,5);
	glRotatef(90,-1,0,0);
	glutSolidCone(0.5,1,20,20);
	glPopMatrix();
}

メモ


キーリピートをOFFにして、アニメーションを使う事で滑らかに移動できる。

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます