Calumnia - RavenEye

Programación Orientada a Objetos (Tower defense - kingdom rush)

Moderator: julianmartinez16

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

PRE-ENTREGA

Post by David Ballesteros V » Tue Apr 02, 2019 2:50 am

PRE-ENTREGA CALUMNIA


-REPOSITORIO:
https://github.com/miguel9804/Calumnia

Image
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

WEEKLY MEETING #9

Post by David Ballesteros V » Thu Apr 04, 2019 11:29 pm

¿QUÉ HEMOS HECHO?
Hemos hablado sobre la organización de nuestro equipo ya que tomando las recomendaciones dadas en la pre-entrega vamos a re-estructurar el equipo para una mayor eficacia.

Image

¿QUÉ VAMOS A HACER?
Vamos a dedicarnos a la programación del juego en totalidad, sin dejar por aparte los acabados gráficos, completaremos y arreglaremos los enemigos y torres.

¿QUÉ DIFICULTAD HEMOS TENIDO?
La compra de torres no ha podido ser solucionada.
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

WEEKLY MEETING #10

Post by David Ballesteros V » Tue Apr 09, 2019 7:19 pm

¿QUÉ HEMOS HECHO?
Se ha empezado a trabajar más equitativamente respecto a la programación:

-Vida Enemigos:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Barra_Vida : MonoBehaviour
{
    public GameObject Enemigo;
    public GameObject Barra;
  
    SpriteRenderer sr;
    private Vector3 Completa;
    public Unidad colision;

    public Animator anim;
    private Rigidbody rb;
    public int vida;

    // Use this for initialization
    void Start()
    {
        rb = colision.GetComponent<Rigidbody>();
        anim = GetComponent<Animator>();
        anim.SetInteger("EstadoVida", 100);

        sr = Completa.GetComponent<SpriteRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        vida = anim.GetInteger("EstadoVida");
        Debug.Log(this.name + vida);

        anim.SetInteger("EstadoVida", vida);

        if (colision.impacto == 1)
        {

            vida = anim.GetInteger("EstadoVida");
            anim.SetInteger("EstadoVida", vida - 20);

        }

        if (colision.impacto == 2)
        {
            vida = anim.GetInteger("EstadoVida");
            anim.SetInteger("EstadoVida", vida - 10);

        }
        
        if (vida < 0 || vida < -1 || vida == -10)
        {
            vida = anim.GetInteger("EstadoVida");
            anim.SetInteger("EstadoVida", vida * 0);
            vida = 0;

            if (vida < 0 && vida < -1 && vida == -10)
            {
                vida = anim.GetInteger("EstadoVida");
                anim.SetInteger("EstadoVida", vida * 0);
                vida = 0;
            }

        }


        if (vida == 0)

        {
            colision.muerte = true;

            if (colision.muerte == true)
            {

                colision.numero_muertes = colision.numero_muertes + 1;
                vida = anim.GetInteger("EstadoVida");
                anim.SetInteger("EstadoVida", vida + 100);
                Debug.Log(vida);
                Muerte();

                if (vida < 0 && vida < -1 && vida == -10)
                {
                    vida = anim.GetInteger("EstadoVida");
                    anim.SetInteger("EstadoVida", vida * 0);
                }

            }



        }

        if (vida < 0 && vida < -1 && vida == -10)
        {
            vida = anim.GetInteger("EstadoVida");
            anim.SetInteger("EstadoVida", vida * 0);
        }


        if (colision.numero_muertes == colision.muerte_definitiva)

        {
            colision.transform.position = colision.posicion_inicial;

        }


    }


    public void Muerte()

    {


        colision.indice = 0;
        colision.transform.position = colision.posicion_inicial;
        colision.posicion_siguiente = colision.ruta.transform.GetChild(colision.indice).position;
        Debug.Log("Muerte");
        colision.muerte = false;


    }
}
¿QUÉ VAMOS A HACER?
Implementación de nuevos códigos como la vida de los enemigos, la torre #3 y arreglos de algunos anteriores.

¿QUÉ DIFICULTADES HEMOS TENIDO?
Falta de comunicación dentro del equipo.
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

User avatar
xacarana
Site Admin
Posts: 1194
Joined: Fri Jan 15, 2016 6:13 pm

Re: Calumnia - RavenEye

Post by xacarana » Thu Apr 11, 2019 1:26 pm

Image
David muy bien

Image
Publicar avance de prorgamación y contar que sucedio, ya que no participo del sprint.
Andrés Bedoya Tobón
Profesor
"I only smile in the dark, I only smile when it's complicated" Raybiez

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

WEEKLY MEETING #10.2

Post by David Ballesteros V » Thu Apr 11, 2019 11:20 pm

¿QUÉ HEMOS HECHO?
Hemos empezado a meter de nuevo mano en animaciones y acabados visuales.
Image

¿QUÉ VAMOS A HACER?
Re-organizaremos algunos códigos y empezaremos a pensar en más acabados artísticos.

¿QUÉ DIFICULTADES HEMOS TENIDO?
Atraso en códigos, pero no tan significativos.
Last edited by David Ballesteros V on Tue Apr 23, 2019 11:56 pm, edited 1 time in total.
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

WEEKLY MEETING #11

Post by David Ballesteros V » Tue Apr 23, 2019 11:29 pm

ACTIVIDAD VIRTUAL (DÍA SIN CARRO)

Consulta acerca de Cardinalidad y tipos de relaciones; Tomamos como referencia el siguiente SlideShare:

https://es.slideshare.net/jmachado614/d ... s-63504919

-Nuestro Diagrama de clases:
Image
PD: Me comí algunos datos Estáticos y no creí necesario implementar cardinalidad.

¿QUÉ HEMOS HECHO?
Se ha trabajado en arreglos de algunos códigos; Enemigos, Oleadas y Torres, modificando la muerte de los enemigos con un Remove y las Oleadas con un List en vez de un ArrayList.

-Enemigos-Remove:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemigos : MonoBehaviour
{
    public GameObject ruta;
    private int indice;
    private Vector3 pos_siguiente;
    public float vel;
    private float dis_punto = 0.5f ;
    [SerializeField]
    private int vida;
    private const string FLECHA = "Flecha";
    private const string BASE = "Base";
    private const string AURA = "Aura";
  
    

    void Start()
    {
        pos_siguiente = ruta.transform.GetChild(0).position;
    }



    void Update()
    {
        Vector3 dir = pos_siguiente - this.transform.position;
        this.transform.position += dir * vel * Time.deltaTime;
        //this.transform.position = this.transform.position+("")
  
            if (dir.magnitude <= dis_punto)
            {
                if (indice + 1 < ruta.transform.childCount)
                {
                    indice++;
                    pos_siguiente = ruta.transform.GetChild(indice).position;
                    //Debug.Log("xs= " + pos_siguiente.x + ", ys= " + pos_siguiente.y);
                }
                else
                {
                    indice = 0;
                    this.transform.position = pos_siguiente;
                    pos_siguiente = ruta.transform.GetChild(0).position;
                }
            }
       
        
    }
    void Muerte()
    {
        Oleadas.Enemigos.Remove(this.gameObject);
        Destroy(this.gameObject);
       
    }
   
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag.Equals(FLECHA))
        {

            Debug.Log("La vida es: " + vida);
            vida = vida - 2;
            if (vida <= 0)
            {
                
                Muerte();
                
            }
        }
        if (collision.gameObject.tag.Equals(AURA))
        {
            vida = vida - 3;
            Debug.Log("La vid es:" + vida);
            if(vida<=0)
            {
                
                Muerte();
            }
            
        }
        if (collision.gameObject.tag.Equals(BASE))
        {
            
            Muerte();
        }
        
    }
    
    
}
-Oleadas-List

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Oleadas : MonoBehaviour {
    private static List<GameObject> enemigos = new List<GameObject>();
    [SerializeField]
    private GameObject enemigo1;
    [SerializeField]
    private GameObject enemigo2;
    [SerializeField]
    private GameObject enemigo3;
    [SerializeField]
    private Transform spawn;
    private int waves = 5;
    private int contador = 0;
    private static int seg = 0;
    private static int inicio_oleada = 100;

    public static List<GameObject> Enemigos
    {
        get
        {
            return enemigos;
        }

        set
        {
            enemigos = value;
        }
    }

    void Oleada1()
    {
        GameObject temp;
        Vector3 pos_inicial = spawn.position;
        Vector3 incremento = new Vector3(0, -5);
        Vector3 n = new Vector3(0, -10);
        for(int i=0;i<2;i++)
        {
            temp = Instantiate(enemigo1, pos_inicial + incremento, Quaternion.identity);
            pos_inicial = temp.transform.position;
            Enemigos.Add(temp);
        }
            
        
    }
    void Oleada2()
    {
        GameObject temp;
        Vector3 pos_inicial = spawn.position;
        Vector3 incremento = new Vector3(0, -5);
        for (int i = 0; i < 4; i++)
        {
            temp = Instantiate(enemigo1, pos_inicial + incremento, Quaternion.identity);
            pos_inicial = temp.transform.position;
            Enemigos.Add(temp);
        }
    }
    void Oleada3()
    {
        GameObject temp;
        GameObject temp2;
        Vector3 pos_inicial = spawn.position;
        Vector3 incremento = new Vector3(0,-5); 
        for(int i =0; i<4;i++)
        {
            temp = Instantiate(enemigo1, pos_inicial + incremento, Quaternion.identity);
            pos_inicial = temp.transform.position;
            Enemigos.Add(temp);
            if (i>=2)
            {
                temp2 = Instantiate(enemigo2, pos_inicial + incremento, Quaternion.identity);
                pos_inicial = temp2.transform.position;
                Enemigos.Add(temp2);
            }

        }

    }
    void Oleada4()
    {
        GameObject temp;
        GameObject temp2;
        Vector3 pos_inicial = spawn.position;
        Vector3 incremento = new Vector3(0, -5);
        for (int i = 0; i < 6; i++)
        {
            temp = Instantiate(enemigo1, pos_inicial + incremento, Quaternion.identity);
            pos_inicial = temp.transform.position;
            Enemigos.Add(temp);
            if (i >= 3)
            {
                temp2 = Instantiate(enemigo2, pos_inicial + incremento, Quaternion.identity);
                pos_inicial = temp2.transform.position;
                Enemigos.Add(temp2);
            }

        }

    }
    void Oleada5()
    {
        GameObject temp;
        GameObject temp2;
        GameObject temp3;
        Vector3 pos_inicial = spawn.position;
        Vector3 incremento = new Vector3(0, -5);
        for (int i = 0; i < 4; i++)
        {
            temp = Instantiate(enemigo1, pos_inicial + incremento, Quaternion.identity);
            pos_inicial = temp.transform.position;
            Enemigos.Add(temp);
            if (i >= 2)
            {
                temp2 = Instantiate(enemigo2, pos_inicial + incremento, Quaternion.identity);
                pos_inicial = temp2.transform.position;
                Enemigos.Add(temp2);
                
            }
            if (i == 3)
            {
                temp3 = Instantiate(enemigo3, pos_inicial + incremento, Quaternion.identity);
                pos_inicial = temp3.transform.position;
                Enemigos.Add(temp3);
            }


        }

    }
    


    // Update is called once per frame
    void Update () {
       
        if (Enemigos.Count == 0)
        {
            seg += 1;
            Debug.Log(seg);
            
            if (seg > inicio_oleada)
            {
                contador++;
                seg = 0;
                if (contador == 1)
                {
                    Oleada1();
                    Debug.Log("Oleada 1");

                }
                else if (contador == 2)
                {
                    Oleada2();
                    Debug.Log("Oleada 2");
                }
                else if (contador == 3)
                {
                    Oleada3();
                    Debug.Log("Oleada 3");
                }
                else if (contador == 4)
                {
                    Oleada4();
                    Debug.Log("Oleada 4");
                }
                else if (contador == 5)
                {
                    Oleada5();
                    Debug.Log("Oleada 5");
                }
                if(contador>waves)
                {
                    SceneManager.LoadScene("Ganar");
                }

            }
            
        }
        

    }
}
-Torres:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Torres : MonoBehaviour {
    private GameObject enemigo;
    private float UmbraldeDistancia = 3f;
    [SerializeField]
    private GameObject disparo;
    private  float seg;

    public GameObject Enemigo
    {
        get
        {
            return enemigo;
        }

        set
        {
            enemigo = value;
        }
    }

    void Start()
    {
        
        seg=30f;
    }
    GameObject BuscarEnemigos()
    {
        List<GameObject> objetivos = Oleadas.Enemigos;
        GameObject temp;
        foreach(Object item in objetivos)
        {
            temp = (GameObject)item;
            if (Vector3.Distance(temp.transform.position, this.transform.position)<UmbraldeDistancia)
            {
                
                return temp;
            }
        }
        return null;
    }
    void Disparar()
    {
        GameObject obj = Instantiate(disparo, this.transform.position, Quaternion.identity);
        Flechas flecha = obj.GetComponent<Flechas>();
        flecha.ActivarFlecha(this);
    }
    
    // Update is called once per frame
    void Update()
        
    {
        seg += 1 + Time.deltaTime;
        Enemigo = BuscarEnemigos();
        if(seg>30f)
        {
            seg = 0f;
            

            if (Enemigo != null)
            {

                Disparar();
                //Debug.Log("Disparo");
                Debug.DrawLine(this.transform.position, enemigo.transform.position, Color.green);

            }
        }
        

    }
}
¿QUÉ VAMOS A HACER?
Vamos a retomar con la parte visual del juego.

¿QUÉ DIFICULTADES HEMOS TENIDO?
No se tuvo suficiente tiempo para hacer avances más significativos por la disponibilidad de los integrantes.
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

WEEKLY MEETING #11.2

Post by David Ballesteros V » Thu Apr 25, 2019 11:12 pm

¿QUÉ HEMOS HECHO?
Se ha trabajado en el arte de la base, el cuadro de elección de torres y el ataque de la torre#2, se han arreglado los siguientes códigos y se agregó por fin la compra de torres:

-Compra de Torres:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Moneda : MonoBehaviour {

    public GameObject centenas, decenas, unidades;
    private Animator ce, de, un;
    private string[] estado = { "Moneda_0", "Moneda_1", "Moneda_2", "Moneda_3", "Moneda_4", "Moneda_5", "Moneda_6", "Moneda_7", "Moneda_8", "Moneda_9" };
    private float tiempoLimite = 50f;
    private float tiempo = 0f;
    private int dinero;
    private bool compro;
    private static Moneda instancia = new Moneda();
    

    public int Dinero
    {
         get
         {
            return dinero;
         }

        set
        {
            dinero = value;
        }
    }

    public bool Compro
    {
        get
        {
            return compro;
        }

        set
        {
            compro = value;
        }
    }

    public static Moneda Instancia
    {
        get
        {
            return instancia;
        }

        set
        {
            instancia = value;
        }
    }




    // Use this for initialization
    void Start()
    {
        ce = centenas.GetComponent<Animator>();
        de = decenas.GetComponent<Animator>();
        un = unidades.GetComponent<Animator>();
        Instancia.Dinero = 50;

        ActualizadorContador(Instancia.Dinero);
    }
    

   

    // Update is called once per frame
    void Update()
    {

        
        
         if(Instancia.Compro==true)
         {
            ActualizadorContador(Instancia.Dinero);
            tiempo++;
           if (tiempo > tiempoLimite)
           {

            Instancia.Dinero ++; 
            ActualizadorContador(Instancia.Dinero);
            tiempo = 0;
           }
         }


    }
    public void ActualizadorContador(int numero)
    {
        int unidades = numero % 10;
        int decenas = numero % 100 - unidades;
        int centenas = numero % 1000 - decenas;
        //Debug.Log("numero " + numero + " centenas " + centenas / 100 + " decenas " + decenas / 10 + " unidades " + unidades);

        decenas = decenas / 10;
        centenas = centenas / 100;

        if (numero > 9)
        {
            de.Play(estado[decenas]);
        }
        else
        {
            de.Play(estado[0]);
        }

        if (numero > 99)
        {
            ce.Play(estado[centenas]);
        }
        else
        {
            ce.Play(estado[0]);
        }
        un.Play(estado[unidades]);

    }
}
-Torre #3:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class T_Barrera : LogicaTorres
{
    [SerializeField]
    private GameObject letrero;

    public override void OnMouseDown()
    {
        if (Moneda.Instancia.Dinero >= 60)
        {
            Moneda.Instancia.Dinero -= 60;

            Moneda.Instancia.Compro = true;
            GameObject temp;
            Vector3 pos = this.transform.position;
            pos.y = pos.y + y;
            pos.x = pos.x + x;
            temp = Instantiate(torre);
            temp.transform.position = pos;
            temp.layer = 5;
            Destroy(letrero.gameObject);
        }


    }
}
-Letrero para elegir Torre:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class T_Letrero : LogicaTorres
{
    public override void OnMouseDown()
    {
        GameObject temp;
        Vector3 pos = this.transform.position;
        pos.y = pos.y + y;
        pos.x = pos.x + x;
        temp = Instantiate(torre);
        temp.transform.position = pos;
        temp.layer = 5;
        Destroy(this.gameObject);
    }
}
-Lógica Torres:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class  LogicaTorres : MonoBehaviour {

    // Use this for initialization
    [SerializeField]
    protected GameObject torre;
    [SerializeField]
    protected float y;
    [SerializeField]
    protected float x;
    

    public abstract void OnMouseDown();
    
}
-Torre#2:

Code: Select all

public class T_Iglesia : LogicaTorres
{
    [SerializeField]
    private GameObject letrero;

    public override void OnMouseDown()
    {
        if (Moneda.Instancia.Dinero >= 75)
        {
            Moneda.Instancia.Dinero -= 75;

            Moneda.Instancia.Compro = true;
            GameObject temp;
            Vector3 pos = this.transform.position;
            pos.y = pos.y + y;
            pos.x = pos.x + x;
            temp = Instantiate(torre);
            temp.transform.position = pos;
            temp.layer = 5;
            Destroy(letrero.gameObject);
        }


    }
}
-Torre #1:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class T_Arcos : LogicaTorres
{
    [SerializeField]
    private GameObject letrero;

    public override void OnMouseDown()
    {
        if(Moneda.Instancia.Dinero>=50)
        {
            Moneda.Instancia.Dinero -= 50;
            
            Moneda.Instancia.Compro = true;
            GameObject temp;
            Vector3 pos = this.transform.position;
            pos.y = pos.y + y;
            pos.x = pos.x + x;
            temp = Instantiate(torre);
            temp.transform.position = pos;
            temp.layer = 5;
            Destroy(letrero.gameObject);
        }
        

    }

}
-Ataque Torre #2:

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Iglesia : MonoBehaviour
{
    [SerializeField]
    private GameObject aura;
    [SerializeField]
    private Transform creacion;
    [SerializeField]
    private float tiempo_aura;
    private bool activar;
    public static int seg;
    private const string ENEMIGO = "Enemigo";

    private void Start()
    {
        seg = 300;
    }
    void Update()
    {
        seg = 1 + seg;
       
        if (seg > 300)
        {
            activar = true;
           
        }
        else
        {
            activar = false;
        }

    }
    private void ActivarAura()
    {
        GameObject crear_aura = Instantiate(aura, creacion.position, creacion.rotation);
        Destroy(crear_aura.gameObject, tiempo_aura);

    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.tag.Equals(ENEMIGO))
        {
            if(activar == true)
            {
                ActivarAura();
                seg = 0;
            
            }
        }
    }
   
}
¿QUÉ VAMOS A HACER?
Empezaremos a prestarle más atención al HUD del juego y empezar a implementar power ups.

¿QUÉ DIFICULTADES HEMOS TENIDO?
Ninguna en esta semana.
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

WEEKLY MEETING #12

Post by David Ballesteros V » Tue Apr 30, 2019 10:58 pm

¿QUÉ HEMOS HECHO?
Se ha estado trabando en los estados de vida de enemigos y torre respecto a la animación y hemos decidido dejar por aparte la creación de banda sonora por ahora.

-Ataque torre#3 Frente:
Image

-Ataque torre#2 sin partículas (Las particulas son agregadas en Unity):
Image

-Ataque torre#1:
Image

¿QUÉ VAMOS A HACER?
Se va a implementar los que vendrían siendo unos power ups.

¿QUÉ DIFICULTADES HEMOS TENIDO?
Last edited by David Ballesteros V on Fri May 03, 2019 10:32 pm, edited 3 times in total.
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

User avatar
xacarana
Site Admin
Posts: 1194
Joined: Fri Jan 15, 2016 6:13 pm

Re: Calumnia - RavenEye

Post by xacarana » Thu May 02, 2019 12:35 pm

Image

Van muy bien, pero la última semana no hay publicaciones validas, recuerden que se debe publicar la evidencia del avance.

Image

¡¡Strike!!
Andrés Bedoya Tobón
Profesor
"I only smile in the dark, I only smile when it's complicated" Raybiez

User avatar
David Ballesteros V
Posts: 85
Joined: Fri Jul 22, 2016 11:04 am

WEEKLY MEETING #12.5

Post by David Ballesteros V » Thu May 02, 2019 11:18 pm

En este post ofrecemos disculpas ya que no se ha manejado bien el tiempo para obtener nuevos avances en cuanto a gráficas ni código, así que preferimos ponernos al día con lo prometido en las pasadas para así empezar de nuevo con el pie derecho.

¿QUÉ DIFICULTADES HEMOS TENIDO?
No se ha manejado muy bien el tiempo que se invierte en este proyecto, ya que se han tenido entregas con una mayor exigencia, esperamos retomar de buena manera este proyecto.

-Se ha estado modificando el post anterior.
David Ballesteros Villa
Fundamentos De Programación - P.O.O

-Contacto:
Correo: Personal: dsktod@gmail.com Institucional: david.ballesteros@upb.edu.co
Redes: www.instagram.com/davidballev

Post Reply