⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgame.cpp

📁 S60 3D游戏引擎开发案例 S60 3D游戏引擎开发案例
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	TInt speed = iCarSpeed;
	if( speed < 0 ) speed = -speed;


	switch( iCameraMode )
		{
		case ECameraBehind:
		case ECameraInCar:
			{
			TVertex camPos;
			if( iCameraMode == ECameraBehind )
				{
				camPos = TVertex( 5000 + speed * 25, -( 3000 + speed * 15 ), 0 );
				iRender->SetCameraAngle( TVertex( 300, -( iCarAngle - KSinTableSize/4 ), 0 ) );
				}
			else
				{
				camPos = TVertex( 500, -500, 0 );
				iRender->SetCameraAngle( TVertex( -iCarTilt/5, -( iCarAngle - KSinTableSize/4 ), -ang ) );
				}
			camPos = i3DBase->RotateY( camPos, ( iCarAngle + KSinTableSize/2 ) );
			iRender->SetCameraPosition( iCarPosition + camPos );
			break;
			}
		case ECameraSouth:
			{
			TVertex camPos( 0, -( 6000 + speed * 15 ), -( 10000 + speed * 25 )	);
			iRender->SetCameraPosition( iCarPosition + camPos );
			iRender->SetCameraAngle( TVertex( 300, 0, 0 ) );
			break;
			}

		case ECameraTV1:
		case ECameraTV2:
		case ECameraTV3:
		case ECameraTV4:
			{
			TVertex camPos;
			switch( iCameraMode )
				{
				case ECameraTV1:
					camPos = TVertex( KTileSize*10,-15000, KTileSize*1  );
					break;
				case ECameraTV2:
					camPos = TVertex( KTileSize*10,-15000, KTileSize*10  );
					break;
				case ECameraTV3:
					camPos = TVertex( KTileSize*15,-5000, KTileSize*15  );
					break;
				case ECameraTV4:
					camPos = TVertex( KTileSize*8,-1000, KTileSize*16  );
					break;
				}
			iRender->SetCameraPosition( camPos );
			
			camPos -= iCarPosition;
			if( camPos.iX == 0 ) camPos.iX = 1;
			if( camPos.iY == 0 ) camPos.iY = 1;

			TReal r;

			Math::ATan( r, camPos.iZ, camPos.iX );
			r = r * KSinTableSize/2.0 / KPi;
			TInt32 a1;
			Math::Int( a1, r );
			a1 = -KSinTableSize / 4 -a1;
			
			TReal n1 = camPos.iZ;
			TReal n2 = camPos.iX;
			Math::Sqrt( r, n1*n1 + n2*n2 );
			Math::ATan( r, r, camPos.iY );
			r = r * KSinTableSize/2.0 / KPi;
			TInt32 a2;
			Math::Int( a2, r );
			a2 = -KSinTableSize / 4 + a2;

			iRender->SetCameraAngle( TVertex( a2,a1,0 ) );
			break;
			}
		}

	// create some text to draw
	TBuf8< 100 >text;
	text.Format( _L8("%d FPS\n%d Tris"), iFps->Fps(), PolygonCount() );
	DrawText( i3dText, text );

	// and draw everything
	iRender->Draw( aScreen );

	// we really want to draw over everything
	// so in OpenGL ES disable z-buffer
	glDisable( GL_DEPTH_TEST );

	// Draw statistics over everything
	// on top left corner
	TInt z = 32; // smaller z is nearer ( bigger ) screen
	TInt i = 1 << KShift;
	TMatrix m(  i, 0, 0, -aScreen.iSize.iWidth/2 * z,
				0, i, 0, -aScreen.iSize.iHeight/2 * z,
				0, 0, i, z * i );
	i3dText->Draw( aScreen, &m );

	glEnable		(GL_DEPTH_TEST);

	// Update Frames Per Second counter
	iFps->Update();
	}

void CGame::Move( TUint8* aKey )
	{
	// check keys and update physics
	TInt carLastSpeed = iCarSpeed;
	
	//
	// Move car to car angle direction by car speed
	//
	iCarPositionAdd = TVertex( iCarSpeed,0,0 );
	iCarPositionAdd = i3DBase->RotateY( iCarPositionAdd, iCarAngle & (KSinTableSize-1) );
	iCarPosition += iCarPositionAdd;
	
	// VERY simple collision detection from tilemap
	TBool collision = EFalse;
	TInt tileX = ( iCarPosition.iX + KTileSize/2 ) / KTileSize;
	TInt tileY = ( iCarPosition.iZ + KTileSize/2 ) / KTileSize;
	
	// first check we stay on map:
	if( ( tileX < 1 ) || ( tileX >= KMapWidth-1 ) ||
		( tileY < 1 ) || ( tileY >= KMapHeight-1 ) )
		{
		collision = ETrue;
		}

	// then check collisions against buildings
	TInt tile = KMap[ tileY ][ tileX ];
	if( tile == 'a' ) // if tile is a building
		{
		collision = ETrue;
		}

	if( collision )
		{
		// move back
		iCarPosition -= iCarPositionAdd;
		// and stop
		iCarSpeed = 0;
		}


	//
	// Move car position with car speed
	// car position is used to rotate wheels
	//
	iCarPos += iCarSpeed;

	//
	// Adjust throttle with key presses
	// arrow up and '2' are throttle
	// arrow down and '8' are reverse ( brake )
	//
	if( aKey[ EStdKeyUpArrow ] || aKey[ '2' ] || aKey[ EStdKeyDevice8 ] )
		{
		iThrottle = 1;
		}
	else if( aKey[ EStdKeyDownArrow ] || aKey[ '8' ] || aKey[ EStdKeyDevice9 ] )
		{
		iThrottle = -1;
		}
	else
		{
		iThrottle = 0;
		}

	//
	// Turn car with steering wheel
	//
	iCarAngleSpeed = ( -iSteerAngle * iCarSpeed ) / KCarTurnDivider;
	iCarAngle += iCarAngleSpeed;

	//
	// Adjust steering wheel with key presses
	// arrow left and '4' are left turn
	// arrow right and '6' are right turn
	//
	if( aKey[ EStdKeyLeftArrow ] || aKey[ '4' ] || aKey[ EStdKeyDevice6 ] )
		{
		iSteerAngle -= KSteeringSpeed;
		}
	else if( aKey[ EStdKeyRightArrow ] || aKey[ '6' ] || aKey[ EStdKeyDevice7 ]  )
		{
		iSteerAngle += KSteeringSpeed;
		}
	else
		{
		if( iSteerAngle > 0 ) iSteerAngle -= KSteeringSpeed;
		if( iSteerAngle < 0 ) iSteerAngle += KSteeringSpeed;
		}

	//
	// Adjust speed by throttle
	//
	iCarSpeed += iThrottle;
	if( iCarSpeed > 0 )
		{
		iCarSpeed -= iCarSpeed * iCarSpeed / KFriction;
		}
	if( iCarSpeed < 0 )
		{
		iCarSpeed += iCarSpeed * iCarSpeed / KFriction;
		}
	if( iThrottle == 0 )
		{
		if( iCarSpeed > 0 ) iCarSpeed -= 1;
		if( iCarSpeed < 0 ) iCarSpeed += 1;
		}
	
	//
	// Adjust steering wheel
	//
	if( iSteerAngle > KSteerLimit ) iSteerAngle = KSteerLimit;
	if( iSteerAngle < -KSteerLimit ) iSteerAngle = -KSteerLimit;

	//
	// Adjust car tilting by speed changes
	//
	iCarTilt += ( iCarSpeed - carLastSpeed ) * KCarTiltForce;
	if( iCarTilt > 0 )
		{
		iCarTilt -= ( iCarTilt * iCarTilt / KCarTiltSpringFactor );
		if( iCarTilt < 0 ) iCarTilt = 0;
		}
	if( iCarTilt < 0 )
		{
		iCarTilt += ( iCarTilt * iCarTilt / KCarTiltSpringFactor );
		if( iCarTilt > 0 ) iCarTilt = 0;
		}

	}

//
// These functions demonstrate how to create 3D objects
// It should be easy to convert objects from your
// favourite 3D object file format to use in here
//

CPolygonObject* CGame::CreateWheel( TInt aRadius, TInt aWidth, TInt aNumPoints )
	{
	CPolygonObject* o = CPolygonObject::NewL( i3DBase, 100,100 );
	TInt16* cos = i3DBase->CosTable();
	TInt16* sin = i3DBase->SinTable();

	TInt i;

	TInt z1 = -aWidth/2;
	TInt z2 = aWidth/2;

	o->AddVertex( TVertex( 0,0,0 ) );
	
	const TInt KTexturePixels = 128;

	for( i=0; i<aNumPoints; i++ )
		{
		TInt a1 = KSinTableSize * i / aNumPoints;
		TInt a2 = ( a1 + KSinTableSize / aNumPoints ) & (KSinTableSize-1);
		
		TInt x1 = ( aRadius * cos[ a1 ] ) >> KShift;
		TInt y1 = ( aRadius * sin[ a1 ] ) >> KShift;
		TInt x2 = ( aRadius * cos[ a2 ] ) >> KShift;
		TInt y2 = ( aRadius * sin[ a2 ] ) >> KShift;

		o->AddVertex( TVertex( x1,y1,z1 ) );
		o->AddVertex( TVertex( x1,y1,z2 ) );

		TInt n1 = i*2;
		TInt n2 = n1 + 1;
		TInt n3 = n1 + 2;
		TInt n4 = n1 + 3;
		if( n3 >= aNumPoints*2 ) n3 -= aNumPoints*2;
		if( n4 >= aNumPoints*2 ) n4 -= aNumPoints*2;

		n1 += 1;
		n2 += 1;
		n3 += 1;
		n4 += 1;

		o->AddFace( TFace( n1,n2,n3, 128,0, 255,0, 128,128 ) );
		o->AddFace( TFace( n3,n2,n4, 128,128, 255,0, 255,128 ) );
		
		// calculate texture pixel positions
		// for wheel rim
		TInt tx1 = KTexturePixels/2 + x1 * ( KTexturePixels/2-1 ) / aRadius;
		TInt ty1 = KTexturePixels/2 + y1 * ( KTexturePixels/2-1 ) / aRadius;
		TInt tx2 = KTexturePixels/2 + x2 * ( KTexturePixels/2-1 ) / aRadius;
		TInt ty2 = KTexturePixels/2 + y2 * ( KTexturePixels/2-1 ) / aRadius;

		o->AddFace( TFace( n1,n3,0, tx1,ty1, tx2,ty2, 64,64 ) );
		
		}

	return o;
	}

CPolygonObject* CGame::CreateObject( const TInt* aVertexData, const TInt* aFaceData,
									 TInt aNumVertices, TInt aNumFaces,
									 const TPoint& aTexOffset, TInt aTexMul )
	{
	// leave some extra room for vertices and polygons
	// otherwise renderer might not have enough space
	// after clipping
	CPolygonObject* o = CPolygonObject::NewL( i3DBase, aNumVertices*2+10, aNumFaces*2+10 );
	
	TInt n=0;
	TInt i;
	for( i=0; i<aNumVertices; i++ )
		{
		o->AddVertex( TVertex(	aVertexData[ n + 0 ],
								aVertexData[ n + 1 ],
								aVertexData[ n + 2 ]
								) );

		n += 3;
		}

	n=0;
	for( i=0; i<aNumFaces; i++ )
		{

		o->AddFace( TFace(	aFaceData[ n + 0 ],
							aFaceData[ n + 1 ],
							aFaceData[ n + 2 ],
							aFaceData[ n + 3 ]*aTexMul+aTexOffset.iX,
							aFaceData[ n + 4 ]*aTexMul+aTexOffset.iY,
							aFaceData[ n + 5 ]*aTexMul+aTexOffset.iX,
							aFaceData[ n + 6 ]*aTexMul+aTexOffset.iY,
							aFaceData[ n + 7 ]*aTexMul+aTexOffset.iX,
							aFaceData[ n + 8 ]*aTexMul+aTexOffset.iY
							) );
		n += 9;
		}

	return o;
	}

void CGame::DrawText( CPolygonObject* aObject, const TDesC8& aStr )
	{
	TInt n = aStr.Length();
	
	// reserve space for polygons in 3D-objects
	aObject->Reset( n*4, n*3 );
	
	TInt x = 0;
	TInt y = 0;
	
	// default font size in 3D-space
	const TInt size = 500;

	// go trough whole string
	for( TInt i=0; i<n; i++ )
		{
		TInt c = aStr[ i ];
		// check for line feed character:
		if( c == '\n' )
			{
			x = 0;
			y++;
			}
		else
			{
			TInt xx = x * size;
			TInt yy = y * size;

			TInt v1 = aObject->AddVertex( TVertex( xx, yy, 0 ) );
			TInt v2 = aObject->AddVertex( TVertex( xx + size, yy, 0 ) );
			TInt v3 = aObject->AddVertex( TVertex( xx + size, yy + size, 0 ) );
			TInt v4 = aObject->AddVertex( TVertex( xx, yy + size, 0 ) );
			
			// fonts are in 16x16 array in bitmap
			// first 16 characters are on first line
			// next 16 characters on second line and so on...
			TInt tx = c & 15;
			TInt ty = c >> 4;
			
			// fonts are 16 pixels high and wide
			// calculate top left ( x1, y1 ) and
			// bottom right( x2, y2 ) pixel positions
			// for current font
			TInt x1 = tx * 16;
			TInt y1 = ty * 16;
			TInt x2 = x1 + 15;
			TInt y2 = y1 + 15;
			
			// each visible font consists of two triangles
			// which make a textured rectangle with font picture
			aObject->AddFace( TFace( v1,v2,v3, x1,y1, x2,y1, x2,y2 ) );
			aObject->AddFace( TFace( v1,v3,v4, x1,y1, x2,y2, x1,y2 ) );

			x++;
			}
		}
	aObject->Init();
	}
	
TInt CGame::PolygonCount()
	{
	return i3DBase->PolygonCount();
	}

void CGame::Command( TInt aCommand )
	{

	switch( aCommand )
		{
		case EExample3DCamera1:
			iCameraMode = ECameraBehind;
			break;
		case EExample3DCamera2:
			iCameraMode = ECameraInCar;
			break;
		case EExample3DCamera3:
			iCameraMode = ECameraSouth;
			break;
		case EExample3DCamera4:
			iCameraMode = ECameraTV1;
			break;
		case EExample3DCamera5:
			iCameraMode = ECameraTV2;
			break;
		case EExample3DCamera6:
			iCameraMode = ECameraTV3;
			break;
		case EExample3DCamera7:
			iCameraMode = ECameraTV4;
			break;
		case EExample3DCameraToggle:
			iCameraMode++;
			if( iCameraMode == ECameraNone )
				{
				iCameraMode = 0;
				}
			break;
		}
	
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -