PDA

Ver la Versión Completa : Error Exception EAccessViolation


Bant
23-03-2016, 12:35:15
Saludos colegas, denuevo vuelvo con un error xDD parece que les caigo bien y siempre me aparecen.
Ando usando Delphi 7 y tengo Windows 8.1 de 64 bits.
Ando creando un juego como veran a continuacion y tiene el siguiente codigo.


program PJuego;

uses
Windows,
Dialogs,
SysUtils,
UJuego in 'UJuego.pas',
UArcade in 'UArcade.pas';


{$R *.res}
var
Teclado : TTeclado;
Temporizador : TTemporizador;


begin
InicializarSDL;
ModoVideo( 640, 480, 16, True );
Teclado := TTeclado.Create;
Temporizador := TTemporizador.Create;
CargarSprites;

while not bSalir do
begin
Temporizador.Actualizar;

if Temporizador.Activado then
begin
Teclado.Leer;
DibujarSprites;
ActualizarPantalla;
Temporizador.Incrementar;
ControlarEventos;
end
else
Temporizador.Esperar;
end;

DestruirSprites;
Temporizador.Free;
Teclado.Free;
FinalizarSDL;
end.



Al ejecutarlo me da el error Exception EACcessViolation in module... at 000527CB. Access violation ant address 004527CB.... Read of address 000000006.El problema me da cuando escribo la linea del procedure ControlarEventos; que se encuentra en la unidad UArcade.pas el programa me corre sin esta pero ya saben.. no hara el proceso xD.

He indagado en internet y segun entendi cuando el address tiene 00000 es que el proceso al que intento llamar no ha sido creado o ya ha sido destruido. Pero reviso en el codigo y a mi parecer no le veo el error. Descargue madExcept que dicen que es un buen rastreador de excepciones y que las maneja pero no encuentro alguna guia para instalarlo en Delphi, aunque como es la version mas reciente se instala ''automaticamente'', o en mi caso no funciona. Por favor quisiera un poco de su sabiduria una vez mas!!

Casimiro Notevi
23-03-2016, 12:39:26
Vale, pero cómo te ayudamos si no vemos ControlarEventos? ;)

Bant
23-03-2016, 12:43:55
Perdon estaba pensando en ponerlo xDD

procedure ControlarEventos;
begin
if Teclado.bDerecha and (Heroe.x < 545 ) then
Inc( Heroe.x);

if Teclado.bIzquierda and ( Heroe.x > 0 ) then
Dec(Heroe.x);

if Teclado.bArriba and ( Heroe.y > 0) then
Dec(Heroe.y);

if Teclado.bAbajo and ( Heroe.y < 407 ) then
Inc (Heroe.y);

end;

Igual que en todo el programa la variable Teclado es de tipo TTeclado que viene siendo una class creada!!

TOPX
23-03-2016, 14:33:35
Saludos colega,

Y Heroe, ¿también?

Le podría hacer seguimiento paso a paso con el depurador de Delphi, para verificar qué parte del código de ControlarEventos tiene valor nil.

-

Bant
23-03-2016, 14:41:23
Heroe es de tipo TSprite una clase tambien creada, de verdad que no se mucho del tema de trackear y reparar este tipo de errores si me pudiera sugerir algunos links del foro o de algun lugar para aprender mas sobre este topico me vendria bien :D^\||/

AgustinOrtu
23-03-2016, 15:29:52
Depura tu programa, las excepciones Access Violation son siempre porque estas intentando trabajar con un objeto que no fue creado

Pon un punto de ruptura (breakpoint) y corre el programa con F9

Revisa la documentacion relacionada con depurar

En esta imagen se ve como colocar un breakpoint:

Setting and Modifying Breakpoints (http://docwiki.embarcadero.com/RADStudio/en/Setting_and_Modifying_Breakpoints)

http://www.drbob42.com/gif/X-09.gif

Los puntos a la izquierda del codigo, son los puntos de ruptura. Si esta en azul significa que en ese lugar podes colocar un punto de ruptura. Si esta en rojo significa que cuando ejecutes con el depurador (F9) cuando se llege a esa instruccion el codigo se detiene y te permite ver el estado de las variables, los objetos, etc

Una llegado a ese punto, tenes varias acciones mas para continuar la depuracion. Por ejemplo con F8 pasas a la siguiente linea ("avanzar"); con F9 vas hasta el proximo punto de ruptura (si no hay ninguno, entonces el programa sigue como si nada)

Podes poner puntos de ruptura una vez el programa ya esta en ejecucion y siendo depurado. Siempre que el flujo del programa llegue a ese punto, el IDE se pondra en primer plano

Revisa esto How To Use the Debugger (http://docwiki.embarcadero.com/RADStudio/en/How_To_Use_the_Debugger)

Bant
23-03-2016, 16:45:46
Segui el consejo de AgustinOrtu e indague sobre el tema del debugger pero termine muy confundido xDD :confused::confused:
Perooo leyendo entendi osea el proceso ControlarEventos; deberia activarse al presionar una tecla debido a que dependiendo la tecla que sea produce una accion (en este caso moveria el Sprite que cargue) para eso tengo el procedure Leer; en la clase TTeclado que me lee algun evento del teclado.

procedure TTeclado.Leer;
begin
// ¿Se ha producido un evento?
if SDL_PollEvent( @Evento ) > 0 then

begin
// ¿Ha pulsado una tecla?
if Evento.type_ = SDL_KEYDOWN then
begin
x := True; //Introducido recientemente
iUltTec := Evento.key.keysym.sym;

case Evento.key.keysym.sym of
SDLK_ESCAPE: bSalir := True;
SDLK_RIGHT: bDerecha := True;
SDLK_LEFT: bIzquierda := True;
SDLK_UP: bArriba := True;
SDLK_DOWN: bAbajo := True;
SDLK_SPACE: bEspacio := True;
SDLK_RETURN: bIntro := True;
SDLK_LCTRL: bCtrl_Izq := True;
end;
end;

// ¿Ha levantado una tecla?
if Evento.type_ = SDL_KEYUP then
begin
iUltTec := 0;

case Evento.key.keysym.sym of
SDLK_RIGHT: bDerecha := False;
SDLK_LEFT: bIzquierda := False;
SDLK_UP: bArriba := False;
SDLK_DOWN: bAbajo := False;
SDLK_SPACE: bEspacio := False;
SDLK_RETURN: bIntro := False;
SDLK_LCTRL: bCtrl_Izq := False;
end;
end;
end;
x := False; //Introducido recientemente
end;

Lo que dice "Introducido recientemente" lo puse asi para que en el bucle principal del programa si se cumple la condicion:

Temporizador.Incrementar;
if x = True then
ControlarEventos;

me ejecute el procedure ControlarEventos; y no cada 25 mls(Debido a que es un juego tiene que tener un tiempo de reaccion rapido no? Por lo cual cada 25 mls el Temporizador se actualiza) ahora cuando lo ejecuto no da error pero no hace nada en el procedure ControlarEventos; y comprobe si se cumplia la condicion y en efecto puse ShowMessage() debajo de cada Introduccido recientemente y al momento de ejecuccion me devolvia los valores asignados, deberas perdon por insistir tanto pero alguna idea de como resolver este meollo :eek::eek::confused:??

AgustinOrtu
23-03-2016, 17:27:48
Y por qué pones X a False? De esa manera nunca vas a entrar en ControlarEventos

El problema no ocurre en TTeclado.Leer, ocurre en ControlarEventos

Debes revisar si esta creado el objeto Heroe

Quien es Heroe? Que es Heroe? Quien lo crea? Como conoce el metodo ControlarEventos a Heroe?

Bant
23-03-2016, 17:36:28
Puse x := False para comprobar que si funcionaba el bucle!! Y sip el objeto Heroe esta creado ya que digamos los eventos DibujarSprites, CargarSprites,DestruirSprites y ControlarEventos; se encuentran en la misma unidad (Otra que no es donde esta el programa principal en si) y funcionan, es decir, a la hora de ejecutar el programa si aparece el Sprite dibujado en el programa y cuando presiona la tecla Escape sale el programa!!.

"Quien es Heroe? Que es Heroe? Quien lo crea? Como conoce el metodo ControlarEventos a Heroe?"

Heroe viene siendo un objeto del tipo TSprite, es decir, el personaje en el videojuego!! Lo crea otro proceso llamado CargarSprites igual que el Fondo que tambien lo crea al ejecutar el programa, si quieres paso la clase TSprite tambien si les parece mejor!!

Casimiro Notevi
23-03-2016, 17:50:23
Vas a tener que pone el código fuente, no somos adivinos ;)

Bant
23-03-2016, 18:27:29
a.a mejor os dejo el proyecto entero !! Incluye un .txt con la pagina de tutorial de donde estoy creando el juego.

https://drive.google.com/file/d/0B4FMYJfpyStPQ0l1YWpBM2k1Smc/view?usp=sharing