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

📄 cgame.cpp

📁 JAVA3D游戏
💻 CPP
字号:
    /*
    *
============================================================================
    *  Name     : CGame.cpp
    *  Part of  : Example3D
    *  Created  : 12/14/2003 by Forum Nokia
    *  Description:
    *     This is the project specification file for Example3D.
    *     Initial content was generated by Series 60 AppWizard.
    *
    *  Version  : 1.0.0
    *  Copyright: Forum Nokia
    *
============================================================================
    */


// INCLUDES
#include "CGame.h"
#include "CPictureLoader.h"
#include "C3DBase.h"
#include "C3DRenderer.h"
#include "CPolygonObject.h"
#include <e32math.h>
#include <eikenv.h>
#include "3DObjects.h"

#include <e32svr.h>
#include <eikenv.h>
#include <eikappui.h>
#include <eikapp.h>



// CONSTANTS

const TInt KFrontWheelRadius = 100;
const TInt KRearWheelRadius = 150;
const TInt KRideHeight = 100;		// car ride height

const TInt KTileSize = 3000;		// tile size in 3D-space

// MEMBER FUNCTIONS

CGame* CGame::NewL( TDisplayMode aDisplayMode, const TBitmap& aScreen )
	{
	CGame* self = new( ELeave )CGame( aDisplayMode );
	CleanupStack::PushL( self );
	self->ConstructL( aScreen );
	CleanupStack::Pop( self );
	return self;
	}

CGame::~CGame()
	{
	delete iTexture.iData;
	delete iTexture2.iData;
	delete i3DBase;
	delete iRender;
	delete i3dHouse;
	delete i3dCar;
	delete i3dRoad;
	delete i3dGrass;
	delete i3dFrontWheel;
	delete i3dRearWheel;
	}

void CGame::ConstructL( const TBitmap& aScreen )
	{


	//
	// load texture
	//
	CPictureLoader* loader = CPictureLoader::NewL();
	CleanupStack::PushL( loader );
	iTexture = loader->LoadL( _L("picture.jpg"), iDisplayMode );
	iTexture2 = loader->LoadL( _L("picture2.jpg"), iDisplayMode );
	CleanupStack::PopAndDestroy( loader );

	//
	// construct 3D base classes
	//
	i3DBase = C3DBase::NewL( aScreen.iSize );
	iRender = C3DRenderer::NewL( i3DBase, 1000 );

	//
	// create 3D-objects
	//
	
	// house
	i3dHouse = CreateObject( KHouseVertexData, KHouseFaceData, KNumHouseVertices, KNumHouseFaces,
							TPoint( 0,0 ), 1 );
							
	i3dHouse->SetTexture( (TUint16*)iTexture2.iData );

	// road
	i3dRoad = CreateObject( KRoadVertexData, KRoadFaceData, KNumRoadVertices, KNumRoadFaces,
							TPoint( 0,0 ), 1 );

	i3dRoad->SetTexture( (TUint16*)iTexture.iData );
	
	// grass tile
	i3dGrass = CreateObject( KGrassVertexData, KGrassFaceData, KNumGrassVertices, KNumGrassFaces,
							TPoint( 0,0 ), 1 );

	i3dGrass->SetTexture( (TUint16*)iTexture2.iData );
	
	// wheels
	i3dFrontWheel = CreateWheel( KFrontWheelRadius, 50, 6 );
	i3dFrontWheel->SetTexture( (TUint16*)iTexture.iData );

	i3dRearWheel = CreateWheel( KRearWheelRadius, 150, 6 );
	i3dRearWheel->SetTexture( (TUint16*)iTexture.iData );

	// car
	i3dCar = CreateObject( KCarVertexData, KCarFaceData, KNumCarVertices, KNumCarFaces,
							TPoint( 0,128 ), 10 );

	i3dCar->SetTexture( (TUint16*)iTexture.iData );


	//
	// add objects to renderer
	//
	TInt n;
	n = iRender->AddObject( i3dRearWheel );
	n = iRender->AddObject( i3dFrontWheel );
	n = iRender->AddObject( i3dRearWheel );
	n = iRender->AddObject( i3dFrontWheel );
	
	n = iRender->AddObject( i3dCar );
	iRender->SetObjectPosition( n, TVertex( 0, -300,4250 ) );
	iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );

	
	TInt y;
	TInt x;

	//
	// Tilemapped city
	//


	for( y=0; y<KMapHeight; y++ )
		{
		TUint8* p = (TUint8*)KMap[ y ];
		for( x=0; x<KMapWidth; x++ )
			{
			switch( *p++ )
				{
				case '0':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );
					iRender->SetObjectPriority( n, 0x7000000 );
					break;
					}
				case '1':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 1024, 0 ) );
					iRender->SetObjectPriority( n, 0x7000000 );
					break;
					}
				case '2':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 2048, 0 ) );
					iRender->SetObjectPriority( n, 0x7000000 );
					break;
					}
				case '3':
					{
					n = iRender->AddObject( i3dRoad );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 3072, 0 ) );
					iRender->SetObjectPriority( n, 0x7000000 );
					break;
					}
				case 'a':
					{
					n = iRender->AddObject( i3dHouse );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );
					iRender->SetObjectPriority( n, 0 );
					break;
					}
				case 'x':
					{
					n = iRender->AddObject( i3dGrass );
					iRender->SetObjectPosition( n, 
						TVertex( x * KTileSize, 200, y * KTileSize ) );
					iRender->SetObjectAngle( n, TVertex( 0, 0, 0 ) );
					iRender->SetObjectPriority( n, 0x7000000 );
					break;
					}

				}
			}
		}
	

	// some initializations
	// start from tile 2,2 ( x,y on map )
	iCarPosition = TVertex( KTileSize * 2, 0, KTileSize * 2 );	
	iCarPositionAdd = TVertex( 0,0,0 );
	iCarSpeed = 0;

	iCameraMode = ECameraSouth;

	i3dHouse->Init();
	i3dCar->Init();
	i3dRoad->Init();
	i3dGrass->Init();
	i3dFrontWheel->Init();
	i3dRearWheel->Init();

	}

CGame::CGame( TDisplayMode aDisplayMode )
	: iDisplayMode( aDisplayMode )
	{

	}

void CGame::Draw( const TBitmap& aScreen )
	{
//  this would clear the screen
//  not needed; 3D is drawn to whole screen
	Mem::FillZ( aScreen.iData, aScreen.iSize.iWidth * aScreen.iSize.iHeight * 2 );

	TInt ang = iCarAngleSpeed*5;
	TInt carAngle = ang + iCarAngle;

	// calculate wheel positions in space
	TVertex v;
	v = TVertex( -500, -KRearWheelRadius, 350 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 0, v );

	v = TVertex(  500, -KFrontWheelRadius, 300 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 1, v );

	v = TVertex(  -500, -KRearWheelRadius, -350 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 2, v );

	v = TVertex(  500, -KFrontWheelRadius, -300 );
	v = i3DBase->RotateY( v, carAngle );
	v += iCarPosition;	
	iRender->SetObjectPosition( 3, v );

	// turn wheels to right direction ( car's direction )
	// add steering angle to front wheels
	// also turn wheels by iCarPos
	iRender->SetObjectAngle( 0, TVertex( 0, carAngle + ( KSinTableSize/2 ), -iCarPos*2 ) );
	iRender->SetObjectAngle( 1, TVertex( 0, -iSteerAngle*4 + carAngle + ( KSinTableSize/2 ), -iCarPos*3 ) );
	iRender->SetObjectAngle( 2, TVertex( 0, carAngle, iCarPos*2 ) );
	iRender->SetObjectAngle( 3, TVertex( 0, -iSteerAngle*4 + carAngle,	iCarPos*3 ) );
	

	if( iCarSpeed < 0 ) ang = -ang;

	// tilt car
	iRender->SetObjectAngle( 4, TVertex( ang, carAngle, -iThrottle * 50 ) );

	// and set car position in space
	iRender->SetObjectPosition( 4, iCarPosition + TVertex( 0,-KRideHeight, 0 ) );
	
	// calculate camera position

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

	switch( iCameraMode )
		{
		case ECameraBehind:
			{
			TVertex camPos( 5000 + speed * 25, -( 3000 + speed * 15 ), 00 );
			camPos = i3DBase->RotateY( camPos, ( iCarAngle + KSinTableSize/2 ) );
			iRender->SetCameraPosition( iCarPosition + camPos );
			iRender->SetCameraAngle( TVertex( 300, -( iCarAngle - KSinTableSize/4 ), 0 ) );
			break;
			}
		case ECameraSouth:
			{
			TVertex camPos( 0, -( 3000 + speed * 15 ), -( 5000 + speed * 25 )  );
			iRender->SetCameraPosition( iCarPosition + camPos );
			iRender->SetCameraAngle( TVertex( 300, 0, 0 ) );
			break;
			}

		case ECameraLookAt:
			{
			TVertex camPos( 0, -200, 5000  );
			iRender->SetCameraPosition( camPos );
			
			camPos -= iCarPosition;
			if( camPos.iZ == 0 ) camPos.iZ = 1;

			TReal r;
			Math::ATan( r, camPos.iX, camPos.iZ );
			r = r * KSinTableSize/2 / KPi;
			TInt32 a1;
			Math::Int( a1, r );
			a1 += KSinTableSize/2;
			
			if( camPos.iY == 0 ) camPos.iY = 1;
			Math::ATan( r, camPos.iZ, camPos.iY );
			r = r * KSinTableSize/2 / KPi;
			TInt32 a2;
			Math::Int( a2, r );
			a2 += KSinTableSize/2 + KSinTableSize/4;
			
			iRender->SetCameraAngle( TVertex( a2, a1, 0 ) );
			break;
			}
		}


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

	}

void CGame::Move( TUint8* aKey )
	{
	// check keys and update physics


	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;
		}
	else
		{
		// then check collisions against buildings
		TInt tile = KMap[ tileX ][ tileY ];
		if( tile == 'a' ) // if tile is a building
			{
			collision = ETrue;
			}
		}

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



	iCarPos += iCarSpeed;

	if( aKey[ EStdKeyUpArrow ] )
		{
		iThrottle = 1;
		}
	else if( aKey[ EStdKeyDownArrow ] )
		{
		iThrottle = -1;
		}
	else
		{
		iThrottle = 0;
		}

	iCarAngleSpeed = ( -iSteerAngle * iCarSpeed ) >> 8;
	iCarAngle += iCarAngleSpeed;

	if( aKey[ EStdKeyLeftArrow ] || aKey[ '5' ] )
		{
		iSteerAngle -= 4;
		}
	else if( aKey[ EStdKeyRightArrow ] || aKey[ '6' ]  )
		{
		iSteerAngle += 4;
		}
	else
		{
		if( iSteerAngle > 0 ) iSteerAngle -= 4;
		if( iSteerAngle < 0 ) iSteerAngle += 4;
		}

	iCarSpeed += iThrottle;

	if( iThrottle == 0 )
		{
		if( iCarSpeed > 0 ) iCarSpeed -= 1;
		if( iCarSpeed < 0 ) iCarSpeed += 1;
		}

	if( iCarSpeed > 100 ) iCarSpeed = 100;
	if( iCarSpeed < -100 ) iCarSpeed = -100;



	TInt steerLimit = 100;
	if( iSteerAngle > steerLimit ) iSteerAngle = steerLimit;
	if( iSteerAngle < -steerLimit ) iSteerAngle = -steerLimit;


	//
	// choose camera mode with keys 1 and 2
	//
	if( aKey[ '1' ] )
		{
		iCameraMode = ECameraBehind;
		}
	if( aKey[ '2' ] )
		{
		iCameraMode = ECameraSouth;
		}


	}


//
// 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 ) );

	for( i=0; i<aNumPoints; i++ )
		{
		TInt a1 = 4096 * i / aNumPoints;
		TInt a2 = ( a1 + 4096 / aNumPoints ) & 4095;
		
		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 ) );

		TInt tx1 = 64 + x1 * 63 / aRadius;
		TInt ty1 = 64 + y1 * 63 / aRadius;
		TInt tx2 = 64 + x2 * 63 / aRadius;
		TInt ty2 = 64 + y2 * 63 / 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;
	}


⌨️ 快捷键说明

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