Jump to content

  • Log In with Google      Sign In   
  • Create Account

Like
8Likes
Dislike

Building a First-Person Shooter Part 1.1: Visual Studio Setup

By Chris Vossen | Published May 08 2015 06:14 AM in Game Programming
Peer Reviewed by (Dave Hunt, jbadams, braindigitalis)

leadwerks visual studio tutorial fps c++ lua native code design mobile ios android pc mac

This is a continuation of a multi-part tutorial on Building a First-Person Shooter - Part 1.0: Creating a Room.

Setting up the VS 2010 project


Now that we've finished building our level it is now time to begin the coding side of the project. For this lesson, we will be using Visual Studio 2010 on Windows, but you can follow the equivalent steps for Xcode on Mac. Right-click on the project name in the project list and select the Open Folder menu item from the context menu that pops up. This will open the project folder in Windows Explorer (or Finder on Mac). Navigate to the Projects/Windows folder and open the file MyGame.sln. At this point in time we are going to create a few blank C++ and Header files that we will be fleshing out throughout the tutorial.

Attached Image: Cpp1.png

Attached Image: cpp2.png

Creating C++ Files


In the Visual Studio’s Solution Explorer (normally located on the left side of the screen) right click on the Source folder and select Add->New Item, A new item window will pop up and we are going to select “C++ File (.cpp)” and name the file “Player” we also want to change the location of this file so on the right side of “Location” click the browse button and navigate to “MyGame/Source” and click “Select Folder” finally click Add and our new Player.cpp file will appear in the Solution Explorer. We will also want a “Node.cpp” file so repeat the process again but this time name the file “Node”.

Attached Image: cpp3.png

Attached Image: cpp4.png

Creating Header Files


Adding header files into Visual Studios 2010 is essentially the same process as adding in a cpp file. This time we will click on the “Header Files” folder in the solution explorer, right click and select Add->New Item. The window from before will pop up, but now we select “Header File (.h)” instead. Once again we will want these files saved in the “MyGame/Source” folder so remember to save to the correct folder. We are going to make three headers for this tutorial so repeat the steps of adding a new file for Player.h, Node.h, and MyGame.h.

Attached Image: cpp5.png

Attached Image: cpp6.png

Now we're ready to start coding.

MyGame.h


Inside MyGame.h we are going to set a series of #define statements that will allow other files to just make a single #define call. You will notice a call to #pragma once, this is a preprocessor directive that says “only include the following files if they’re not already included”. After this call we insert #define calls to leadwerks.h, node.h, and player.h:

#pragma once
#include "Leadwerks.h"
#include "Node.h"
#include "Player.h"

App Class


By default the App class contains two functions for structuring a game. App::Start() will be called when the game begins, and App::Loop() will be called continuously until the game ends. Inside App.h we are going to remove the default camera and add in a Player, the resulting file should look as such:

#pragma once
#include "Leadwerks.h"
#include "MyGame.h"

using namespace Leadwerks;

class App
{
public:
    Window* window;
    Context* context;
    World* world;
    Player* player;

    App();
    virtual ~App();

    virtual bool Start();
    virtual bool Loop();
};

Since we removed the default camera from App.h we will also need to remove the initialization call within the App constructor inside App.cpp:

App::App() : window(NULL), context(NULL), world(NULL){}

Next we are going to create a new instance of a player in App::Start() as well as call the player’s Update function in App::Loop():

//Create the player
player = new Player;
//Update the player
player->Update();

Also inside the App::Start() function, we are going to load an ambient background sound, then have that sound play on a continuous loop. (We'll replace this with something more advanced later on, but this is fine for now):

Sound* sound = Sound::Load("Sound/Ambient/cryogenic_room_tone_10.wav");
Source* source = Source::Create();
source->SetSound(sound);
source->SetLoopMode(true);
source->Play();

By the end of these changes your finished App class should look like the following:

#include "App.h"
#include "MyGame.h"

using namespace Leadwerks;

App::App() : window(NULL), context(NULL), world(NULL) {}

App::~App()
{
    //delete world; delete window;
}

bool App::Start()
{
    //Create a window
    window = Window::Create("MyGame");

    //Create a context
    context = Context::Create(window);

    //Create a world
    world = World::Create();

    //Create the player
    player = new Player;

    std::string mapname = System::GetProperty("map","Maps/start.map");
    if (!Map::Load(mapname)) Debug::Error("Failed to load map \""+mapname+"\".");

    //Move the mouse to the center of the screen
    window->HideMouse();
    window->SetMousePosition(context->GetWidth()/2,context->GetHeight()/2);

    Sound* sound = Sound::Load("Sound/Ambient/cryogenic_room_tone_10.wav");
    Source* source = Source::Create();
    source->SetSound(sound);
    source->SetLoopMode(true);
    source->Play();
    world->SetAmbientLight(0,0,0,1);

    return true;
}

bool App::Loop()
{
    //Close the window to end the program
    if (window->Closed() || window->KeyDown(Key::Escape)) return false;

    //Update the game timing
    Time::Step();

    //Update the world
    world->Update();

    //Update the player
    player->Update();

    //Render the world
    world->Render();

    //Sync the context
    context->Sync(true);

    return true;
}

Node Class


Next we are going to create a base class which we will call Node. All classes in our game will be derived from this base class. This is called inheritance, because each class inherits members and functions from the class it's derived from. We can override inherited class functions with new ones, allowing us to create and extend behavior without rewriting all our code each time.

The Node class itself will be derived from the Leadwerks Object class, which is the base class for all objects in Leadwerks. This will give us a few useful features right off the bat. Our Node class can use reference counting, and it can also be easily passed to and from Lua. The node header file will get just one member, an Entity object:

#pragma once
#include "MyGame.h"

using namespace Leadwerks;

class Node : public Object
{
public:
    Entity* entity;

    Node();
    virtual ~Node();
};

In the Node.cpp file, we'll add the code for the Node constructor and destructor:

#include "MyGame.h"

Node::Node() : entity(NULL)
{
}

Node::~Node()
{
    if (entity)
    {
        if (entity->GetUserData()==this) entity->SetUserData(NULL);
        entity->Release();
        entity = NULL;
    }
}

Our code foundation has now been laid and it is finally time to move onto developing the player class, which will be the subject of our next lesson.



About the Author(s)


Chris Vossen is a developer at Leadwerks Software. A few of his contributions to the Leadwerks 3 Engine include designing and creating the LE3 particle system as well as building the example game Darkness Awaits. Areas of knowledge include:C++, Lua, Leadwerks Engine 3, Gameplay programming,and Particle systems.

License


GDOL (Gamedev.net Open License)






Comments

I don't know Chris, I always considered comments such as

 //Create a window
window = Window::Create("MyGame");

//Create a context
context = Context::Create(window);

 

...mildly insulting (besides being noise). But I'm very interested in Leadwerks, so carry on with those articles please!

It's very redundant I know, but it is an attempt to have the tutorials be inclusive to all levels of programming skill. 

 

There should be a tutorial released for the next few Mondays!

Is there any reason why you don't use any C++11 features? (nullptr, smart pointers, etc)

No real reasons in particular just trying to stick to the basics. 

http://bit.ly/1W9i4Xx
http://bit.ly/1WIiSlZ
http://bit.ly/1TOtSbq
http://bit.ly/258USdF
http://bit.ly/1s1RJ0U
http://bit.ly/1qBWahB
http://bit.ly/1VeFRUB
http://bit.ly/22jSQFF
http://bit.ly/1YNc3h2
http://bit.ly/1ORt8pN
http://bit.ly/1NEqV0y
http://bit.ly/1OGrW37
http://bit.ly/242rjIa
http://bit.ly/1XIPXxM
http://bit.ly/258V6kZ
http://bit.ly/1TrA9Ky
http://bit.ly/1U6wC3J
http://bit.ly/1WJDvPh
http://bit.ly/1TOu1eN
http://bit.ly/1XpgmAb
http://bit.ly/1WIiYtP
http://bit.ly/1Tv9r5W
http://bit.ly/27Mmfwk
http://bit.ly/25fAR8E
http://bit.ly/1XIQ9gz
http://bit.ly/1U6wktv
http://bit.ly/258VnEt
http://bit.ly/1XpgAqU
http://bit.ly/1TmTXnI
http://bit.ly/1ORt0Xi
http://bit.ly/1TmUA0q
http://bit.ly/1U6wykp
http://bit.ly/1OGs6HL
http://bit.ly/1TrAtJb
http://bit.ly/1U6zv7m
http://bit.ly/1s1S1ow
http://bit.ly/242s83y
http://bit.ly/242rzqC
http://bit.ly/25fANFT
http://bit.ly/1ORtkoN
http://bit.ly/258Vpfw
http://bit.ly/1qBWg8R
http://bit.ly/1OGrVfC
http://bit.ly/1TmUiXy
http://bit.ly/27MmszA
http://bit.ly/1ORtEUN
http://bit.ly/258Vr78
http://bit.ly/1XIQArg
http://bit.ly/1TrAEUY
http://bit.ly/1s1RJxT
http://bit.ly/1ORtlcs
http://bit.ly/1WIj4BM
http://bit.ly/1YNcR5s
http://bit.ly/1RgEHRu
http://bit.ly/1TA56zG
http://bit.ly/1Tv9y1u
http://bit.ly/1TOuk9E
http://bit.ly/20laBTo
http://bit.ly/20lbbkb
http://bit.ly/1OGrTV4
http://bit.ly/1TrAL2T
http://bit.ly/22jTe7b
http://bit.ly/25fB2kh
http://bit.ly/25fBbEo
http://bit.ly/1RgEhur
http://bit.ly/1U6zVdW
http://bit.ly/1XpgmQJ
http://bit.ly/1ORtqgm
http://bit.ly/242rUcU
http://bit.ly/1XpgZcX
http://bit.ly/27MnHPc
http://bit.ly/1WJDX00
http://bit.ly/1s1SqY3
http://bit.ly/1U6zCA0
http://bit.ly/1TOuM7O
http://bit.ly/1TA4Qkk
http://bit.ly/1OGshmg
http://bit.ly/1NEryqY
http://bit.ly/1U6wvoO
http://bit.ly/1XIR806
http://bit.ly/1OGsnKI
http://bit.ly/20laPdf
http://bit.ly/1NErzv7
http://bit.ly/1RgF4LU
http://bit.ly/1NErh7l
http://bit.ly/25fBFu5
http://bit.ly/1WIjHew
http://bit.ly/1ORtywm
http://bit.ly/1ORtFIc
http://bit.ly/1WIjp7y
http://bit.ly/1W9j79O
http://bit.ly/20lb7Rj
http://bit.ly/1NErGqv
http://bit.ly/1U6wHV5
http://bit.ly/1TA5Ch5
http://bit.ly/1sMlyTW
http://bit.ly/1Tvapz6
 


Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere where collaboration is valued above all else.




PARTNERS