Forum Discussion

edandresvan's avatar
edandresvan
Copper Contributor
Feb 08, 2023

Ejercicio: Dibujar círculos con macroquad

Primeros Pasos con Rust

 

Hola compañeros, si tienen un tiempo libre podrían ayudarme a terminar este corto programa con macroquad.

El objetivo es dibujar en varios círculos de radio aleatorio en filas sin exceder las dimensiones de la pantalla. Para esto estoy creando un iterator personalizado que tiene en cuenta los últimos valores de radio y posiciones x e y generadas, y que trata de verificar que el círculo se pueda dibujar dentro del ancho y el alto de la ventana.

 

Por el momento, mi programa dibuja los círculos en una diagonal. Creo que debo corregir el método next().

 

Gracias por su ayuda.

 

 

 

 

cargo new shapes --vcs none

 

 

 

 

 

 

 

[package]
name = "shapes"
version = "0.1.0"
rust-version = "1.67"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
macroquad = "0.3"
rand = "0.8"

 

 

 

 

main.rs:

 

 

 

 

use ::rand as ra;
use macroquad::{color, prelude::*};
use ra::Rng;
//use macroquad::rand::rand::prelude::*;

/// Representa un objeto para ubicar un círculo en la pantalla.
struct Posicionador {
  ultimo_r: f32,
  ultimo_x: f32,
  ultimo_y: f32,
  aleatorio: ra::rngs::ThreadRng,
}

impl Posicionador {
  /// Crea un nuevo objeto.
  fn new() -> Self {
    Self {
      ultimo_r: 0.0,
      ultimo_x: 0.0,
      ultimo_y: 0.0,
      aleatorio: ra::thread_rng(),
    }
  }
}

// Un iterador para crear varios círculos
impl Iterator for Posicionador {
  type Item = Circulo;

  fn next(&mut self) -> Option<Self::Item> {
    // Espacio entre los círculos
    let espacio: f32 = 15.0;

    // Crear un radio aleatorio
    let nuevo_radio: f32 = self.aleatorio.gen_range(20..101) as f32;

    // Verificar que las dimensiones del círculo no sobrepasen las dimensiones de la ventana
    if (nuevo_radio + self.ultimo_x > screen_width())
      || (nuevo_radio + self.ultimo_y > screen_height())
    {
      // Aquí un círculo ya no cabe en la pantalla, por lo que terminamos el iterador
      return None;
    }

    // Actualizar los valores para el recién círculo creado
    self.ultimo_r = nuevo_radio;
    self.ultimo_x += nuevo_radio + espacio;
    self.ultimo_y += nuevo_radio + espacio;

    // Retornar el círculo pedido
    Some(Circulo {
      radio: self.ultimo_r,
      color: color::GOLD,
      posicion: Punto {
        x: self.ultimo_x,
        y: self.ultimo_y,
      },
    })
  }
}

/// Representa la ubicación x e y de un círculo.
#[derive(Debug, Clone)]
struct Punto {
  x: f32,
  y: f32,
}

/// Representa un círculo geométrico.
struct Circulo {
  radio: f32,
  color: macroquad::color::Color,
  posicion: Punto,
}

impl Circulo {
  /// Dibuja el círculo en la pantalla
  fn dibujar(&self) {
    draw_circle(self.posicion.x, self.posicion.y, self.radio, self.color);
  }
}

#[macroquad::main("Figuras")]
async fn main() {
  // Iterador para crear los círculos
  let mut posicionador = Posicionador::new();
  // Vector de círculos
  let mut circulos: Vec<Circulo> = vec![];

  // Crear tantos círculos como el iterador permita.
  while let Some(circulo) = posicionador.next() {
    circulos.push(circulo);
  }

  loop {
    clear_background(LIGHTGRAY);

    // Dibujar los círculos generados
    for circulo in &circulos {
      circulo.dibujar();
    }

    next_frame().await
  }
}

 

 

 

 

 

 

 

 

  • elbruno's avatar
    elbruno
    Iron Contributor
    Wow, idea genial!

    Le doy un vistazo y si se me ocurre algo lo comparto, me agrada el challenge 😄

Resources