Skip to content

Commit 93b4c01

Browse files
Add OOP_Introduction
1 parent 21eff80 commit 93b4c01

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

assets/oop_intro_diagram.png

77.6 KB
Loading

web/src/pages/OOP_Introduction.mdx

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import StarlightPage from '@astrojs/starlight/components/StarlightPage.astro';
2+
import { Image } from 'astro:assets';
3+
import imageDiagram from '../../../assets/oop_intro_diagram.png';
4+
5+
<StarlightPage frontmatter={{
6+
template: 'doc',
7+
title: 'OOP Introduction',
8+
tableOfContents: false,
9+
}}>
10+
11+
This is a scripting tutorial explaining to you what **object orientated programming** is and teaching you how to use the **OOP features of MTA**. This was originally created by qaisjp on June 8, 2014 ([Forum post](https://forum.multitheftauto.com/topic/65029-wikitut-oop-introduction/)).
12+
13+
### Introduction to OOP
14+
15+
OOP stands for *object orientated programming*. Three simple words, and you'll probably understand the last word the most. OOP is where all functions relating to a single instance are called on that instance, an instance being a creation of a class — an element class, a database class, a player, a vehicle.
16+
17+
Originally, everything was *procedural*, you had to do things like:
18+
19+
```lua
20+
local vehicle = createVehicle(411, 0, 0, 3)
21+
setVehicleDamageProof(vehicle, true)
22+
setElementFrozen(vehicle, true)
23+
setElementHealth(vehicle, 1000)
24+
setElementVelocity(vehicle, 0.2, 0.2, 0.2)
25+
destroyElement(vehicle)
26+
```
27+
28+
More often than not, you know what you're dealing with. The variable almost always links back to the type, you would name a vehicle that exploded as **explodedVehicle**, or at least in context you would understand that **exploded** implies a vehicle when in the **onVehicleExplode** event.
29+
30+
So you have to write a long function *and* refer to the vehicle manually when working procedurally. Painful. Object orientated programming is very different to this and works with each "object" individually. Instead of having to call a function and referencing it inside the call, you actually call the function *inside* the class.
31+
32+
You probably think everything you can create and pass to functions are elements. A vehicle is an element. A player is an element. Anything that is an element is also a class. Connections create an instance of a class, but **"connection"** isn't an element, it's an instance — an object.
33+
34+
Throughout the tutorial when I say *object*, I don't mean `createObject` (unless I actually mention it), but to make things clearer I will avoid mentioning physical objects as I write this article.
35+
36+
Here is a fancy Venn diagram I created to show the simple organisation of classes and elements:
37+
38+
<Image src={imageDiagram} width="600" alt="Diagram"/>
39+
40+
The functions on the left are sorted to show what kind of category the returned value rests in. We've got Classes, Elements and "Problem children".
41+
42+
**Problem children** aren't real categories written in the code, just functions that break rules. Everything you can play with are classes: resources, vehicles, and teams.
43+
44+
All elements are classes, you can do:
45+
46+
```lua
47+
destroyElement(ped)
48+
```
49+
50+
But you can't do:
51+
52+
```lua
53+
destroyElement(resource)
54+
```
55+
56+
Problem children are weird things. You can't do all the functions mentioned in (actually, all elements don't allow the full assortment of functions to be applied to them, but I've especially mentioned a few of them) in the "Element functions" section of the functions list, but you *can* do `destroyElement()` on them.
57+
58+
There are children of classes, for example, with players, the system goes like: *Element → Ped → Player*. All Players are Peds and all Peds are Elements. Not all Peds are Players, and certainly not all Elements are Players.
59+
60+
The main point here is that almost everything that you can create or retrieve and then reuse later use a class.
61+
62+
Instead of the code before, the code could be replaced with this:
63+
64+
```lua
65+
local vehicle = Vehicle(411, 0, 0, 3)
66+
vehicle:setDamageProof(true)
67+
vehicle:setFrozen(true)
68+
vehicle:setHealth(1000)
69+
vehicle:setVelocity(0.2, 0.2, 0.2)
70+
vehicle:destroy()
71+
```
72+
73+
It works pretty similar to how a table works, it's just like `customTable.setSomething()` except the use of `:` makes Lua convert `customTable:setSomething()` into `customTable.setSomething(customTable)`. This is pretty internal stuff about *syntactic sugar* and you don't really need to worry much about it.
74+
75+
Those functions are pretty useful, but there are more changes with OOP — I'll explain this below.
76+
77+
### Instantiation, Variables
78+
79+
OOP removes the need to say the "create" part of the function, so instead of saying **createVehicle**, you just say **Vehicle**. It works exactly the same way — it's almost just like doing `Vehicle = createVehicle`. Fancy, isn't it?
80+
81+
The only difference here is that you miss out on the extra things offered. `Vehicle` doesn't have these extra things, but `Player` definitely does. For example, instead of doing `getPlayerFromName()`, you would do `Player.getFromName()`. It's a nice and simple way to organise functions.
82+
83+
> 💡 **Tip**: `Vehicle()` works because it actually accesses the `Vehicle.create` function — this allows you to omit the `.create` when simply "creating an object".
84+
85+
Since OOP sits on top of procedural, many things have been inherited from the procedural style. But to make things easier, we have variables for all the functions that require a single input.
86+
87+
We've shortened `getElementDimension()` down to `element:getDimension()`, but we can also go one layer deeper: `element.dimension`.
88+
89+
Yep, just like a variable. You can set this variable just like a normal variable and read from it just like a normal variable.
90+
91+
Hey, you could even do this:
92+
93+
```lua
94+
local function incrementDimension()
95+
local player = Player.getRandom() -- get a random player
96+
player.dimension = player.dimension + 1 -- increment dimension
97+
end
98+
99+
Timer(incrementDimension, 60*1000, 10) -- set a timer for sixty thousand milliseconds, sixty seconds, one minute
100+
```
101+
102+
This code would take a random player and move them to the next dimension every minute for the next ten minutes.
103+
104+
### Vectors
105+
106+
`player.position` works too! But how do you change three arguments... using one variable? **Vectors.**
107+
108+
Vectors are very powerful classes and they come in multiple forms. For the purpose of this introduction, I'll just cover a three-dimensional vector in terms of elements.
109+
110+
Using a vector is very simple, and is, of course, optional. Wherever you can currently use positions, you can use a vector.
111+
112+
So, this is a simple example of creating a vehicle and moving it to the centre of the map using vectors:
113+
114+
```lua
115+
-- First, create a three-dimensional vector
116+
local position = Vector3(300, -200, 2) -- some place far away
117+
local vehicle = Vehicle(411, position) -- create a vehicle at the position
118+
vehicle.position = centreOfMap - Vector3(300, -200, 0) -- move the vehicle two units above the center of the map
119+
```
120+
121+
Yes, I used the negative sign. Vectors aren't just fancy ways for positions or 3D rotations or whatever — you can use **maths** on them. The *special* maths hasn't been documented yet, but I'll try and work on that.
122+
123+
So, as you can see in line one, I created a 3D vector at `300, -200, 2`, and then in line two I created the vehicle at that position.
124+
125+
`vehicle.position` returned a vector and also takes a vector — it is pretty much `setElementPosition()` without the `()`.
126+
127+
Just a simple variable. So, in line three, I changed the vector value of the position of the vehicle.
128+
129+
This is where the maths happened — in simple terms, this is what is going on:
130+
131+
```lua
132+
x = 300 - 300
133+
y = -200 - -200
134+
z = 2 - 0
135+
```
136+
137+
Vector maths is slightly complicated but it definitely allows for a wide variety of mathematical magic.
138+
139+
Check out the useful links below related to Vectors and Matrices (*Matrices* = plural form of *Matrix*) to understand more about how this works.
140+
141+
### Understanding the Documentation
142+
143+
The documentation for the OOP syntax intends to be very simplistic and is supported by the procedural syntax. To keep things simple, everything is consistently formatted in a certain way.
144+
145+
#### Example
146+
147+
> Set the variable to `nil` to execute [`removePedFromVehicle`](https://wiki.multitheftauto.com/wiki/RemovePedFromVehicle)
148+
> Syntax: `ped:warpIntoVehicle(vehicle)`
149+
> Counterpart: `getPedOccupiedVehicle`
150+
151+
* Sometimes a note is added to the page. This will explain any special differences in the use of OOP for that function.
152+
* Methods can either start like `player:` or `Player.` — the former is only for a function on an instance (like `setPlayerHealth`) and the latter is a static method (like `getRandomPlayer`).
153+
* The counterpart section allows you to see at a glance how the variable can be used. In most cases, this can be inferred from the function page.
154+
155+
</StarlightPage>

0 commit comments

Comments
 (0)