This page contains a few code snippets taken from work in my portfolio, to show some small examples of my work and personal coding standards.
A wrapper class for a generic game using GLUT for window management and input. Uses static functions that can be assigned to GLUT callback functions, which in turn call the instance specific callback function. These callback functions are virtual, and thus can have overrides in base classes that are called via these static callbacks taking advantage of polymorphism.
#ifndef GAME_H #define GAME_H #include#include #include "camera.h" #include "gameState.h" #include "Physics.h" #include "Actors.h" #include "glut.h" #include "uncopyable.h" #include "log.h" #include "timer.h" #include "BASS\bass.h" #define FPS 60.f #define RENDER_DETAIL 15 namespace GameFramework { class GLUTGame : private Uncopyable { private: // Pointer to current instance (for callback wrappers) static GLUTGame* instance; // Window Parameters std::string m_title; int m_windowHeight; int m_windowWidth; // GLUT Initialization void InitGLUT(int argc, char *argv[]); /* BASS Initialization */ void InitBASS(); /* The game's clear color */ static Vec3 ClearColor; /* Used For timers */ clock_t lastElapsedTime; clock_t newElapsedTime; /* Renders a textured cube */ void RenderTexturedCube(GLint size); /* Milliseconds since the last frame */ Fl32 m_milliSecondsSinceLastFrame; /* Calculates Delta Time */ void CalculateDeltaTime(); protected: // GL Initialization virtual void InitGL(); // Physics Simulation Objects Physics::Scene* m_scene; Fl32 m_pxTimeStep; // Renders the given geometric object void RenderGeometry(physx::PxGeometryHolder h, bool textured = false); Camera camera; /* Current Delta Time */ Fl32 deltaTime; /* Physics Time Step Timer */ Fl32 simTimer; /* Get window dimensions */ Vec2 WindowDimensions() const; /* Is using a 2D camera */ bool m_is2D; /* Used for frame rate calculations */ int m_fps, m_time, m_timebase, m_frame; void CalculateFrameRate(); public: // Construction/Destruction GLUTGame(std::string title, int windowWidth, int windowHeight); ~GLUTGame(); /* Updates the games projection matrix */ static void UpdatePerspective(const Fl32& FOV); /* Set the game's clear color */ void SetClearColor(const Vec3& color); /* Get the game's clear color */ static Vec3 GetClearColor(); void Run(int argc, char *argv[]); // Enters the main loop virtual void Init(); // Instance Callback Functions virtual void Render(); virtual void Idle(); virtual void Reshape(int width, int height); virtual void MouseButton(int button, int state, int x, int y) = 0; virtual void MouseMove(int x, int y) = 0; virtual void KeyboardDown(unsigned char key, int x, int y) = 0; virtual void KeyboardUp(unsigned char key, int x, int y) = 0; virtual void SpecKeyboardDown(int key, int x, int y) = 0; virtual void SpecKeyboardUp(int key, int x, int y) = 0; virtual void Exit(); // Callback wrappers, used to call instance callbacks static void RenderWrapper(); static void IdleWrapper(); static void ReshapeWrapper(int width, int height); static void MouseButtonWrapper(int button, int state, int x, int y); static void MouseMoveWrapper(int x, int y); static void KeyboardDownWrapper(unsigned char key, int x, int y); static void KeyboardUpWrapper(unsigned char key, int x, int y); static void SpecKeyboardDownWrapper(int key, int x, int y); static void SpecKeyboardUpWrapper(int key, int x, int y); static void ExitWrapper(); }; } #endif #GAME_H
The header file contains all declarations as it should, and most of the important documentation is done here such that the user can refer to the use of a function without digging into the code in the cpp file.
#include "glutGame.h" #includeusing namespace physx; namespace GameFramework { GLUTGame* GLUTGame::instance = NULL; Vec3 GLUTGame::ClearColor = Vec3(.5f, 1.f, 1.f); static const int MAX_NUM_CONVEXMESH_TRIANGLES = 1024; static unsigned int gConvexMeshTriIndices[3 * MAX_NUM_CONVEXMESH_TRIANGLES]; GLUTGame::GLUTGame(std::string title, int windowWidth, int windowHeight) { Physics::PxInit(); // initialize physics m_scene = new Physics::Scene(); m_scene->Init(); // initialize scene instance = this; // Assign current instance for callback wrapper functions m_title = title; m_windowHeight = windowHeight; m_windowWidth = windowWidth; lastElapsedTime = 0; newElapsedTime = 0; deltaTime = 0; m_is2D = false; m_milliSecondsSinceLastFrame = 0; simTimer = 0; m_frame = 0; m_timebase = 0; m_fps = 0; } GLUTGame::~GLUTGame() { RELEASE(m_scene); } void GLUTGame::Run(int argc, char *argv[]) { Log::Write("Game Run Function Invoked...\n", ENGINE_LOG); InitGLUT(argc, argv); InitGL(); InitBASS(); Log::Write("Initializing Game...\n", ENGINE_LOG); Init(); Log::Write("Entering main game loop...\n", ENGINE_LOG); glutMainLoop(); } void GLUTGame::Init() { } void GLUTGame::UpdatePerspective(const Fl32& FOV) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); Fl32 r = glutGet(GLUT_INIT_WINDOW_WIDTH) / glutGet(GLUT_INIT_WINDOW_HEIGHT); gluPerspective(FOV, r, .1, 100); glMatrixMode(GL_MODELVIEW); } void GLUTGame::InitGL() // Virtual Initialization - Override to change lighting params { Log::Write("Intializing OpenGL (context version ", ENGINE_LOG); Log::Write((char*)glGetString(GL_VERSION), ENGINE_LOG); Log::Write(")...\n", ENGINE_LOG); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); Fl32 ambientColor[] = { .5f, .5f, .5f, 1.f }; Fl32 diffuseColor[] = { .4f, .4f, .4f, 1.f }; Fl32 specularColor[] = { 1.f, 1.f, 1.f, 1.f }; Fl32 position[] = { 1.f, 0.f, 0.f, 0.0f }; glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor); glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor); glLightfv(GL_LIGHT0, GL_POSITION, position); glEnable(GL_LIGHT0); } void GLUTGame::InitBASS() { Log::Write("Initializing BASS...\n", ENGINE_LOG); if (!BASS_Init(-1, 44100, 0, 0, 0)) Log::Write("Error initializing BASS!\n", ENGINE_LOG); } void GLUTGame::InitGLUT(int argc, char *argv[]) { Log::Write("Intializing GLUT ", ENGINE_LOG); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH) - m_windowWidth) / 2, (glutGet(GLUT_SCREEN_HEIGHT) - m_windowHeight) / 2); glutInitWindowSize(m_windowWidth, m_windowHeight); glutCreateWindow(m_title.c_str()); // Assign wrappers to callbacks glutDisplayFunc(RenderWrapper); glutIdleFunc(IdleWrapper); glutReshapeFunc(ReshapeWrapper); glutMotionFunc(MouseMoveWrapper); glutMouseFunc(MouseButtonWrapper); glutKeyboardFunc(KeyboardDownWrapper); glutKeyboardUpFunc(KeyboardUpWrapper); glutSpecialFunc(SpecKeyboardDownWrapper); glutSpecialUpFunc(SpecKeyboardUpWrapper); atexit(ExitWrapper); } void GLUTGame::RenderGeometry(PxGeometryHolder h, bool textured) { switch (h.getType()) { case PxGeometryType::eBOX: glScalef(h.box().halfExtents.x, h.box().halfExtents.y, h.box().halfExtents.z); if (textured) RenderTexturedCube(2.0f); else glutSolidCube(2.0f); break; case PxGeometryType::eSPHERE: glutSolidSphere(h.sphere().radius, RENDER_DETAIL, RENDER_DETAIL); break; case PxGeometryType::eCONVEXMESH: PxConvexMesh* mesh = h.convexMesh().convexMesh; const PxU32 nbPolys = mesh->getNbPolygons(); const PxU8* polygons = mesh->getIndexBuffer(); const PxVec3* verts = mesh->getVertices(); PxU32 numTotalTriangles = 0; for (PxU32 i = 0; i < nbPolys; i++) { PxHullPolygon data; mesh->getPolygonData(i, data); const PxU32 nbTris = data.mNbVerts - 2; const PxU8 vref0 = polygons[data.mIndexBase + 0]; for (PxU32 j = 0; j < nbTris; j++) { const PxU32 vref1 = polygons[data.mIndexBase + 0 + j + 1]; const PxU32 vref2 = polygons[data.mIndexBase + 0 + j + 2]; if (numTotalTriangles < MAX_NUM_CONVEXMESH_TRIANGLES) { gConvexMeshTriIndices[3 * numTotalTriangles + 0] = vref0; gConvexMeshTriIndices[3 * numTotalTriangles + 1] = vref1; gConvexMeshTriIndices[3 * numTotalTriangles + 2] = vref2; numTotalTriangles++; } } } if (numTotalTriangles < MAX_NUM_CONVEXMESH_TRIANGLES) { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, verts); glDrawElements(GL_TRIANGLES, numTotalTriangles * 3, GL_UNSIGNED_INT, gConvexMeshTriIndices); glDisableClientState(GL_VERTEX_ARRAY); } } } void GLUTGame::SetClearColor(const Vec3& color) { ClearColor = color; glClearColor(color.x, color.y, color.z, 1.f); } Vec3 GLUTGame::GetClearColor() { return ClearColor; } void GLUTGame::CalculateFrameRate() { m_frame++; m_time = glutGet(GLUT_ELAPSED_TIME); if (m_time - m_timebase > 1000) { m_fps = m_frame*1000.0 / (m_time - m_timebase); m_timebase = m_time; m_frame = 0; } } void GLUTGame::CalculateDeltaTime() { newElapsedTime = clock(); deltaTime = newElapsedTime - lastElapsedTime; deltaTime = deltaTime / (double)CLOCKS_PER_SEC; deltaTime = deltaTime / 1000; lastElapsedTime = newElapsedTime; } /*-------------------------------------------------------------------------\ | VIRTUAL CALLBACK FUNCTION DEFINITIONS | \-------------------------------------------------------------------------*/ void GLUTGame::Render() { } void GLUTGame::Idle() { CalculateDeltaTime(); m_milliSecondsSinceLastFrame += deltaTime; if (m_milliSecondsSinceLastFrame * 1000 >= 1.f / 60.f) { glutPostRedisplay(); m_milliSecondsSinceLastFrame = 0.f; } } void GLUTGame::Reshape(int width, int height) { glViewport(0, 0, width, height); if (m_is2D) gluOrtho2D(0, 1, 1, 0); else { glMatrixMode(GL_PROJECTION); glLoadIdentity(); Fl32 ratio = (Fl32)width / (Fl32)height; gluPerspective(camera.FOV, ratio, .1, 100); glMatrixMode(GL_MODELVIEW); } } void GLUTGame::MouseButton(int button, int state, int x, int y) { } void GLUTGame::MouseMove(int x, int y) { } void GLUTGame::KeyboardDown(unsigned char key, int x, int y) { } void GLUTGame::KeyboardUp(unsigned char key, int x, int y) { } void GLUTGame::SpecKeyboardDown(int key, int x, int y) { } void GLUTGame::SpecKeyboardUp(int key, int x, int y) { } void GLUTGame::Exit() { Log::Shutdown(); BASS_Free(); } Vec2 GLUTGame::WindowDimensions() const { return Vec2(m_windowWidth, m_windowHeight); } /*-------------------------------------------------------------------------\ | WRAPPER FUNCTION DEFINITIONS - USED TO CALL INSTANCE EQUIVALENT FUNCTIONS | \-------------------------------------------------------------------------*/ void GLUTGame::RenderWrapper() { instance->Render(); } void GLUTGame::IdleWrapper() { instance->Idle(); } void GLUTGame::ReshapeWrapper(int width, int height) { instance->Reshape(width, height); } // Mouse Wrappers void GLUTGame::MouseButtonWrapper(int button, int state, int x, int y) { instance->MouseButton(button, state, x, y); } void GLUTGame::MouseMoveWrapper(int x, int y) { instance->MouseMove(x, y); } // Keyboard Wrappers void GLUTGame::KeyboardDownWrapper(unsigned char key, int x, int y) { instance->KeyboardDown(key, x, y); } void GLUTGame::KeyboardUpWrapper(unsigned char key, int x, int y) { instance->KeyboardUp(key, x, y); } void GLUTGame::SpecKeyboardDownWrapper(int key, int x, int y) { instance->SpecKeyboardDown(key, x, y); } void GLUTGame::SpecKeyboardUpWrapper(int key, int x, int y) { instance->SpecKeyboardUp(key, x, y); } // Exit Wrapper void GLUTGame::ExitWrapper() { instance->Exit(); } }
The following code was used to represent a city in the game Kinect Rampage taken from my portfolio.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System.IO; using HKFramework; using HKFramework.ThreeD; using HKFramework.ThreeD.Entity; namespace KinectGame { /// <summary> /// Used to represent the size of individual buildings. /// <summary> public enum BuildingSize { Small, Medium, Large } /// <summary> /// Represents a map of a city. /// </summary> public struct CityMap { #region Declarations public Texture2D Map; private Texture2D characterTile; private Point currentPlayerPosition; public Vector2 Offset; public const int BLOCK_HEIGHT = 64; public const int BLOCK_WIDTH = 64; #endregion /// <summary> /// Constructs a new map. /// </summary> /// <paramname="city">The city to create a map of.</param> public CityMap(City city) { Map = new Texture2D(GameUtils.GetUtil(), city.Width * BLOCK_WIDTH, city.Height * BLOCK_HEIGHT); Offset = new Vector2((Config.Width/2 - Map.Width/2), (Config.Height/2) - (Map.Height/2)); characterTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/PlayerTile"); currentPlayerPosition = Point.Zero; #region Load Assets Texture2D crossRoadTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/CrossRoadTile"); Texture2D cityHallTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/cityHallTile"); Texture2D powerPlantTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/PowerPlant"); Texture2D heliPadTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/HeliPadTile"); Texture2D airportTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/AirPortTile"); Texture2D academyTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/SuperHeroTile"); Texture2D labTile = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/LabTile"); // Create transparency Color[] data = new Color[BLOCK_HEIGHT * BLOCK_WIDTH]; crossRoadTile.GetData<Color>(data); for (int i = 0; i < data.Length; i++) data[i].A = HUD.HUD_ALPHA; crossRoadTile.SetData<Color>(data); cityHallTile.GetData<Color>(data); for (int i = 0; i < data.Length; i++) data[i].A = HUD.HUD_ALPHA; cityHallTile.SetData<Color>(data); powerPlantTile.GetData<Color>(data); for (int i = 0; i < data.Length; i++) data[i].A = HUD.HUD_ALPHA; powerPlantTile.SetData<Color>(data); heliPadTile.GetData<Color>(data); for (int i = 0; i < data.Length; i++) data[i].A = HUD.HUD_ALPHA; heliPadTile.SetData<Color>(data); airportTile.GetData<Color>(data); for (int i = 0; i < data.Length; i++) data[i].A = HUD.HUD_ALPHA; airportTile.SetData<Color>(data); academyTile.GetData<Color>(data); for (int i = 0; i < data.Length; i++) data[i].A = HUD.HUD_ALPHA; academyTile.SetData<Color>(data); labTile.GetData<Color>(data); for (int i = 0; i < data.Length; i++) data[i].A = HUD.HUD_ALPHA; labTile.SetData<Color>(data); #endregion for (int y = 0; y < city.Height; y++) { for (int x = 0; x < city.Width; x++) { int currentTile = x + y * city.Width; // Initialize data to be used for map data = new Color[BLOCK_HEIGHT * BLOCK_WIDTH]; // Get required data if (city.Blocks[currentTile].BlockType == CityBlock.Type.Residential) crossRoadTile.GetData<Color>(data); else if (city.Blocks[currentTile].BlockType == CityBlock.Type.CityHall) cityHallTile.GetData<Color>(data); else if (city.Blocks[currentTile].BlockType == CityBlock.Type.SuperheroAcademy) academyTile.GetData<Color>(data); else if (city.Blocks[currentTile].BlockType == CityBlock.Type.PowerPlant) powerPlantTile.GetData<Color>(data); else if (city.Blocks[currentTile].BlockType == CityBlock.Type.Airport) airportTile.GetData<Color>(data); else if (city.Blocks[currentTile].BlockType == CityBlock.Type.Helipad) heliPadTile.GetData<Color>(data); else if (city.Blocks[currentTile].BlockType == CityBlock.Type.Lab) labTile.GetData<Color>(data); Map.SetData<Color>(0, new Rectangle(x * BLOCK_WIDTH, y * BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT), data, 0, data.Length); } } } /// <summary> /// Draws the map and player location. /// </summary> public void Draw() { GameUtils.GetUtil ().Begin(); GameUtils.GetUtil ().Draw(Map, Offset, Color.White); float rotation = 0f; if (GameHandler.CurrentLevel.PlayerDirection.X == -1) rotation = 90f; if (GameHandler.CurrentLevel.PlayerDirection.X == 1) rotation = -90f; if (GameHandler.CurrentLevel.PlayerDirection.Y == 1) rotation = 180f; rotation = MathHelper.ToRadians(rotation); GameUtils.GetUtil ().Draw(characterTile, Offset + new Vector2((currentPlayerPosition.X * BLOCK_WIDTH) + characterTile.Width / 2, (currentPlayerPosition.Y * BLOCK_HEIGHT) + characterTile.Height / 2), null, Color.White, rotation, new Vector2(characterTile.Width / 2, characterTile.Height / 2), 1f, SpriteEffects.None, 1f); GameUtils.GetUtil ().End(); } /// <summary> /// Updates the player's current position on the map. /// </summary> /// <paramname="playerPosition">The new player position.</param> public void Update(Point playerPosition) { currentPlayerPosition = playerPosition; } /// <summary> /// Changes the map to mark a destroyed structure at the given position. /// </summary> /// <paramname="position"></param> public void DestroyBlock(Point position) { Color[] tileData = new Color[BLOCK_WIDTH*BLOCK_HEIGHT]; Rectangle tileRect = new Rectangle(position.X * BLOCK_WIDTH, position.Y * BLOCK_HEIGHT, BLOCK_WIDTH, BLOCK_HEIGHT); Map.GetData<Color>(0, tileRect, tileData, 0, tileData.Length); for (int i = 0; i < tileData.Length; i++) tileData[i] = Color.Lerp(tileData[i], Color.Gray, 0.9f); Texture2D crossText = GameUtils.GetUtil ().Load ("2DAssets/Map Tiles/DestroyedTile"); Color[] crossData = new Color[crossText.Width * crossText.Height]; crossText.GetData<Color>(crossData); for (int i = 0; i < tileData.Length; i++) { if (crossData[i].A != 0) tileData[i] = crossData[i]; } Map.SetData<Color>(0, tileRect, tileData, 0, tileData.Length); } } /// <summary> /// Represents a single city block. /// </summary> public class CityBlock { /// <summary> /// Used to represent the type of a block in the city. Value correseponds to health and score. /// </summary> public enum Type { Residential = 0, CityHall = 700, PowerPlant = 450, Helipad = 300, SuperheroAcademy = 400, Lab = 250, Airport = 350 } #region Declarations private ModelEntity[] _buildings; private ModelEntity _structure; private ModelEntity _roadSegment; private TexturedVertexEntity _ground; private Point _position; private Type _blockType; private Building _building; public BoundingSphere BoundingSphere; #endregion /// <summary> /// Creates city block given a position in tile coordinates, a type and a block scalar. /// </summary> /// <paramname="position">Position in tile coordinates of the block.</param> /// <paramname="type">The type of block.</param> /// <paramname="scale">The block scalar.</param> public CityBlock(Point position, Type type, float scale, Terrain.Type terrainType) { _blockType = type; // Define cityblock sizes float spacing = scale * 2; float buildingSpacing = scale - 1; Texture2D texture = GameUtils.GetUtil ().Load ("Textures/Grass"); ; switch (terrainType) { case Terrain.Type.Sand: texture = GameUtils.GetUtil ().Load ("Textures/Sand"); break; case Terrain.Type.Snow: texture = GameUtils.GetUtil ().Load ("Textures/Snow"); break; } // Initialize base of block _ground = new TexturedVertexEntity(new Vector3(position.X * spacing, 0, position.Y * spacing), new Vector3(-90, 0, 0), VertexEntity.PredefinedObject.Plane, new Color(0, 255, 0), new Vector3(scale, scale, 1), texture); _roadSegment = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/crossroad"), _ground.Position + new Vector3(0, 1.01f, 0), Vector3.Zero, new Vector3((scale/4)+0.015f, (scale/4)+0.015f, 1)); _position = position; // Initialize bounding box List bBox = new List (); bBox.Add(new Vector3((Position.X * scale) * 2, Camera.PlayerHeight, (Position.Y * scale) * 2)); bBox.Add(new Vector3((Position.X * scale) * 2, Camera.PlayerHeight, (Position.Y * scale) * 2)); BoundingSphere = BoundingSphere.CreateFromPoints(bBox); if(_blockType != Type.Residential) BoundingSphere.Radius = 6.0f; #region Initialize based on type switch (_blockType) { case Type.Residential: Random rand = new Random(DateTime.Now.Millisecond); BuildingSize[] sizes = new BuildingSize[4]; for (int i = 0; i < sizes.Length; i++) sizes[i] = (BuildingSize)rand.Next(3); _buildings = new ModelEntity[4]; for (int i = 0; i < 4; i++) { Vector3 currentPos = Vector3.Zero; // Determine building position if (i == 0) currentPos = new Vector3(-buildingSpacing, 1, -buildingSpacing); if (i == 1) currentPos = new Vector3(buildingSpacing, 1, -buildingSpacing); if (i == 2) currentPos = new Vector3(buildingSpacing, 1, buildingSpacing); if (i == 3) currentPos = new Vector3(-buildingSpacing, 1, buildingSpacing); currentPos += _ground.Position; if (sizes[i] == BuildingSize.Small) _buildings[i] = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/smallBuilding"), currentPos + new Vector3(0, 0, 0), Vector3.Zero, new Vector3(1, 1, 1)); if (sizes[i] == BuildingSize.Medium) _buildings[i] = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/mediumBuilding"), currentPos, Vector3.Zero, new Vector3(1, 1, 1)); if (sizes[i] == BuildingSize.Large) _buildings[i] = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/largeBuilding"), currentPos, Vector3.Zero, new Vector3(1, 1, 1)); } break; case Type.CityHall: _structure = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/cityHall"), _ground.Position + new Vector3(0, 1, 0), new Vector3(-90, 0, 0), new Vector3(1, 1, 1)); Texture2D hallTex = GameUtils.GetUtil ().Load ("2DAssets/Buildings/CityHall"); _building = new Building(hallTex, new Vector2(Config.Width / 2, Config.Height - (hallTex.Height / 2)), _blockType); break; case Type.PowerPlant: _structure = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/powerPlant"), _ground.Position + new Vector3(0, 1, 0), Vector3.Zero, new Vector3(1, 1, 3)); Texture2D plantTex = GameUtils.GetUtil ().Load ("2DAssets/Buildings/PowerPlant"); _building = new Building(plantTex, new Vector2(Config.Width / 2, Config.Height - (plantTex.Height / 2)), _blockType); break; case Type.Airport: _structure = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/airport"), _ground.Position + new Vector3(0, 1, 0), Vector3.Zero, new Vector3(1, 1, 1)); Texture2D airportTex = GameUtils.GetUtil ().Load ("2DAssets/Buildings/airPort"); _building = new Building(airportTex, new Vector2(Config.Width / 2, Config.Height - (airportTex.Height / 2)), _blockType); break; case Type.Helipad: _structure = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/heliPad"), _ground.Position + new Vector3(0, 1, 0), Vector3.Zero, new Vector3(1, 1, 1)); Texture2D helipadTex = GameUtils.GetUtil ().Load ("2DAssets/Buildings/Helipad"); _building = new Building(helipadTex, new Vector2(Config.Width / 2, Config.Height - (helipadTex.Height / 2)), _blockType); break; case Type.SuperheroAcademy: _structure = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/academy"), _ground.Position + new Vector3(0, 1, 0), Vector3.Zero, new Vector3(1, 1, 1)); Texture2D academyTex = GameUtils.GetUtil ().Load ("2DAssets/Buildings/Academy"); _building = new Building(academyTex, new Vector2(Config.Width / 2, Config.Height - (academyTex.Height / 2)), _blockType); break; case Type.Lab: _structure = new ModelEntity(GameUtils.GetUtil ().Load ("Models/City/lab"), _ground.Position + new Vector3(0, 1, 0), Vector3.Zero, new Vector3(1, 1, 1)); Texture2D labTex = GameUtils.GetUtil ().Load ("2DAssets/Buildings/Lab"); _building = new Building(labTex, new Vector2(Config.Width / 2, Config.Height - (labTex.Height / 2)), _blockType); break; } #endregion } /// <summary> /// Draws the city block and all of it's structures. /// </summary> public void Draw() { if (_blockType == Type.Residential) { for (int i = 0; i < _buildings.Length; i++) _buildings[i].Draw(); } else { if(_building.Destroyed == false) _structure.Draw(); } _ground.Draw(); if (_blockType == Type.Residential) _roadSegment.Draw(); else { if (_building.Destroyed) _roadSegment.Draw(); } //BoundingSphereRenderer.Render(BoundingSphere, GameUtils.GetUtil (), Camera.View, Camera.Projection, Color.Red); } public void Update() { if (_blockType != Type.Residential) { if (_building.Destroyed) BoundingSphere.Radius = 0.1f; } } public Point Position { get { return _position; } } public Type BlockType { get { return _blockType; } } public Building Building { get { return _building; } } } /// <summary> /// Represents a city. /// </summary> public class City { #region Declarations private CityBlock[] _blocks; private int _width, _height; const int BUILDINGS_PER_BLOCK = 4; CityMap _map; float _blockScale; public int NumberOfPowerPlants = 0, NumberOfHelipads = 0, NumberOfAirPorts = 0, NumberOfAcademies = 0; #endregion /// <summary> /// Generates a new city. /// </summary> /// <paramname="height">The height of the city in blocks.</param> /// <paramname="width">The width of the city in blocks.</param> /// <paramname="CHlocation">The City Hall location.</param> /// <paramname="pPlants">The power plant locations (leave null for none)</param> /// <paramname="hPads">The helipad locations (leave null for none)</param> /// <paramname="aPorts">The airport locations (leave null for none)</param> /// <paramname="academies">The academy site locations (leave null for none)</param> public City(CityData data) { _blockScale = data.BlockScale; _width = data.Width; _height = data.Height; NumberOfPowerPlants = data.NumberOfPowerPlants; NumberOfHelipads = data.NumberOfHelipads; NumberOfAirPorts = data.NumberOfAirports; NumberOfAcademies = data.NumberOfAcademies; _blocks = data.Blocks; _map = new CityMap(this); } /// <summary> /// Draws the city blocks and map. /// </summary> /// <paramname="drawMap">Whether or not to draw the map.</param> public void Draw(bool drawMap) { for (int i = 0; i < _blocks.Length; i++) _blocks[i].Draw(); if(drawMap) _map.Draw(); } /// <summary> /// Updates the player's current position. /// </summary> /// <paramname="currentPlayerPosition">The new player position.</param> public void Update(Point currentPlayerPosition) { _map.Update(currentPlayerPosition); for (int i = 0; i < _blocks.Length; i++) _blocks[i].Update(); } /// <summary> /// Returns the city block at the given position. /// </summary> public CityBlock BlockAt(Point position) { return _blocks[position.X + position.Y * Width]; } // Public Accessors public CityBlock[] Blocks { get { return _blocks; } } public float BlockScale { get { return _blockScale; } } public Point Dimensions { get { return new Point(_width, _height); } } public int Width { get { return _width; } } public int Height { get { return _height; } } public CityMap Map { get { return _map; } } public int TotalStructures { get { return NumberOfAcademies + NumberOfAirPorts + NumberOfHelipads + NumberOfPowerPlants; } } } /// <summary> /// Used to pass data in a package from Level /// </summary> public struct CityData { public float BlockScale; public int Height, Width; public int NumberOfAirports, NumberOfHelipads, NumberOfPowerPlants, NumberOfAcademies; public Terrain.Type TerrainType; public CityBlock[] Blocks; } }
Webpage powered by Bootstrap.
© Henri Keeble 2014