Sveiki, mačiau bent pora prašymų parašyti pamoką apie vartus su klavišo paspaudimu.
Šioje pamokoje aprašysiu du dalykus:
- Elementarus kodas vartams
- Paprastesnsi kodas turint daugiau nei vieną porą vartų
Elementarus kodas vartams
Šiame pavyzdyje kursime "labirinto" vartus atidaromus su mygtuku SPACE. Ko mums reikės?
- Uždarytų vartų koordinačių
- Atidarytų vartų koordinačių
- Dviejų kintamųjų
Pradėsim nuo kintamųjų:
new LabirintoVartuObjektas, bool:LabirintoVartaiUzdaryti = true;
Tarkime kad mano koordinatės:
Uždaryti: 1240.0, 500.0, 14.0, 0.0, 0.0, 0.0
Atidaryti: 1240.0, 500.0, 20.0, 0.0, 0.0, 90.0
Kaip matote, mano vartai pakils aukštyn ir pasisuks Z ašyje.
Sukurkime objektą. Pagalvokite ar norite kad vartai būtų uždaryti ar ne, atitinkamai rinkites ir koordinates:
public OnGameModeInit()
{
LabirintoVartuObjektas = Createobject(objekto_modelis, 1240.0, 500.0, 14.0, 0.0, 0.0, 0.0);
return 1;
}
Na iki dabar buvo vaikų žaidimai, pereinam prie atidarymo/uždarymo su mygtuku.
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
// Patikriname ar buvo nuspaustas ir atleistas mygtukas.
// KEY_SPRINT paprastai būna tarpas.
if((newkeys & KEY_SPRINT) && !(oldkeys & KEY_SPRINT))
{
// Čia koordinatės kur žaidėjas turi būti kad veiktų vartai. Pas mane, jos sutampa su uždarytų vartų pozicijoa.
if(IsPlayerInRangeOfPoint(playerid, 5.0, 1240.0, 500.0, 14.0))
{
if(LabirintoVartaiUzdaryti)
MoveObject(LabirintoVartuObjektas, 1240.0, 500.0, 20.0, 1.0, 0.0, 0.0, 90.0);
else
MoveObject(LabirintoVartuObjektas, 1240.0, 500.0, 14.0, 1.0, 0.0, 0.0, 0.0);
// Ši eilutė nustatys LabirintoVartaiUzdaryti reikšmę į priešingą. Jeigu buvo true, bus false. Jei buvo false, bus true.
LabirintoVartaiUzdaryti = !LabirintoVartaiUzdaryti;
return 1;
}
}
return 1;
}
MoveObject naudojimas
Parametras | Privalomas | Reikšmė |
---|---|---|
objectid | Taip | Objetko, kuris bus pajudintas, ID. |
Float:X | Taip | X koordinatė į kurią keliaus objektas |
Float:Y | Taip | Y koordiantė į kurią keliaus objektas |
Float:Z | Taip | Z koordinatė į kurią keliaus objektas |
Float:Speed | Taip | Greitis kuriuo judės objektas. Vienas per sekundę. Tai reiškia kad atstumą 1.0 nukeliaus per sekundę |
Float:RotX | Ne | Galutinis objekto pasisukimas X ašyje |
Float:RotY | Ne | Galutinis objekto pasisukimas Y ašyje |
Float:RotZ | Ne | Galutinis objekto pasisukimas Z ašyje |
Paprastesnsi kodas turint daugiau nei vieną porą vartų
Pažiūrėjus į praeitą kodą jis neatrodo ilgas. Bet jei turime 50 vartų? Ar norite tą patį rašyti 50 kartų?
Todėl siūlau susidėti visas koordinates į masyvą!
enum E_VARTU_DUOMENYS
{
Objektas,
bool:Uzdaryti,
Float:JudejimoGreitis,
Float:AtidarytuX,
Float:AtidarytuY,
Float:AtidarytuZ,
Float:AtidarytuRX,
Float:AtidarytuRY,
Float:AtidarytuRZ,
Float:UzdarytuX,
Float:UzdarytuY,
Float:UzdarytuZ,
Float:UzdarytuRX,
Float:UzdarytuRY,
Float:UzdarytuRZ,
};
new const VartuDuomenys[][ E_VARTU_DUOMENYS ] =
{
{1243, true, 1.0, 1240.0, 500.0, 14.0, 0.0, 0.0, 0.0, 1240.0, 500.0, 20.0, 0.0, 0.0, 90.0},
{kiti vartai....}
};
new VartuObjektuID[ sizeof(VartuDuomenys) ],
bool:VartaiUzdaryti[ sizeof(VartuDuomenys ]) ];
Jau dabar galima matyti keletą privalumų. Pavyzdžiui kad visi vartų duomenys bus vienoje vietoje.
public OnGameModeInit()
{
for(new i = 0; i < sizeof(VartuDuomenys); i++)
{
if(VartuDuomenys[ i ][ Uzdaryti ])
{
VartuObjektuID[ i ] = CreateObject(VartuDuomenys[ i ][ Objektas ], VartuDuomenys[ i ][ UzdarytuX ], VartuDuomenys[ i ][ UzdarytuY ], VartuDuomenys[ i ][ UzdarytuZ ], VartuDuomenys[ i ][ UzdarytuRX ], VartuDuomenys[ i ][ UzdarytuRY ], VartuDuomenys[ i ][ UzdarytuRZ ]);
VartaiUzdaryti[ i ] = true;
}
else
{
VartuObjektuID[ i ] = CreateObject(VartuDuomenys[ i ][ Objektas ], VartuDuomenys[ i ][ AtidarytuX ], VartuDuomenys[ i ][ AtidarytuY ], VartuDuomenys[ i ][ AtidarytuZ ], VartuDuomenys[ i ][ AtidarytuRX ], VartuDuomenys[ i ][ AtidarytuRY ], VartuDuomenys[ i ][ AtidarytuRZ ]);
VartaiUzdaryti[ i ] = false;
}
}
return 1;
}
Objektų sukūrimas irgi šiek tiek pailgėjo, tačiau kad ir kiek bus vartų, šitas kodas nebesikeis. Pereinam prie atidarymo/uždarymo:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if((newkeys & KEY_SPRINT) && !(oldkeys & KEY_SPRINT))
{
for(new i = 0; i < sizeof(VartuDuomenys); i++)
{
if(IsPlayerInRangeOfPoint(playerid, 5.0, VartuDuomenys[ i ][ UzdarytuX ], VartuDuomenys[ i ][ UzdarytuY ], VartuDuomenys[ i ][ UzdarytuZ ]))
{
if(VartaiUzdaryti[ i ])
MoveObject(VartuObjektuID[ i ], VartuDuomenys[ i ][ AtidarytuX ], VartuDuomenys[ i ][ AtidarytuY ], VartuDuomenys[ i ][ AtidarytuZ ], VartuDuomenys[ i ][ JudejimoGreitis ], VartuDuomenys[ i ][ AtidarytuRX ], VartuDuomenys[ i ][ AtidarytuRY ], VartuDuomenys[ i ][ AtidarytuRZ ]);
else
MoveObject(VartuObjektuID[ i ], VartuDuomenys[ i ][ UzdarytuX ], VartuDuomenys[ i ][ UzdarytuY ], VartuDuomenys[ i ][ UzdarytuZ ], VartuDuomenys[ i ][ JudejimoGreitis ] VartuDuomenys[ i ][ UzdarytuRX ], VartuDuomenys[ i ][ UzdarytuRY ], VartuDuomenys[ i ][ UzdarytuRZ ]);
VartaiUzdaryti[ i ] = !VartaiUzdaryti[ i ];
}
}
}
return 1;
}
Ir viskas! Vienintelis kodas kurį reikės keisti pridedant vartus tai tik masyvas su jų duomenimis.
Štai pamoka ir baigta. Žinoma mygtukus, atstumas, greičius, koordinates keiskite pagal savo norus :)
Karolis_Handza prieš 9 metus
Graži pamoka, bet jai žaidėjas nori prisitaikyti vartus tam tikram pvz darbui ? ( pagal antra variantą )
Bebras prieš 9 metus
Tai į masyvą reikėtų prisidėti kokį nors darbo ID ir žaidėjui bandant atidaryti vartus tikrinti ar jo darbo ID sutampa su tų vartų prie kurių jis stovi.
Ron prieš 9 metus
Aš pasidaręs, kad vartai atsidarytų automatiškai esant netoliese jų (~2-3 metrai), ir nesu panaudojęs nei vieno tim'erio bei IsPlayerInRangeOfPoint :) Su viena funkcija viskas veikia automatiškai, t.y. Nereikia spausti mygtuko norint atidaryti/uždaryti vartus.
Ron prieš 9 metus
@Zombis Na matai, pamokos ir yra kuriamos tam kad išmoktų kiti, bet šiuo atveju ėjau kitu keliu, ir stengiausi pabandyti tai sukūrti, ir reikiamą rezultatą pasiekiau. Kas liečia gyrimasi tai nieko bendro neturi su mano pranešimais, o jei tu taip manai, tuomet niekuo tau padėti negaliu.
Virsenas prieš 9 metus
Matosi kokie čia protinguoliai lankosi forume. Einšteinai susirinkę Lietuvos.
Aš pasidaręs, kad vartai atsidarytų automatiškai esant netoliese jų (~2-3 metrai), ir nesu panaudojęs nei vieno tim'erio bei IsPlayerInRangeOfPoint :blush: Su viena funkcija viskas veikia automatiškai, t.y. Nereikia spausti mygtuko norint atidaryti/uždaryti vartus.
Ne tik, kad IsPlayerInRangeOfPoint naudoja X ir Y koordinates, bet ir geriau patikrina ar žaidėjas yra tam tikroj pozicijoj, nes dar patikrina ir Z koordinatę. Sugalvojai durnesnį patikrinimą. Bravo. Tikriausiai labai ilgai galvojai, kad surastum kvailesnį būdą kaip patikrinti ar žaidėjas prie vartų.
Greičiau šito durnyno nebebūtų.