[Tutorial] Бreas
#1

Бreas
[*] Introducciуn
Buenas, 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.
Esas son algunas de las pocas cosas que podemos hacer si creamos бreas, obviamente, existen cosas mucho mбs complejas que esas.


[*] 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);
Esa x e y que obtenemos en esa lнnea, son las distancias respecto al origen (punto en el que se cortan ambos ejes). Pues bien, teniendo x e y, obtenemos un punto sobre el mapa: P(x, y). Y esos puntos definen los bordes de nuestras superficies.

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
};
Entre esos cuatro puntos tenemos una superficie, en este caso un rectбngulo, que serб nuestra бrea.

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.
    Por lo tanto, si conseguimos esto con el comando /save:
    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.
    Por lo tanto, si conseguimos esto con el comando /save:
    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.
    Por lo tanto, si conseguimos esto con el comando /save:
    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.
    Los que no sepan mucho de esto, seguramente se preguntarбn que cosas son minx, miny, maxx, maxy. Pero vamos a simplificarlo con un esquema grбfico:

    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
    Y la X azul igual a esto:
    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
    Teniendo esos datos, ya podemos crear nuestro rectбngulo:
    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.
    Para entender lo del eje Z (la altura), recomiendo que vean CreateDynamicCylinder mбs arriba. O pueden interpretar la siguiente grбfica:


    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.
    En esta imagen tenemos cuatro puntos: A, B, C y D. Cada punto tiene coordenadas distintas.


    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. */
    Entre esos cuatro puntos tenemos una superficie, en este caso un rectбngulo, que serб nuestra бrea. Recordemos que un rectбngulo tambiйn es un polнgono, ya que son cuatro segmentos que se unen por los extremos.

    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.
    Entonces, entendemos que tenemos que crear una matriz de la siguiente manera:
    pawn Код:
    new Float:Puntos[] = {
        x1, y1,
        x2, y2,
        x3, y3,
        ......,
        x1, y1
    };
    En nuestro caso, como tenemos cuatro puntos, serнa asн:
    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. */
    Teniendo estos datos, ya podemos crear nuestro polнgono:
    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);
Los que sepan algo de inglйs ya se habrбn dado cuenta para que sirve cada una, los que no, vean esta sencilla explicaciуn:
  • 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.
Reply
#2

Perfecto, pero:

Quote:
Originally Posted by [DOG]irinel1996
Посмотреть сообщение
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.
їNo serнa la x roja es minx y maxy, y tambiйn la azul maxx y maxy o estoy equivocado?
Reply
#3

No, si colocas el eje de coordenadas a la izquierda serнa tal como yo dije.

Si lo colocas a la derecha del rectбngulo, la azul serнa la equivalente a: (maxx, miny) y la roja serнa (minx, maxy).



Hay que tener en cuenta el origen del eje de coordenadas, depende de como lo pongas, puede variar o no. Pero en este caso, se mantienen los valores.

EDIT: lo que tu dices no estб del todo mal, pero serнa asн:
  • Esquina de la X roja: maxY - minX
  • Esquina debajo de la X roja: minY - minX
  • Esquina de la X azul: maxX - minY
  • Esquina encima de la X azul: maxX - maxY
Reply
#4

Quisiera compartir tambiйn una imagen que acabo de hacer. (Otra forma de sacar las coordenadas)



Donde la M es el punto de coordenada MaxX y MaxY y la m es el punto de coordenada minX y minY. Notece que la N es de norte y la S es de Sur
Reply
#5

Esa imagen tambiйn es correcta, lo que cambia respecto a la que yo puse, son las esquinas.

Un saludo.
Reply
#6

Buen tutorial, me diste una idea +rep
Reply
#7

No hay problema men, ya nos contarбs la idea (me gusta escuchar ideas ъnicas), jajaja...

Un saludo.

_________________________________________
Voy a poner esta explicaciуn aquн.



Tenemos el eje de coordenadas pasando por el centro del mapa, y un rectбngulo.

їCuales son las minX, minY, maxX, maxY? La respuesta es: depende de que esquinas miramos.

Si miramos A y C:
A: minX - maxY
C: maxX - minY


Si miramos D y B:
D: minX - minY
B: maxX - maxY
Reply
#8

Lindo bastante ъtiles las funciones de Streamer (vivo usбndolas jajaja).

Deberнas hacer un tutorial explicando otras funciones que casi nadie conoce de Streamer, quizбs alguna sea ъtil.
Reply
#9

Echarй un vistazo a ver que cosa necesita una explicaciуn detallada para hacer otro tutorial despuйs de terminar este.

Gracias EnzoMetlc, un saludo men.
Reply
#10

Lindo tutorial irinel , con funciones como estas uno puede divertirse creando cosas .
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)