29.12.2014, 13:38
(
Последний раз редактировалось [DOG]irinel1996; 16.06.2015 в 00:04.
)
Бreas
[*] IntroducciуnBuenas, decidн hacer este tutorial para que tengan una pequeсa referencia a la hora de crear бreas. Lo que me empujу a hacerlo fue la duda de un usuario de este foro, asн que, aquн os dejo una guнa para poder crear бreas correctamente. Yo enfocarй este tutorial sobre todo a las funciones del Streamer de Incognito, aunque tambiйn echaremos un vistazo al asunto sin usar plugins/includes/etc.
Antes de todo, tenemos que aclarar algunas dudas a las personas que no saben nada sobre бreas y superficies.
[*] їPara quй sirven?
Pues bбsicamente sirven para detectar cuando un jugador entra en una zona determinada.
Algunos ejemplos:
- Echar a un jugador normal de una zona VIP.
- Prohibir ciertos vehнculos/armas en determinadas zonas.
- Activar una canciуn cuando alguien entra en una discoteca.
- Tener vida infinita si un jugador estб en un бrea de Spawn, asн no hacen Spawn-Kill.
- Mostrar un mensaje/TextDraw/GameText/etc. cuando entra en una zona determinada.
[*] Diferencias entre бrea y superficie
Si estudiamos formas en 2D, el бrea y la superficie son dos cosas iguales, podrнamos decir que ambos conceptos son lo mismo. En el caso de las formas en 3D, son dos cosas distintas, pero no entraremos por ahн ya que nosotros estudiaremos esto sobre el mapa del GTA San Andreas.
El mapa del San Andreas, visto desde arriba, serнa una forma bidimensional (2D). Y si entramos al juego y nos ponemos a jugar, lo verнamos en 3D. Pero nosotros estudiaremos el бrea SOBRE EL MAPA.
Entonces, el бrea en el caso de las formas en 2D, serнa equivalente a la superficie que encierra dicha forma. Por ejemplo, en el rectбngulo que tenemos a continuaciуn lo que estб pintado de amarillo serнa el бrea o la superficie.
Matemбticamente, el бrea es el resultado del producto de a · b, y su unidad de medida es metros cuadrados (m2).
Este es el mapa del GTA San Andreas en 2D, ahora si colocamos sobre йl un eje de coordenadas con el origen (0) en el centro del mapa, obtendrнamos un sistema (X, Y).
Imagino que todos sabrбn que el centro del mapa (origen de coordenadas) es la famosa granja que se encuentra en Blueberry Acres. Como sabrбn, cuando vamos al juego y damos /save obtenemos una lнnea con el siguiente formato:
pawn Код:
AddPlayerClass(skin, Float:x, Float:y, Float:z, Float:Angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo);
En esta imagen tenemos cuatro puntos: A, B, C y D. Cada punto tiene coordenadas distintas.
Entonces, como cada punto tiene una x e y distinta, podemos decir que tenemos varias parejas de coordenadas:
pawn Код:
new Float:Puntos[8] = {
ax, ay,
bx, by,
cx, cy,
dx, dy
};
Sabiendo esto, podemos seguir adelante estudiando las funciones en sн.
[*] Funciones del Streamer
Como ya dije, este tutorial va enfocado hacia el Streamer de Incognito, las funciones para crear бreas son estas:
pawn Код:
native CreateDynamicCircle(Float:x, Float:y, Float:size, worldid = -1, interiorid = -1, playerid = -1);
native CreateDynamicCylinder(Float:x, Float:y, Float:minz, Float:maxz, Float:size, worldid = -1, interiorid = -1, playerid = -1);
native CreateDynamicSphere(Float:x, Float:y, Float:z, Float:size, worldid = -1, interiorid = -1, playerid = -1);
native CreateDynamicRectangle(Float:minx, Float:miny, Float:maxx, Float:maxy, worldid = -1, interiorid = -1, playerid = -1);
native CreateDynamicCuboid(Float:minx, Float:miny, Float:minz, Float:maxx, Float:maxy, Float:maxz, worldid = -1, interiorid = -1, playerid = -1);
native CreateDynamicPolygon(Float:points[], Float:minz = -FLOAT_INFINITY, Float:maxz = FLOAT_INFINITY, maxpoints = sizeof points, worldid = -1, interiorid = -1, playerid = -1);
- CreateDynamicCircle
Esta funciуn crea un бrea circular alrededor de un punto indicado, cubrirб todas las posiciones que estйn por encima/debajo de ella. O sea, funcionarб aunque estemos a cualquier altura por encima, o bien por debajo del suelo.
Код:Float:x -> la coordenada X del punto. Float:y -> la coordenada Y del punto. Float:size -> tamaсo de la circunferencia, si el valor aumenta, el diбmetro de la circunferencia aumenta. worldid -> Virtual World en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Virtual Worlds. interiorid -> Interior en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Interiors. playerid -> Si se introduce un valor distinto al -1, solo tendrб efecto para el jugador con esa ID. Si se deja -1, funcionarб para todos los jugadores.
pawn Код:AddPlayerClass(1, 1958.33, 1343.12, 15.36, 269.15, 26, 36, 28, 150, 0, 0);
/* Extraemos las coordenadas */
// X = 1958.33
// Y = 1343.12
/* Creamos nuestro бrea circular */
CreateDynamicCircle(1958.33, 1343.12, 50.0, -1, -1, -1);
/* Hay que observar que para crear un бrea circular solo necesitamos un punto. */ - CreateDynamicCylinder
Esta funciуn es idйntica a la anterior, se diferencia en que podemos definir las alturas en las que tendrб efecto, dando lugar a un cilindro finito. La funciуn anterior, tambiйn serнa un cilindro, pero con los extremos en el infinito.
Код:Float:x -> la coordenada X del punto. Float:y -> la coordenada Y del punto. Float:minz -> el punto mбs bajo de la coordenada Z que alcanzarб el бrea. Float:maxz -> el punto mбs alto de la coordenada Z que alcanzarб el бrea. Float:size -> si el valor aumenta, el diбmetro del cilindro aumenta. worldid -> Virtual World en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Virtual Worlds. interiorid -> Interior en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Interiors. playerid -> Si se introduce un valor distinto al -1, solo tendrб efecto para el jugador con esa ID. Si se deja -1, funcionarб para todos los jugadores.
pawn Код:AddPlayerClass(1, 1958.33, 1343.12, 15.36, 269.15, 26, 36, 28, 150, 0, 0);
/* Extraemos las coordenadas X e Y */
// X = 1958.33
// Y = 1343.12
/* Sabemos que Z = 0.0 equivale al nivel del mar, entonces podrнamos definir nuestra propia altura. */
// minZ = -10.0 -> El cilindro empieza un poquito menos por debajo del nivel del mar.
// maxZ = 480.3623 -> El cilindro termina a la altura del Monte Chiliad.
/* Creamos nuestro бrea cilнndrico */
CreateDynamicCylinder(1958.33, 1343.12, -10.0, 480.3623, 50.0, -1, -1, -1);
/* Hay que observar que para crear un бrea cilнndrico solo necesitamos un punto y dos alturas distintas. */ - CreateDynamicSphere
Esta funciуn crea una esfera, darнa lugar a un бrea tridimensional, necesitamos X, Y, Z para crear una esfera.
Код:Float:x -> la coordenada X del punto. Float:y -> la coordenada Y del punto. Float:z -> la coordenada Z del punto, serнa el centro de la esfera. Float:size -> si el valor aumenta, la esfera aumenta. worldid -> Virtual World en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Virtual Worlds. interiorid -> Interior en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Interiors. playerid -> Si se introduce un valor distinto al -1, solo tendrб efecto para el jugador con esa ID. Si se deja -1, funcionarб para todos los jugadores.
pawn Код:AddPlayerClass(1, 1958.33, 1343.12, 15.36, 269.15, 26, 36, 28, 150, 0, 0);
/* Extraemos las coordenadas X Y Z */
// X = 1958.33
// Y = 1343.12
// Z = 15.36
/* Creamos nuestro бrea esfйrico */
CreateDynamicSphere(1958.33, 1343.12, 15.36, 50.0, -1, -1, -1);
/* Hay que observar que para crear un бrea esfйrico necesitamos los valores de los tres ejes: X Y Z. */ - CreateDynamicRectangle
Esta funciуn crea un rectбngulo, las alturas van a menos infinito, y a mбs infinito. O sea que tiene efecto sin importar a que altura te encuentras, algo parecido a CreateDynamicCircle. Esta funciуn tiene algo bastante peculiar, que son sus parбmetros, ya que son diferentes a los que tenнan las funciones anteriores. A pesar de eso, son del todo lуgicos, vamos a verlos:
Код:Float:minx -> valor X mбs prуximo al origen. Float:miny -> valor Y mбs prуximo al origen. Float:maxx -> valor X mбs alejado del origen. Float:maxy -> valor Y mбs alejado del origen. worldid -> Virtual World en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Virtual Worlds. interiorid -> Interior en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Interiors. playerid -> Si se introduce un valor distinto al -1, solo tendrб efecto para el jugador con esa ID. Si se deja -1, funcionarб para todos los jugadores.
Como ven, se necesitan dos posiciones sacadas con /save, siendo cada una la esquina contraria del rectбngulo. Recordemos que donde se juntan los ejes X Y, se encuentra el origen. Un usuario de este foro, precisamente OTACON, hizo un tutorial sobre como sacar estas coordenadas. Usarй una de sus imбgenes para explicarlo con mas precisiуn.
Colocando el eje de coordenadas en el lado izquierdo del rectбngulo que ven en la foto, la X roja tendrнa los valores minx, maxy. Mientras que la X azul tendrнa los valores maxx, miny. Recordemos que las X de la imagen son dos posiciones obtenidas con el comando /save, entonces suponiendo que la X roja es igual a esto:
pawn Код:AddPlayerClass(0, 1958.33, 1343.12, 15.36, 269.15, 26, 36, 28, 150, 0, 0);
/* Extraemos los valores respectivos */
// minX = 1958.33
// maxY = 1343.12
pawn Код:AddPlayerClass(1, 2300.35, 1000.12, 15.36, 269.15, 26, 36, 28, 150, 0, 0);
/* Extraemos los valores respectivos */
// maxX = 2300.35
// minY = 1000.12
pawn Код:CreateDynamicRectangle(1958.33, 1000.12, 2300.35, 1343.12, -1, -1, -1); - CreateDynamicCuboid
Si se dan cuento, esto es lo mismo que lo anterior, pero le podemos indicar que altura queremos que tenga, dando lugar a una figura 3D (a un cubo). Entonces, veamos sus parбmetros:
Код:Float:minx -> valor X mбs prуximo al origen. Float:miny -> valor Y mбs prуximo al origen. Float:minz -> valor Z mбs prуximo al origen. Float:maxx -> valor X mбs alejado del origen. Float:maxy -> valor Y mбs alejado del origen. Float:maxz -> valor Z mбs alejado del origen. worldid -> Virtual World en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Virtual Worlds. interiorid -> Interior en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Interiors. playerid -> Si se introduce un valor distinto al -1, solo tendrб efecto para el jugador con esa ID. Si se deja -1, funcionarб para todos los jugadores.
En definitiva, si suponemos que tenemos los siguientes datos:
pawn Код:// minX = 1958.33
// maxY = 1343.12
// maxX = 2300.35
// minY = 1000.12
// minZ = 0.0 -> La base inferior del cubo empieza a la altura del nivel del mar.
// maxZ = 480.3623 -> El la base superior del cubo termina a la altura del Monte Chiliad.
/* Con estos datos ya podemos crear nuestro cubo. */
CreateDynamicCuboid(1958.33, 1000.12, 0.0, 2300.35, 1343.12, 480.3623, -1, -1, -1); - CreateDynamicPolygon
Esta funciуn creo que es la mбs compleja, ya que se trata de un polнgono: figura plana compuesta por una secuencia finita de segmentos rectos consecutivos que cierran una regiуn en el plano.
Es decir, una cantidad de segmentos rectos que se juntan por los extremos y encierran una superficie llamada бrea. Dependiendo de la cantidad de segmentos, nuestro polнgono recibirб distintos nombres (triбngulo, pentбgono, octбgono, etc.).
Entonces, concluyo que un polнgono ha de tener mнnimo tres lados para poder encerrar una superficie.
Veamos los parбmetros de la funciуn:
Код:Float:points[] -> matriz que contiene todos los valores de los puntos del polнgono. Float:minz -> Para entender esto vean CreateDynamicCylinder, o bien pongan -FLOAT_INFINITY para que la Z vaya a menos infinito. Float:maxz -> Para entender esto vean CreateDynamicCylinder, o bien pongan FLOAT_INFINITY para que la Z vaya a mбs infinito. maxpoints -> nъmero total de valores que definen nuestro polнgono. worldid -> Virtual World en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Virtual Worlds. interiorid -> Interior en el que tendrб efecto, si dejamos -1, tendrб efecto en todos los Interiors. playerid -> Si se introduce un valor distinto al -1, solo tendrб efecto para el jugador con esa ID. Si se deja -1, funcionarб para todos los jugadores.
Entonces, como cada punto tiene unas coordenadas X Y Z propias, podemos decir que tenemos varias parejas de coordenadas:
pawn Код:new Float:Puntos[12] = {
ax, ay, az,
bx, by, bz,
cx, cy, cz,
dx, dy, dz
};
/* Siendo 12 el nъmero total de valores. */
Vayamos ahora al tema de Incognito, donde nos ha dejado esta nota interesante:
Quote:Originally Posted by Incognito
The points in CreateDynamicPolygon and CreateDynamicPolygonEx need to be specified as a sequence of ordered pairs (x1, y1, x2, y2, ..., xn, yn). The number of elements in the array must be divisible by two for this reason. The first point must also be equal to the last point to form a closed path.Quote:Originally Posted by Incognito
Los puntos en CreateDynamicPolygon y CreateDynamicPolygonEx deben estar definidos como una secuencia de parejas ordenadas (x1, y1, x2, y2, ..., xn, yn). Debido a lo anterior, el nъmero de elementos de la matriz ha de ser divisible por dos. El primer punto ha de ser igual al ъltimo para formar un camino cerrado.
pawn Код:new Float:Puntos[] = {
x1, y1,
x2, y2,
x3, y3,
......,
x1, y1
};
pawn Код:new Float:Puntos[10] = {
ax, ay,
bx, by,
cx, cy,
dx, dy,
ax, ay /* El ъltimo punto, ha de ser igual al primer punto para cerrar la figura. */
};
/* Como tenemos 10 valores en total (dos valores por cada posiciуn), le damos un tamaсo de 10 a nuestra matriz. */
/*
1є. Recta de (ax, ay) a (bx, by).
2є. Recta de (bx, by) a (cx, cy).
3є. Recta de (cx, cy) a (dx, dy).
4є. Recta de (dx, dy) a (ax, ay).
*/
/* De esta manera, encerramos un бrea, eso explica estos puntos que hemos usado. */
pawn Код:new Float:Puntos[10] = {
ax, ay,
bx, by,
cx, cy,
dx, dy,
ax, ay
};
CreateDynamicPolygon(Puntos, -FLOAT_INFINITY, FLOAT_INFINITY, sizeof(Puntos), -1, -1, -1);
/* En este caso yo hice que mi polнgono detecte cualquier altura, pero como ya dije,
ustedes pueden definir una altura determinada. Para entenderlo mejor, miren la funciуn de CreateDynamicCylinder. */
[*] Callbacks del Streamer
El Streamer de Incognito solo tiene dos callbacks que nos permite interactuar con las бreas creadas anteriormente, estas callbacks son las siguientes:
Код:
forward OnPlayerEnterDynamicArea(playerid, areaid); forward OnPlayerLeaveDynamicArea(playerid, areaid);
- OnPlayerEnterDynamicArea
Код:playerid -> ID del jugador que entra en el бrea creada. areaid -> ID del бrea, valor devuelto por la funciуn con la que hemos creado el бrea.
- OnPlayerLeaveDynamicArea
Код:playerid -> ID del jugador que sale del бrea creada. areaid -> ID del бrea, valor devuelto por la funciуn con la que hemos creado el бrea.
- Ejemplo
pawn Код:new miArea;
public OnGameModeInit()
{
miArea = CreateDynamicCylinder(1958.33, 1343.12, -10.0, 480.3623, 50.0, -1, -1, -1);
return 1;
}
public OnPlayerEnterDynamicArea(playerid, areaid)
{
if(areaid == miArea)
{
SendClientMessage(playerid, 0x00FF00FF, "Has entrado en un cilindro.");
}
return 1;
}
public OnPlayerLeaveDynamicArea(playerid, areaid)
{
if(areaid == miArea)
{
SendClientMessage(playerid, 0x00FF00FF, "Has salido del cilindro en el que habнas entrado.");
}
return 1;
}
[*] Notas Importantes
- Los ejes de coordenadas los he colocado segъn mis costumbres, pero pueden estar colocados de diferentes maneras segъn cada quiйn.
[*] Otro
Esto es todo por ahora, si encuentran faltas de ortografнa o algъn fallo en la explicaciуn, dejad un comentario aquн por favor.