Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Duda Windows Forms Con Vs.net 03 Y C#

Iniciado por nsL, 16 de Febrero de 2006, 08:58:00 PM

« anterior - próximo »

nsL

 Ya veo.... joer como sabes todo eso jejejej, yo mire cosillas de msdn y clases y demas, pero vamos, lo de la cola no lo sakaria ni en mil años :P

Bueno, entos una vez resuelto la duda del porque, queda el como. Si se van metiendo en la cola los repintados que ha de hacer, y cada uno de ellos respecto a un par (x,y), no puedo ir modificando esas variables, ya que entonces pasa lo de ahora, q repinta N veces en la ultima coordenada.....

Es que si me fijo, este problema solo lo tendre al cargar inicialmente el mapa vacio, ya que luego voy dibujando tile a tile, y solo se hace un invalide por evento, asi q no hay mas en la cola.

Tu como has hecho para solucionar esto? :P, para pintar todos al principio. Se me ocurre pintar todos sin hacer invalidates y hacer un invalidate final a todo el panel. Pero no se como acceder a la estructura Graphics desde algun sitio q no sea una funcion de eventos, para que me proporcione el PaintEventArgs.

Saludos! y gracias de nuevo :P
Yo no muero hasta la muerte -

zupervaca

 Para pintar todos los bloques debes de tener un array con todos los bloques e ir con un for pintandolos, es decir:

int [,] bloques = new int[100,100];
... (inicializar los bloques con valores)

// Esto en el evento de pintar
for( int x = 0; x < 100; x++ )
{
 for( int y = 0; y < 100; y++ )
 {
    int indice = bloques[x,y];
    Bitmap imagen = imagenes[indice];
    graphics.drawimage(imagen, x*32, y*32)
 }
}

Fijate que el codigo que te he puesto es algo muy sencillo y muy concreto, pero sirve para que te hagas una idea.

nsL

 Bueno, despues de tomarme un descansito, que llevaba todo el dia mirando cosas :P he vuelto a la carga. Por un lado ya va. Funciona para pintar todas las imagenes, ademas si adapto el panel Hijo me salen las barras de scroll y todo perfecto  (ole) . El problema es cuando las uso, q se me distorsiona la imagen. He probado varios eventos del panel, pero todos afectan a el panel en si, no a sus barras. Seguramente haya alguno que se ejecute cuando use las barras o similar. Te pongo una imagen de como queda distorsionada la imagen:



Saludos!
Yo no muero hasta la muerte -

zupervaca

 Por lo que veo el problema es que pintas a partir de el Rectangle que te pasa la funcion, cada vez que desplazas la barra de scroll el Rectangle solo tiene la zona que se va a actualizar, para que te hagas una idea de lo que digo:

La zona roja es la que se va a actualizar al hacer el scroll horizontal, si le dices que pinte a partir de la X del rectangulo estaras pintando el inicio de la imagen en esa posicion, por eso ves ese efecto, para evitar esto te hacen falta las matematicas :D, debes de calcular la posicion de la imagen respecto al ancho de la imagen, es decir, X = (X / anchoimagen) * anchoimagen, con eso haras que la imagen comience a pintarse en el sitio correcto, lo haces multiplo, tambien puedes poner esta otra formula X -= X % anchoimagen;, aqui tal vez alguien metido en arquitecturas nos podria decir que formula es mas rapida.

nsL

 jajajaj y asi es como lo has hecho tu para tu editor?

Madre mia, el que me dijo que hacer esto era facil debe estar revolviendose en su tumba :P

Lo bueno de todo es que estoy aprendiendo mas de lo que esperaba sobre windows forms y demas  (ole)

Voy a probarlo a ver si sako algo en claro.

Saludos!
Yo no muero hasta la muerte -

nsL

 Dios mio, que paranoia, veo ya la maldita cara hasta cuando cierro los ojos....

Vamos a ver. Lo ulltimo que he conseguido es esto (por pasos):

1. Dibujo las caras en filas y columnas. Por ejemplo: Dibujo 7x7 caras. Con una variable bool controlo que es el primer pintado, y no el de scroll.
2. Para no hacerme lios uso un panel siempre igual en tamaño. En este caso es 550x450. Y cada cara es 100x100.
3. Segun las voy pintando la primera vez (cuando le doy al boton) voy calculando el numero de caras que pinto horizontalmente en una variable X. Es variable la multiplico x 100 para saber donde va a acabar la cara.
4. Si en una iteracion del bucle de pintado resulta que 550 (ancho del panel) - X (numero de caras pintadas)*100 < 100 , es decir, que la diferencia del ancho del panel, con la posicion de la ultima cara es menor que 100, la siguiente cara se va a partir y no se pinta entera. Entonces me quedo con esa distancia (por ejemplo variable Actual) y sigo pintando todo.
5. Ya he acabado de pintar todo y pongo la bool de primer pintado a false;
6. Dentro de la rutina de pintado (la qu me diste de GDI) hago un if para ver si es el primer pintado, en ese caso pintar la cara entera con BitBlt, y en caso contrario indicarle a BitBlt que pinte la cara a partir de la distancia guardada antes (Actual).
7. Hago scroll y empieza a pintarse el resto de la cara  (ole) (mas o menos, porq no considero el tamaño de la barra de Scroll, luego el tamaño ancho del panel ya no es 550, es algo menos. Pero eso de momento me da igual) pero se acaba la alegria cuando veo que se pinta rayada tb :P

Obviamente se pinta rayada porq a partir de ahora estoy pintando caras a partir de esa posicion (Actual). Lo que deberia hacer ahora es ir actualizando esa variable Actual y cada vez ir pintando con BitBlt a partir de esa posicion. Pero aqui ya me pierdo y no se seguir ;)

Si a todo esto le añades que tb hay q controlar scroll a la izquierda, arriba y abajo pues.... ami me dan ganas de pegarme un tiro jajaja

Por otro lado he estado pensando en el parametro BackgroundImage del panel. Seguramente esa imagen de fondo se autorepinte sola con el scroll. Si consigo hacer un Blit a esa imagen igual ya no tengo que preocuparme de controlar estas cosas. ¿Que opinas?

Por hoy creo que ya valio, voy a jugar a algo ;)

Saludos!
Yo no muero hasta la muerte -

nsL

 Weno, despues de un dia de tirones de pelo ya he conseguido solucionar el problema  (ole)

Para ello tuve que bajarme un libro en pdf sobre c# que casualmente tenia un apartado sobre Drawing and Scrolling, y casualmente pintaba una imagen en un panel con scroll :P

Al final el problema no era tan complejo como pensabamos. Se resumia a dibujar con esta sentencia:

e.Graphics.DrawImage(imagen,main.AutoScrollPosition.X,main.AutoScrollPosition.Y,imagen.Width,imagen.Height);


Siendo imagen el Bitmap y main el Panel. esta era la funcion para una imagen. Si la ejecutabas N veces en el bucle te repintaba todas las imagenes encima de la anterior. Asi que habia que añadir esto:
Citar
e.Graphics.DrawImage(imagen,main.AutoScrollPosition.X+x,main.AutoScrollPosition.Y+y,imagen.Width,imagen.Height);

x e y se van incrementando en el bucle y son las que dicen donde va cada imagen. Asi ya funciona y salen todas las imagenes.

Ahi va una captura:


Asi que al hacer scroll se ven todas las imagenes a la perfeccion ;) (cambie la imagen, q la cara ya me saturaba :P)

Ahora queda todo lo demas, pero sin duda es un gran paso  B)

Por cierto, al final no uso tu funcion de GDI, pero vamos, dudo que sea muy dificl adaptarla para estos nuevos parametros :P

Os mantendre informados!

Saludos!
Yo no muero hasta la muerte -

ZüNdFoLGe

Cita de: "zupervaca"te hacen falta las matematicas :D, debes de calcular la posicion de la imagen respecto al ancho de la imagen, es decir, X = (X / anchoimagen) * anchoimagen, con eso haras que la imagen comience a pintarse en el sitio correcto
X = (X / anchoimagen) * anchoimagen , qué matemáticas son esas?  :blink:  

zupervaca

 Eso sirve para hacer multiplo del ancho de la image el valor de X, ejemplo:

X = 48
AnchoImage = 32

48/32=1.5
1.5=1 por que es Int
1*32=32

Se queda en la posicion 32, para la posicion X=105 se quedaria en la posicion 96 haciendolo multiplo de 32 otra vez

ZüNdFoLGe

 
Cita de: "zupervaca"por que es Int
:rolleyes: ví la formula sin considerar el tipo de x... demasiadas matemáticas en la uni :wacko:  

zupervaca

 Te aviso que el valor de AutoScrollPosition.X hace que pintes todos los tiles aunque no sean visibles, es decir, si estas en la posicion 100 de la barra de scroll el valor de AutoScrollPosition.X es -100, con lo que estas pintando desde -100 que es fuera de la parte visible del control.

nsL

 
Citar
Te aviso que el valor de AutoScrollPosition.X hace que pintes todos los tiles aunque no sean visibles, es decir, si estas en la posicion 100 de la barra de scroll el valor de AutoScrollPosition.X es -100, con lo que estas pintando desde -100 que es fuera de la parte visible del control.
Ya ya, eso presuponia :P

De todas formas ese tipo de pintado solo lo hare al principio y cuando haga scroll. Para cuando pase el puntero por encima tengo pensado hacer lo que me dijiste de actualizar por cuadrados solamente lo que se modifican.

De todas maneras, el scroll va bastante fluido. Si bien es verdad que tampoco uso muchos tiles de momento, supongo que a media que haya grandes mapas hacer scroll sera mas costoso.

¿Para evitar eso que habria que volver a nuestro querido problema de pintar trozos? :P

PD: Ptra cosa q se me acaba de ocurrir ahora mismo es la sigiuente: Como las coordenadas X y Y definen las coordenadas del panel visibles (sin sumarle autoscroll.x ni nada), podria mediante algunos calculos pintar solo los tiles que vayan a tener algnua parte visible en el panel. Se me acaba de ocurrir ahora, pero no creo que suponga muchos calculos y optimizaria bastante para mapa grandes. ¿Que opinas?

Gracias por la ayuda ;)
Yo no muero hasta la muerte -

zupervaca

 Ese sistema es el que te comentaba antes, siempre se debe de pintar lo justo ya que no todo el mundo tiene una supermaquina ;)  

Vicente

 Hola,

resucito esto: para el doble buffer usais esto?

"To fully enable double-buffering, you must set the UserPaint, AllPaintingInWmPaint, and DoubleBuffer bits to true."

Es de esta página.

Un saludo!

Vicente

nsL

 Exacto :P

yo pongo esto:

this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer,true);


Lo sake de aqui.

La verdad es que se nota una burrada la mejoria :)

Saludos!
Yo no muero hasta la muerte -






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.