Comportamiento extraño de las líneas de mis figuras

Hola! Soy nuevo y estoy aprendiendo por mi mismo, pero estoy teniendo bastantes problemas: estoy haciendo un juego muy sencillo y creo yo que con código muy rudimentario. Quiero que aparezca una imagen durante cierto tiempo, junto con su texto, pero no lo logro; además las líneas de las figuras se empiezan a dibujar desde el vértice superior izquierdo de la pantalla… ¿me podrían ayudar por favor?

boolean space,up,down,left,right;
float x=300,y=450, h=50;//Tamaño personaje
float vidaE=0, vE=0,vida=100;
float speedY=1; //Rapidez del cuadro
float speedX=1;

float Damage=0,Porcentaje=0;//Daño
int Punteria=0;//Acierta o no el ataque
int Precision=0;

int CFondo=0;//Inicializa el escenario

int Tecnica=0,TecnicaE=0;//Ataques a realizar
float TEnemigo=0;
int Ataque=1,Defensa=1,Constitucion=0;//Puntos del personaje
PShape Punch;//Técnica 1
PImage Kick;//Técnica 2

boolean A=true;//Aparece menú y su texto, además del personaje
boolean B=false;//Permite cambios de escenario
boolean D=true;//Inicialización de la vida enemigos
boolean E=false;//Ataque realizado
boolean F=false;//El enemigo solo puede morir una vez
boolean G=false;

int C=0;//Aparecen enemigos o no

int T1_X,T1_Y;//Botón1
int T2_X,T2_Y;//Botón2
int T3_X,T3_Y;//Botón3
int T4_X,T4_Y;//Botón4

int rectW,rectH;//Tamaño botones
color rectColor;//Color botón
color rectHighlight;//Sombrea botón
boolean rectOver1=false;
boolean rectOver2=false;
boolean rectOver3=false;
boolean rectOver4=false;

float Tiempo=millis();
float TimePast=0;

void setup()
{
  size(1000,600);
  background(0);
  
  rectColor = color(255);//Blanco
  rectHighlight = color(150);//Gris
  rectW=270;
  rectH=70;
  
  T1_X=20;
  T1_Y=420;
  T2_X=20;
  T2_Y=500;
  T3_X=300;
  T3_Y=420;
  T4_X=300;
  T4_Y=500;
  
  Punch=loadShape("Golpe.svg");
  Kick=loadImage("Patada.png");
}

void draw()
{
  println(x,y,mouseX,mouseY);//Imprimir en consola posición del personaje y del mouse
  println(Porcentaje,Punteria,Damage,Ataque,Tecnica);
  println(rectOver1,rectOver2,rectOver3,rectOver4);
  
  CambiosFondo();
  if(A)
  {
    Personaje();
    Menu();
  }
  Movimiento();
  Limite();
}

void keyPressed()
{
  if(keyCode==32)
  {
    space=true;
  }
  if(keyCode==UP)
  {
    up=true;
  }
  if(keyCode==DOWN)
  {
    down=true;
  }
  if(keyCode==LEFT)
  {
    left=true;
  }
  if(keyCode==RIGHT)
  {
    right=true;
  }
}

void keyReleased()
{
  if(keyCode==UP)
  {
    up=false;
  }
  if(keyCode==32)
  {
    space=false;
  }
  if(keyCode==DOWN)
  {
    down=false;
  }
  if(keyCode==LEFT)
  {
    left=false;
  }
  if(keyCode==RIGHT)
  {
    right=false;
  }
}

void Damage()
{
  if(G)
  {
  switch(Tecnica)
  {
    case 1://Puñetazo
    {
      Damage=random(5*Ataque,15*Ataque);
      Damage=round(Damage);
      Precision=80;
      Punteria();
      
      if(Punteria!=0)
      {
        shape(Punch,725,175,50,50);
        textSize(30);
        fill(#B90205);
        text(Damage,700,125);
      }
      else
      {
        textSize(30);
        text("Miss",700,125);
      }
      vidaE=vidaE-Damage;
      Tecnica=0;
      G=false;
      break;
    }
    case 2://Patada
    {
      Damage=random(10*Ataque,15*Ataque);
      Damage=round(Damage);
      Precision=50;
      Punteria();
      
      if(Punteria!=0)
      {
        image(Kick,725,175,50,50);
        textSize(30);
        fill(#B90205);
        text(Damage,700,125);
      }
      else
      {
        textSize(30);
        text("Miss",700,125);
      }
      vidaE=vidaE-Damage;
      Tecnica=0;
      G=false;
      break;
    }
  }
  }
}

void Punteria()
{
  Porcentaje=random(0,100);
  round(Porcentaje);
  if(Porcentaje<=Precision)
  {
    Punteria=1;
  }
  else
  {
    Punteria=0;
  }
  Damage=Damage*Punteria;
  Precision=0;
}

void CambiosFondo()
{
  switch(CFondo)
  {
    case 0:
    {
      PantallaINICIO();
      break;
    }
    case 1:
    {
      CASA();
      break;
    }
    case 2:
    {
      EntradaCUEVA();
      break;
    }
    case 3:
    {
      CUEVA();
      break;
    }
    case 100:
    {
      PantallaPelea();
      break;
    }
    case 101:
    {
      PantallaGanasteP();
      break;
    }
    default:
    {
      PantallaMoriste();
      break;
    }
  }
}

void PantallaINICIO()
{
  A=false;//Desaparece personaje y menu
  background(0);//Negro
  fill(#02D803);//Verde
  textSize(40);
  text("ADVENTURE QUEST MX",300,200);
  textSize(20);
  text("Presiona cualquier tecla para empezar",300,350);
  if(keyPressed)//Si hace click, se inicia
  {
    CFondo=1;//Casa
    A=true;//Aparece el personaje y el menu
  }
}

void PantallaPelea()
{
  background(0);//Negro
  A=false;//Desaparece el menu y el personaje
  
  stroke(0);//Negro
  fill(155);//Gris
  ellipse(200,400,300,300);//Suelo
  ellipse(750,200,300,250);
  
  Vida();//Aparece las barras de vida
  
  fill(#0007AD);//Azul
  rect(0,400,width,200);//Menu pelea

  Botones();

  fill(255);//Blanco
  stroke(0);//Negro
  rect(150,300,100,100);//Personaje

  switch(C)//Selecciona que enemigo debe aparecer
  {
    case 0://Enemigo ECueva
    {
      fill(#F00004);//Rojo
      rect(700,150,100,100);
    }
  }
  Damage();
  Enemigo();
}

void PantallaGanasteP()
{
  A=false;//Desaparece personaje y menu
  
  speedX=0;
  speedY=0;
  background(0);//Negro
  fill(#FFD900);//Amarillo
  textSize(70);
  text("¡Ganaste la pelea!",width/5,height/3);
  textSize(45);
  text("Presione barra espaciadora",width/5,400);
    
  if(space)//Para continuar
  {
    CFondo=2;//ECueva
    A=true;//Aparece menu y personaje
    speedX=1;
    speedY=1;
    x=600;
    y=300;
  }
}

void PantallaMoriste()
{
  A=false;
  background(155);//Gris
  speedX=0;
  speedY=0;
  fill(#B90205);//Rojo sangre
  textSize(70);
  text("¡Moriste!",width/3,height/3);
  textSize(45);
  text("¿Otra vez?Presione click",width/4+40,400);
  
  if(mousePressed)//Reinicia
  {
    CFondo=1;//Casa
    A=true;//Aparece menu y personaje
    C=0;//Reinicia a los enemigos
    D=true;//Reinicia vida de los enemigos
    vida=100;
    speedX=1;
    speedY=1;
    x=300;
    y=450;
  }
}

void CASA()
{
  background(0);//Negro  
  fill(#02D803);//Verde
  stroke(#02D803);//Verde
  rect(250,300,width-250,height-300);//Camino
  
  fill(#02B2B9);//Azul
  stroke(#02B2B9);//Azul
  rect(350,200,100,100);//Casa
  rect(550,200,100,100);
  rect(450,200,100,25);
  rect(300,150,400,50);
  rect(350,100,300,50);
  rect(575,50,25,50);

  B=true;
  if(B)//Permite cambios de fondo
  {
    if((x>=470&&x<=525)&&y<=275)//Entrada casa
    {
      CFondo=99;//Pantalla moriste
      x=300;
      y=450;
      B=false;//Permite cambio solo una vez
    }
    
    if(x>=width-50)//Borde derecho
    {
      CFondo=2;//ECueva
      x=300;
      y=450;
      B=false;//Permite cambio solo una vez
    }
  }
}

void EntradaCUEVA()
{
  background(0);//Negro  
  fill(#02D803);//Verde
  stroke(#02D803);//Verde
  rect(250,300,width-250,height-300);//Camino
  
  fill(155);//Gris
  stroke(155);//Gris
  rect(550,0,450,200);//Cueva
  rect(500,50,50,250);
  rect(400,100,100,200);
  rect(350,250,50,50);
  rect(650,200,350,100);

  if(C<1)//Hace aparecer al enemigo
  {
    stroke(0);//Negro
    fill(#F00004);//Rojo
    rect(575,250,50,50);//Enemigo
  }
  
  B=true;
  if(B)//Permite los cambios de fondo una vez
  {
    if(x<=width-750)//Borde izquierdo
    {
      CFondo=1;//Casa
      x=900;
      y=450;
      B=false;//Permite el cambio solo una vez
    }
    
    if((x>=550&&x<=650)&&y<=275)//Entrada Cueva
    {
      if(C<1)//Si hay enemigo
      {
        CFondo=100;//Fondo pelea
      }
      else if(C>=1)//Si no hay enemigo
      {
        CFondo=3;//Cueva
        x=300;
        y=450;
        B=false;//Permite el cambio una sola vez
      }
    }
  }
}

void CUEVA()
{
  background(155);//Gris  
  fill(#02D803);//Verde
  stroke(#02D803);//Verde
  rect(250,300,width-250,height-300);//Camino
  
  fill(255);//Blanco
  stroke(255);//Blanco
  rect(250,400,100,100);//Salida
  
  B=true;
  if(B)//Permite cambio de pantalla
  {
    if(x<=250 && (y>=400&&y<=475))//Salida Cueva
    {
      CFondo=2;//ECueva
      x=575;
      y=300;
      B=false;//Permite cambio solo una vez
    }
  }
}

void Menu()
{
  fill(#0007AD);//Azul
  stroke(0);//Negro
  rect(0,0,250,height);//Menú

  Vida();//Hace aparecer la vida del personaje en el menú principal

  fill(150);//Gris
  rect(20,100,100,100);
  rect(130,100,100,100);
  rect(20,210,100,100);
  rect(130,210,100,100);
  rect(20,320,100,100);
  rect(130,320,100,100);
}


void Enemigo()
{
  if(CFondo==100 && G==false)
  {
    TEnemigo=random(1,2);
    TecnicaE=round(TEnemigo);
    switch(TecnicaE)
    {
      case 1://Puñetazo
      {
        Damage=random(5*Ataque,15*Ataque);
        Damage=round(Damage);
        Punteria();
      
        if(Punteria!=0)
        {
          shape(Punch,175,325,50,50);
          textSize(30);
          fill(#B90205);
          text(Damage,150,275);
        }
        else
        {
          textSize(30);
          text("Miss",150,275);
        }
        vida=vida-Damage;
        TecnicaE=0;
        G=true;
        break;
      }
      case 2://Patada
      {
        Damage=random(10*Ataque,15*Ataque);
      Damage=round(Damage);
      Precision=50;
      Punteria();
      
      if(Punteria!=0)
      {
        image(Kick,175,325,50,50);
        textSize(30);
        fill(#B90205);
        text(Damage,150,275);
      }
      else
      {
        textSize(30);
        text("Miss",700,125);
      }
      vidaE=vidaE-Damage;
      Tecnica=0;
      G=true;
      break;
      }
    }
  }
}

void Movimiento()
{
  if(space)
  {
  }
  if(A)
  {
    if(up)
    {
      y=y-3*speedY;
    }
    if(down)
    {
      y=y+3*speedY;
    }
    if(right)
    {
      x=x+3*speedX;
    }
    if(left)
    {
      x=x-3*speedX;
    }
  }
}

void Limite()
{
  x=constrain(x,250,width-50);
  y=constrain(y,250,height-50);
}

void Personaje()
{
  stroke(0);//Personaje
  fill(255);
  rect(x,y,50,h);
}

void Botones()
{
  update(mouseX, mouseY);
  stroke(0);//Negro
//________________________________________
  if(rectOver1)
  {
    fill(rectHighlight);
  }
  else
  {
    fill(rectColor);
  }
  rect(T1_X,T1_Y,rectW,rectH);
//________________________________________
  if(rectOver2)
  {
    fill(rectHighlight);
  }
  else
  {
    fill(rectColor);
  }
  rect(T2_X,T2_Y,rectW,rectH);
//________________________________________
  if(rectOver3)
  {
    fill(rectHighlight);
  }
  else
  {
    fill(rectColor);
  }
  rect(T3_X,T3_Y,rectW,rectH);
//________________________________________
  if(rectOver4)
  {
    fill(rectHighlight);
  }
  else
  {
    fill(rectColor);
  }
  rect(T4_X,T4_Y,rectW,rectH);
//________________________________________

  fill(0);//Negro
  text("Puñetazo",100,460);
  text("Patada",100,540);
  text("Codazo",400,460);
  text("Rodillazo",400,540);
}

void update(int X, int Y)
{
  if(overRect(T1_X,T1_Y,rectW,rectH))
  {
    rectOver1=true;
  }
  else if(overRect(T2_X,T2_Y,rectW,rectH))
  {
    rectOver2=true;
  }
  else if(overRect(T3_X,T3_Y,rectW,rectH))
  {
    rectOver3=true;
  }
  else if(overRect(T4_X,T4_Y,rectW,rectH))
  {
    rectOver4=true;
  }
  else
  {
    rectOver1=false;
    rectOver2=false;
    rectOver3=false;
    rectOver4=false;
  }
}
void mousePressed()
{
  if(CFondo==100)//Si están en pantalla de pelea habilita sus botones 
  {
      if(rectOver1)
      {
        Tecnica=1;
      }
      if(rectOver2)
      {
        Tecnica=2;
      }
      if(rectOver3)
      {
        Tecnica=3;
      }
      if(rectOver4)
      {
        Tecnica=4;
      }
  }
}

boolean overRect(int X, int Y, int width, int height)
{
  if (mouseX >= X && mouseX <= X+width && mouseY >= Y && mouseY <= Y+height)
  {
    return true;
  }
  else
  {
    return false;
  }
}

void Vida()
{
  fill(150);//Gris
  rect(20,20,110,20);//FondoVida
  fill(#00FF0A);//Verde
  rect(25,25,vida,10);//BarraVida

  fill(255);
  textSize(15);
  text(vida,55,55);
  text("HP:",35,55);

  if(CFondo==100)//Si se acerca a un enemigo, muestra su barra de vida
  {
    fill(150);//Gris
    rect(1000-(vE+10),20,vE,20);//FondoVida
    fill(#F00004);//Rojo
    rect(1000-(vE+5),25,vidaE,10);//BarraVida
  
    fill(255);
    textSize(15);
    text(vidaE,900,55);
    text("HP:",880,55);
  }
  
  switch(C)//Determina la vida de cada enemigo
  {
    case 0://Enemigo ECueva
    {
      if(D)//Asignación de vida
      {
        vidaE=50;
        F=true;//Permite la muerte del enemigo
        vE=vidaE+10;//Variable para ajustar el tamaño de su barra de vida
        D=false;//Asigna la vida una sola vez
      }
    }
  }

  if(F)//Habilita la muerte del enemigo
  {
    if(vidaE<=0)//Determina cuando muere el enemigo
    {
      vidaE=0;//Asegura la muerte del enemigo
      CFondo=101;//Manda a la pantalla de Ganaste
      C=C+1;//Borra al enemigo de la pantalla de aventura
      F=false;//Si muere, ya no puede morir otra vez
    }
  }

  if(vida<=0)//Determina cuando el personaje muere
  {
    vida=0;//Asegura la muerte
    x=0;//Detiene el movimiento
    CFondo=99;//Manda a la pantalla moriste
  }
}
1 Like

Hola @anon12363945, tu código es muy largo para analizarlo en detalle, pero referente a lo que comentas:

Esto es porque así está definido en processing, el centro de coordenadas está en la esquina superior izquierda, pero lo puedes cambiar usando la funcion translate(nuevoOrigenX,nuevoOrigenY);, por ejemplo, si lo prefieres desde la esquina inferior izquierda, sería: translate(0,height); y todo lo que escribas después tomará ese punto como referencia y si quieres que los ejes vayan hacia arriba, también puedes añadir la funcion scale(escalaX,escalaY);, que multiplica todo lo relativo a “x” e “y” de las funciones (por ejemplo rect(x,y,anchura,altura); ) por esos valores (también es muy útil para meter zoom), entonces para cambiar el sentido del eje Y, podrías usar: scale(1,-1); y listo. Para resetear estas escalas y traslaciones (también rotaciones si las utilizas) puedes usar los comandos relativos a matrix, como resetMatrix(); que inicializa los ejes de coordenadas a los del principio, hay también más opciones como pushMatrix(); pushStyle(); popMatrix(); pushStyle(); que son bastante útiles, miralas en la referencia o pregunta si necesitas más ayuda en este tema :wink:.

En cuanto a

Hay varias maneras de hacerlo pero una sencillita que se me ocurre es usando un timer y un if, royo:

if(tiempo < 1000){
 image(...);
 text(...);
}

Y bueno, se puede personalizar más en función de lo que quieras realmente, hay varias opciones, por ejemplo que tengas varias imagenes que quieras presentar x tiempo, puedes usar contadores float tiempo1, tiempo2, etc; puedes controlar ese tiempo en segundos o según los fps a los que se ejecute tu código, etc.

No dudes en preguntar lo que necesites, y parece muy chulo el juego :stuck_out_tongue:

3 Likes

Muchas gracias @Waboqueox ! Probaré tu idea:

Con lo de las líneas yo me refería a que pasa esto:

Aaaa, creo que eso es debido al .svg tal vez.
Cuando lo ejecuto yo (y comento el loadShape y el loadImage) a mi no me aprecen:

Igual le tienes que echar un ojo a tu shape (por desgracia no tengo mucha experiencia en cargar ficheros svg, pero igual en el archivo pone que empiecen las formas desde el 0,0 o algo que te de una pista de como solucionarlo )

1 Like

¡Muchas gracias! Convertí los fondos en imágenes que cargaré después.