Recent

Author Topic: get an unexpected Exception External:SIGSGEV  (Read 2065 times)

krull

  • New Member
  • *
  • Posts: 12
get an unexpected Exception External:SIGSGEV
« on: April 07, 2017, 07:40:33 pm »
Sorry for another Newbish qustion.

For practice I wanted to write an upward moving Spacefighter.
I know I'm only at the beginning. :)

Here's the problem. When my shot hit the upper edge the compiler means External:SIGSGEV.
Perhapse this has something to do with the 'shot.free';

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows ,Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, BGRABitmap, BGRABitmapTypes;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     playerPosTimer : TTimer;
  16.     shotTimer: TTimer;
  17.     procedure FormClick(Sender: TObject);
  18.     procedure FormCreate(Sender: TObject);
  19.     procedure playerPosTimerTimer(Sender: TObject);
  20.     procedure playerPaint(Sender:Tobject);
  21.     procedure shotTimerTimer(Sender: TObject);
  22.     procedure shotPaint(Sender:TObject);
  23.   private
  24.     { private declarations }
  25.   public
  26.     { public declarations }
  27.  
  28.    playerShip : TBGRABitmap;
  29.    shot : TBGRABitmap;
  30.    pPlayer : Point;
  31.    pFormer: Point;
  32.    shotSpeed : Integer;
  33.    pShot : Point;
  34.    shooting : Integer;
  35.    leftClick : boolean;
  36.   end;
  37.  
  38. var
  39.   Form1: TForm1;
  40.  
  41. implementation
  42.  
  43. {$R *.lfm}
  44.  
  45. { TForm1 }
  46.  
  47. procedure TForm1.playerPosTimerTimer(Sender: TObject);
  48. begin
  49.   pFormer:= pPlayer;
  50.   pPlayer:= Mouse.CursorPos;
  51.   pPlayer:= Form1.ScreenToClient(pPlayer);
  52.   playerPaint(Sender);
  53. end;
  54.  
  55. procedure TForm1.FormCreate(Sender: TObject);
  56. begin
  57.   playerShip := TBGRABitmap.Create('1.png');
  58.   pPlayer:= Mouse.CursorPos;
  59.   pPlayer:= Form1.ScreenToClient(pPlayer);
  60.   shooting:=0;
  61.   shotSpeed:=10;
  62.   leftClick:= false;
  63.   pShot.y:=1;
  64. end;
  65.  
  66. procedure TForm1.FormClick(Sender: TObject);
  67. begin
  68.   leftClick:=true;
  69. end;
  70.  
  71. procedure TForm1.playerPaint(Sender:Tobject);
  72. begin
  73.   Form1.Canvas.FillRect(pFormer.x-round(0.5*playerShip.Width),pFormer.y-round(0.5*playerShip.Height),pformer.x+playerShip.Width-round(0.5*playerShip.Width),pFormer.y+playerShip.Height-round(0.5*playerShip.Height));
  74.   playerShip.Draw(Canvas, pPlayer.x-round(0.5*playerShip.Width),pPlayer.y-round(0.5*playerShip.Height),false);
  75. end;
  76.  
  77. procedure TForm1.shotTimerTimer(Sender: TObject);
  78. begin
  79.   if (leftClick = true) and (shooting = 0) then
  80.   begin
  81.     try shot:= TBGRABitmap.Create('Beam1.png'); except end;
  82.     pShot.x:=pPlayer.x- round(0.5*shot.width);
  83.     pShot.y:=pPlayer.y- round(0.5*playerShip.Height)-shot.Height;
  84.     shot.draw(Canvas,pShot.x,pShot.y,true);
  85.     shooting:= shooting+1;
  86.   end;
  87.   leftClick:=false;
  88.   if pShot.y <= 0 then
  89.   begin
  90.     shot.Free;
  91.     shooting:=shooting-1;
  92.   end;
  93.   if shooting >=1 then
  94.   begin
  95.     pShot.y:= pShot.y-shotSpeed;
  96.     shotPaint(Sender);
  97.   end;
  98. end;
  99.  
  100. procedure TForm1.shotPaint(Sender:TObject);
  101. begin
  102.  Form1.canvas.FillRect(pShot.x, pShot.y+shotSpeed, pShot.x+shot.Width, pShot.y+shot.Height+shotSpeed);
  103.  shot.draw(Canvas,pShot.x,pShot.y,true);
  104. end;
  105.  
  106. end.

jmm72

  • Jr. Member
  • **
  • Posts: 79
  • Very experienced in being a beginner...
Re: get an unexpected Exception External:SIGSGEV
« Reply #1 on: April 09, 2017, 05:46:54 am »
It's just a simple logic check which is flawed. Don't worry, it happens to everyone, me included (dozens of times).

After you destroy the shot object with shot.Free, the next time the shotTimer triggers, 'if pShot.y <= 0 then' still executes and it's still true, thus tries to free the object again, which causes the sigsev.

Just replace everything after the 'leftclick := false;' (keep that one) with this, it's just your code with the check moved and merged with another part of the code. With this change it works.

Code: Pascal  [Select][+][-]
  1. if shooting >=1 then
  2.   begin
  3.     if pShot.y <= 0 then
  4.     begin
  5.       shot.Free;
  6.       shooting:=shooting-1;
  7.     end
  8.     else
  9.     begin
  10.       pShot.y:= pShot.y-shotSpeed;
  11.       shotPaint(Sender);
  12.     end;
  13.   end;

With this change, the check for shot being at the top only happens if you're shooting; if true, destroys the object and stops shooting, otherwise moves the shot.
Lazarus 1.6.4 + FPC 3.0.2 64bits under Windows 7 64bits
Only as a hobby nowadays
Current proyect release: TBA

 

TinyPortal © 2005-2018