VB too slow or I'm a bad programmer!

Posted on 1999-01-26
Last Modified: 2012-05-04
I'm telling you right now I'm a bad programmer. I sat and looked at this code for a long time and could not speed it up. It takes a long time run this loop to it's end. It's a classic case... I need to put my tiles to the picture box. I have mutipal layers. 6 to be exact. The code is below. Please take a look and tell me what you think. Thanks.

Sub draw_map()
If xcord < 1 Then xcord = 1
If ycord < 1 Then ycord = 1
mapeditor.VScroll1.Value = ycord
mapeditor.HScroll1.Value = xcord
Dim page As Byte:  'the page the curent tile is being pulled off of
Dim Xmapshwon As Byte
Dim ymapshown As Byte
Dim xnow As Long
Dim ynow As Long
Dim temp_tile As Integer
Dim tilex As Integer
Dim tiley As Integer
Dim tilenow(6) As Integer
mapeditor.Picture1.Picture = LoadPicture
ANACLOCK_SET = anaclock2
'GoTo test

XMAPSHOWN = Int(375 / tile_width)
ymapshown = Int(325 / tile_Height)
tilex = xcord
tiley = ycord

For xnow = 0 To XMAPSHOWN * (tile_width + 1) Step tile_width
tilex = tilex + 1
tiley = ycord
For ynow = 0 To ymapshown * (tile_Height + 1) Step tile_Height

'this is the order of the tiles drawn
tilenow(1) = map(tilex, tiley).land1
tilenow(2) = map(tilex, tiley).land2
tilenow(3) = map(tilex, tiley).object
tilenow(4) = map(tilex, tiley).sprite
tilenow(5) = map(tilex, tiley).land3
tilenow(6) = map(tilex, tiley).land4

For tile_type_draw = 1 To 6
If tilenow(tile_type_draw) < 1000 Then GoTo no_draw
page = Int(tilenow(tile_type_draw) / 1000)
tile = ((tilenow(tile_type_draw) Mod 1000) - 1)
If page = 22 Then
temp_tile = get_ana_tile(((tilenow(tile_type_draw) Mod 1000)), ANACLOCK_SET)
page = Int(temp_tile / 1000)
tile = (temp_tile Mod 1000) - 1
End If
'i = BitBlt(mapeditor.Picture1.hdc, xnow, ynow, tile_width, tile_Height, masks(page), ((tile Mod temtiles_ud) * (tile_width + 2)) + 1, ((tile \ temtiles_rl) * (tile_Height + 2)) + 1, SRCAND)
'i = BitBlt(mapeditor.Picture1.hdc, xnow, ynow, tile_width, tile_Height, Graphics.Graphics_pages(page).hdc, ((tile Mod temtiles_ud) * (tile_width + 2)) + 1, ((tile \ temtiles_rl) * (tile_Height + 2)) + 1, SRCINVERT)
i = BitBlt(mapeditor.Picture1.hdc, xnow, ynow, tile_width, tile_Height, Graphics.Graphics_pages(page + 9).hdc, ((tile Mod temtiles_ud) * (tile_width + 2)) + 1, ((tile \ temtiles_rl) * (tile_Height + 2)) + 1, SRCAND)
i = BitBlt(mapeditor.Picture1.hdc, xnow, ynow, tile_width, tile_Height, Graphics.Graphics_pages(page).hdc, ((tile Mod temtiles_ud) * (tile_width + 2)) + 1, ((tile \ temtiles_rl) * (tile_Height + 2)) + 1, SRCINVERT)

Next tile_type_draw

tiley = tiley + 1
Next 'ynow
Next 'xnow
If mapeditor.Gridonoff.Value = 1 Then draw_grid
Exit Sub
End Sub

Some intresting notes:
The reason there are four BitBlts is because the first two will draw the tile using a mask in a DC (Masks(page)), The second two will draw the tile using a mask that is in a picture box. I would like to swich over to all DCs and no Picture boxes. I have decided to tackle the masks first. Now the intresting part is that when I use both picture boxes and no DCs it is faster! I don't understand why... I thought that DCs were better! Good luck to any one who thinks they can handle this problem :) -way out of my leage...
Question by:rpg_rpg
LVL 15

Expert Comment

by:Tommy Hui
ID: 1470795
Pictures are optimized to display stuff so unless you are able to some more optimizations that what Pictures already give you, you won't be able to beat it.

Here's how you can though. First, think of the screen as a grid of pixels. The first step to optimizing the drawing of the pixels is to make sure you don't ever draw any pixel twice. Drawing on the screen takes a long time and if you can stop drawing any pixel twice, you would have saved a lot of screen refresh.

But how do you do this, you ask? Go through all of your layers and find out which areas overlap. For those that overlap, only draw the topmost layers. For the other layers that overlap, these will be hidden and can be removed from the updating of that layer. So for example, if you have a bottom layer from (0, 0) - (40, 40) and another top layer from (20, 20) - (60, 60). This takes three updates: (0, 0) - (40, 20); (0, 20) - (20, 40); (20, 20) - (60, 60). Even though it takes a bit to calculate this, the speed is more than made up for in the screen update. The speed up is more dramatic with more layers.

Author Comment

ID: 1470796
I may not be understanding you corectly but how I see it I can't do what you say because the reason I use layers is to give the effect of backround. I can put a tree on grass with out drawing a tile with grass and a tree. But anyway I don't understand what I can do if I need the tiles below... Thanks for the help.

Expert Comment

ID: 1470797
If you can, locate my book "Visual Basic 4 Network Gaming Adventure Set" (published by Coriolis).  While it's old, one of the games in the book (DirectConflict!) shows how to do multi-object bltting very quickly to a native VB hDC.

Good luck!
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.


Expert Comment

ID: 1470798
Recoding isn't the way for you to go, I believe. But there are ways and means. Have you thought of using DirectX?
Blitting using DirectDraw is 12 times faster, on average, than BitBlt, and the function is called more or less the same way.
To test this, try out PolyMedia's DirectX ActiveX control, which is available from:,4,0-62067,1000.html

Huggably yours,


Accepted Solution

Vingamel earned 130 total points
ID: 1470799
Try using Imageboxes instead of Pictureboxes.  I also have a similar-sounding game as yours, and found that using imageboxes was faster, plus able to see tiles below when tiles above had transparent pixels.  Also, if you aren't already, convert any BMP images to Gif or JPG.  My game is more of a strategy game (in which high-speed graphics are negligible), however, and what I may find a satisfactory speed may be quite unsatisfactory for you.  

Expert Comment

ID: 1470800
Thanks and holler if you need any more ideas or help, seeing that we are working on similar types of games.  --Vingamel

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question