Results 1 to 9 of 9

Thread: "Scratch off" approaches

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    23,694

    "Scratch off" approaches

    I saw another site where some VB5 and VB6 programmers were arguing over the best way to produce an educational game "lottery ticket scratch off" effect for answers to questions.

    All of them look like they would work, but they seemed very convoluted involving multiple regions and blitting operations (at best) or weird gymnastics setting pixel-by-pixel reveals calculating curves and on and on.

    Seemed odd to me, but here Is one way I cobbled together. As far as I can tell it works from Win NT 4.0 forward, though not on Win9x due to GDI limitations there.


    Basically I create a broad (24 pixels here) geometric brush from the "printed" message to be revealed. Then clear the PictureBox to all "silver." Finally let the user click and drag to "scratch" the ticket.

    Make a new Project with a Form, add two controls and this code:

    Code:
    Option Explicit
    
    'This Form has 1 PictureBox:    Picture1
    '              1 CommandButton: Command1
    
    Private Const WIN32_NULL As Long = 0
    
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    
    Private Enum PenStyles 'Abbreviated list.
        PS_GEOMETRIC = &H10000
    End Enum
    
    Private Enum BrushStyles 'Abbreviated list.
        BS_PATTERN = 3&
    End Enum
    
    Private Type LOGBRUSH
        lbStyle As BrushStyles
        lbColor As Long
        lbHatch As Long
    End Type
    
    Private Declare Function ExtCreatePen Lib "gdi32" ( _
        ByVal dwPenStyle As PenStyles, _
        ByVal dwWidth As Long, _
        ByRef LOGBRUSH As LOGBRUSH, _
        Optional ByVal dwStyleCount As Long = 0, _
        Optional ByVal lpStyle As Long = WIN32_NULL) As Long
    
    Private Declare Function SelectObject Lib "gdi32" ( _
        ByVal hDC As Long, _
        ByVal hObject As Long) As Long
    
    Private hPen As Long
    Private hPenOrig As Long
    
    Private Sub NewScratcher()
        Const PLAY_AGAIN As String = "SORRY, PLAY AGAIN"
        Dim I As Long
        Dim Text As String
        Dim LOGBRUSH As LOGBRUSH
    
        With Picture1
            .Visible = False
            .BackColor = vbWhite
            .ForeColor = &HC08040
            'Print generated message centered:
            I = Int(Rnd() * 13)
            If I = 0 Then
                .CurrentY = (.ScaleHeight - .TextHeight(PLAY_AGAIN)) / 2
                .CurrentX = (.ScaleWidth - .TextWidth(PLAY_AGAIN)) / 2
                Picture1.Print PLAY_AGAIN;
            Else
                Text = MonthName(I)
                .CurrentY = (.ScaleHeight - .TextHeight(Text) * 3) / 2
                .CurrentX = (.ScaleWidth - .TextWidth(Text)) / 2
                Picture1.Print Text
                Text = "will be"
                .CurrentX = (.ScaleWidth - .TextWidth(Text)) / 2
                Picture1.Print Text
                Text = WeekdayName(Int(Rnd() * 7) + 1, , vbSunday)
                .CurrentX = (.ScaleWidth - .TextWidth(Text)) / 2
                Picture1.Print Text;
            End If
            'Convert the message to a brush:
            LOGBRUSH.lbStyle = BS_PATTERN
            LOGBRUSH.lbHatch = .Image.Handle
            If hPen <> WIN32_NULL Then DeleteObject hPen
            hPen = ExtCreatePen(PS_GEOMETRIC, 24, LOGBRUSH)
            'Add "scratch-off layer" by clearing to a silvery color and select our brush:
            .BackColor = &HD8D8D8
            .Visible = True
            hPenOrig = SelectObject(.hDC, hPen)
        End With
    End Sub
    
    Private Sub Command1_Click()
        NewScratcher
    End Sub
    
    Private Sub Form_Load()
        Caption = "Click and drag to scratch off"
        With Picture1
            'Position and size as desired, such as at design-time:
            .Move (ScaleWidth - 3600) / 2, _
                  120, _
                  3600, _
                  1200
            .FontName = "Comic Sans MS"
            .FontSize = 12
            .AutoRedraw = True
            'More positioning:
            Command1.Caption = "New scratcher"
            Command1.Move (ScaleWidth - 1800) / 2, _
                          .Top + .Height + 120, _
                          1800
        End With
        NewScratcher
    End Sub
    
    Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
        If Button = vbLeftButton Then
            Picture1.Line Step(0, 0)-(X, Y)
        Else
            Picture1.CurrentX = X
            Picture1.CurrentY = Y
        End If
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
        SelectObject hDC, hPenOrig
        DeleteObject hPen
    End Sub
    Anyone have anything simpler to suggest?

  2. #2
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    7,803

    Re: "Scratch off" approaches

    If I were doing this, I'd start with a surface painted with whatever image represents the "cover". I'd have a separate image in memory that holds the image of whatever is to be revealed. As the user moves the mouse to "scratch", I'd draw parts of the image in memory over the painted surface based on the where they were scratching. Seems like the most straightforward way to do this.

    I wouldn't mind doing a sample but the thought of having to wade through all of my old VB6 project to copy paste GDI function imports makes me nauseous. I'm just too lazy to do all that right now lol... Maybe later I'd knock together something in a few minutes in .Net though. Seems like an interesting distraction.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    23,694

    Re: "Scratch off" approaches

    Working code isn't as important as concepts.

    I suppose you could blit a series of small rectangles from the "message" to the "cover" following the mouse. I'm not sure about the quality of the effect though.

    In mine the line-drawing endcaps default to round and this gives more of a "rubbing" effect. I'd rather have some kind of ragged endcaps but I'm not sure how to do that.

  4. #4
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    8,173

    Re: "Scratch off" approaches

    Just to be fun, one might consider a way to make the "brush" have less density or hardness. This is all just aesthetics, but it might be fun, and give a bit more of the feel of something actually being scratched off.

    Less dense:
    Name:  LessDense.png
Views: 100
Size:  16.0 KB

    Less hard:
    Name:  LessHard.png
Views: 113
Size:  6.6 KB

    And, you could do both.

    When I first read your OP, I was thinking it'd have a fuzz on the edges (less hard). IDK, just something to make them work a bit more at it to do the scratch-off. I mean, otherwise, just have a button that says "Reveal".
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  5. #5

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    23,694

    Re: "Scratch off" approaches

    So... many ways to scratch a cat.

  7. #7
    Fanatic Member
    Join Date
    Jun 2015
    Posts
    748

    Re: "Scratch off" approaches

    Ha that would be great, top layer cat, under layer cat skeleton.
    Or top layer cute girl under layer scary witch or lingerie or witch in lingerie sure why not,

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Feb 2006
    Posts
    23,694

    Re: "Scratch off" approaches

    I think anyone who wants this is probably making a game for kids. I doubt photorealism is very important since it just another funky way to "reveal" answers or hints or something.

  9. #9
    Hyperactive Member
    Join Date
    Nov 2018
    Posts
    486

    Re: "Scratch off" approaches

    So... many ways to scratch a cat.
    I love the simplicity in your solution.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width