Important note: The first few postings were 2008, but i switched to 2010 so while the code is exactly the same, you may not be able to directly load the project into 2008. I don't know for sure.
This thread over the next few weeks will document the development of a really simple game written in .net. It will demonstrate the following programming uses:
1. Doing custom graphics drawing in the paint event.
2. Showing a simple game loop
3. Using windows api with .net for input (specifically, keypresses)
4. Later on, simple sound functionality will be added.
5. Also, for flexibility, the game window will be able to be resized dynamically.
So here goes:
The game we will be creating is a Snake clone called "Wormy".
More information on exactly what a Snake game is can be found here.
It is pretty much industry standard to figure out the function of a program before you write it, then come up with a user interface. I know what functionality i expect out of the program, and have created a simple form with a score area on the left. It consists of a docked panel with 8 labels on it. four for text and four for various data feedback to the game player. then i added another control for the game area. A picturebox control. I docked this control in the center. Now i can set the form to whatever size i wish and the game area will resize to fit. The finished user interface is below: You will see i also added a command button. This will be used to start the game loop. I've since changed the caption to "Start". Also i set the image control's backcolor to brown because it's kind of dirtlike and it's a game with worms in it.
Last edited by Lord Orwell; Jan 19th, 2011 at 09:14 AM.
Reason: changed title
Now we add some simple code as proof of concept. Since we will be drawing in the paint event directly to the picturebox control, we need to set the form's doublebuffer property to true. This ensures we won't have any annoying flickering or graphics areas not being properly redrawn. Basically what it does is redirect all drawing we do onto a buffer and when all drawing is done, the buffer is displayed. Makes for much smoother graphics.
I created a public variable which will be used for multiple purposes later, but now is only going to serve one purpose: To display text on the screen telling you to press start to play. Here's the code:
vb Code:
Public Class frmWormy
Public NowPlaying As Boolean
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
NowPlaying = False
End Sub
Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If NowPlaying = False Then
e.Graphics.DrawString("Press Start to Play", Me.Font, Brushes.Azure, 100, 100)
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Basically all this does is create a new variable called "NowPlaying". Clicking the command button toggles it to true or false. While false, the paint event draws a message on the paint box.
In the next installment, i will add both a simple starter gameloop and code to detect keypresses, as well as some variables that will be needed later on.
Last edited by Lord Orwell; May 30th, 2008 at 09:25 PM.
ok now that proof of concept has been shown, it's time to implement a game loop. This is in fact pretty easy. all you have to do for a simple game such as this is add a timer control with interval set to a low value. Since i am also using this control to detect keyboard input AT ALL TIMES, i have set it at an interval of one, and it is automatically started with the form. The purpose of this is for future expandability. I could for example detect when the enter key is pressed and start the game.
Other changes i have made to the code are to add constants to represent virtual key codes of the arrow keys and the P and U keys for Pause/Unpause functionality. These codes are used with the GetAsyncKeyState api call. I added a module to the program, placed the declaration inside it along with the currently needed declarations, and added a simple-to-call function that will return in plain text what key was pressed.
You can get a full list of the virtual keycodes and exactly what they are here
.
This part of the design required me to come to a decision: Did i want to allow diagonal movement? I was required to come up with an answer on this because this would determine how i designed the keypress detection routine. If i allowed diagonal movement and wanted to use the arrow keys i would need to be able to detect multiple keypresses. I decided against this and stuck to a simple to understand design so people could easily understand how the keypress detection works.
As a final note, i added code to retrieve/save the high-score in a my.settings.HighScore You can access your project's settings tab and create any descriptive setting you wish here and use them for whatever you wish, including custom user colors, form placement, etc. So far the attached project uses a single setting so you should have no trouble understanding how they work.
Other various changes include removing the test code for drawing on the picturebox and adjusting the form layout a little for appearance.
So basic run-down of the changes:
1. user input implemented through getasynckeystate and virtual keycodes
2. game loop implemented by placing timer on form(but not used for anything other than user input yet)
3. adjusted user interface, and made button function pretty much as it will in final version
4. implemented load/save of high-score using my.settings
about the only thing it does right now is show which key you have pressed in the caption!
In the next version we will do more planning, such as the dimensions of the game grid, and set up most of the variables needed (such as a multi-dimensional array for the game grid)
EDIT: Had to remove attached package. The IDE corrupted the form and it was unreadable. The next post has a working zip file.
Last edited by Lord Orwell; May 31st, 2008 at 11:30 PM.
ok i managed to save the data from the last post. it somehow corrupted the form1 file. I managed to get the code out with notepad. Anyway...
On to today's update:
Edit: I didn't realize until post 17 that my "press start to play" was lost in the file corruption. It is back in posts 18 on.
Today is a relatively simple update to the setup. An implementation of the game grid. This is all of the added code that lets you draw whatever you want on the game screen:
Code:
Dim GameGrid(49, 49) As String 'game area
that goes in the general declarations of the form
This is the code i have added to the picture box's paint event:
Code:
Private Sub pbGameArea_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles pbGameArea.Paint
Dim x As Integer, y As Integer
Dim Squaresize As Point
'code dynamically figures out how big squares are
Squaresize.X = Me.pbGameArea.Width / 50
Squaresize.Y = Me.pbGameArea.Height / 50
For x = 0 To UBound(GameGrid, 1)
For y = 0 To UBound(GameGrid, 2)
Select GameGrid(x, y)
Case "S" 'snake part
e.Graphics.FillRectangle(Brushes.Red, x * Squaresize.X, y * Squaresize.Y, (Squaresize.X), (Squaresize.Y))
Case "1", "2", "3", "4", "5", "6", "7", "8", "9" 'food pellets of differing value
e.Graphics.FillRectangle(Brushes.Pink, x * Squaresize.X, y * Squaresize.Y, (Squaresize.X), (Squaresize.Y))
Case "W" 'wall (future expansion?)
e.Graphics.FillRectangle(Brushes.Black, x * Squaresize.X, y * Squaresize.Y, (Squaresize.X), (Squaresize.Y))
End Select
Next
Next
End Sub
now simplicity is as simplicity does, but i left a little flexibility in the program. If you change the dimensions of the game grid in code for whatever reason, it automatically adjusts and draws it correctly anyway based on the window size. An important note to realize is that if you change the window size AT RUN TIME the game grid stretches and adjusts in real time as well!
To keep the game basic (and keep with the flavor of a snake game) we are representing everything with squares, although i have made a concession and used color. To see the grid at work, press the start button. I have added a simple initialization routine that will place one of each type of square in the game grid, and you can witness that the grid drawing routine does in fact work. Note i had to add a refresh in the game loop so it would redraw the window. Attached is a new (AND WORKING) project with the listed changes as well as some minor differences thanks to the IDE screwing it up.
In the next installment, we will be coupling the keyboard input with the game grid, and you will be able to cursor around the snake's head, although his tail won't be functional yet.
Last edited by Lord Orwell; Jan 18th, 2011 at 12:05 AM.
OK there are a few different changes made to the program. One, i changed the class to a standard module.
Second, you can now cursor around the screen with the snake (but tail doesn't erase)
Next expansion will keep the snake moving automatically and add collision detection to kill you with. Tail erasing won't be implemented fully until food pellets are used.
Various code changes were added throughout the program to implement the movement, starting with the initialize sub:
Code:
rivate Sub InitializeNewGame()
Dim x As Integer, y As Integer
'first clear the game grid to ensure no garbage is left from last game
GameGrid.Initialize()
''''purpose of next two for loops is to draw a wall around game grid
For x = 0 To UBound(GameGrid)
GameGrid(x, 0) = "W"
GameGrid(x, UBound(GameGrid, 2)) = "W"
Next
For y = 0 To UBound(GameGrid, 2)
GameGrid(0, y) = "W"
GameGrid(UBound(GameGrid), y) = "W"
Next
'Now set the snake start position in the grid
'this code has been changed because we now store snake position
'and we also want to make sure we center that snake.
Call InitializeSnake(Int(UBound(GameGrid) / 2), Int(UBound(GameGrid, 2) / 2))
GameGrid(Int(UBound(GameGrid) / 2), Int(UBound(GameGrid, 2) / 2)) = "S"
NowPlaying = True : Paused = False
End Sub
Notice also it calls a 2nd initialization sub in the module, called initialize snake. All it does is make sure the snake's personal array is empty and then sets the pointers to start values. Then it places the head of the snake in position 1.
Code:
Public Sub InitializeSnake(ByVal x As Integer, ByVal y As Integer)
HeadPointer = 1
TailPointer = 0
body.Initialize()
body(1).X = x
body(1).Y = y
End Sub
The game loop has this change done to it:
Code:
If NowPlaying = True Then
If Paused = False Then
CL = CL + 1
If CL = 10 Then
CL = 0
HeadPos = MoveHead(InKey)
'add head to game grid
GameGrid(HeadPos.X, HeadPos.Y) = "S"
'
'
'actual game loop here
'
'
End If
Me.pbGameArea.Refresh()
End If
End If
pretty self explanitory, but it basically slows down the snake loop. Added to the loop is a routine that moves the head then places the new head position in the game grid. The routine it calls is here:
Code:
Function MoveHead(ByVal Direction As String) As Point
'this function is going to return the new head position
Dim CurrentHeadPos As Point
CurrentHeadPos = body(HeadPointer)
Select Case Direction
Case "UP"
CurrentHeadPos.Y -= 1
Case "DOWN"
CurrentHeadPos.Y += 1
Case "LEFT"
CurrentHeadPos.X -= 1
Case "RIGHT"
CurrentHeadPos.X += 1
End Select
'next lines increment headpointer (resetting to zero if necessary)
'then add the new headpos to the array
HeadPointer += 1
If HeadPointer = 1000 Then HeadPointer = 0
body(HeadPointer) = CurrentHeadPos
'now, move tail pointer unless snake is currently growing
If AmountToGrow = 0 Then
TailPointer += 1
If TailPointer = 1000 Then TailPointer = 0
Else
AmountToGrow -= 1
End If
MoveHead = CurrentHeadPos
End Function
there's some future support in here already. If i set a value to AmountToGrow the snake's tail will grow by that much. You can't actually tell this yet though since the tail itself hasn't been implemented. Remember that most of the code in this sub is tail support. the whole purpose of the array in this sub is merely to track where the snake's tail is laying.
Other minor changes include adding more comments and renaming some variables for clarity.
Also i changed some data types in the paint function due to an unacceptable precision error about where the boxes were being drawn in relation to the game window.
in this update:
* changed some variables default values: Nowplaying defaults to false, and the head and tail indexes start at zero.
* Added a "CurrentDirection" string variable. this stores the current direction the snake is moving and this is referenced during each tick of the inner game loop to keep the snake moving. It is also used in a routine added to the game loop which prevents you from doing a 180 degree direction change.
* Added a line of code in module to assign value to "TailPositionToErase" which will be obviously used to delete the trailing end of tail.
Code:
TailPositionToErase = body(TailPointer)
* added a simple collision detection routine that pops up an alert if you hit anything. This will be used in a future update to exit game on death or detect when you eat food.
*the tail deletion is working now. I hardcoded a set length of 5 currently since there's no way to eat with no food on the grid. But i did this by adding a value of 5 to the "amount to grow" so you can see it works perfectly.
The game loop changes are highlighted in red...
Code:
Sub tmrGameLoop_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGameLoop.Tick
Dim InKey As String
Dim HeadPos As Point
InKey = WhichKeyPressed()
'next lines give keyboard support for pause/unpause by
'simply calling the event for the command button when the
'game is running.
If InKey = "P" And Paused = False Or InKey = "U" And Paused = True Then
If NowPlaying = True Then Call btnStart_Click(btnStart, e)
Else
If InKey = "UP" Or InKey = "DOWN" Or InKey = "LEFT" Or InKey = "RIGHT" Then
'next lines prevent you reversing direction
Select InKey
Case "UP"
If CurrentDirection = "DOWN" Then InKey = "DOWN"
Case "DOWN"
If CurrentDirection = "UP" Then InKey = "UP"
Case "LEFT"
If CurrentDirection = "RIGHT" Then InKey = "RIGHT"
Case "RIGHT"
If CurrentDirection = "LEFT" Then InKey = "LEFT"
End Select
CurrentDirection = InKey 'stores last key press to track direction
' snake needs to move if no key pressed
' next time
End If
End If
If NowPlaying = True Then
If Paused = False Then 'nothing moves/happens if paused
CL = CL + 1
If CL = 10 Then
CL = 0
'next line keeps snake moving when no keys pressed
If InKey = "" Then InKey = CurrentDirection
HeadPos = MoveHead(InKey)
'add head to game grid
GameGrid(TailPositionToErase.X, TailPositionToErase.Y) = "" 'erase tail
If CurrentDirection <> "" Then
Select Case GameGrid(HeadPos.X, HeadPos.Y)
Case "S", "W" 's is snake and w is a wall segment
nowplaying = false: MsgBox("dead"): btnStart = "Start"
Case "1", "2", "3", "4", "5", "6", "7", "8", "9"
MsgBox("food")
End Select
End If
GameGrid(HeadPos.X, HeadPos.Y) = "S"
'
'
'actual game loop here
'
'
End If
Me.pbGameArea.Refresh()
End If
End If
End Sub
Bugs fixed in this post: 1. I was incorrectly clearing the game array. this bug did not present itself until i had a way to end and restart the game. The array.initialize has been replaced with a really complicated line:
latest update:
In a nutshell, now you have something to eat, and you grow when you eat it. It's broken down in more detail in the bullets below.
* Added a constant (which can easily be made a variable) called MaxPellets.
This is intended to be the maximum number of food pellets on the game grid at one time. You can use this in your own game to customize play.
* Added a variable in the paint event called FoundFood.
The value of this variable is incremented one for each food pellet on the game grid. This number is then compared to the max number of pellets. If the number is less than max, a new subroutine is called. This subroutine is explained next.
* added a routine to place food pellets called PlaceFoodPellet. It generates a random location for placement of a food pellet on the game grid. If this location is already occupied by wall, snake, other food, it generates a new location.
* snake gets longer when eating food now. Made the AmountToGrow variable public so it could be modified from the collision routine.
* score increments. Really simple. Basically equal to length. You can modify easily to allow different levels, etc.
* added code in form_closing to update high-score before saving it, if necessary.
*known bugs: clicking the pause button works fine, but for some reason you die if you unpause on the keyboard. Edit: The reason was i was running the rest of the code in the game loop after pausing and the game assumed you moved another square when you hadn't so you hit your own head. Fixed in post 13
*known bug *2: It's possible to turn around on yourself sometimes even though there is code to prevent it. Edit: this bug was caused by reading keypresses more often than you move. It gets fixed eventually in post 13
Last edited by Lord Orwell; Jan 18th, 2011 at 12:14 AM.
update: The following code change fixes the two known bugs. I will be adding to this project soon.
Code:
Sub tmrGameLoop_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrGameLoop.Tick
Dim InKey As String
Dim HeadPos As Point
InKey = WhichKeyPressed()
CL = CL + 1
If CL = 10 Then
CL = 0
'next lines give keyboard support for pause/unpause by
'simply calling the event for the command button when the
'game is running.
If InKey = "P" And Paused = False Or InKey = "U" And Paused = True Then
If NowPlaying = True Then Call btnStart_Click(btnStart, e)
Else
If Paused = True Then Exit Sub
If InKey = "UP" Or InKey = "DOWN" Or InKey = "LEFT" Or InKey = "RIGHT" Then
'next lines prevent you reversing direction
Select Case InKey
Case "UP"
If CurrentDirection = "DOWN" Then InKey = "DOWN"
Case "DOWN"
If CurrentDirection = "UP" Then InKey = "UP"
Case "LEFT"
If CurrentDirection = "RIGHT" Then InKey = "RIGHT"
Case "RIGHT"
If CurrentDirection = "LEFT" Then InKey = "LEFT"
End Select
CurrentDirection = InKey 'stores last key press to track direction
' snake needs to move if no key pressed
' next time
End If
End If
If NowPlaying = True Then
If Paused = False Then 'nothing moves/happens if paused
'next line keeps snake moving when no keys pressed
If InKey = "" Then InKey = CurrentDirection
HeadPos = MoveHead(InKey)
'add head to game grid
GameGrid(TailPositionToErase.X, TailPositionToErase.Y) = ""
If CurrentDirection <> "" Then
Select Case GameGrid(HeadPos.X, HeadPos.Y)
Case "S", "W"
: NowPlaying = False : MsgBox("dead")
btnStart.Text = "Start"
Case "1", "2", "3", "4", "5", "6", "7", "8", "9"
AmountToGrow = Val(GameGrid(HeadPos.X, HeadPos.Y))
lblScore.Text = Val(lblScore.Text) + Val(GameGrid(HeadPos.X, HeadPos.Y))
End Select
End If
GameGrid(HeadPos.X, HeadPos.Y) = "S"
'
'actual game loop here
'
'
End If
Me.pbGameArea.Refresh()
End If
End If
End Sub
what was happening is movement keys were allowed even if the game was paused and if you pressed two keys that put you into going the opposite direction, you died when unpausing. I solved this by bypassing all keypresses except the pause key when paused.
(change in red)
A related bug to this was the fact the movement keys were being detected ten times as often as the snake movement was being drawn. So if for example you pressed down while moving right and then pressed left almost immediately you would die because the snake hadn't moved yet. I solved this by changing how often the keypress was read. Now the entire loop is done in sequence in every timer tick.
(change in purple)
download the most recent zip and then cut and paste this update.
update: Didn't fix both bugs after all. The pause bug is fixed in post #13
Last edited by Lord Orwell; Jan 18th, 2011 at 12:16 AM.
ok in this update, i have made the following changes:
* I cleaned up some of the comments for clarity and accuracy. Most pertinent is the gamearea_paint comments which referred to non-existent code and was just plain inaccurate in general, but small tweaks abound.
* I moved gameover into it's own subroutine. This is to keep the game loop clean. I also relocated the code to save the highscore and update the highscore label from the form closing event to the new gameover subroutine. This is because the old method simply didn't work as intended. The game was only checking the current score upon exit, and if you had played another game since then you lost your score.
Code:
Private Sub Gameover()
NowPlaying = False : MsgBox("dead")
btnStart.Text = "Start"
'code here saves high-score
If Val(lblHighScore.Text) < Val(lblScore.Text) Then
lblHighScore.Text = lblScore.Text
End If
My.Settings.HighScore = CLng(Me.lblHighScore.Text)
End Sub
*another minor change is i now am checking if the game is currently being played in the gamearea paint event. This is because it was drawing food pellets before the game was being played. This has also allowed me to create a custom background for when the game ISN'T being played. In this iteration, it's basically just going to say "snakey" and "press p to play".
*The paint routine now also checks for five different characters in the game grid for the snake display. This is for future expansion where i draw images instead of shapes. Not moving is called "STATIC" now, and is stored in the correct variable.
this check is also performed in the movement code and the head relocation code inside the module.
to test that it works as planned, i have temporarily colored the snake a different color for each direction.
*Finally, i did in fact stomp out the death bug if you pause/unpause on keyboard. The "P" does both now, and i fixed it by exiting the sub after clicking the pause/unpause button. Code was being executed based on pause state later in the sub that was causing problems if the state changed after the sub was called.
This is pretty much all then changes i am going to squeeze into this update.
Future updates will include:
Graphics support
levels
sound
enemies which you can shoot with acid spit (maybe)
level-based dangers?
The next update will include the actual drawing of the text on the screen, and will incorporate basic sound support!
attached is the latest as of jan 16, 2011.
Known issue:
The first drawing of the game grid doesn't fill in the upper left corner. I have no idea why as subsequent calls to the exact same subs fill it in. Edit: The tail erase routine was doing it. The next update will prevent the routine from being called if the snake isn't moving.
Last edited by Lord Orwell; Jan 18th, 2011 at 12:21 AM.
tried the game but the arrow keys had no affect on the snake. It just kept going straignt into the wall. Maybe I don't understand what I'm supose to be doing. I'm running Win7 64 with an i7 procedssor.
i don't know why they wouldn't work. does the pause button (P) do anything? I am reading keyboard state for key inputs so it shouldn't even matter if the program has focus.
tried the game but the arrow keys had no affect on the snake. It just kept going straignt into the wall. Maybe I don't understand what I'm supose to be doing. I'm running Win7 64 with an i7 procedssor.
Thanks for your feedback. I was not aware of the problem with 64-bit OSes.
The following code change SHOULD fix it.
Replace the beginning of the module down to the first comment block with it.
Code:
Imports System.Runtime.InteropServices
Public Module GameFunctions
<DllImport("user32.dll")> _
Public Function GetAsyncKeyState(ByVal vKey As Integer) As UShort
End Function
'key codes are hex values.
Const VK_LEFT = &H25 ' LEFT ARROW key
Const VK_UP = &H26 ' UP ARROW key
Const VK_RIGHT = &H27 ' RIGHT ARROW key
Const VK_DOWN = &H28 'DOWN ARROW key
Const VK_P = &H50 'p
Const VK_U = &H55 'u
'''
''' variables needed for snake movement
This post will be all about bringing sound to our simple game.
The first thing we realize is that while there are numerous ways to play a sound in vb.net, most of them let you only play one sound at a time. These include: Windows Media Player control - Active x control
PlaySound API - Api Call, exact same functionality as my.computer.audio.play my.computer.audio.play
As we are running a game, and only the simplest games such as Pong can get away with one sound at a time, we choose from the 2nd list.
Of the three choices, fmod is easily the most powerful. It also has the distinction of being cross-platform (as in gamecube, wii, ps3, etc). If you have a game installed, you can almost guarantee there's a fmod.dll in the directory structure. However, in this case, with great power comes more complicated code. But if you want file format support, this dll will play pretty much anything including playlists and lets you hook for sound events triggers/ spectrum displays, etc. Sample code is on the site in multiple programming languages. This is way overkill for our simple game, and requires a dll.
One of our other choices, bass.dll, is a dll wrapper for directsound. It however expands upon it and includes code to play formats directsound won't. It's compact size is a plus, however it requires a different dll depending on if you are targeting 32 or 64 bit and the .net wrapper causes frustration for people trying to use it.
The choice for our simple game will be DirectSound. It has many benefits in this situation including support for all modern OSes with no special code, able to play files from a directory OR a resource, and no extra files. Due to the simplicity of use (trust me, it's MUCH simpler than directx graphics), it is our choice.
My next post will be of a new module which will consist of directsound initialization and creating all the sound objects from external files. There will also be a cleanup sub which will be called when the program exits. This will be necessary to clear all buffers, etc. Finally there will be a function that plays whichever sound you wish based on a parameter you pass to it. I will probably list the pros and cons of using resources for sound files as compared to external files. Expect this update in a month. I will be off of the forums for a while due to some personal business out of town.
Last edited by Lord Orwell; Jan 19th, 2011 at 09:16 AM.
Okay so there is now food up and it can be eaten but the sanke doesnt increase in size and the scoreboard randomly goes up.
Could you help me out with this please?
Okay so there is now food up and it can be eaten but the sanke doesnt increase in size and the scoreboard randomly goes up.
Could you help me out with this please?
the score may be working correctly. The food pellets are valued one thru 9 depending on how potent they are although right now they all look the same.
The snake tail should be getting longer by adding the value of the food to the "amounttogrow" variable. Every movement of the snake, this variable is checked, and if the value of it is greater than zero the tail doesn't move and the variable is made one smaller. Check to see if you are somehow not adding this value to amounttogrow.
Okay thanks ill have a look now Also the high score doesnt work and the whole pressing p to pause then pressing u to unpause ends the game thing. How do you fix that?
Many thanks
[Function MoveHead(ByVal Direction As String) As Point
'this function is going to return the new head position
Dim CurrentHeadPos As Point
CurrentHeadPos = body(HeadPointer)
Select Case Direction
Case "UP"
CurrentHeadPos.Y -= 1
Case "DOWN"
CurrentHeadPos.Y += 1
Case "LEFT"
CurrentHeadPos.X -= 1
Case "RIGHT"
CurrentHeadPos.X += 1
End Select
'next lines increment headpointer (resetting to zero if necessary)
'then add the new headpos to the array
HeadPointer += 1
If HeadPointer = 1000 Then HeadPointer = 0
body(HeadPointer) = CurrentHeadPos
'now, move tail pointer unless snake is currently growing
If AmountToGrow = 0 Then
TailPointer += 1
If TailPointer = 1000 Then TailPointer = 0
Else
AmountToGrow -= 1
End If
MoveHead = CurrentHeadPos
TailPositionToErase = body(TailPointer)
End Function
Public Sub InitializeSnake(ByVal x As Integer, ByVal y As Integer)
HeadPointer = 0
TailPointer = 0
body.Initialize()
body(0).X = x
body(0).Y = y
AmountToGrow = 5 'debug
End Sub]
geez are you using the most recent upload? That is ancient code. No wonder it's not growing. If you were to work step by step from the top to the bottom in this thread you would see your problem. There isn't code in there to keep score. I am guessing you downloaded the link on post 7. If you read that post you will see a known bug-list and the location they were fixed.
As of right now, the most recent upload is in post 13, with a bug fix if you are using a 64-bit OS available in a later post so keyboard input works.
Last edited by Lord Orwell; Feb 22nd, 2011 at 06:50 PM.
I've tried downloading the lastest one but when i go to debug it says there are build errors and wont let me run it. Also it wont let me open the main form to try and see what's wrong with the code. This is why i downloaded the earlier version and worked from that.
well the latest one is in 2010 so that may be your problem. I'll post the code itself later in the forum instead of a zip so people having that problem can run it.