Solved

Hexagon-shaped image or picture boxes?

Posted on 1998-12-07
17
330 Views
Last Modified: 2010-05-03
I am attempting to create a tile-based strategy game and would like the be able to create map tiles in hexagon shapes rather than squares.  Is there any way to create a control array of hexagon shaped tiles all interlocked together on a form?  Each tile must have different values (visible if explored, description, etc.).  Can this be done with one big map picture and creating multiple hotspots, or do I still have to go with individual hexagon-shaped image boxes?  Be explicit with your info as I am a dummy...I will award more than 200 points if I get something that works well.  Thanks so much.  --Vingamel  
0
Comment
Question by:Vingamel
  • 8
  • 6
  • 2
  • +1
17 Comments
 

Expert Comment

by:skiprosebaugh
Comment Utility
You'll probably have to go with individual imageboxes. I'll try to scrape togeather a solution for you. BTW, do you have a control for hexagon-shaped imageboxes or do you need that too?
0
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
This might help you. This shows how to change shape of a form. You can do similar things for a control.

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=794

Private Declare Function CreateEllipticRgn Lib "gdi32" _
        (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, _
        ByVal Y2 As Long) As Long

Private Declare Function SetWindowRgn Lib "user32" _
        (ByVal hWnd As Long, ByVal hRgn As Long, _
        ByVal bRedraw As Boolean) As Long

Private Sub Form_Load()
       Show 'The form!
       SetWindowRgn hWnd, CreateEllipticRgn(0, 0, 300, 200), True
End Sub
0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
To Skiprosebaugh: Kinda what I figured is that I will need individual image boxes...re: Hex-shaped image-boxes, I do need the code for that if you can provide that.

To Mirkwood: With your code above, do I just plop this into a module and it takes off?...like I said, I need explicit info on this stuff.  I will try this tonight and see how it goes.  Thanks.  Still dumb, but still learning.--Vingamel
0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
I increased the point value for this question because I want explicit instructions--not just code--on how to do this.  Assume I a beginner, because I am.  I have bumped in API stuff before, but I plop it into code boxes and hit run, and walla, nothin' happens.  See, I need to know the whole smorgasbord here.  Thanks a gob.  --Vingamel
0
 
LVL 13

Accepted Solution

by:
Mirkwood earned 300 total points
Comment Utility
OKE, Here is the complete code.
What do you need to do.
1) Create a new user control
2) Add this code to this usercontrol
3) Create a form
4) Add instances usercontrol to the form

What does the code do
1) Create a control that has the shape of a hexagon
2) Control has property backcolor
3) Control shows msgbox with name when clicked upon

How does it work:
1) On resize the usercontrol is made a square
2) On resize is creates a new window shape using the polygon region functions.

Private Declare Function CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount As Long, ByVal nPolyFillMode As Long) As Long
Private Type POINTAPI
        x As Long
        y As Long
End Type

Private Declare Function SetWindowRgn Lib "user32" _
        (ByVal hWnd As Long, ByVal hRgn As Long, _
        ByVal bRedraw As Boolean) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Dim hRegion As Long

Public Property Get BackColor() As OLE_COLOR
    BackColor = UserControl.BackColor
End Property

Public Property Let BackColor(ByVal newvalue As OLE_COLOR)
    UserControl.BackColor = newvalue
End Property


Private Sub UserControl_Click()
    'Display name
    MsgBox Ambient.DisplayName
End Sub


Private Sub UserControl_Resize()
        'Make square
        If (Width > Height) Then Width = Height
        If (Height > Width) Then Height = Width
       
        'Create polygon
        Dim points(5) As POINTAPI
        'Top
        points(0).x = (ScaleWidth / 2 + ScaleLeft) / Screen.TwipsPerPixelX
        points(0).y = ScaleTop / Screen.TwipsPerPixelY
        'Right top
        points(1).x = (ScaleLeft + ScaleWidth) / Screen.TwipsPerPixelX
        points(1).y = (ScaleHeight / 3 + ScaleTop) / Screen.TwipsPerPixelY
       
        'right bottom
        points(2).x = points(1).x
        points(2).y = (2 * ScaleHeight / 3 + ScaleTop) / Screen.TwipsPerPixelY
       
        'Bottom
        points(3).x = points(0).x
        points(3).y = (ScaleTop + ScaleHeight) / Screen.TwipsPerPixelY
       
        'Right top
        points(4).x = ScaleLeft / Screen.TwipsPerPixelX
        points(4).y = points(2).y
       
        'right bottom
        points(5).x = points(4).x
        points(5).y = points(1).y
       
        'Delete region
        If (hRegion <> 0) Then DeleteObject hRegion
'        hRegion = CreateEllipticRgn(ScaleLeft / Screen.TwipsPerPixelX, ScaleTop / Screen.TwipsPerPixelY, (ScaleLeft + ScaleWidth) / Screen.TwipsPerPixelX, (ScaleTop + ScaleHeight) / Screen.TwipsPerPixelY)
        'Change window size to a region
        hRegion = CreatePolygonRgn(points(0), 6, 2)
        'Make region active region
        SetWindowRgn hWnd, hRegion, True
End Sub

Private Sub UserControl_Terminate()
        'Destroy region
        If (hRegion <> 0) Then DeleteObject hRegion
        hRegion = 0
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    BackColor = PropBag.ReadProperty("BackColor", &H8080FF)
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    PropBag.WriteProperty "BackColor", BackColor, &H8080FF
End Sub

0
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
BTW, the old example also worked, you should have tried harder. For example click on it or change the background color.
0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
Thanks, Mirkwood, for all your help.  I will work with this and see what I come up with.  I will take your word that it works and not make you wait until I test it out.  --Vingamel
0
 
LVL 1

Expert Comment

by:Eklipse
Comment Utility
Hi
I saw the question and I was looking for a simple answer.
There are many answers to your questions,and they vary from to a simple one to very complex.
I'm gonna show you a method (no API involved) .Please follow the indications step by step,VERY carefully:

1-You will need a bitmap with 100x100 pixels size by example with a black background and a white hexagon
Please be careful :Black (0,0,0) and white (255,255,255) .Save it like Hexagon.bmp

Next,you need an other bitmap,that you will use like texture.By example,clouds.bmp .
(I think there's a bitmap in the windows directory with that name)

1-Start VB ,New Project,Select ActiveX Control
 A UserControl form appear in the project.The UserControl it's a kind of form,that you can use for develop
visual controls.

2-Select UserControl properties (F4) and set:
BackStyle=Transparent
MaskColor=&H00000000&
MaskPicture=Here you must load the bitmap that you built (the hexagon one)
Picture=Here you must load the clouds.bmp o the bitmap what you want.

2-Select a control label and put on the form
Select Label's properties and set:
BackStyle=Transparent (this is VERY important,don't forget it)
Caption=Whatever you want
Try to put the label in the upper left corner of the UserControl form.
You don't have to worry about the position,we solve that later.

If everything goes right,you will see a single form with a bitmap that you select.You won't see the hexagon...yet

3-add this code.It will set the form size,and we'll add some events and properties
Drop this code in the usercontrol :
--------------------------------------------------------------------------------------------
Option Explicit
Dim PicSelected$
Event Click() 'Activate the Click Event
Event DblClick() 'Activate de DblClick Event

Private Sub UserControl_Resize() 'Set Size constant (100 is the size of the bitmap mask)
   Size 100 * Screen.TwipsPerPixelX, 100 * Screen.TwipsPerPixelY
End Sub

Private Sub UserControl_Click() 'Enable Click
   RaiseEvent Click
End Sub

Private Sub usercontrol_dblclick() 'enable DblClick
   RaiseEvent DblClick
End Sub

'Establish a property to change the bitmap
Public Property Let PicturePath(ByVal P As String) 'Select Picture
On Error GoTo Perror
PicSelected = P 'Remember the picture selected
UserControl.Picture = LoadPicture(PicSelected) 'Load the picture
PropertyChanged "PicturePath" 'Alert for changes
Exit Property
Perror:
MsgBox "Error " & Err.Number & " " & Err.Description 'Error if you give a wrong picture path
End Property

Public Property Get PicturePath() As String
End Property

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
 PropBag.WriteProperty "PicturePath", PicSelected, ""
End Sub
-------------------------------------------------------------------------------------------------------------

4-Select File ,Add project and select Standard EXE, open it
In the project explorer,you will see two projects:Project1 with UserControl form and Project2 with
a standard Form1.
Open the Project Explorer
Select the UserControl form in the project explorer ,double click it,and close it(clicking in X) ,so we only see the Form1.

5-Select ToolBox
You will see a new control:It's like a Square 4-divided with a pencil.That is your control.
Go with the mouse and move it over  (don't select it) .it will display a UserControl1 tooltip.
(if the control is gray you cannot use it ; it's beacuse the UserControl Form window is open;you must close it and you will see
the control in color)

6-Select the UserControl1 control from the ToolBox  and drop it in the form.If everything goes ok,you will see the hexagon
and the label. You can drop many UserControl1 in the form.

You can select a different bitmap in every hexagon,with the PictureGraph property.

7-Go to the UserControl form and try to center the label into the hexagon.Yep it's a little difficult because you cannot see
the hexagon.

I think this is the simplest way that I know.It has many problems:
1-It would be desiderable that you can change the hexagon size ,in design time.In this example the hexagon size
depends on a bitmap,so you must change the MaskBitmap to accomplish it.(Baaaaad)
2-Note that this is a very single solution.
Better solution would include more properties (like hexagon size,rotation,more events,etc.) but you will need to know
about Classes,API calls ,and another things.

3- you can compile the example and generate a OCX.Select de UserControl and then File,Compile UserControl.OCX
(save it in Windows\System\)
Later,for use in other project,you have to include the OCX,using Project components and selecting de OCX

Maybe this example helps you

Good Luck
Fer
 
 
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
If you have problems or questions, tell me. Please also tell me if it works OK. That makes me feel good :-)
0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
To Mirkwood & Eklipse:
I already gave Mirkwood the 300 points, but I see that Eklipse has given me another option as well.  Eklipse...thanks so much for the second opinion, and I apologize that I was unable to get your resolution before shooting the points over to Mirkwood.  If your fix is better than Mirkwood's, I should like to compensate you some how for your time.  Thanks to both of you for your expert help!!!
--Vingamel
0
 
LVL 1

Expert Comment

by:Eklipse
Comment Utility
Well ,I hope this things help you and let's you know what happened.

Happy christmas
Fer

0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
Eklipse: Your solution worked well...also gave me some other ideas for aspects of project I am working on.  Thanks very much, and Merry Christmas to you.  --Vingamel
0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
Mirkwood: Your solution gave me a hexagon (with unequal sides).  Curious if hexagon can contain various bitmaps so that each hex has its own unique terrain?  Anyway, you've helped me considerably and I thank you.  Merry Christmas.  --Vingamel
0
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
Yes, just set the picture property of the usercontrol and see what happens.
Now, make the picture property a property of your control.

0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
Mirkwood: Very cool...and I supposer there is a way to fix the shape of the hex so that the sides are equal, and then plop them down on a form (see the original question above).  Thank ya very much.  --Vingamel  

Eklipse: Although your solution gave me a hex, trying to interconnect several onto a form is strange because we actually dealing with squares with invisible corners...so a user could think he was clicking on hex one, but actually click on the invisible corner of the neighboring hex...or am I not seeing something here.  Thanks so much.  --Vingamel
0
 
LVL 13

Expert Comment

by:Mirkwood
Comment Utility
Sure just change position of  points.
0
 
LVL 1

Author Comment

by:Vingamel
Comment Utility
Thanks so much...I should be able do okay now and not bother you any more.  Until my next 300 point question, see ya.  --Vingamel
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now