Learn to Code Space Invaders – Lesson 4 – Creating and Moving Sprites
23rd July 2019Learn to Code Space Invaders – Lesson 6 – Firing Bullets
23rd July 2019Space Invaders Lesson 5 – Storing Data in Tables and Objects
Storing Data in Tables and Objects – First Steps in Object Orientated Programming (OOP)
We’ve seen how the computer can remember bits of information using variables. Each variable is like a labelled box that you can put some data into. Each variable keeps track of some property of your program, e.g the x and y coordinates of your player ship sprite.
As our program grows we’ll create more variables. Some of these will describe our player ship, some the aliens, player bullets and so on. We can easily create individual variables for each of these values, e.g.
playerShipX, playerShipY, bullet, bulletY, playerShipSprite, bulletSpeed, etc.
But doing this becomes a bit messy and cumbersome. It would be much better if we could package all the variables for a single part of our program together. In this way we could put all off the player ship variables into a package which would then contain all the player ship information. This package would then in effect represent a player ship object in our code. We could then do the same for each other part of our program and create objects for the bullets, aliens, missiles and so on. This lets the structure of our program data reflect the objects that make up our game.
Each data object ‘encapsulates’ the variables for that item. This idea of creating data objects is the start of Object Orientated Programming (OOP).
In TIC 80 we’ll use Lua’s table feature to create these data objects. A table is a special type of variable. We’ve already seen that a variable can hold an integer number, a string of characters, a Boolean (true or false) value, a floating point or real number, etc. But we’ll now see that a variable can also hold a table. A table is basically a big box inside which we can put a collection of other variables. So our table variable will contain a number of its own variables which we call attributes.
To create a table we use the curly braces { and } and then put variables inside it.
myTable = { myVariable = 10 }
This assigns the variable myTable a value which is a table with a single variable (attribute) inside it called myVariable which has the value 10.
If we use the variable myTable, we will be referring to the whole table. To get to the individual parts of the table we need to use a dot notation.
myTable.myVariable refers to the single variable inside the table. We can assign values to that attribute (variable) in the normal way, e.g.
myTable.myVariable = 20
will change the value of myTable.myVariable to 20, just like a normal variable.
We can also use the table’s attribute in our expressions, e.g.
answer = myTable.myVariable
would assign the value 20 to the variable answer, and
if myTable.myVariable == 20 then -- do this end
would evaluate to true and the ‘do this’ code would execute.
If we want to store more than one variable in a table we simply separate them with a comma.
myTable = { myVariable1 = 10, myVariable2 = "Hello" }
So now the statement
answer = myTable.myVariable2
Would assign the value “Hello” to answer.
Breaking Up Objects Into Smaller Objects
If we look at the data we need to store for our player ship. We need its x and y position, the number of the sprite needed to draw it, the speed at which it moves and the maximum and minimum values for its x coordinate so it stays on the screen. If we consider the bullets and aliens we know that those will also have to store the on screen positions. It makes sense that we should store this position data in the same way for each object to make life easier or ourselves. So we could create a position object which holds an x and y variable. So,
position = { x = 10, y = 100 }
Creates a variable called position which is an object (Lua table) with position.x and position.y.
Since this is a variable we can store it inside our player ship object. So we get
playerShip = { position = { x = 120, y = 128 } spriteNum = 0, minx = 0, maxX = 232, speed = 1 }
This now lets us access the x and y variables using the dot notation.
playerShip is the whole player ship object
playerShip.speed is the number variable speed encapsulated in the object.
playerShip.position is the whole position object.
playerShip.position.x is the x coordinate of the ship on the screen.
Why Bother with OOP
Objects are a very powerful way of organising your data and making it easy to pass large blocks of information from one bit of code to another. We’ll make heavy use of this feature as the project progresses, especially when we start to look at creating our own functions.
This data encapsulation is only the very beginning of your OOP learning. We won’t be covering full object features in this course but be aware that they are able to store code as well as variables which can make objects ‘smart’ and self contained elements within your code. As you progress through later courses you’ll learn more and more about objects.
Code for Lesson 5
-- title: Space Invaders -- author: Bob Grant -- desc: Lesson 5 -- script: lua playerShip = { position = { x = 120, y = 128 }, spriteNum = 0, minX = 0, maxX = 232, speed = 1 } function TIC() cls() if(btn(2)) then playerShip.position.x = playerShip.position.x - playerShip.speed end if(btn(3)) then playerShip.position.x = playerShip.position.x + playerShip.speed end if (playerShip.position.x < playerShip.minX) then playerShip.position.x = playerShip.minX end if (playerShip.position.x > playerShip.maxX) then playerShip.position.x = playerShip.maxX end spr(playerShip.spriteNum, playerShip.position.x, playerShip.position.y) end