We help IT Professionals succeed at work.

Opinions on best way to do this...

Palamedes
Palamedes asked
on
Medium Priority
222 Views
Last Modified: 2010-04-05
Hey gang,

I'm creating an application that will accompany a board game that some friends and I play.  Basically the application is to keep track of our map movements.

I have a HUGE image that has territories on it.  I want to be able to color those territories based on who owns them.  I had originally intended to do this via the web and just use HTML but it turned into a larger task and I think it requires an application of its own.  

My question is, what is the best way to individually color each territory.  Do I need to "cut" each territory into its own image, or is there a way I can overlay a color for that specific territory?  

Each map segment (territory) can be any random shape, sort of like the board game RISK.  Plus there can be hundreds of them..  A way to individually color them without having to resort to creating a colored image for each would be nice..

Thoughts?  Did I explain what I want well enough?

I use Delphi 5 btw..

Thanks guys.
Comment
Watch Question

Commented:
Use
windows.CreatePolygonRgn

Commented:
Here is an example of painting
procedure TForm1.MOPaintBox1Paint(Sender: TObject);
var
  dc: HDC;
  br: HBRUSH;
  Index: integer;
  hr: HRGN;
  x,y: integer;
begin
  dc := MOPaintBox1.Canvas.Handle;
  if not bEmptyRgn then
    begin
    hr := CreateRectRgn(0,0,MOPaintBox1.Width,MOPaintBox1.Height);
    CombineRgn(hr,hr,hrd,RGN_DIFF);
    SelectClipRgn(dc,hr);
    end;
  MOPaintBox1.Canvas.Draw(0,0,imFoto.Picture.Graphic);

  SelectClipRgn(dc,hrd);
  if not bEmptyRgn then
    begin
    Index := ListBox1.ItemIndex;
    if Index >= 0 then
      begin
      x := 0;
      repeat
        y := 0;
        repeat
          imKostka.Canvas.Draw(x,y,TBitmap(ListBox1.Items.Objects[Index]));
          y := y + TBitmap(ListBox1.Items.Objects[Index]).Height-1;
        until y > imKostka.Picture.Height;
        x := x + TBitmap(ListBox1.Items.Objects[Index]).Width-1;
      until x > imKostka.Picture.Width;
      end;
    MOPaintBox1.Canvas.Draw(0,0,imKostka.Picture.Bitmap);
    end;
end;

Commented:
And region creation

procedure TForm1.MOPaintBox1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  hr: HRGN;
begin
  Xo := X;
  Yo := Y;
  Xp := X;
  Yp := Y;
  if tbDraw.Down then
    begin
    if ssLeft in Shift then
      begin
      if bDrawLine then
        begin
        if ilPun <= MAXPUN then
          begin
          tabPun[ilPun].x := X;
          tabPun[ilPun].y := Y;
          Inc(ilPun);
          end;
        end
      else
        begin
        bDrawLine := True;
        tabPun[0].x := X;
        tabPun[0].y := Y;
        ilPun := 1;
        end;
      end;
    if ssRight in Shift then
      begin
      if ilPun > 2 then
        begin
        if bEmptyRgn then
          begin
          hrd := CreatePolygonRgn(tabPun,ilPun,ALTERNATE);
          bEmptyRgn := False;
          end
        else
          begin
          hr := CreatePolygonRgn(tabPun,ilPun,ALTERNATE);
          bEmptyUndoRgn := False;
          CombineRgn(hru,hrd,hrd,RGN_OR);
          CombineRgn(hrd,hrd,hr,RGN_OR);
          end;
        end;
      bDrawLine := False;
      ilPun := 0;
      MOPaintBox1.Invalidate;
      end;
    end;
end;
Mokule is right, windows.CreatePolygonRgn is the way to go.

Do you plan on having one map or many?

If your maps are going to change, you might consider creating some kind of editor by which you can create your map region ploygons with.

I recommend you look at the following articles on www.delphizine.com;

Although they are not articles on painting regions, there is great information on how to create a ploygon region editor.

If you are not a member, you can create a free limited time membership.

Shane

Hot Spots: Part I
http://www.delphizine.com/features/2002/02/di200202vh_f/di200202vh_f.asp

Hot Spots: Part II
http://www.delphizine.com/features/2002/03/di200203vh_f/di200203vh_f.asp

Author

Commented:
Thanks guys.. I'll read those articles shaneholmes.

Mokule, I'm trying to use your snippets but getting all kinds of undeclared identifiers..
bEmptyRgn, hrd, imFoto, etc..

I'm guessing you pulled this from another application?

Author

Commented:
Shane,

How do I become a free limited time member to view those articles?  I don't want to have to pay if at all possible.
You didn't hear this from me, but a little bird once told me that all you had to do was create a psuedo account using a free email address (i.e. yahoo, hotmail, etc) - <SMILE>

shane

Commented:
Sorry for some mess.
Yes of course it was cut from bigger application.

Author

Commented:
Thanks Shane  =)

One thing I don't think I made clear though in my original question..

I need to be able to color the individual sections..  They map sections have wonderful detail that I don't want to completely overwrite.. I just want to be able to give them a HUE of the color that owns them.. so some sort of opacity is needed here..  

Commented:
Here should be declaratons.
But now I'm not sure wether cut it from the same version.
My fault


{
type TUndo = record
  Xp,Yp: integer;
  Xk,Yk: integer;
  op:
  end;
  }
const
  MAXPUN = 100;

type
  TForm1 = class(TForm)
    ImageList1: TImageList;
    Panel1: TPanel;
    ListBox1: TListBox;
    Panel2: TPanel;
    ToolBar1: TToolBar;
    tbRect: TToolButton;
    tbEllipse: TToolButton;
    ToolButton3: TToolButton;
    StatusBar1: TStatusBar;
    Panel3: TPanel;
    MOPaintBox1: TMOPaintBox;
    Splitter1: TSplitter;
    tbNew: TToolButton;
    tbOpen: TToolButton;
    tbSave: TToolButton;
    ToolButton5: TToolButton;
    tbUndo: TToolButton;
    tbErase: TToolButton;
    ToolButton8: TToolButton;
    ToolButton1: TToolButton;
    tbDraw: TToolButton;
    tbFoto: TToolButton;
    opDlg: TOpenPictureDialog;
    imFoto: TImage;
    imKostka: TImage;

    procedure MOPaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure MOPaintBox1MouseLeave(Sender: TObject);
    procedure ListBox1DrawItem(Control: TWinControl; Index: Integer;
      Rect: TRect; State: TOwnerDrawState);
    procedure FormCreate(Sender: TObject);
    procedure MOPaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure MOPaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure MOPaintBox1Paint(Sender: TObject);
    procedure ListBox1Click(Sender: TObject);
    procedure tbNewClick(Sender: TObject);
    procedure tbEraseClick(Sender: TObject);
    procedure tbUndoClick(Sender: TObject);
    procedure tbFotoClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure tbDrawClick(Sender: TObject);
  private
    { Private declarations }
    bPocz: boolean;
    Xo,Yo: integer;
    Xp,Yp: integer;
    hrd: HRGN;
    hru: HRGN;
    bEmptyUndoRgn: boolean;
    bEmptyRgn: boolean;
    bDrawLine: boolean;
    tabPun: array[0..MAXPUN] of TPoint;
    ilPun: integer;
  public
    { Public declarations }
  end;
Right, like I said, the links only describe how to create your own editor to load your image (map), and create a polygon region of your map, which you can use in your painting algorithm

Shane
What I would do once you have the polygonal region of the map, is too create a algorithm which you can invert the color in that region .

Shane
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.