Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Problema renderizacion Argentum ONline vb 6

Iniciado por Surion, 28 de Enero de 2010, 04:18:16 PM

« anterior - próximo »

Surion

BUenas a todos otra vez, esta vez os escribo para consultaros sobre un problema de rendering que tiene mi cliente. Al ir al borde de los mapas (cambios de mapa) o sitios muy cargados de grhs diferentes y angostos el cliente se relentiza mucho en la creacion de grh, haciendo que los persoanjes se muevan 10 veces mas lento. Un amigo estuvo averiguando y la contestacion que recibio fue la siguiente:

El problema es más o menos sencillo. La función de rendering, ni me
acuerdo a esta altura del nombre, pero es fácil encontrarla, tira
errores al caminar por los bordes. Estos errores son por referenciar
posiciones de los arreglos y listas inexistentes (por debajo del 1 o por
encima del 100). Lo que agrava el problema, es que el error se ignora,
porque la función tiene un:
On Error Resume Next
o similar, que hace que se continue con la siguiente linea.

En VB6, cuando se genera un error, se crean una instancia con la
información del error, para poder tomar una acción correctiva. NUNCA
debe usarse 'On Error Resume Next', porque no solo relantece la
ejecución del programa, sino que el programa puede terminar haciendo
cualquier cosa. Por suerte, con el rendering no pasa nada grave, salvo
que el proceso (que necesita ser rapidísimo) se relantece en varios
ordenes de magnitud.

El cambio pasa por hacer 2 cosas:

(1) primero eliminar ese desafortunado 'on error resume next', para que
SALTEN los errores, y entonces poder corregirlos. Corre el Argentum Online desde el
IDE, para ver dónde y porqué saltan los errores, y

(2) seguro vas a encontrar que falta comprobar los límites del mapa al
momento de renderizarlo. Debe ser cuestión de agregar algún:
AND x >=1 AND x <= 100 AND Y >=1 AND Y <= 100
o algo parecido en 1 o 2 IFs. Con ese poquito, se arregla todo. Y nunca
más funcionará lento el rendering :)



Aqui dejo el code de mi renderscreen, quizas a alguno se le ocurra como mejorar el rendimiento y arreglar este gran errror:

Sub RenderScreen(tilex As Integer, tiley As Integer, PixelOffsetX As Integer, PixelOffsetY As Integer)


On Error Resume Next

If UserCiego Then Exit Sub

Dim Y        As Integer 'Keeps track of where on map we are
Dim X        As Integer 'Keeps track of where on map we are
Dim minY     As Integer 'Start Y pos on current map
Dim maxY     As Integer 'End Y pos on current map
Dim minX     As Integer 'Start X pos on current map
Dim maxX     As Integer 'End X pos on current map
Dim ScreenX  As Integer 'Keeps track of where to place tile on screen
Dim ScreenY  As Integer 'Keeps track of where to place tile on screen
Dim Moved    As Byte
Dim Grh      As Grh     'Temp Grh for show tile and blocked
Dim TempChar As Char
Dim TextX    As Integer
Dim TextY    As Integer
Dim iPPx     As Integer 'Usado en el Layer de Chars
Dim iPPy     As Integer 'Usado en el Layer de Chars
Dim rSourceRect      As RECT    'Usado en el Layer 1
Dim iGrhIndex        As Integer 'Usado en el Layer 1
Dim PixelOffsetXTemp As Integer 'For centering grhs
Dim PixelOffsetYTemp As Integer 'For centering grhs

'Figure out Ends and Starts of screen
' Hardcodeado para speed!
minY = (tiley - 15)
maxY = (tiley + 15)
minX = (tilex - 17)
maxX = (tilex + 17)

'Draw floor layer
ScreenY = 8 + RenderMod.iImageSize
For Y = (minY + 8) + RenderMod.iImageSize To (maxY - 8) - RenderMod.iImageSize
   ScreenX = 8 + RenderMod.iImageSize
   For X = (minX + 8) + RenderMod.iImageSize To (maxX - 8) - RenderMod.iImageSize
       If X > 100 Or Y < 1 Then Exit For
       'Layer 1 **********************************
       With MapData(X, Y).Graphic(1)
           If (.Started = 1) Then
               If (.SpeedCounter > 0) Then
                   .SpeedCounter = .SpeedCounter - 1
                   If (.SpeedCounter = 0) Then
                       .SpeedCounter = GrhData(.GrhIndex).Speed
                       .FrameCounter = .FrameCounter + 1
                       If (.FrameCounter > GrhData(.GrhIndex).NumFrames) Then _
                           .FrameCounter = 1
                   End If
               End If
           End If

           'Figure out what frame to draw (always 1 if not animated)
           iGrhIndex = GrhData(.GrhIndex).Frames(.FrameCounter)
       End With

       rSourceRect.Left = GrhData(iGrhIndex).sX
       rSourceRect.Top = GrhData(iGrhIndex).sY
       rSourceRect.Right = rSourceRect.Left + GrhData(iGrhIndex).pixelWidth
       rSourceRect.Bottom = rSourceRect.Top + GrhData(iGrhIndex).pixelHeight

       'El width fue hardcodeado para speed!
       Call BackBufferSurface.BltFast( _
               ((32 * ScreenX) - 32) + PixelOffsetX, _
               ((32 * ScreenY) - 32) + PixelOffsetY, _
               SurfaceDB.GetBMP(GrhData(iGrhIndex).FileNum), _
               rSourceRect, _
               DDBLTFAST_WAIT)
       '******************************************
       If Not RenderMod.bNoCostas Then
           'Layer 2 **********************************
           If MapData(X, Y).Graphic(2).GrhIndex <> 0 Then
               Call DDrawTransGrhtoSurface( _
                       BackBufferSurface, _
                       MapData(X, Y).Graphic(2), _
                       ((32 * ScreenX) - 32) + PixelOffsetX, _
                       ((32 * ScreenY) - 32) + PixelOffsetY, _
                       1, _
                       1)
           End If
           '******************************************
       End If
       ScreenX = ScreenX + 1
   Next X
   ScreenY = ScreenY + 1
   If Y > 100 Then Exit For
Next Y

'Draw Transparent Layers  (Layer 2, 3)
ScreenY = 8 + RenderMod.iImageSize
For Y = (minY + 8) + RenderMod.iImageSize To (maxY - 1) - RenderMod.iImageSize
   ScreenX = 5 + RenderMod.iImageSize
   For X = (minX + 5) + RenderMod.iImageSize To (maxX - 5) - RenderMod.iImageSize
       If X > 100 Or X < -3 Then Exit For
       iPPx = ((32 * ScreenX) - 32) + PixelOffsetX
       iPPy = ((32 * ScreenY) - 32) + PixelOffsetY

       'Object Layer **********************************
       If MapData(X, Y).ObjGrh.GrhIndex <> 0 Then
           Call DDrawTransGrhtoSurface( _
                   BackBufferSurface, _
                   MapData(X, Y).ObjGrh, _
                   iPPx, iPPy, 1, 1)
       End If
       '***********************************************
       'Char layer ************************************
       If MapData(X, Y).CharIndex <> 0 Then
           TempChar = CharList(MapData(X, Y).CharIndex)
           PixelOffsetXTemp = PixelOffsetX
           PixelOffsetYTemp = PixelOffsetY

           Moved = 0
           'If needed, move left and right
           If TempChar.MoveOffset.X <> 0 Then
               TempChar.Body.Walk(TempChar.Heading).Started = 1
               TempChar.Arma.WeaponWalk(TempChar.Heading).Started = 1
               TempChar.Escudo.ShieldWalk(TempChar.Heading).Started = 1
               PixelOffsetXTemp = PixelOffsetXTemp + TempChar.MoveOffset.X
               TempChar.MoveOffset.X = TempChar.MoveOffset.X - (8 * Sgn(TempChar.MoveOffset.X))
               Moved = 1
           End If
           'If needed, move up and down
           If TempChar.MoveOffset.Y <> 0 Then
               TempChar.Body.Walk(TempChar.Heading).Started = 1
               TempChar.Arma.WeaponWalk(TempChar.Heading).Started = 1
               TempChar.Escudo.ShieldWalk(TempChar.Heading).Started = 1
               PixelOffsetYTemp = PixelOffsetYTemp + TempChar.MoveOffset.Y
               TempChar.MoveOffset.Y = TempChar.MoveOffset.Y - (8 * Sgn(TempChar.MoveOffset.Y))
               Moved = 1
           End If
           'If done moving stop animation
           If Moved = 0 And TempChar.Moving = 1 Then
               TempChar.Moving = 0
               TempChar.Body.Walk(TempChar.Heading).FrameCounter = 1
               TempChar.Body.Walk(TempChar.Heading).Started = 0
               TempChar.Arma.WeaponWalk(TempChar.Heading).FrameCounter = 1
               TempChar.Arma.WeaponWalk(TempChar.Heading).Started = 0
               TempChar.Escudo.ShieldWalk(TempChar.Heading).FrameCounter = 1
               TempChar.Escudo.ShieldWalk(TempChar.Heading).Started = 0
           End If

           'Dibuja solamente players
           iPPx = ((32 * ScreenX) - 32) + PixelOffsetXTemp
           iPPy = ((32 * ScreenY) - 32) + PixelOffsetYTemp
           If TempChar.Head.Head(TempChar.Heading).GrhIndex <> 0 Then
               If Not CharList(MapData(X, Y).CharIndex).invisible Then
                   '[CUERPO]'
                      If (TempChar.macreando = 1) Then
                       Call Dialogos.DrawText(iPPx - 20, iPPy + 50, "<MACREANDO>", RGB(RandomNumber(0, 255), RandomNumber(0, 255), RandomNumber(0, 255)))
                      End If

                       Call DDrawTransGrhtoSurface(BackBufferSurface, TempChar.Body.Walk(TempChar.Heading), _
                               (((32 * ScreenX) - 32) + PixelOffsetXTemp), _
                               (((32 * ScreenY) - 32) + PixelOffsetYTemp), _
                               1, 1)
'no posteo la parte de los chars, la veo innecesaria, mas abajo esta lo siguiente:
       '************************************************
       ScreenX = ScreenX + 1
   Next X
   ScreenY = ScreenY + 1
   If Y >= 100 Or Y < 1 Then Exit For
Next Y


PD: Aun soy muy novato en programacion, por lo que no entiendo alguna de las expreciones que empleo el que me aconsejo lo del  "on error resume", de ser posible y si conoceis la respuesta agradeceria que lo hagais de la forma menos compleja que se puada, muchisimas gracias de antemano.

valnar

Hombre, asi a bote pronto y sin mirar mucho el código (y teniendo en cuenta que lo que dices es el problema), tendrías que hacer esto:

1.- Para ver estos errores que te saltan, tendrías que debuggear el cliente y poner puntos de interrupción.
2.- Aplica las soluciones que te da, primero quita el error resume next
3.- Me imagino que el asunto de los IFs que te comenta se aplica en esta línea If X > 100 Or Y < 1 Then Exit For

Ya te digo que no me he fijado mucho, pero yo creo que lo que podrias hacer por de pronto es lo del debug.
Valnar Games
All your base are belong to us.
@valnar

Surion

Cita de: valnar en 28 de Enero de 2010, 04:57:00 PM
Hombre, asi a bote pronto y sin mirar mucho el código (y teniendo en cuenta que lo que dices es el problema), tendrías que hacer esto:

1.- Para ver estos errores que te saltan, tendrías que debuggear el cliente y poner puntos de interrupción.
2.- Aplica las soluciones que te da, primero quita el error resume next
3.- Me imagino que el asunto de los IFs que te comenta se aplica en esta línea If X > 100 Or Y < 1 Then Exit For

Ya te digo que no me he fijado mucho, pero yo creo que lo que podrias hacer por de pronto es lo del debug.

Me da verguenza molestar tanto... pero como lo poco que aprendi programando fue con un mod de argentum (codigo libre) me temo que nunca he hecho un "debug" y no se exactamente ocmo funciona, he quitado  el on error resume next,  al compilarlo no salen errores, sin embargo si le doy a debug me marca un error en la carga de un grafico (esto supongo que es normal), que deberia hacer? hacer el debug solo  a ese frm?? DIsculpar mi poca experiencia... solo intento aprender .

Muchas gracias.

[EX3]

Debugear, o es castellano, depurar, no es mas que ejecutar linea a linea el codigo (mediante F8 o Mayusculas+F8 en VB6.0) o detener la ejecucion en puntos concretos del codigo (marcando sobre el margen a la altura de una linea especifica o pulsando F9, se remarca en rojo) y ayudandote del objeto Debug y su instruccion Print (Debug.Print <expresion>) para mostrar valores en la ventana de inmediato (la sacas con Control+G). De esa forma puedes saber el trazado de la ejecucion del codigo en tiempo de ejecucion (por donde esta pasando el codigo) o incluso desplazar el punto de ejecucion a otra linea de codigo (arrastrando el punto del margen con el raton) y con el objeto Debug mostrar valores de variables en la ventana de inmediato. Es importante saber manejar eso y mas en proyectos grandes como este.

CitarPD: Aun soy muy novato en programacion, por lo que no entiendo alguna de las expreciones que empleo el que me aconsejo lo del  "on error resume", de ser posible y si conoceis la respuesta agradeceria que lo hagais de la forma menos compleja que se puada, muchisimas gracias de antemano.
Si estas empezando en esto de la programacion en general, y encima orientado a juegos, el Argentum Online se te queda un poco grande para empezar creo yo :P Es que explicar como funciona el render de un juego que no ha programado uno mismo no es facil ni sencillo de explicar ni a un novato ni a un veterano (y mas si es solo un parte del conjunto completo).

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt






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.