Skip to content

Kapitola 1.1: Proměnné a typy

Domů | Proměnné a typy | Další: Pole, mapy a množiny >>


Úvod

Enforce Script je skriptovací jazyk enginu Enfusion, který používá DayZ Standalone. Jedná se o objektově orientovaný jazyk se syntaxí podobnou jazyku C, v mnoha ohledech podobný C#, ale s vlastní sadou typů, pravidel a omezení. Pokud máte zkušenosti s C#, Javou nebo C++, budete se rychle cítit jako doma --- ale věnujte pozornost rozdílům, protože právě tam, kde se Enforce Script od těchto jazyků odchyluje, se skrývají chyby.

Tato kapitola pokrývá základní stavební kameny: primitivní typy, jak deklarovat a inicializovat proměnné a jak funguje konverze typů. Každý řádek kódu DayZ modu začíná právě zde.


Primitivní typy

Enforce Script má malou, pevnou sadu primitivních typů. Nemůžete definovat nové hodnotové typy --- pouze třídy (viz Kapitola 1.3).

TypVelikostVýchozí hodnotaPopis
int32bitový se znaménkem0Celá čísla od -2 147 483 648 do 2 147 483 647
float32bitový IEEE 7540.0Čísla s plovoucí řádovou čárkou
bool1 bit logickýfalsetrue nebo false
stringProměnlivá"" (prázdný)Text. Neměnný hodnotový typ --- předávaný hodnotou, ne referencí
vector3x float"0 0 0"Tříkomponentový float (x, y, z). Předávaný hodnotou
typenameReference enginunullReference na samotný typ, používaná pro reflexi
voidN/AN/APoužíván pouze jako návratový typ k označení "nevrací nic"

Diagram hierarchie typů

Typové konstanty

Některé typy nabízejí užitečné konstanty:

c
// hranice int
int maxInt = int.MAX;    // 2147483647
int minInt = int.MIN;    // -2147483648

// hranice float
float smallest = float.MIN;     // nejmenší kladný float (~1.175e-38)
float largest  = float.MAX;     // největší float (~3.403e+38)
float lowest   = float.LOWEST;  // nejzápornější float (-3.403e+38)

Deklarace proměnných

Proměnné se deklarují uvedením typu následovaného názvem. Můžete deklarovat a přiřadit v jednom příkazu nebo odděleně.

c
void MyFunction()
{
    // Pouze deklarace (inicializováno na výchozí hodnotu)
    int health;          // health == 0
    float speed;         // speed == 0.0
    bool isAlive;        // isAlive == false
    string name;         // name == ""

    // Deklarace s inicializací
    int maxPlayers = 60;
    float gravity = 9.81;
    bool debugMode = true;
    string serverName = "My DayZ Server";
}

Klíčové slovo auto

Když je typ zřejmý z pravé strany výrazu, můžete použít auto, aby kompilátor typ odvodil:

c
void Example()
{
    auto count = 10;           // int
    auto ratio = 0.75;         // float
    auto label = "Hello";      // string
    auto player = GetGame().GetPlayer();  // DayZPlayer (nebo cokoliv GetPlayer vrátí)
}

Toto je čistě pro pohodlí --- kompilátor vyhodnotí typ při kompilaci. Neexistuje žádný rozdíl ve výkonu.

Konstanty

Použijte klíčové slovo const pro hodnoty, které by se po inicializaci nikdy neměly měnit:

c
const int MAX_SQUAD_SIZE = 8;
const float SPAWN_RADIUS = 150.0;
const string MOD_PREFIX = "[MyMod]";

void Example()
{
    int a = MAX_SQUAD_SIZE;  // OK: čtení konstanty
    MAX_SQUAD_SIZE = 10;     // CHYBA: nelze přiřadit konstantě
}

Konstanty se obvykle deklarují na úrovni souboru (mimo jakoukoli funkci) nebo jako členy třídy. Konvence pojmenování: UPPER_SNAKE_CASE.


Práce s int

Celá čísla jsou nejpoužívanějším typem. DayZ je používá pro počty předmětů, ID hráčů, hodnoty zdraví (při diskretizaci), hodnoty výčtů, bitové příznaky a další.

c
void IntExamples()
{
    int count = 5;
    int total = count + 10;     // 15
    int doubled = count * 2;    // 10
    int remainder = 17 % 5;     // 2 (modulo)

    // Inkrementace a dekrementace
    count++;    // count je nyní 6
    count--;    // count je opět 5

    // Složené přiřazení
    count += 3;  // count je nyní 8
    count -= 2;  // count je nyní 6
    count *= 4;  // count je nyní 24
    count /= 6;  // count je nyní 4

    // Celočíselné dělení ořezává (nezaokrouhluje)
    int result = 7 / 2;    // result == 3, ne 3.5

    // Bitové operace (používané pro příznaky)
    int flags = 0;
    flags = flags | 0x01;   // nastavit bit 0
    flags = flags | 0x04;   // nastavit bit 2
    bool hasBit0 = (flags & 0x01) != 0;  // true
}

Příklad z praxe: Počet hráčů

c
void PrintPlayerCount()
{
    array<Man> players = new array<Man>;
    GetGame().GetPlayers(players);
    int count = players.Count();
    Print(string.Format("Players online: %1", count));
}

Práce s float

Čísla s plovoucí řádovou čárkou představují desetinná čísla. DayZ je hojně používá pro pozice, vzdálenosti, procenta zdraví, hodnoty poškození a časovače.

c
void FloatExamples()
{
    float health = 100.0;
    float damage = 25.5;
    float remaining = health - damage;   // 74.5

    // Specifické pro DayZ: násobitel poškození
    float headMultiplier = 3.0;
    float actualDamage = damage * headMultiplier;  // 76.5

    // Dělení floatů dává desetinné výsledky
    float ratio = 7.0 / 2.0;   // 3.5

    // Užitečná matematika
    float dist = 150.7;
    float rounded = Math.Round(dist);    // 151
    float floored = Math.Floor(dist);    // 150
    float ceiled  = Math.Ceil(dist);     // 151
    float clamped = Math.Clamp(dist, 0.0, 100.0);  // 100
}

Příklad z praxe: Kontrola vzdálenosti

c
bool IsPlayerNearby(PlayerBase player, vector targetPos, float radius)
{
    if (!player)
        return false;

    vector playerPos = player.GetPosition();
    float distance = vector.Distance(playerPos, targetPos);
    return distance <= radius;
}

Práce s bool

Booleovské proměnné obsahují true nebo false. Používají se v podmínkách, příznacích a sledování stavů.

c
void BoolExamples()
{
    bool isAdmin = true;
    bool isBanned = false;

    // Logické operátory
    bool canPlay = isAdmin || !isBanned;    // true (OR, NOT)
    bool isSpecial = isAdmin && !isBanned;  // true (AND)

    // Negace
    bool notAdmin = !isAdmin;   // false

    // Výsledky porovnání jsou bool
    int health = 50;
    bool isLow = health < 25;       // false
    bool isHurt = health < 100;     // true
    bool isDead = health == 0;      // false
    bool isAlive = health != 0;     // true
}

Pravdivost v podmínkách

V Enforce Scriptu můžete v podmínkách používat i hodnoty, které nejsou typu bool. Následující jsou považovány za false:

  • 0 (int)
  • 0.0 (float)
  • "" (prázdný řetězec)
  • null (nulová reference na objekt)

Vše ostatní je true. To se běžně používá pro kontrolu null:

c
void SafeCheck(PlayerBase player)
{
    // Tyto dva zápisy jsou ekvivalentní:
    if (player != null)
        Print("Player exists");

    if (player)
        Print("Player exists");

    // A tyto dva také:
    if (player == null)
        Print("No player");

    if (!player)
        Print("No player");
}

Práce s string

Řetězce v Enforce Scriptu jsou hodnotové typy --- jsou kopírovány při přiřazení nebo předání do funkce, stejně jako int nebo float. To se liší od C# nebo Javy, kde jsou řetězce referenčními typy.

c
void StringExamples()
{
    string greeting = "Hello";
    string name = "Survivor";

    // Zřetězení pomocí +
    string message = greeting + ", " + name + "!";  // "Hello, Survivor!"

    // Formátování řetězců (zástupné znaky indexované od 1)
    string formatted = string.Format("Player %1 has %2 health", name, 75);
    // Výsledek: "Player Survivor has 75 health"

    // Délka
    int len = message.Length();    // 17

    // Porovnání
    bool same = (greeting == "Hello");  // true

    // Konverze z jiných typů
    string fromInt = "Score: " + 42;     // NEFUNGUJE -- je nutné explicitně převést
    string correct = "Score: " + 42.ToString();  // "Score: 42"

    // Použití Format je preferovaný přístup
    string best = string.Format("Score: %1", 42);  // "Score: 42"
}

Escape sekvence

Řetězce podporují standardní escape sekvence:

SekvenceVýznam
\nNový řádek
\rNávrat na začátek řádku
\tTabulátor
\\Literální zpětné lomítko
\"Literální uvozovka

Varování: Ačkoli jsou tyto sekvence zdokumentovány, zpětné lomítko (\\) a escapované uvozovky (\") jsou známy tím, že v některých kontextech způsobují problémy s CParserem, zejména při operacích souvisejících s JSON. Při práci s cestami k souborům nebo řetězci JSON se zpětným lomítkům pokud možno vyhněte. Pro cesty používejte lomítka --- DayZ je akceptuje na všech platformách.

Příklad z praxe: Zpráva v chatu

c
void SendAdminMessage(string adminName, string text)
{
    string msg = string.Format("[ADMIN] %1: %2", adminName, text);
    Print(msg);
}

Práce s vector

Typ vector obsahuje tři float komponenty (x, y, z). Je to základní typ DayZ pro pozice, směry, rotace a rychlosti. Stejně jako řetězce a primitivní typy jsou vektory hodnotové typy --- jsou kopírovány při přiřazení.

Inicializace

Vektory lze inicializovat dvěma způsoby:

c
void VectorInit()
{
    // Způsob 1: Inicializace řetězcem (tři čísla oddělená mezerami)
    vector pos1 = "100.5 0 200.3";

    // Způsob 2: Konstruktorová funkce Vector()
    vector pos2 = Vector(100.5, 0, 200.3);

    // Výchozí hodnota je "0 0 0"
    vector empty;   // empty == <0, 0, 0>
}

Důležité: Formát inicializace řetězcem používá jako oddělovače mezery, ne čárky. "1 2 3" je platný; "1,2,3" ne.

Přístup ke komponentám

K jednotlivým komponentám se přistupuje pomocí indexování ve stylu pole:

c
void VectorComponents()
{
    vector pos = Vector(100.5, 25.0, 200.3);

    // Čtení komponent
    float x = pos[0];   // 100.5  (Východ/Západ)
    float y = pos[1];   // 25.0   (Nahoru/Dolů, nadmořská výška)
    float z = pos[2];   // 200.3  (Sever/Jih)

    // Zápis komponent
    pos[1] = 50.0;      // Změnit nadmořskou výšku na 50
}

Souřadnicový systém DayZ:

  • [0] = X = Východ(+) / Západ(-)
  • [1] = Y = Nahoru(+) / Dolů(-) (nadmořská výška)
  • [2] = Z = Sever(+) / Jih(-)

Statické konstanty

c
vector zero    = vector.Zero;      // "0 0 0"
vector up      = vector.Up;        // "0 1 0"
vector right   = vector.Aside;     // "1 0 0"
vector forward = vector.Forward;   // "0 0 1"

Běžné vektorové operace

c
void VectorOps()
{
    vector pos1 = Vector(100, 0, 200);
    vector pos2 = Vector(150, 0, 250);

    // Vzdálenost mezi dvěma body
    float dist = vector.Distance(pos1, pos2);

    // Kvadrát vzdálenosti (rychlejší, vhodný pro porovnání)
    float distSq = vector.DistanceSq(pos1, pos2);

    // Směr z pos1 do pos2
    vector dir = vector.Direction(pos1, pos2);

    // Normalizace vektoru (délka = 1)
    vector norm = dir.Normalized();

    // Délka vektoru
    float len = dir.Length();

    // Lineární interpolace (50 % mezi pos1 a pos2)
    vector midpoint = vector.Lerp(pos1, pos2, 0.5);

    // Skalární součin
    float dot = vector.Dot(dir, vector.Up);
}

Příklad z praxe: Pozice spawnu

c
// Získat pozici na zemi na daných souřadnicích X, Z
vector GetGroundPosition(float x, float z)
{
    vector pos = Vector(x, 0, z);
    pos[1] = GetGame().SurfaceY(x, z);  // Nastavit Y na výšku terénu
    return pos;
}

// Získat náhodnou pozici v okruhu od středového bodu
vector GetRandomPositionAround(vector center, float radius)
{
    float angle = Math.RandomFloat(0, Math.PI2);
    float dist = Math.RandomFloat(0, radius);

    vector offset = Vector(Math.Cos(angle) * dist, 0, Math.Sin(angle) * dist);
    vector pos = center + offset;
    pos[1] = GetGame().SurfaceY(pos[0], pos[2]);
    return pos;
}

Práce s typename

Typ typename uchovává referenci na samotný typ. Používá se pro reflexi --- zkoumání a práci s typy za běhu. Setkáte se s ním při psaní generických systémů, načítačů konfigurací a továrních vzorů.

c
void TypenameExamples()
{
    // Získat typename třídy
    typename t = PlayerBase;

    // Získat typename z řetězce
    typename t2 = t.StringToEnum(PlayerBase, "PlayerBase");

    // Porovnat typy
    if (t == PlayerBase)
        Print("It's PlayerBase!");

    // Získat typename instance objektu
    PlayerBase player;
    // ... předpokládejme, že player je platný ...
    typename objType = player.Type();

    // Zkontrolovat dědičnost
    bool isMan = objType.IsInherited(Man);

    // Převést typename na řetězec
    string name = t.ToString();  // "PlayerBase"

    // Vytvořit instanci z typename (tovární vzor)
    Class instance = t.Spawn();
}

Konverze výčtu s typename

c
enum DamageType
{
    MELEE = 0,
    BULLET = 1,
    EXPLOSION = 2
};

void EnumConvert()
{
    // Výčet na řetězec
    string name = typename.EnumToString(DamageType, DamageType.BULLET);
    // name == "BULLET"

    // Řetězec na výčet
    int value;
    typename.StringToEnum(DamageType, "EXPLOSION", value);
    // value == 2
}

Třída Managed

Managed je speciální základní třída, která vypíná počítání referencí enginem. Třídy rozšiřující Managed nejsou sledovány garbage collectorem enginu --- jejich životnost je plně řízena skriptovými ref referencemi.

c
class MyScriptHandler : Managed
{
    // Tato třída nebude garbage collectována enginem
    // Bude smazána teprve když je uvolněna poslední ref
}

Většina čistě skriptových tříd (které nepředstavují herní entity) by měla rozšiřovat Managed. Třídy entit jako PlayerBase, ItemBase rozšiřují EntityAI (což je řízeno enginem, NE Managed).

Kdy použít Managed

Použijte Managed pro...NEpoužívejte Managed pro...
Datové třídy konfiguracePředměty (ItemBase)
Singletonové manažeryZbraně (Weapon_Base)
UI kontroleryVozidla (CarScript)
Objekty obsluhy událostíHráče (PlayerBase)
Pomocné/utilitní třídyJakoukoliv třídu rozšiřující EntityAI

Pokud vaše třída nepředstavuje fyzickou entitu v herním světě, měla by téměř jistě rozšiřovat Managed.


Konverze typů

Enforce Script podporuje implicitní i explicitní konverze mezi typy.

Implicitní konverze

Některé konverze probíhají automaticky:

c
void ImplicitConversions()
{
    // int na float (vždy bezpečné, žádná ztráta dat)
    int count = 42;
    float fCount = count;    // 42.0

    // float na int (OŘEZÁVÁ, nezaokrouhluje!)
    float precise = 3.99;
    int truncated = precise;  // 3, NE 4

    // int/float na bool
    bool fromInt = 5;      // true (nenulové)
    bool fromZero = 0;     // false
    bool fromFloat = 0.1;  // true (nenulové)

    // bool na int
    int fromBool = true;   // 1
    int fromFalse = false; // 0
}

Explicitní konverze (parsování)

Pro konverzi mezi řetězci a číselnými typy použijte metody parsování:

c
void ExplicitConversions()
{
    // Řetězec na int
    int num = "42".ToInt();           // 42
    int bad = "hello".ToInt();        // 0 (selže tiše)

    // Řetězec na float
    float f = "3.14".ToFloat();       // 3.14

    // Řetězec na vector
    vector v = "100 25 200".ToVector();  // <100, 25, 200>

    // Číslo na řetězec (pomocí Format)
    string s1 = string.Format("%1", 42);       // "42"
    string s2 = string.Format("%1", 3.14);     // "3.14"

    // int/float .ToString()
    string s3 = (42).ToString();     // "42"
}

Přetypování objektů

Pro typy tříd použijte Class.CastTo() nebo ClassName.Cast(). Toto je podrobně pokryto v Kapitole 1.3, ale zde je základní vzor:

c
void CastExample()
{
    Object obj = GetSomeObject();

    // Bezpečné přetypování (preferované)
    PlayerBase player;
    if (Class.CastTo(player, obj))
    {
        // player je platný a bezpečný k použití
        string name = player.GetIdentity().GetName();
    }

    // Alternativní syntaxe přetypování
    PlayerBase player2 = PlayerBase.Cast(obj);
    if (player2)
    {
        // player2 je platný
    }
}

Rozsah platnosti proměnných

Proměnné existují pouze v bloku kódu (složených závorkách), kde byly deklarovány. Enforce Script neumožňuje opětovnou deklaraci stejného názvu proměnné ve vnořených nebo sourozených blocích.

c
void ScopeExample()
{
    int x = 10;

    if (true)
    {
        // int x = 20;  // CHYBA: opětovná deklarace 'x' ve vnořeném bloku
        x = 20;         // OK: úprava vnějšího x
        int y = 30;     // OK: nová proměnná v tomto bloku
    }

    // y zde NENÍ přístupné (deklarováno ve vnitřním bloku)
    // Print(y);  // CHYBA: nedeklarovaný identifikátor 'y'

    // DŮLEŽITÉ: toto platí i pro cykly for
    for (int i = 0; i < 5; i++)
    {
        // i existuje zde
    }
    // for (int i = 0; i < 3; i++)  // CHYBA v DayZ: 'i' již deklarováno
    // Použijte jiný název:
    for (int j = 0; j < 3; j++)
    {
        // j existuje zde
    }
}

Past sourozených bloků

Toto je jeden z nejznámějších zvláštností Enforce Scriptu. Deklarace stejného názvu proměnné v blocích if a else způsobí chybu kompilace:

c
void SiblingTrap()
{
    if (someCondition)
    {
        int result = 10;    // Deklarováno zde
        Print(result);
    }
    else
    {
        // int result = 20; // CHYBA: vícenásobná deklarace 'result'
        // I přesto, že se jedná o sourozený blok, ne stejný blok
    }

    // OPRAVA: deklarujte nad if/else
    int result;
    if (someCondition)
    {
        result = 10;
    }
    else
    {
        result = 20;
    }
}

Priorita operátorů

Od nejvyšší po nejnižší prioritu:

PrioritaOperátorPopisAsociativita
1() [] .Seskupení, přístup k poli, přístup ke členůmZleva doprava
2! - (unární) ~Logický NOT, negace, bitový NOTZprava doleva
3* / %Násobení, dělení, moduloZleva doprava
4+ -Sčítání, odčítáníZleva doprava
5<< >>Bitový posunZleva doprava
6< <= > >=RelačníZleva doprava
7== !=RovnostZleva doprava
8&Bitový ANDZleva doprava
9^Bitový XORZleva doprava
10|Bitový ORZleva doprava
11&&Logický ANDZleva doprava
12||Logický ORZleva doprava
13= += -= *= /= %= &= |= ^= <<= >>=PřiřazeníZprava doleva

Tip: Pokud si nejste jistí, použijte závorky. Enforce Script dodržuje pravidla priority podobná jazyku C, ale explicitní seskupení zabraňuje chybám a zlepšuje čitelnost.


Osvědčené postupy

  • Vždy explicitně inicializujte proměnné při deklaraci, i když výchozí hodnota odpovídá vašemu záměru -- sděluje to záměr budoucím čtenářům.
  • Používejte const pro jakoukoli hodnotu, která by se nikdy neměla měnit; umísťujte konstanty na úroveň souboru nebo třídy s pojmenováním UPPER_SNAKE_CASE.
  • Preferujte string.Format() před zřetězením pomocí + při míchání typů -- vyhnete se problémům s implicitní konverzí a je to lépe čitelné.
  • Používejte vector.DistanceSq() místo vector.Distance() při porovnávání vzdáleností -- vyhnete se drahé odmocnině.
  • Nikdy neporovnávejte floaty pomocí ==; vždy použijte epsilon toleranci přes Math.AbsFloat(a - b) < 0.001.

Pozorováno v reálných modech

Vzory potvrzené studiem zdrojového kódu profesionálních DayZ modů.

VzorModDetail
const string LOG_PREFIX na úrovni třídyCOT / ExpansionKaždý modul definuje řetězcovou konstantu pro prefixy logů, aby se předešlo překlepům
Pojmenování členů m_PascalCaseVPP / Dabs FrameworkVšechny členské proměnné konzistentně používají prefix m_, i pro primitivní typy
string.Format pro veškerý výstup logůExpansion MarketNikdy nepoužívá zřetězení + s čísly -- vždy zástupné znaky %1..%9
vector.Zero místo literálu "0 0 0"COT Admin ToolsPoužívá pojmenované konstanty pro čitelnost a aby se vyhnul režii parsování řetězce

Teorie vs. praxe

KonceptTeorieRealita
Klíčové slovo autoMělo by odvodit jakýkoli typFunguje pro jednoduchá přiřazení, ale může zmást čtenáře -- většina modů typy deklaruje explicitně
Ořezávání float na intZdokumentováno jako "zaokrouhluje směrem k nule"Nachytá téměř každého alespoň jednou; 3.99 se stane 3, ne 4
string je hodnotový typPředáván kopií jako intPřekvapuje vývojáře v C#/Java, kteří očekávají referenční sémantiku; úpravy kopie nikdy neovlivní originál

Časté chyby

1. Neinicializované proměnné používané v logice

Primitivní typy dostávají výchozí hodnoty (0, 0.0, false, ""), ale spoléhání na to činí kód křehkým a špatně čitelným. Vždy inicializujte explicitně.

c
// ŠPATNĚ: spoléhání na implicitní nulu
int count;
if (count > 0)  // Toto funguje, protože count == 0, ale záměr je nejasný
    DoThing();

// SPRÁVNĚ: explicitní inicializace
int count = 0;
if (count > 0)
    DoThing();

2. Ořezávání float na int

Konverze float na int ořezává (zaokrouhluje směrem k nule), ne zaokrouhluje k nejbližšímu:

c
float f = 3.99;
int i = f;         // i == 3, NE 4

// Pokud chcete zaokrouhlení:
int rounded = Math.Round(f);  // 4

3. Přesnost float při porovnávání

Nikdy neporovnávejte floaty na přesnou rovnost:

c
float a = 0.1 + 0.2;
// ŠPATNĚ: může selhat kvůli reprezentaci s plovoucí řádovou čárkou
if (a == 0.3)
    Print("Equal");

// SPRÁVNĚ: použijte toleranci (epsilon)
if (Math.AbsFloat(a - 0.3) < 0.001)
    Print("Close enough");

4. Zřetězení řetězců s čísly

Nemůžete jednoduše přidat číslo k řetězci pomocí +. Použijte string.Format():

c
int kills = 5;
// Potenciálně problematické:
// string msg = "Kills: " + kills;

// SPRÁVNĚ: použijte Format
string msg = string.Format("Kills: %1", kills);

5. Formát vektorového řetězce

Inicializace vektoru řetězcem vyžaduje mezery, ne čárky:

c
vector good = "100 25 200";     // SPRÁVNĚ
// vector bad = "100, 25, 200"; // ŠPATNĚ: čárky nejsou správně parsovány
// vector bad2 = "100,25,200";  // ŠPATNĚ

6. Zapomenutí, že řetězce a vektory jsou hodnotové typy

Na rozdíl od objektů tříd jsou řetězce a vektory při přiřazení kopírovány. Úprava kopie neovlivní originál:

c
vector posA = "10 20 30";
vector posB = posA;       // posB je KOPIE
posB[1] = 99;             // Změní se pouze posB
// posA je stále "10 20 30"

Praktická cvičení

Cvičení 1: Základy proměnných

Deklarujte proměnné pro uložení:

  • Jména hráče (string)
  • Jeho procenta zdraví (float, 0-100)
  • Jeho počtu zabití (int)
  • Zda je administrátor (bool)
  • Jeho pozice ve světě (vector)

Vytiskněte formátovaný přehled pomocí string.Format().

Cvičení 2: Převodník teploty

Napište funkci float CelsiusToFahrenheit(float celsius) a její inverzi float FahrenheitToCelsius(float fahrenheit). Otestujte s bodem varu (100C = 212F) a bodem mrazu (0C = 32F).

Cvičení 3: Kalkulačka vzdálenosti

Napište funkci, která přijme dva vektory a vrátí:

  • 3D vzdálenost mezi nimi
  • 2D vzdálenost (ignorující výšku / osu Y)
  • Výškový rozdíl

Nápověda: Pro 2D vzdálenost vytvořte nové vektory s [1] nastaveným na 0 před výpočtem vzdálenosti.

Cvičení 4: Žonglování s typy

Máte řetězec "42", převeďte ho na:

  1. int
  2. float
  3. Zpět na string pomocí string.Format()
  4. bool (mělo by být true, protože hodnota int je nenulová)

Cvičení 5: Pozice na zemi

Napište funkci vector SnapToGround(vector pos), která přijme libovolnou pozici a vrátí ji s komponentou Y nastavenou na výšku terénu na daném místě X, Z. Použijte GetGame().SurfaceY().


Shrnutí

KonceptKlíčový bod
Typyint, float, bool, string, vector, typename, void
Výchozí hodnoty0, 0.0, false, "", "0 0 0", null
KonstantyKlíčové slovo const, konvence UPPER_SNAKE_CASE
VektoryInicializace řetězcem "x y z" nebo Vector(x,y,z), přístup přes [0], [1], [2]
RozsahProměnné omezeny na bloky {}; žádná opětovná deklarace ve vnořených/sourozených blocích
Konverzefloat na int ořezává; pro parsování řetězců použijte .ToInt(), .ToFloat(), .ToVector()
FormátováníVždy používejte string.Format() pro sestavování řetězců ze smíšených typů

Domů | Proměnné a typy | Další: Pole, mapy a množiny >>

Released under CC BY-SA 4.0 | Code examples under MIT License