-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfrmSnake.frm
375 lines (311 loc) · 9.69 KB
/
frmSnake.frm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
VERSION 5.00
Begin VB.Form frmSnake
BackColor = &H00000000&
BorderStyle = 0 'None
Caption = "Snake"
ClientHeight = 6510
ClientLeft = 0
ClientTop = 0
ClientWidth = 8010
KeyPreview = -1 'True
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 6510
ScaleWidth = 8010
ShowInTaskbar = 0 'False
StartUpPosition = 3 'Windows Default
WindowState = 2 'Maximized
Begin VB.Timer timGameLoop
Enabled = 0 'False
Left = 2880
Top = 2040
End
Begin VB.Shape shpFood
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 135
Left = 2160
Shape = 1 'Square
Top = 840
Width = 135
End
Begin VB.Shape shpBlock
FillColor = &H00C00000&
FillStyle = 0 'Solid
Height = 255
Index = 0
Left = 1080
Shape = 1 'Square
Top = 840
Visible = 0 'False
Width = 255
End
End
Attribute VB_Name = "frmSnake"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Const INTERVAL As Long = 100
Dim lastKeyPress As Integer
Dim nextKeyPress As Integer
Dim blockSize As Long
Dim blocksWide As Long
Dim headIsOnScreen As Long
Dim tailBlock As Long
Dim headBlock As Long
'The tags of all blocks contain the LIFETIME of the block in clock ticks
' Each timer pulse decreases all block lifetimes by 1. Anything with 0 life left is destroyed
'
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
'If it it a up, down, left, right - use it
Select Case KeyCode
Case vbKeyUp, vbKeyW
If lastKeyPress <> vbKeyDown Then
nextKeyPress = vbKeyUp
End If
Case vbKeyDown, vbKeyS
If lastKeyPress <> vbKeyUp Then
nextKeyPress = vbKeyDown
End If
Case vbKeyRight, vbKeyD
If lastKeyPress <> vbKeyLeft Then
nextKeyPress = vbKeyRight
End If
Case vbKeyLeft, vbKeyA
If lastKeyPress <> vbKeyRight Then
nextKeyPress = vbKeyLeft
End If
Case vbKeyEscape
'Quit
End
End Select
End Sub
Private Sub MoveFoodOnThisComputer()
'Move food to random location
Dim blockX As Long
Dim blockY As Long
Dim i As Long
Dim continue As Boolean
shpFood.Visible = False
'Pick random numbers in loop
Do
'Pick a random block from 0 to SCREEN_<h/w> - 1
blockX = Int((blocksWide - 1) * Rnd)
blockY = Int((BLOCKS_HIGH - 1) * Rnd)
'Move the food
shpFood.Left = blockSize * blockX + ((blockSize - shpFood.Width) / 2)
shpFood.Top = blockSize * blockY + ((blockSize - shpFood.Height) / 2)
'Check if it's in the snake
continue = False
For i = tailBlock To headBlock
If CheckCollision(shpBlock(i), shpFood) Then
continue = True
Exit For
End If
Next
Loop While continue
shpFood.Visible = True
End Sub
Private Function CheckCollision(ctrl1 As Control, ctrl2 As Control) As Boolean
CheckCollision = ctrl1.Left + ctrl1.Width > ctrl2.Left And _
ctrl2.Left + ctrl2.Width > ctrl1.Left And _
ctrl1.Top + ctrl1.Height > ctrl2.Top And _
ctrl2.Top + ctrl2.Height > ctrl1.Top
End Function
Private Sub Form_Load()
Randomize
End Sub
Private Sub timGameLoop_Timer()
'Do block life draining
Dim i As Long
For i = tailBlock To headBlock
shpBlock(i).Tag = Int(shpBlock(i).Tag - 1)
If shpBlock(i).Tag = 0 Then
'Kill
Unload shpBlock(i)
tailBlock = tailBlock + 1
End If
Next
'Process head block
If headIsOnScreen Then
'Set tail colour
shpBlock(headBlock).FillColor = vbYellow
'Determine new position for the head
Dim newX As Long 'In blocks
Dim newY As Long 'In blocks
newX = shpBlock(headBlock).Left / blockSize
newY = shpBlock(headBlock).Top / blockSize
Select Case nextKeyPress
Case vbKeyUp
newY = newY - 1
'Check if off screen
If newY < 0 Then
'Jump to bottom
newY = BLOCKS_HIGH - 1
End If
Case vbKeyDown
newY = newY + 1
'Check if off screen
If newY >= BLOCKS_HIGH Then
'Jump to top
newY = 0
End If
Case vbKeyLeft
newX = newX - 1
'Check if off screen
If newX < 0 Then
'Notify snake exit, then exit sub
headIsOnScreen = False
EventCSnakeExit False, newY
Exit Sub
End If
Case vbKeyRight
newX = newX + 1
'Check if off screen
If newX >= blocksWide Then
'Notify snake exit, then exit sub
headIsOnScreen = False
EventCSnakeExit True, newY
Exit Sub
End If
End Select
'Load new head block / notify of snake exit
MakeNewHead newX, newY
'Check for collision with ourselves
For i = tailBlock To headBlock - 1
If CheckCollision(shpBlock(headBlock), shpBlock(i)) Then
EventCSnakeDead
Exit Sub
End If
Next
'Check for food collision
If shpFood.Visible And CheckCollision(shpBlock(headBlock), shpFood) Then
'Eat the food
shpFood.Visible = False
EventCFoodEat
End If
End If
'Copy lastKeyPress
lastKeyPress = nextKeyPress
End Sub
'Creates a new head block at the given block position
Private Sub MakeNewHead(ByVal blockX As Integer, ByVal blockY As Integer)
headBlock = headBlock + 1
Load shpBlock(headBlock)
With shpBlock(headBlock)
'Set block lifetime
.Tag = SnakePieceCount
'Colour and position
.FillColor = vbBlue
.Move blockX * blockSize, blockY * blockSize
.Visible = True
End With
End Sub
' ======================================
' Game Events
' ======================================
'Occurs after food has been eaten on any computer
' makeFood tells weather food should be created on this computer
Public Sub EventFoodEaten(ByVal makeFood As Boolean)
'Pause snake for 1 tick
Dim i As Long
For i = tailBlock To headBlock
shpBlock(i).Tag = Int(shpBlock(i).Tag + 1)
Next
'Make food
If makeFood Then MoveFoodOnThisComputer
End Sub
'Occurs when the snake's head enters this computer
' isRight is true when the snake enteres from the right
' position is the block from the stop the snake entered at (top block is 0)
' Number of pieces in the snake is from SnakePieceCount
Public Sub EventSnakeEnter(ByVal isRight As Boolean, ByVal position As Integer)
'Get X coordinate + update current keys
Dim blockX As Integer
If isRight Then
lastKeyPress = vbKeyLeft
nextKeyPress = vbKeyLeft
blockX = blocksWide - 1
Else
lastKeyPress = vbKeyRight
nextKeyPress = vbKeyRight
blockX = 0
End If
'Make new head
headIsOnScreen = True
MakeNewHead blockX, position
End Sub
'Occurs when the snake is dead
Public Sub EventSnakeDead()
'If we have the snake, colour head red
If headIsOnScreen Then
shpBlock(headBlock).FillColor = vbRed
shpBlock(headBlock).ZOrder
End If
'Stop timer
timGameLoop.Enabled = False
End Sub
'Occurs when the game is started and restarted
Public Sub EventRestartGame(ByVal makeSnake As Boolean, ByVal makeFood As Boolean)
'Calculate block size
blockSize = ScaleHeight / BLOCKS_HIGH
blocksWide = ScaleWidth / blockSize
'Hide food
shpFood.Visible = False
shpFood.Width = blockSize / 2
shpFood.Height = blockSize / 2
'Set block template size
shpBlock(0).Height = blockSize
shpBlock(0).Width = blockSize
'Reset stuff
lastKeyPress = vbKeyUp
nextKeyPress = vbKeyUp
'Show snake screen and hide the snake and the food
Dim i As Long
If headBlock > 0 Then
For i = tailBlock To headBlock
Unload shpBlock(i)
Next
End If
tailBlock = 1
headBlock = 0
shpFood.Visible = False
'Create snake if nessesary
If makeSnake Then
'Put snake in middle
Load shpBlock(1)
Load shpBlock(2)
Load shpBlock(3)
shpBlock(2).Top = Int((BLOCKS_HIGH - 1) / 2) * blockSize
shpBlock(2).Left = Int((blocksWide - 1) / 2) * blockSize
shpBlock(2).Visible = True
shpBlock(3).FillColor = vbYellow
shpBlock(2).Tag = 2
shpBlock(1).Left = shpBlock(2).Left
shpBlock(1).Top = shpBlock(2).Top + blockSize
shpBlock(1).Visible = True
shpBlock(3).FillColor = vbYellow
shpBlock(1).Tag = 1
shpBlock(3).Left = shpBlock(2).Left
shpBlock(3).Top = shpBlock(2).Top - blockSize
shpBlock(3).Visible = True
shpBlock(3).FillColor = vbBlue
shpBlock(3).Tag = 3
headBlock = 3
headIsOnScreen = True
Else
headIsOnScreen = False
End If
'Create food if nessesary
If makeFood Then
MoveFoodOnThisComputer
End If
'Restart timer
timGameLoop.INTERVAL = 0
timGameLoop.INTERVAL = INTERVAL
timGameLoop.Enabled = True
Show
End Sub