|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
This is "The Time Waster", a game I originally saw on the Mac that up till now has been missing a .NET port of the game. I believe this is the only game Mac's were designed to play, so really a PC should have no problem with cycles to spare :-) Step 1Modifying your form's startupFirst thing is, we need to change the way your form starts so we can control the loading procedure. This is fairly simple to accomplish. What you need to do is create a Shared Sub Main()
Application.Run(New frmSlider())
Application.Exit()
End Sub
This will start up the form named Public Sub New()
MyBase.New()
InitializeComponent()
initGame()
End Sub
All that's left to do now is change the project's startup properties to make it use our Step 2Creating the classPublic Class cPieces
' Cell this number is in
Public position As Integer = 0
' What number is this
Public number As Integer ' Image for the tile
Private image As New Bitmap(32, 32, Imaging.PixelFormat.Format32bppRgb)
' The X and Y of where its located
Private chords As New Point
' This sub takes a cell location (0-24) and determins the chords
' and sets the position
'
Public Sub setLocation(ByVal loc As Integer)
Dim row = Int(loc / 5)
Dim col = loc - (row * 5)
row = row * 32
col = col * 32
chords = New Point(col, row)
position = loc
End Sub
' This creates the tile and sets its number
'
Public Sub New(ByVal thisnumber As Integer)
Dim g As Graphics = Graphics.FromImage(image)
Dim f As New Font("Impact", 15, FontStyle.Regular)
Dim sze As SizeF = g.MeasureString(thisnumber, f)
g.FillRectangle(Brushes.White, 0, 0, image.Width, image.Height)
g.DrawRectangle(Pens.Black, 0, 0, image.Width, image.Height)
g.DrawString(thisnumber, f, Brushes.Black, _
(image.Width - sze.Width) / 2, _
(image.Height - sze.Height) / 2)
number = thisnumber
f.Dispose()
g.Dispose()
End Sub
' This draws the tile
'
Public Sub draw(ByVal g As Graphics)
If Not number = 24 Then
g.DrawImage(image, chords)
End If
End Sub
End Class
There really shouldn't be anything you haven't seen in here before, it's a standard class that stores the information for each tile and creates a bitmap.
Step 3ControlsGo to your form, add a Step 4Part of the codeYou always have to start out initializing your variables. See the Public debug = True
Public pieces(24) As cPieces
Public moves As Integer = 0
Public start As Date
Next the initialization sub. ' Initalize pieces and draw the board
'
Private Sub initgame()
Dim counter As Integer
Dim nextRnd As Integer
Dim rndPos(24) As Boolean
Dim randomNum As New Random
Me.ClientSize = New Size(32 * 5, 32 * 5)
moves = 0
start = Now
For counter = 0 To 24
rndPos(counter) = False
Next
For counter = 0 To 24
Do
nextRnd = randomNum.Next(0, 25)
Loop Until rndPos(nextRnd) = False
pieces(counter) = New cPieces(counter)
pieces(counter).setLocation(nextRnd)
rndPos(nextRnd) = True
Next
game.Invalidate()
End Sub
Pretty straight forward, it initializes your values as well as determines random locations for the tiles. This part: Do
nextRnd = randomNum.Next(0, 25)
Loop Until rndPos(nextRnd) = False
Generates a random number then checks to see that it hasn't used that number before. Very handy. Then the final command is Now the ' Redraw the cells
'
Private Sub game_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) Handles game.Paint
Dim counter As Integer
For counter = 0 To 24
pieces(counter).draw(e.Graphics)
Next
End Sub
Again very straight forward, asks each tile to redraw itself. Why not run your game now and marvel at the output? Step 5More interesting gameYour game is not very interesting now, try as you might clicking on tiles seems to do nothing! Well, perhaps we should take care of that. ' Converts mouse clicks into tile cells
'
Private Sub game_MouseUp(ByVal sender As Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles game.MouseUp
Dim posX As Integer = Int((e.X * 1.06) / 32)
Dim posy As Integer = Int((e.Y * 1.06) / 32)
If debug Then
Console.WriteLine("Mouse: " & posX & ", " & posy)
End If
moveTiles(posX, posy)
End Sub
This is a standard mouse event tied to the game ' Can we move one or more tiles, lets see
'
Sub moveTiles(ByVal thisCellX As Integer, ByVal thisCelly As Integer)
Dim counter As Integer
Dim thisCell = (thisCelly * 5) + thisCellX
Dim blankCellY = Int(pieces(24).position / 5)
Dim blankCellX = pieces(24).position - (blankCellY * 5)
Dim blankCell = pieces(24).position
If debug Then
Console.WriteLine("")
Console.WriteLine("Blank Cell X: " & blankCellX & ", Y: " & _
blankCellY)
Console.WriteLine(" This Cell X: " & thisCellX & ", Y: " & _
thisCelly)
End If
If blankCellY = thisCelly Then ' Move horizontally
moves += 1
If blankCell > thisCell Then ' Move to right
For counter = blankCell - 1 To thisCell Step -1
swaptiles(counter, counter + 1)
Next
End If
If blankCell < thisCell Then ' Move to Left
For counter = blankCell + 1 To thisCell
swaptiles(counter, counter - 1)
Next
End If
ElseIf blankCellX = thisCellX Then ' Move Vertically
moves += 1
If blankCell > thisCell Then ' Move Down
For counter = blankCell To thisCell + 5 Step -5
swaptiles(counter, counter - 5)
Next
End If
If blankCell < thisCell Then ' Move Up
For counter = blankCell To thisCell - 5 Step 5
swaptiles(counter, counter + 5)
Next
End If
End If
Dim Winner As Boolean = True
For counter = 1 To 24
If pieces(counter).position <> counter Then Winner = False
Next
If Winner Then
MsgBox("You have won in " & moves & " moves and wasted " & _
DateDiff(DateInterval.Minute, start, Now) & _
" minutes, don't you feel productive.", &
MsgBoxStyle.Exclamation, "Time Waster")
End If
End Sub
I'm not going to explain this, it's just basic math. If the cell and the blank are in the same row then yadda yadda yadda. However, at the end of the ' This function takes a cell position from the board and figures out
' what tile occupies that space
'
Private Function findtile(ByVal findme As Integer)
Dim Counter As Integer
Dim tiles(24)
' Create an array of tiles but based on position not value
'
For Counter = 0 To 24
tiles(pieces(Counter).position) = Counter
Next
Return tiles(findme)
End Function
' Swaps the cells on the board
'
Private Sub swaptiles(ByVal source As Integer, _
ByVal destination As Integer)
' Figures out what tile is at the cell
'
Dim sTileNumber = findtile(source)
Dim dTileNumber = findtile(destination)
' Changes them
'
pieces(sTileNumber).setLocation(destination)
pieces(dTileNumber).setLocation(source)
If debug Then Console.WriteLine("Swapping: Number: " & _
findtile(source) & " (Position: " & source & ") and Number: " & _
findtile(destination) & " (Position: " & destination & ")")
game.Invalidate()
End Sub
Ok, I lied, you need two more Step 6Creating a better interfaceGo to your form and drag out that good ol' menubar control and create three menu entries. Call the root menu "Game Controls" with "New" and "Exit" as its menu choices. Double click on "New" and set it to regenerate the board. Double click on "Exit" and tell it ' Menu Commands
'
Private Sub MenuItem2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MenuItem2.Click
initgame()
End Sub
Private Sub MenuItem3_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MenuItem3.Click
Me.Close()
End Sub
Well, that's it. You should have a fully working tile game.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||