Mark Brady
asked on
Image click to return the name and position of that image ?
I have a panel with 16 small images 50 * 50. They are 4 wide and 4 deep.
The last image has no picture (blank). Images are named Image1 through to Image15 and the last one is named 'Imblank'.
I want to create a puzzel that when you click on an image next to the blanl one, the image and blank slide places. Just like the number squares game (only I'm using a picture all diced up).
The GUI is all set up but the coding for this one I'm having difficulty with.
If you can't help with an idea, then can you tell me how to get the Image name returned to a variable once an image is clicked and to work out if the blank image is next to it and able to be moved there ?
Thanks
Mark
The last image has no picture (blank). Images are named Image1 through to Image15 and the last one is named 'Imblank'.
I want to create a puzzel that when you click on an image next to the blanl one, the image and blank slide places. Just like the number squares game (only I'm using a picture all diced up).
The GUI is all set up but the coding for this one I'm having difficulty with.
If you can't help with an idea, then can you tell me how to get the Image name returned to a variable once an image is clicked and to work out if the blank image is next to it and able to be moved there ?
Thanks
Mark
here is a whole code of puzzle.
DG - TDrawGrid 4 x 4
Image1 - source image for puzzle, it will be splitted by 16 parts
Do not forget to assign an events :)
-----
Igor
unit u78;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, ExtCtrls;
type
TData16 = array[0..3, 0.. 3] of Integer;
TImg16 = array[0..15] of TBitmap;
TForm1 = class(TForm)
DG: TDrawGrid;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure DGDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
procedure DGClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
Data: TData16;
Imgs: TImg16;
procedure PrepareImgs;
procedure DoneImgs;
procedure SetNewData;
procedure ShowData;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.SetNewData;
var
I, J, N: Integer;
L: TList;
begin
Randomize;
L := TList.Create;
for I := 0 to 15 do
L.Add(Pointer(I));
for I := 0 to 3 do
for J := 0 to 3 do
begin
N := Random(L.Count);
Data[I, J] := Integer(L[N]);
L.Delete(N);
end;
L.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
PrepareImgs;
SetNewData;
DG.Invalidate;
end;
procedure TForm1.ShowData;
begin
end;
procedure TForm1.DGDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if Data[ACol, ARow] = 0 then
DG.Canvas.FillRect(Rect)
else
DG.Canvas.StretchDraw(Rect , Imgs[Data[ACol, ARow]]);
end;
procedure TForm1.DGClick(Sender: TObject);
var
X, Y: Integer;
procedure Move(AX, AY: Integer);
begin
Data[AX, AY] := Data[X, Y];
Data[X, Y] := 0;
end;
begin
X := DG.Col;
Y := DG.Row;
if (X > 0) and (Data[X - 1, Y] = 0) then Move(X - 1, Y) else
if (X < 3) and (Data[X + 1, Y] = 0) then Move(X + 1, Y) else
if (Y > 0) and (Data[X, Y - 1] = 0) then Move(X, Y - 1) else
if (Y < 3) and (Data[X, Y + 1] = 0) then Move(X, Y + 1) else
Beep;
DG.Invalidate;
end;
procedure TForm1.PrepareImgs;
var
X, Y: Integer;
W, H: Integer;
I: Integer;
B: TBitmap;
RS, RD: TRect;
begin
B := Image1.Picture.Bitmap;
W := B.Width div 4;
H := B.Height div 4;
SetRect(RD, 0, 0, W, H);
for X := 0 to 3 do
for Y := 0 to 3 do
begin
SetRect(RS, W * X, H * Y, W * X + W, H * Y + H);
I := 15 - (X + Y * 4);
Imgs[I] := TBitmap.Create;
Imgs[I].Width := W;
Imgs[I].Height := H;
Imgs[I].Canvas.CopyRect(RD , B.Canvas, RS);
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DoneImgs;
end;
procedure TForm1.DoneImgs;
var
I: Integer;
begin
for I := 0 to 15 do
Imgs[I].Free;
end;
end.
DG - TDrawGrid 4 x 4
Image1 - source image for puzzle, it will be splitted by 16 parts
Do not forget to assign an events :)
-----
Igor
unit u78;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, ExtCtrls;
type
TData16 = array[0..3, 0.. 3] of Integer;
TImg16 = array[0..15] of TBitmap;
TForm1 = class(TForm)
DG: TDrawGrid;
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure DGDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
procedure DGClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
Data: TData16;
Imgs: TImg16;
procedure PrepareImgs;
procedure DoneImgs;
procedure SetNewData;
procedure ShowData;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.SetNewData;
var
I, J, N: Integer;
L: TList;
begin
Randomize;
L := TList.Create;
for I := 0 to 15 do
L.Add(Pointer(I));
for I := 0 to 3 do
for J := 0 to 3 do
begin
N := Random(L.Count);
Data[I, J] := Integer(L[N]);
L.Delete(N);
end;
L.Free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
PrepareImgs;
SetNewData;
DG.Invalidate;
end;
procedure TForm1.ShowData;
begin
end;
procedure TForm1.DGDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if Data[ACol, ARow] = 0 then
DG.Canvas.FillRect(Rect)
else
DG.Canvas.StretchDraw(Rect
end;
procedure TForm1.DGClick(Sender: TObject);
var
X, Y: Integer;
procedure Move(AX, AY: Integer);
begin
Data[AX, AY] := Data[X, Y];
Data[X, Y] := 0;
end;
begin
X := DG.Col;
Y := DG.Row;
if (X > 0) and (Data[X - 1, Y] = 0) then Move(X - 1, Y) else
if (X < 3) and (Data[X + 1, Y] = 0) then Move(X + 1, Y) else
if (Y > 0) and (Data[X, Y - 1] = 0) then Move(X, Y - 1) else
if (Y < 3) and (Data[X, Y + 1] = 0) then Move(X, Y + 1) else
Beep;
DG.Invalidate;
end;
procedure TForm1.PrepareImgs;
var
X, Y: Integer;
W, H: Integer;
I: Integer;
B: TBitmap;
RS, RD: TRect;
begin
B := Image1.Picture.Bitmap;
W := B.Width div 4;
H := B.Height div 4;
SetRect(RD, 0, 0, W, H);
for X := 0 to 3 do
for Y := 0 to 3 do
begin
SetRect(RS, W * X, H * Y, W * X + W, H * Y + H);
I := 15 - (X + Y * 4);
Imgs[I] := TBitmap.Create;
Imgs[I].Width := W;
Imgs[I].Height := H;
Imgs[I].Canvas.CopyRect(RD
end;
end;
procedure TForm1.FormDestroy(Sender:
begin
DoneImgs;
end;
procedure TForm1.DoneImgs;
var
I: Integer;
begin
for I := 0 to 15 do
Imgs[I].Free;
end;
end.
ASKER
Hi ugay
Hey that looks real interesting. It's a little over my head but I'd love to give it a try. Can you tell me what I'd need on my form to make this work ? Do I start with a blank project and paste this code into it ?? Buttons ?
Sorry, but I just don't know where to start. Any more help would be very good.
thanks
Mark
Hey that looks real interesting. It's a little over my head but I'd love to give it a try. Can you tell me what I'd need on my form to make this work ? Do I start with a blank project and paste this code into it ?? Buttons ?
Sorry, but I just don't know where to start. Any more help would be very good.
thanks
Mark
Yes, you can start from empty form
1. drop TDrawGrid and set it's property:
Name = DG
ColCount = 4
RowCount = 4
FixedRows = 0
FixedCols = 0
DefaultColWidth = your choice
DefaultRowHeight = your choice
2. Drop TImage and load any bitmap you want
3. Insert type definition
TData16 = array[0..3, 0.. 3] of Integer;
TImg16 = array[0..15] of TBitmap;
4. write procedures and implementations for TForm (you can copy and paste my code)
public
Data: TData16;
Imgs: TImg16;
procedure PrepareImgs;
procedure DoneImgs;
procedure SetNewData;
procedure ShowData;
end;
5. Create an events and place the same code as in sample here
procedure FormCreate(Sender: TObject);
procedure DGDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
procedure DGClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
Thats all.
Let me know if you still have a troubles.
____
Igor
1. drop TDrawGrid and set it's property:
Name = DG
ColCount = 4
RowCount = 4
FixedRows = 0
FixedCols = 0
DefaultColWidth = your choice
DefaultRowHeight = your choice
2. Drop TImage and load any bitmap you want
3. Insert type definition
TData16 = array[0..3, 0.. 3] of Integer;
TImg16 = array[0..15] of TBitmap;
4. write procedures and implementations for TForm (you can copy and paste my code)
public
Data: TData16;
Imgs: TImg16;
procedure PrepareImgs;
procedure DoneImgs;
procedure SetNewData;
procedure ShowData;
end;
5. Create an events and place the same code as in sample here
procedure FormCreate(Sender: TObject);
procedure DGDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect;
State: TGridDrawState);
procedure DGClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
Thats all.
Let me know if you still have a troubles.
____
Igor
ASKER
I tried all that but I have a few problems. It can't find
'Variants.dcu'. Then I get a bunch of 'undeclared identifier' errors even though those things are on my form.
Any chance you could compile a quick example and send me the exe and the project files for me to study ?
If so, please send to elvin66@xtra.co.nz
Many thanks for your time.
Mark
'Variants.dcu'. Then I get a bunch of 'undeclared identifier' errors even though those things are on my form.
Any chance you could compile a quick example and send me the exe and the project files for me to study ?
If so, please send to elvin66@xtra.co.nz
Many thanks for your time.
Mark
hi Mark,
did you try to remove Variants from uses clause?
-----
Igor
did you try to remove Variants from uses clause?
-----
Igor
ASKER
yes I did. That solved that problem but still I get a lot of other errors. It might be easier for me to study and customise If I could see a complete project file(s) and see how it runs. If you don't want to send it, then can you be more clear on how to set it up ? Like, with image1, do I place that next to the drawgrid or over top of it or what ?
Mark
Mark
ASKER
Also, thius creates an error.
type
TData16 = array[0..3, 0.. 3] of Integer;
error = ': expected but = found' however I modify that line it doesn't work. Hmmm
Mark
type
TData16 = array[0..3, 0.. 3] of Integer;
error = ': expected but = found' however I modify that line it doesn't work. Hmmm
Mark
Hi elvin66
I can post whole project to you,
but seems we are using different Delphi versions,
I have D6 source only. Not sure in backward compatibility.
Ok, I will try to send you only .DFM and .PAS files.
------
Igor
I can post whole project to you,
but seems we are using different Delphi versions,
I have D6 source only. Not sure in backward compatibility.
Ok, I will try to send you only .DFM and .PAS files.
------
Igor
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
that would be great. I'll check my email. I'm using delphi 5
ASKER
That works perfectly ! Never mind the email, I got it working and changed the bitmap to the picture I want to use. Now I will go and put a button on the form that lets user load different images. Thank you so much !
Mark
Mark
I know the game you mean. Just an idea.
You have to create an array[0..3, 0..3] of integers and keep you data here.
Also you have create some visualization for array. I recommend you to use TDrawGrid.
It would be easy to implement.
____
Igor