FANDOM


OverviewEdit

In this lesson I will be covering basically all of the general skills left before beginning to program actual games. That will include objects, functions, and pointers.

Object-Oriented ProgrammingEdit

The first big jump after the early programming languages was to create better systems of making programs smaller. How they did this was by making a collection known as an object. Objects are comprised of one or more data members (things like variables and arrays) called attributes and/or functions called methods. There are two main types of objects that you will ever see: structs and classes. I will focus on classes because they can do everything that the struct can as well as a lot more.

Declaring a ClassEdit

Here is a pretty standard class declaration:

public class Person
{
    public string Name;
    public int Age;

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    public int Change(string name, int age)
    {
        Name = name;
        Age = age;
        return 1;
    }
}

There is a lot to unpack even with something this short. I will start with the first line.

Access/Visibility ModifiersEdit

The first thing you see is the word public. public falls under a category of modifiers which control what can access what. public allows the entire class and anything else that wants to call on it, to call on it i.e. run it. The public modifier is used on variables that you want to be accessible outside the class. I will explain more about this as these topics come up. The other modifier (there are actually two others but we rarely use one of them ^^) is private. private restricts the access of a variable to only be used inside the class. The reasons for wanting to do this I will explain a little later.

Naming ConventionsEdit

There is really only one naming convention that programmers generally use for classes. That is to make the first letter of the class name, attributes, and methods uppercase. That is all really. Other than that feel free to do whatever you want ^^.

AttributesEdit

Imagine that attributes are kind of like the normal variables that you would write in main except that you cannot do operations with them inside the same scope they are defined. You can still set them to a value when initializing them but you cannot do something like this:

public class Person
{
    public string Name;
    public int Age;
    Age=1; //DO NOT DO!!!
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    public int Change(string name, int age)
    {
        Name = name;
        Age = age;
        return 1;
    }
}

MethodsEdit

This is where the utility of classes in C# really comes into play. It allows us to make and use functions. For those of you who do not know, a function is "a mathematical correspondence that assigns exactly one element of one set to each element of the same or another set". This is a very broad definition that I don't mind. Functions in computer have some similarities with those of mathematics and some differences. Functions (at least in C#) can have as many input variables(and arrays kind of) as you want but only one output. This output can be an array if you design it carefully so you can send back more than just one thing. I will explain how to do that a little later. Ignoring the first function you see called Person(I will explain that later), look at the method called Change. You will first see an access modifier which in this case is public and then you will see the word int. This should look familiar.

Return typeEdit

As I stated before, functions (often) return a value. In order for the compiler to know what type of value to expect, we use the key words that correspond to the data type. Arrays have there own somewhat special notation. It goes as follows:

 public int[] AddONE (int[] array, int length)
    {
        int[] newarray= array;
        for(int i=0; i<length; i++)
          {
              newarray[i]++;
          }
        return newarray;
    }

In this example, I created a function that returns an array whose elements are each one greater than the inputted array.

There is one other return type which is actually to return nothing. For this, you use void.

Input variablesEdit

For any given function, you may have have as many or as few input variables as you want. The variables are put inside of parethes(is/es?) and separated by commas similar to how functions look in mathematics. The variable names you choose for your function are arbitrary and are only visible within the scope of the function. Thus, the names of the variables you choose for your functions will not need to match the names of the variables you eventually send into it. You can think of these as placeholders that take the value of the variables. This is an important property. This means that you cannot change the value (actually you can but that comes later :)) of the variable you send into the function. Therefore if I use the function above and were to do something like length=5, the variable length inside of the function would change but whatever variable I eventually use to send to it would not. (This may be a bit confusing but just go with it for now. It will all make sense soon.) N.B. You can have several functions of the same name as long as they do not have identical input variable type(s)

ReturnEdit

The last thing I will mention about about functions is the return command. After you do whatever you want in the function you must remember to return something back unless it is a void function. In that case, you do not need a return statement but you can do one like this:    return;

For all the other return types, you can return variables, arrays, or constants like false, 1.345 or "abcde". For these, you should use return VARIABLE_NAME; or return 5;   etc.

ConstructorsEdit

Now I will address what the Person function is. It is called a constructor. A constructor is what a class refers to when it is being initialized (more on this next). Effectively it behaves like a function but looks a little different. First, it has no return type and second, it must have the same name as the class. There can be more than one constructor for a class as long as the input variable types are not identical. For example, I could have:

 public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
 public Person(string name)
    {
        Name=name;
        Age=0;
    }
 public Person(int age)
    {
        Name="";
        Age=age;
    }
 public Person()
    {
        Name="";
        Age=0;
    }

These 4 can account for many of the possibilities although they are endless. You do need to have at least one constructor for any class you write even if it doesn't change anything.

Using a ClassEdit

       using System;
       public class Person
       {
           public string Name;
           public int Age;
           public Person(string name, int age)
           {
               Name = name;
               Age = age;
           }
           //Other properties, methods, events...
       }
       
       class Program
       {
           static void Main()
           {
               Person person1 = new Person("Leopold", 6);
               Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);
       
               // Declare  new person, assign person1 to it.
               Person person2 = person1;
       
               //Change the name of person2, and person1 also changes.
               person2.Name = "Molly";
               person2.Age = 16;
       
               Console.WriteLine("person2 Name = {0} Age = {1}", person2.Name, person2.Age);
               Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);
       
               // Keep the console open in debug mode.
               Console.WriteLine("Press any key to exit.");
               Console.ReadKey();
       
           }
       }
         

This here is a utilization of the Person class we looked at before. I didn't write this one; instead I found it here. There are some other cool aspects about this code which I didn't know but I will talk about those later or never because they aren't really important for game development. Back to the topic at hand, we can see a utilization of the class in the Main function. Effectively, there are only three main things that I need to point out. One is that classes become a usable datatype like int, string, etc. The second is the usage of the dot operator "." (it is a period). The dot operator acts as the bridge between the public class methods and attributes and the instantiation of the class. To use it, it goes something like this:

CLASS_NAME VARIABLE_NAME= new CLASS_NAME(); //initialization
VARIABLE_NAME.METHOD_NAME();

The third thing is the initialization of classes. As you can see in the very general example that I just wrote, you use the new operator to instantiate classes using the constructor.

public vs. private revisitedEdit

Now that you have seen an actual use of classes, I can explain the differences between public and private in a bit more detail. As I mentioned before, the difference comes in what can access them. Public parts of a class can be accessed in any scope that the class is instantiated like we see here. If Name and Age were private, then we could not have used the dot operator to access to access them. The same is true for private class functions. The important aspect of private is that because it can only be accesed by functions within the class we do not have to worry about accidentally changing things we don't intend to. It also does make a slight speed difference even though it would be hard to detect in the things we are doing right now.

set and getEdit

This is a feature that is pretty important to C#. These are two modifier-ish things for variables. They come in the form of a function. Here is an example:

using System;
public class Employee
{
    public static int NumberOfEmployees;
    private static int counter;
    private string name;

    // A read-write instance property: 
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    // A read-only static property: 
    public static int Counter
    {
        get { return counter; }
    }

    // A Constructor: 
    public Employee()
    {
        // Calculate the employee's number:
        counter = ++counter + NumberOfEmployees;
    }
}

class TestEmployee
{
    static void Main()
    {
        Employee.NumberOfEmployees = 107;
        Employee e1 = new Employee();
        e1.Name = "Claude Vige";

        System.Console.WriteLine("Employee number: {0}", Employee.Counter);
        System.Console.WriteLine("Employee name: {0}", e1.Name);
    }
}
/* Output:
    Employee number: 108
    Employee name: Claude Vige
*/

As you can see here is a pretty abstract way to assign/retrieve things to name and counter. It is one of the methods of indirect assignment to the variables that I had hinted about. get is called when the value in Name is requested and set is called when there is an assignment is done. This method is does not seem to be the most intuitive means of doing it but it is how it is done. This took me a long time to get a firm grasp on so don't expect to know when and how to do it right from the start.

N.B. Don't worry a lot about the term static used in the example, but if you want to know more, you can check here .

InheritanceEdit

Of the key properties of modern computing is inheritance. Inheritance allows you to take properties from one class and transfer them to another. The donor is known as the parent class and the receiver is known as the child class. In C#, a parent can has many children as you want but a child may only have one parent; a child of a parent can have children of its own and those children keep traits from both the parent, grandparent, and all the parents above them. Thus, you get a genealogy!

TraitsEdit

The "traits" passed down are both the attributes and the methods. These cannot be removed from the child class but they can be changed. For example, if you have a function in a class like Shapes that is to find the area of a shape and you have a child class that is Circles, we know a formula that is good for finding the area of a circle 3.14*r*r. We could change the initial function which might be some kind of numerical integration to something as simple as that. We can also add new attributes and methods that were not in the parent class. 

Another important aspect of inheriting these traits is that you do not have to rewrite the things that you don't want to change

SyntaxEdit

The syntax for a parent class-child class relation is this CHILDCLASS : PARENTCLASS at the beginning of the class definition. Here is a rather large example to show everything that I have just told you about:

using System;
{
   class Rectangle
   {
      //member variables
      protected double length;
      protected double width;
      public Rectangle(double l, double w)
      {
         length = l;
         width = w;
      }
      
      public double GetArea()
      {
         return length * width;
      }
      
      public void Display()
      {
         Console.WriteLine("Length: {0}", length);
         Console.WriteLine("Width: {0}", width);
         Console.WriteLine("Area: {0}", GetArea());
      }
   }//end class Rectangle  
   
   class Tabletop : Rectangle
   {
      private double cost;
      public Tabletop(double l, double w) : base(l, w)
      { }
      public double GetCost()
      {
         double cost;
         cost = GetArea() * 70;
         return cost;
      }
      public void Display()
      {
         base.Display();
         Console.WriteLine("Cost: {0}", GetCost());
      }
   }
   class ExecuteRectangle
   {
      static void Main(string[] args)
      {
         Tabletop t = new Tabletop(4.5, 7.5);
         t.Display();
         Console.ReadLine();
      }
   }
}

N.B. The protected members are very similar to private but child classes can still access them.

PointersEdit

The last thing I need to expose you to before getting into the wonderful world of video game programming.