ich habe nach einiger Zeit mal wieder angefangen ein wenig an meinen Programmierkenntnissen zu arbeiten, und um zu schauen was so hängen geblieben ist wollte ich ein sehr simples Memory-Spiel bauen. Leider hänge ich nun schon so ziemlich am Anfang ziemlich fest, da das Programm beim Zeichnen auf eine PaintBox einen Fehler auswirft
.Projekt myMemory hat Exception-Klasse >>External: SIGSEGV<< ausgelöst. In Datei '.\include\canvas.inc' in Zeile 25
Mein Plan war, eine PaintBox zu nutzen und alle Grafiken direkt auf die PaintBox zu zeichnen. Beim initialisieren zeichne ich ein Hintergrundbild auf die Box und lasse dann (in Reihen/Spalten angeordnet) die Memory-Karten zeichnen, zu Beginn mit der Rückseite nach oben. Beim Klick auf die PaintBox ermittle ich die Klickposition, anhand der ich dann die angeklickte Karte identifiziere. Ist die Karte noch nicht sichtbar (die Info habe ich in Records in einem Array gespeichert), soll sie umgedreht werden.
Hier die aus meiner Sicht relevanten Code-Abschnitte:
Code: Alles auswählen
type
TCard = Record
value: Integer;
visible: Boolean;
end;
type TCardArray = Array of TCard;
Code: Alles auswählen
procedure TForm1.BitBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
r, c: Integer;
begin
r := y div CBgBit.Height;
c := x div CBgBit.Width;
GameField[c][r].visible := not GameField[c][r].visible;
BitBox.Repaint;
end;
Code: Alles auswählen
procedure TForm1.BitBoxPaint(Sender: TObject);
var
r, c: Integer;
begin
BitBox.Canvas.Draw(0, 0, bgBit);
for r := 0 to CBoardRows - 1 do
begin
for c := 0 to CBoardCols - 1 do
begin
if GameField[c][r].visible then
BitBox.Canvas.Draw(c * CBgBit.Width, r * CBgBit.Height, Imgs[GameField[c][r].value]) else
BitBox.Canvas.Draw(c * CBgBit.Width, r * CBgBit.Height, CBgBit);
end;
end;
end;
Ich hoffe, dass mir jemand helfen kann

Der Vollständigkeit halber hier noch der komplette Code...
Code: Alles auswählen
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, Math;
type
TIntegerArray = Array of Integer;
type
TCard = Record
value: Integer;
visible: Boolean;
end;
type TCardArray = Array of TCard;
{ TForm1 }
TForm1 = class(TForm)
BitBox: TPaintBox;
procedure BitBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBoxPaint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
GameField: Array of TCardArray;
Imgs: Array of TBitmap;
BgBit: TBitmap;
CBgBit: TBitmap;
procedure CreateGameField;
procedure LoadBitmaps;
procedure ShuffleArr(arr: TIntegerArray; loops: Integer = 5);
public
end;
var
Form1: TForm1;
const
CImgCount = 12;
CBoardCols = 6;
CBoardRows = 4;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
CreateGameField;
LoadBitmaps;
Form1.Width := BgBit.Width;
Form1.Height := BgBit.Height;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i: Integer;
begin
BgBit.Destroy;
CBgBit.Destroy;
for i := 0 to Length(Imgs) - 1 do
Imgs[i].Destroy;
end;
procedure TForm1.ShuffleArr(arr: TIntegerArray; loops: Integer = 5);
var
tmp: TIntegerArray;
i, r: Integer;
begin
while loops > 0 do
begin
tmp := Copy(arr, 0, Length(arr));
for i := 0 to Length(arr) - 1 do
begin
r := Random(Length(arr));
while tmp[r] = -1 do
r := Random(Length(arr));
arr[i] := tmp[r];
tmp[r] := -1;
end;
dec(loops);
end;
end;
procedure TForm1.CreateGameField;
var
i, j: Integer;
arr: TIntegerArray;
begin
SetLength(arr, CBoardRows * CBoardCols);
for i := 0 to Length(arr) - 1 do
if(i < (Length(arr) - 1) div 2) then
arr[i] := i else
arr[i] := i - (Length(arr) - 1) div 2;
ShuffleArr(arr);
SetLength(GameField, CBoardCols);
for i := 0 to CBoardCols - 1 do
begin
SetLength(GameField[i], CBoardRows);
for j := 0 to CBoardRows - 1 do
begin
GameField[i][j].value := arr[i * CBoardRows + j];
GameField[i][j].visible := False;
end;
end;
end;
procedure TForm1.LoadBitmaps;
var
i: Integer;
path, s: string;
begin
path := ExtractFilePath(ParamStr(0));
BgBit := TBitmap.Create;
BgBit.LoadFromFile(path + 'bg.bmp');
CBgBit := TBitmap.Create;
CBgBit.LoadFromFile(path + 'bg_c.bmp');
SetLength(Imgs, CImgCount);
for i := 0 to CImgCount - 1 do
begin
s := path + IntToStr(i) + '.bmp';
Imgs[i] := TBitmap.Create;
Imgs[i].LoadFromFile(s);
end;
end;
procedure TForm1.BitBoxPaint(Sender: TObject);
var
r, c: Integer;
begin
BitBox.Canvas.Draw(0, 0, bgBit);
for r := 0 to CBoardRows - 1 do
begin
for c := 0 to CBoardCols - 1 do
begin
if GameField[c][r].visible then
BitBox.Canvas.Draw(c * CBgBit.Width, r * CBgBit.Height, Imgs[GameField[c][r].value]) else
BitBox.Canvas.Draw(c * CBgBit.Width, r * CBgBit.Height, CBgBit);
end;
end;
end;
procedure TForm1.BitBoxMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
r, c: Integer;
begin
r := y div CBgBit.Height;
c := x div CBgBit.Width;
showmessage(inttostr(gamefield[c][r].value) + ' | ' +
inttostr(c * cbgbit.Width) + ' | ' + inttostr(r * cbgbit.Height));
GameField[c][r].visible := not GameField[c][r].visible;
BitBox.Repaint;
end;
end.