
Time for action — building some cities
For each of the objects in RocketCommander
, we will build an individual class, in its own file. So, let's just do that.
- Create a new empty script and save it under the name
cityClass.monkey
. - Add the usual
Strict
statement to it and import ourgameClasses.monkey
file.Strict Import gameClasses
- Create a global list that stores all instances of the city class.
Global cities := New List<city>
Besides the methods of an object, we will create some functions that we can use from within the
mainClass
file; for example, a function to render all the cities in one batch. These helper functions are wrappers for code, which we could have stored inside themainClass.monkey
file. But, we want to keep things nice and neat. So let's create them here.The first wrapper function will be the one that renders all cities in one call on the canvas.
- Create a new function called
RenderCities
.Function RenderCities:Int()
- Now, loop through our list of cities.
For Local city := Eachin cities
- Inside the loop, we will call a method of the
city
class, which we will implement soon. ThisRender
method will render that particular city.city.Render()
- Now, close the FOR loop, and also close the function in the usual way.
Next Return True End
Next will be a function to create a new city. As a function parameter, it will have its horizontal (
x
) position in pixels. As all cities sit always at the same height, we don't need to add another parameter for this. - Create a new function header called
CreateCity
.Function CreateCity:Int(xpos:Float)
- Create a local instance of the city class.
Local c:city = New city
- To initialize the properties of a new city, we will call its
Init
method, which we will add soon. As a parameter, we will give thex
position.c.Init(xpos)
- Now, add this city to the list of cities and close the function.
cities.AddLast(c) Return True End
Even if a function basically wraps only one line of code, it makes sense from a higher level of view. The next function clears the list of cities. A list in Monkey is a one-line statement. Let's assume that we want to use a different way of storing cities, such as in an array, for example. Then, we would only need to change the wrapper function, but the call in the
main
class could stay the same. - Add a function called
RemoveCities
.Function RemoveCities:Int()
- Call the
Clear
method of the cities list to empty it. Then close off the function.cities.Clear() Return True End
The same goes for the next function, used to determine the number of cities stored inside the cities list.
- Create a new function called
GetCityCount
.Function GetCityCount:Int()
- Instead of returning
TRUE
, we will return the result of theCount
method of the cities list. Then close the function.Return cities.Count() End
Enough of these wrapper functions! It is time to build our actual city class.
- Create a new class called
city
, which is not extended from any other class.Class city
- Add two fields to store the
x
andy
positions of the city.Field x:Float = 0.0 'x pos of a city Field y:Float = 0.0 'y pos of a city
- Add the previously mentioned method called
Init
, to initialize a new city.Method Init:Int(xpos:Float)
- Set its fields, giving an
x
position and a height, which is calculated as the canvas height minus40
. Then close this method.x = xpos y = game.cHeight - 40.0 Return True End
Now, we will create a method that draws a city on the canvas. You will notice that all the objects in the game have mostly the same methods. The difference will be in the details of each method.
- Add a method called
Render
.Method Render:Int()
- Set the drawing color to a bright yellow.
SetColor(255,255,0)
- Draw the city as three rectangles and their
x
andy
positions on the canvas.DrawRect(x - 30, y - 20, 20, 20) DrawRect(x - 10, y - 30, 20, 30) DrawRect(x + 10, y - 10, 20, 10)
- Close this method, and the
city
class.Return True End End
That's it for the city
class. No other functions and/or methods are needed. Just make sure that you have saved the file.
What just happened?
Here we are. We didn't build Rome, but we can now build small little cities for our game. Each city has the methods Render
and Init
. As cities are not dynamic objects, and we don't need to check for collisions, you won't need an Update
or CollisionCheck
method for them. We have also built wrapper functions that will do the dirty work for us when it comes to rendering all the cities at once, or deleting all the cities that are remaining.