19.01.2013, 15:16
(
Последний раз редактировалось [DOG]irinel1996; 07.07.2015 в 13:16.
)
El lнmite de los TextDraws
[*] IntroducciуnBuenas chavales, decidн hacer este pequeсo tutorial sobre el lнmite de los TextDraws porque veo un montуn de filterscripts usбndolos de mala manera.
Y sin mencionar todas las dudas que tienen sobre ellos los usuarios mбs nuevos en PAWN.
Aclaro que no explicarй sus funciones, sino cуmo se alcanza el lнmite y quй tipo de TextDraw usar en diferentes situaciones.
No se preocupen si no entienden ciertas cosas a primera vista, porque al final de todo explico todo de forma mбs detallada.
Tambiйn menciono que si no sabes como funcionan las matrices, es posible que se te complique un poquito mбs, aunque yo lo explicarй lo mejor que pueda.
[*] Tipos
En la versiуn actual del SA-MP hay dos tipos de TextDraws, vamos a ver cуmo era antes y cуmo es ahora.
- Antes de SA-MP 0.3e
[1] Global:
Hasta antes del reciente SA-MP 0.3e existнa solo un tipo de TextDraw: el global
Global quiere decir que es igual para todo el mundo en todo momento, el contenido (texto) de este es igual para todos los jugadores.
PHP код:new
Text:tuto_gTextDraw //Aquн se guarda la ID del TextDraw que creamos a continuaciуn.
;
public OnGameModeInit() {
tuto_gTextDraw = TextDrawCreate(240.0, 580.0, "Hola!");
/*
Igual que en el caso de los jugadores, el primer TextDraw creado recibe la ID 0.
Si el lнmite de los TextDraws globales es 2048, entonces ya tenemos 1/2048.
Podemos crear 2047 TextDraws mбs iguales a este.
*/
return 1;
}
Pero el verdadero problema es que el texto de ellos serб igual para todo el mundo, y por eso si nosotros queremos hacer un TextDraw que indique el dinero del jugador no podemos usar este tipo ya que cada jugador tendrнa su cantidad de dinero y necesitamos un TextDraw para cada jugador.
Imaginense que todos los jugadores tienen 100$ siempre, podrнamos usar este TextDraw porque el valor es el mismo para todos. Pero al tener diferentes cantidades de dinero, no podemos usar un solo TextDraw teniendo varios jugadores en el servidor, para eso necesitamos los TextDraws por jugador.
[2] Global por jugador:
Aun asн, se inventу una manera de usar los TextDraws globales para crear TextDraws por jugador, o sea que cada jugador tenнa su propio TextDraw global con su propio contenido.
їEn quй consiste?
Pues se declara una matriz (el TAG Text se incluye) usando un determinado valor para las celdas de esta, pero la mayorнa de los scripters usan el famoso MAX_PLAYERS que tiene un valor de 500 por defecto.
Luego hay dos formas de crearlos, todos a la vez usando un bucle for (por ejemplo) en OnGameModeInit
PHP код:new
Text:tuto_gTPJ[MAX_PLAYERS]
;
public OnGameModeInit() {
for (new x; x < MAX_PLAYERS; x++) {
tuto_gTPJ[x] = TextDrawCreate(240.0, 580.0, "100$");
}
return 1;
}
public OnPlayerSpawn(playerid) {
new
name[MAX_PLAYER_NAME]
;
GetPlayerName(playerid, name, MAX_PLAYER_NAME);
format(name, MAX_PLAYER_NAME, "%s", name);
TextDrawSetString(tuto_gTPJ[playerid], name);
TextDrawShowForPlayer(playerid, tuto_gTPJ[playerid]);
/*
Cogemos la celda que coincide con playerid, y el valor que contiene es la ID del TextDraw.
Luego se lo mostramos, їpero cuбl mostramos si tenemos 500?
La ID que tenemos almacenada en la celda con el mismo valor que playerid.
*/
return 1;
}
Tambiйn podemos crearlos cuando un jugador se conecte en OnPlayerConnect, si usamos este tipo de TextDraw yo recomendarнa esta forma, ya que no se crean todos a la vez, y creamos uno cuando un jugador entra.
PHP код:new
Text:tuto_gTPJ[MAX_PLAYERS]
/*
La matriz se declara con 500 celdas, pero no usamos un bucle para crear los TextDraws
a la vez, sino que las celdas se quedan vacias. Y cuando un jugador se conecta
se crea un TextDraw y en la celda que coincide con playerid se guarda la
ID que justу se creo en OnPlayerConnect.
*/
;
public OnPlayerConnect(playerid) {
tuto_gTPJ[playerid] = TextDrawCreate(240.0, 580.0, "100$");
/*
Usando la matriz tuto_gTPJ guardamos la ID del TextDraw en la celda que corresponde a playerid.
*/
return 1;
}
public OnPlayerDisconnect(playerid) {
TextDrawDestroy(tuto_gTPJ[playerid]);
/*
Aquн lo destruimos cuando el jugador sale, asн restamos un TextDraw
y liberamos un slot mбs para TextDraws
*/
return 1;
}
No hay ningъn truco, es algo de lуgica. Veamos:
1є. Se crea una matriz con el tamaсo de MAX_PLAYERS (por ejemplo).
2є. Cuando un jugador entra se crea un TextDraw y se guarda la ID en la celda correspondiente a playerid, o bien usamos el bucle en OnGameModeInit.
3є. Modificamos ese TextDraw identificando la celda correspondiente con playerid.
їQuй contiene la celda que corresponde a playerid?
Contiene un valor, y es la ID de un TextDraw.
Cada celda tiene una ID diferente, si usamos MAX_PLAYERS para declarar la matriz tendrнamos 500 celdas, y cada una tendrнa una ID diferente lo que quiere decir que tenemos 500 TextDraws (dependiendo de la tйcnica que usemos para crearlos).
Da le sensaciуn que el jugador tiene su propio TextDraw, pero en realidad es uno global que solo lo usamos para un determinado jugador.
Quote:
Aquн se suele cometer el mayor error, al usar MAX_PLAYERS, como ya sabemos que tiene un valor de 500 al usar el bucle for ya crearнamos 500 TextDraws a la vez, aunque nosotros solo tengamos 100 slots.
Si usamos 100 slots y usamos MAX_PLAYERS solo usaremos 100 TextDraws y los otros 400 solo estarбn ahн ocupando espacio, asн alcanzaremos mбs rбpido el lнmite.
La mejor forma de crear este tipo de TextDraw es en OnPlayerConnect ya que solo se crea uno para el jugador cuando se conecta y se destruye cuando sale.
- Desde SA-MP 0.3e
En la ъltima versiуn publicada de manera oficial, 0.3e, se aсadiу un nuevo tipo: el TextDraw por jugador.
Es exactamente lo mismo que un TextDraw global, pero solo se crea para un jugador. Lo bueno es que podemos crear 256 TextDraws de este tipo para cada jugador, y segъn mis experiencias parece que no tienen nada que ver con el otro lнmite de 2048.
Eso sн, las funciones son diferentes en cuanto a los nombres, pero es muy pequeсa la diferencia. Y ahora hay que agregar un parбmetro mбs.
їCуmo se crean y quй debemos usar?
Aun se necesita una matriz pero esta vez funciona totalmente diferente, segъn la wiki puede que haya mezclas de IDs y que se muestre a un jugador un TextDraw incorrecto, y al parecer se arregla usando una matriz (array).
PHP код:new
PlayerText:tuto_gTD[MAX_PLAYERS]
;
public OnPlayerConnect(playerid) {
tuto_gTD[playerid] = CreatePlayerTextDraw(playerid, 240.0, 580.0, "Hola!");
return 1;
}
****** me dijo que podemos crear 256 TextDraws de este tipo para cada jugador.
Lo ideal es crearlos en OnPlayerConnect, tambiйn menciono que se destruyen automбticamente cuando un jugador se desconecta. Asн que es mala idea crearlos en OnGameModeInit.
їPor quй se necesita una matriz en estos TextDraws?
Porque cada jugador podrб tener 256 TextDraws de este tipo, y las IDs de los TextDraws para todos los jugadores irбn del 0 al 255. A veces el orden de creaciуn de los TextDraws es alterado y puede que en una variable se guarden dos valores distintos, cosa que no es posible. Por eso necesitamos matrices, para que no lleguen a mezclarse.
Un ejemplo muy claro:
PHP код:new
PlayerText:A,
PlayerText:B
;
public OnPlayerConnect(playerid) {
if (IsPlayerAdmin(playerid)) {
A = CreatePlayerTextDraw(playerid, 0.0, 0.0, "A"); //Este TextDraw tendrб la ID 0 si el jugador es admin.
}
B = CreatePlayerTextDraw(playerid, 0.0, 0.0, "B");
/*
Pero la ID del B dependerб de la condiciуn de mбs arriba, ї0 o 1?
Si el jugador no es admin tendrб la ID 0, pero si lo es tendrб la ID 1.
Imaginen que tenemos dos jugadores, uno admin y otro no.
Entra el admin y el orden de sus TextDraws es A (ID 0) y B (ID 1), entra el segundo y solo tiene B (ID 0).
Entonces en la variable A se guardarб la ID 0 del TextDraw A del jugador con admin,
pero en la variable B se guardarб la ID 0 del jugador sin admin mбs la ID 1 del jugador con admin.
Entonces tendrнamos dos valores distintos en una sola variable, cosa que no es posible,
por eso se llegarб a la pйrdida de informaciуn, y la mezcla.
*/
return 1;
}
PHP код:#include <a_samp>
new
PlayerText:A,
PlayerText:B,
PlayerText:C
;
public OnPlayerConnect(playerid) {
if (playerid == 0) {
A = CreatePlayerTextDraw(playerid, 0.0, 0.0, "A"); //A - ID 0
B = CreatePlayerTextDraw(playerid, 0.0, 0.0, "B"); //B - ID 1
C = CreatePlayerTextDraw(playerid, 0.0, 0.0, "C"); //C - ID 2
} else if (playerid == 1) {
C = CreatePlayerTextDraw(playerid, 0.0, 0.0, "C"); //C - ID 0
A = CreatePlayerTextDraw(playerid, 0.0, 0.0, "A"); //A - ID 1
B = CreatePlayerTextDraw(playerid, 0.0, 0.0, "B"); //B - ID 2
}
return 1;
}
Para facilitar el entendimiento, son similares a los objetos por jugador (Player Objects) y los globales como los objetos normales.
No me adentro mбs en este tipo, como dije solo iba a hablar sobre los lнmites.
[*] Cuando usarlos
- Globales
Deberнan usarse en Textos que siempre son iguales para todos, fondos, contadores (siempre y cuando la cuenta sea igual para todo el mundo), etc.
PHP код:// ---------------------[Mostrar Web en TextDraw]--------------------------- //
#include <a_samp>
new
Text:tuto_gTD,
;
public OnGameModeInit(playerid) {
tuto_gTD = TextDrawCreate(240.0, 580.0, "www.sa-mp.com");
return 1;
}
public OnPlayerSpawn(playerid) {
TextDrawShowForPlayer(playerid, tuto_gTD);
return 1;
}
public OnPlayerDeath(playerid, killerid, reason) {
TextDrawHideForPlayer(playerid, tuto_gTD);
return 1;
}
- Por jugador
Para mostrar estadнsticas, barras animadas, y cosas que pueden tener diferentes valores entre los jugadores: dinero, score, etc.
PHP код:// ---------------------[Mostrar dinero en TextDraw]--------------------------- //
#include <a_samp>
new
bool:tuto_gSpawned [MAX_PLAYERS],
PlayerText:tuto_gTD [MAX_PLAYERS]
;
public OnPlayerConnect(playerid) {
tuto_gSpawned[playerid] = false;
tuto_gTD[playerid] = CreatePlayerTextDraw(playerid, 240.0, 580.0, "Hola!");
return 1;
}
public OnPlayerSpawn(playerid) {
tuto_gSpawned[playerid] = true;
PlayerTextDrawShow(playerid, tuto_gTD[playerid]);
return 1;
}
public OnPlayerDeath(playerid, killerid, reason) {
tuto_gSpawned[playerid] = false;
PlayerTextDrawHide(playerid, tuto_gTD[playerid]);
return 1;
}
public OnPlayerUpdate(playerid) {
if (tuto_gSpawned[playerid]) {
new
cadena[50]
;
format(cadena, 50,
"~w~%d~g~~h~$",
GetPlayerMoney(playerid)
);
PlayerTextDrawSetString(playerid, tuto_gTD[playerid], cadena);
PlayerTextDrawShow(playerid, tuto_gTD[playerid]);
}
return 1;
}
Algunas cosas que me han servido a la hora de usar TextDraws:
- Si son TextDraws de decoraciуn y son iguales para todo el mundo nunca uses TextDraws por jugador.
- No olviden de destruir los TextDraws por jugador si los crean en OnPlayerConnect basбndose en los TextDraws globales, vean mi ejemplo.
- Cuando usemos los TextDraws globales para crear TextDraws por jugador, en vez de usar MAX_PLAYERS con 500 como valor, deberнamos definirlo de nuevo con el nъmero de slots que usamos:
PHP код:#include <a_samp>
//---
#undef MAX_PLAYERS
#define MAX_PLAYERS (100)
//---
//Otros includes.
- Si ya usan la 0.3e recomendarнa no usar mбs los TextDraws globales para crear TextDraws por jugador, algunas personas dicen que tienen problemas con ellos, yo personalmente no he tenido ninguno.
- Deben saber que los TextDraws de los filterscripts, includes, etc. se juntan todos para alcanzar el lнmite. Quiero decir que si tienes 1 FS no puedes tener 4096 TextDraws (2048 del FS + 2048 del GM).
Globales | Por Jugador |
2048 | 256 (Como dije, cada jugador puede tener 256 de este tipo) |
[*] Fin
Es esto seсores.
Menciono que toda la informaciуn estб basada en mis propias experiencias y la wiki.
Una pequeсa cosa del lнmite del nuevo tipo de TextDraw de la 0.3e, me la confirmу ****** porque tenнa una duda.
Tambiйn doy las gracias a MrDeath537 (que al parecer ya no estб en el foro), que me lo explicу a mi cuando yo no lo entendнa.
Cualquier duda, aporte de informaciуn, algъn fallo que haya cometido en el tutorial, si quieren que explique mejor una cosa especifica, o quieren algъn tutorial de alguna otra cosa, etc. comenten.
ЎSaludos, y lo siento si hay faltas de ortografнa!