CSC123 C# Assignment: Inheritance and the Observer Pattern 1

CSC123 Halloween Assignment: Professor and Goblins

Due October 31st



I'm assuming in the following that you were present for my demonstrations:

For this assignment you are to write a small video game using animated gifs. It's adopted from a Java assignment I gave to my CSC15 students. The difference is that you will use C# and inheritance. This assignment is meant for you to become familiar with the mechanics of C#/Java programming, so we can move on to more advanced topics later. I'll be giving you quite a bit of a head start, and will guide you along the way.

First, download the file goblinapp.cs from the homepage. Also download the animated gif files (right click on images above). The program you downloaded runs by itself - you'll see a little human figure ("the professor") in the lower right corner, which you can control using the arrow keys and the space bar. The figure wraps around the edges of the window.

The file itself contains two classes: "goblinapp" is the application class and includes the method "mainloop", which you will modify. Despite appearances, this is actually a tail-recursive function: the call to Invalidate() at the end invokes a windows "event" that triggers the "OnPaint" method, which will then call mainloop() again. Set the "stop" variable to true to exit the loop. The "human" class is for the "professor" object. You will be creating (at least) two additional classes, one for goblins and one for the diamond/treasure, both of which will be similar to the human class. If you are not confident enough, you may first copy, paste and edit the human class to create two new classes. But ultimately you'll need to adopt an inheritance scheme. You are required to define an interface and a superclass for all "objects" in the game. The human, goblin, and treasure subclasses will extend the superclass and implement the interface. (interfaces are distinct from abstract superclasses because you can implement multiple ones). Declare your object variables inside the goblinapp class (where the professor is declared - careful, mainloop's local vars will be recreated on each call!). Create instances of the three classes in the init() method of the goblinapp public class, and animate them by calling their draw() or move() methods from the mainloop() method. Why do you need three separate sub-classes? Each class must contain some attributes that are distinct from the others, and those that override some method in the superclass. For example, the goblins, unlike the professor, should not be allowed to wrap around the edges. The treasure object should hover randomly. That is, they will have different move() methods. You can vary them further. It's your design choice. To generate a random number in C#:

  Random rand = new Random();
  int dx = rand.Next(-5,6); // returns random int from -5 to +5.
The graphical image of the professor is an animated gif. However, internally the object is represented as a circle, and thus the key attributes of the object are the x,y coordinates of the center of the circle, and the radius. The properties dx and dy is the movement vector of the object. That is, they control how much the x and y coordinates will change each time the move() function is called. The x, y and radius values are set by the constructor while (dx.dy) is set by the "setdirection" method. You'll have to study the program I gave you to understand it fully, though you don't have to worry about how InitializeComponents and the event handler functions work.

Two circles overlap if the distance between their center coordinates is less than the sum of the radii. You can find the static method "dist" already provided by the super-nice professor. "static" means it can be called without creating an instance of a class (just like Math.Sqrt). You should define (in the superclass!) a method

  public bool overlap(gameobject other)
assuming gameobject is the name of the superclass. This will allow you to detect if two objects have collided (if (object1.overlap(object2))...). The bounds of the window are defined by the (static) values XBOUND and YBOUND in the goblinapp class.

"Oh no! This program needs MATH!"

Depending on how nice you want to make the program you may need some vector algebra, though not much. To make the goblin chase the professor, adjust the DX and DY values of the goblin to move toward the professor's position: that is, if professor.Y is less than you.Y, then you're below the professor and should give a negative value to you.DY. To make the goblin intercept the professor at a point in the future, assume the goblin is at (x0,y0) and the professor is at (x1,y1) and moving in direction (dx1,dy1). Then to intercept the professor in t number of moves, use the following movement vector:

 dx = ((x1-x0)/t) + dx1, dy = ((y1-y0)/t) + dy1 
If you set t=1, then you'll catch the professor in the very next move, which is hardly fair. So you need to use these formulas judiciously to make a nice simulation.

The game should end when the goblins catch the professor or the professor gets the diamond. Alternatively, you can make the professor protect the diamond. You can also change the animated gifs after the game ends - so you might need to create some additional state variables in your classes.

To summarize, you are going to create objects that can move around and detect if they have collided with other objects. The objects are controlled by their X, Y, DX and DY properties. The objects should inherit from a superclass what they have in common. Then, modify the code already provided for you in the goblinapp public class to write a game. Create the objects in the init() function, and animate them in the mainloop function by calling the move() and setdirection() methods of the objects. When the game is over, display a message (see code for how) and set bool stop to true. Look at other sample C# programs for syntax and other hints.