Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VB.NET
I am creating an open source video game called "WubStar"(Like guitar hero for electronic music). I got a good portion through and then encountered an error. The Write sub-routine isn't running, AT ALL! Here's the code for the form I encountered the error on, please take a look, I'm hoping that if someone looks at it with a fresh set of eyes they'll be able to catch a (probably small) error that I wasn't able to catch, thanks in advance,
 
Jordan
 
VB.net code(Somewhat annotated):
Imports System.Drawing
Imports System.IO
 
Public Class Form2
 
    'Game Palet
    Dim pWidth As Integer = 750
    Dim pHeight As Integer = 550
    Dim tSize As Integer = 32
 
    'Graphics Vars
    Dim G As Graphics
    Dim BBG As Graphics
    Dim BBI As Bitmap
    Dim pTile As Bitmap
    Dim S1 As Bitmap
    Dim S2 As Bitmap
    Dim sRect As Rectangle
    Dim dRect As Rectangle
 
    'Framerate Vars
    Dim tSec As Integer = TimeOfDay.Second
    Dim Tick As Integer = 0
    Dim Max As Integer = 0
 
    'Game State
    Dim isRunning As Boolean = True
    Public isWaiting As Boolean = False
 
    'Mouse Mapping
    Dim mouseX As Integer = 15
    Dim mouseY As Integer = 9
 
    'Mouse Button Handler Vars
    Dim lMouse As Boolean = False
    Dim rMouse As Boolean = False
 
    'Key Handler Vars
    Dim Key1 As Boolean = False
    Dim Key2 As Boolean = False
    Dim Key3 As Boolean = False
    Dim Key4 As Boolean = False
    Dim Key5 As Boolean = False
    Dim Key6 As Boolean = False
    Dim Key7 As Boolean = False
    Dim Key8 As Boolean = False
    Dim Up As Boolean = False
    Dim Down As Boolean = False
 
    'Note Mapping
    Dim mLength(tSize * 4, 0) As Integer
    Dim nMap(11, 0) As Integer
    Dim nMapSave(11, 0) As Integer
    Dim nMax As Integer = 0
    Dim Count As Integer = 0
    Dim inc As Integer = 8
    Dim gMax As Integer
    Dim dCount As Integer = 0
    Dim nMapSize As Integer = tSize / 4
 
    'Song Vars
    Public Song As String
    Dim Path As String
    Dim Browse As OpenFileDialog
    Public LoadSong As Boolean = False
 
    Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        MsgBox("nMap 0,0: " & nMap(0, 0))
        MainMenu.Show()
    End Sub
 
    Private Sub Form2_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Me.Show()
        Me.Focus()
 
        'Initialize Graphics
        G = Me.CreateGraphics
        BBI = New Bitmap(pWidth, pHeight)
        pTile = New Bitmap(Sprites.BG.Image)
        S1 = New Bitmap(Sprites.S1.Image)
        S2 = New Bitmap(Sprites.S2.Image)
 
        'Initialize nMapping Vars
        If LoadSong = False Then
            For i As Integer = 0 To 11
                nMap(i, 0) = 0
            Next
        End If
 
        'Initialize Game Vars
        If LoadSong = False Then
            Browse = New OpenFileDialog
            Browse.Filter = "Audio Wave Files|*.wav"
            Browse.Title = "Open Song"
            If Browse.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
                Path = Browse.FileName()
            Else
                MsgBox("Couldn't open file", MsgBoxStyle.Critical, "Error")
                End
            End If
            Song = InputBox("Song Name:", "Name")
            If Not Song = "" Then
                Try
                    MkDir(CurDir() & "\Data\" & Song)
                Catch ex As Exception
                    End
                    MsgBox(ex, MsgBoxStyle.Critical, "Error")
                End Try
                Try
                    'Save song in songs database
                    If My.Computer.FileSystem.FileExists(CurDir() & "\Data\Songs.slst") Then
                        Using Write As StreamWriter = New StreamWriter(CurDir() & "\Data\Songs.slst", True)
                            Write.WriteLine(Song)
                            Write.Close()
                            Write.Dispose()
                        End Using
                    Else
                        Using Write As StreamWriter = New StreamWriter(CurDir() & "\Data\Songs.slst")
                            Write.Write(Song & vbNewLine)
                        End Using
                    End If
 
                    'Create .wub file to store notes
                        Using Write As StreamWriter = New StreamWriter(CurDir() & "\Data\" & Song & "\" & Song & ".wub")
                            Write.WriteLine("#Generated: " & DateAndTime.Now)
                            Write.Close()
                            Write.Dispose()
                        End Using
                Catch ex As Exception
                    MsgBox(ex, MsgBoxStyle.Critical, "Error")
                    End
                End Try
                Try
                    FileCopy(Path, CurDir() & "\Data\" & Song & "\" & Song & ".wav")
                Catch ex As Exception
                    MsgBox(ex, MsgBoxStyle.Critical, "Error")
                End Try
            End If
        ElseIf LoadSong = True Then
            Me.Hide()
            LoadForm.Show()
            isWaiting = True
            Do While isWaiting = True
                Application.DoEvents()
            Loop
            LoadForm.Hide()
            Me.Show()
        End If
        Designer(Song)
        End
    End Sub
 
    Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        Select Case e.KeyCode
            Case Keys.A
                Key1 = True
            Case Keys.S
                Key2 = True
            Case Keys.D
                Key3 = True
            Case Keys.F
                Key4 = True
            Case Keys.H
                Key5 = True
            Case Keys.J
                Key6 = True
            Case Keys.K
                Key7 = True
            Case Keys.L
                Key8 = True
            Case Keys.Escape
                isRunning = False
        End Select
    End Sub
 
    Private Sub Form1_KeyUp(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
        Select Case e.KeyCode
            Case Keys.A
                Key1 = False
            Case Keys.S
                Key2 = False
            Case Keys.D
                Key3 = False
            Case Keys.F
                Key4 = False
            Case Keys.H
                Key5 = False
            Case Keys.J
                Key6 = False
            Case Keys.K
                Key7 = False
            Case Keys.L
                Key8 = False
        End Select
    End Sub
 
    Private Sub Designer(ByVal Name As String)
        'On Error GoTo A
        G.DrawImage(pTile, 0, 0)
        MsgBox("Song load/creation successfull, going to designer", MsgBoxStyle.Information, "Success")
        Do While isRunning = True
            Application.DoEvents()
            Write()
 
            Draw()
 
            Save()
            'Check for Up/Down arrow events
            If Up = True & Count = 0 Then  Else If Up = True Then Count -= 1
            If Down = True & Count = nMax Then
                nMapSave = nMap
                nMax += 1
                ReDim nMap(11, nMax)
                nMap = nMapSave
                ReDim nMapSave(11, nMax)
                Count += 1
            ElseIf Down = True Then
                Count += 1
            End If
        Loop
    End Sub
 
    Private Sub Write()
        If Key1 = True & nMap(0, Count) = 0 Then
            nMap(0, Count) = 1
        ElseIf Key1 = True Then
            nMap(0, Count) = 0
        End If
    End Sub
 
    Private Sub Draw()
 
    End Sub
 
    Private Sub Save()
 
    End Sub
End Class
Posted 7-Dec-12 10:19am
Sicppy1.4K
Comments
joshrduncan2012 at 7-Dec-12 17:59pm
   
How do you know that particular sub is not running? Can you place a MessageBox in places around it to see where the breakdown happens?
Akbar Ali Hussain at 7-Dec-12 18:01pm
   
Which portion is not working?
Sergey Alexandrovich Kryukov at 7-Dec-12 18:32pm
   
This code is complete mess; I don't think it worth considering. First of all, you are trying to use DoEvents in order to simulate something resembling thread functionality. Don't do it. Explain what do you want to achieve by that, chances are, you need just real threads.
 
A number of key variables, long case which does nothing but assign True -- all this is totally pointless. The code should be written in civilized manner first, and then we can discuss what to fix...
--SA
Sicppy at 11-Dec-12 20:54pm
   
First of all, this code isn't supposed to be very pretty, its a free software it doesn't have to be super professional, second of all, by putting the Application.DoEvents() it keeps the program responsive, if I don't have that when the while loop is running it, (1) Won't register key press events (2) Wont't register when the form is closed, minimized, or maximized.
Sergey Alexandrovich Kryukov at 11-Dec-12 22:11pm
   
I read: "First of all, this code isn't supposed to be very pretty, its a free software it doesn't have to be super professional".
 
OK, you see, this closes the question. With such your attitude, there is no way I would agree to waste time on it. Thank you for asking your question. Maybe someone else will answer, but don't expect "super professional" help.
 
(And of course your use of DoEvents is perfectly wrong...)
 
--SA
Sicppy at 12-Dec-12 2:21am
   
I was not trying to give you the impression that I was unwilling to take your advice, it is a free open source program because I'm trying to give something back to the community, I would like help with this because it is something that has been bugging me for awhile, but it is not my first priority to other programs I am designing in HLLs to gain support for my business, this is why I'm not trying to make it super highly professional and organised.
Sergey Alexandrovich Kryukov at 12-Dec-12 2:31am
   
Thank you for accurate explanation of your reasons, but my experience shows me that this kind of "economy" does not save you any time... You decide though; and also it could be a matter of personal style, to certain extent...
 
Good luck,
—SA
Sicppy at 12-Dec-12 2:52am
   
I see what you mean, I realized that my other comment had reflected something other than my intent, I appreciate your understanding in that I wasn't trying to come come across rude or arrogant, thanks for your luck
 
-Jordan
 
P.S.
I am doing this project in my free time, more of a side project than something that should be consuming a lot or most of my time, however thank you for the advice.
Sergey Alexandrovich Kryukov at 12-Dec-12 11:24am
   
No, you are perfectly correct, and we're good, I hope.
--SA
Sicppy at 12-Dec-12 2:56am
   
Also, what would you suggest I do to keep my program responsive and still continue the rest of my code running instead of constantly waiting for something to happen, thanks in advance,
 
-Jordan
Sergey Alexandrovich Kryukov at 12-Dec-12 11:26am
   
Threads. Never anything else. I have some universal threading answers compiled from my past answers. Would you like the links?
--SA
Sicppy at 12-Dec-12 12:01pm
   
Yes that would be extremely helpful, if you post it as an answer to this question I will accept it, I would also like to take this time to thank for your help on this(and other) questions
Sergey Alexandrovich Kryukov at 12-Dec-12 13:18pm
   
I will do it now, but, as I don't know some relevant detail related to your goals, feel free to ask me further questions -- by adding comments to my answer.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

My best guess is that the application.doevents line is taking long time to process and write sub is never called as stated at msdn
Quote:
Calling this method causes the current thread to be suspended while all waiting window messages are processed. If a message causes an event to be triggered, then other areas of your application code may execute. This can cause your application to exhibit unexpected behaviors that are difficult to debug. If you perform operations or computations that take a long time, it is often preferable to perform those operations on a new thread. For more information about asynchronous programming, see Asynchronous Programming Model (APM).

 
Read it here
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Jordan wrote:
Also, what would you suggest I do to keep my program responsive and still continue the rest of my code running instead of constantly waiting for something to happen…
First of all, as System.Drawing is used and UI is involved, it looks like the UI library is System.Windows.Forms (please, always tag it when asking questions, as well as application type, in this case, tag "Forms"). My advice is also applicable to WPF UI. You certainly need to use threads. This is not a matter of parallelism in the sense of performance or CPU utilization, but a logic and a workflow of the application. The event-oriented UI should be executed by a thread which is kept in the wait state when the user does not do any input, while other threads can do their job as soon as some task is provided.
 
There is one problem specific to the UI. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).
 
You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].
 
See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].
 
—SA
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

One of the problems in your code I mentioned can be easily resolved and save a lot of time and enable some maintainability of the application, which is now pretty much killed. I mean repeated code "Dim Key1", "Dim Key2", etc. Instead, simply define an array of case. What you do also provokes you to write long switch statement, which is always hard to support. Instead, you should have a dictionary of keys: index type is the key codes or a character, value types is whatever is associated with the key; some class or structure.
 
A very universal extension of this idea is shown in my CodeProject article: Dynamic Method Dispatcher[^]. (Full name "Dynamic Method Dispatcher", No more long switch statements!; the "short description" part of the title now disappeared from the article pages; I'll have to ask to restore it, because lack of it may mangle the meaning of the title.)
 
This approach is very easy to use and completely eliminate a need of long switch or if statements. The key can be anything, even a type. And a value can be anything, including, most importantly, a delegate instance. This delegate instance provides the most of flexibility: it replaced any arbitrary block of code in switch case or if statement. Indeed, no more long switch statements!
 
Please understand that no one here tries to brain-wash you with technological stuff and force you into extra work, just the opposite, such works attempt to make your life better. We human are not designed to do a lot of boring tedious work, but most of us are pretty good with abstractions and using elegant techniques.
 
Good luck,
—SA
  Permalink  
Comments
Sicppy at 12-Dec-12 17:21pm
   
Thanks, I never thought about doing an array but that would probably be helpful
Sergey Alexandrovich Kryukov at 12-Dec-12 17:26pm
   
Certainly. Well, now think about it (array or collection which you can even persist and load if and when you see a need in it). Hope you can accept this advice, too -- thanks.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 12 Dec 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100