 |
|

01-23-2004, 11:55 PM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Im stuck in tiles
|
|
I have tried several times. I can draw tiles to the screen with BitBlt without problem. The first problem comes when i redraw the whole screen when you move the player. The second problem is that the screen should be moving and not the player. I have no source so please try to help me.
Let's say that im using tiles that are 32*32 in size. When running in a resolution of 640*480 it will gives you 20*15(300 tiles). Lets also say that to the left there is another screen with 300 tiles, so if you press the left key some tiles from the left(that are too far away so be seen)enters the screen and the exactly the same amount from the screen dissapears on the right side(scrolling). Dont point me to any 700 lines code, i only want a simple base to start from.
|
|

01-24-2004, 11:04 AM
|
 |
Sinecure Expert
Preferred language: Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 6,748
|
|
Depending on the size of your whole map, you would blt the ones visible
on the screen, to the screen. Since you didn't specify, we'll take the
simple case of moving by full tiles.
Using your example, we'll say the map is 40*15.
The current tile in the upper left would be number (20, 0), So we'll use a
variable MapL, to hold the current Displayed Left tile offset (set to 20).
To draw the map then would be something like.
Code:
'DrawMap
For y = 0 to 14 'our 15 tiles vertically
For x = MapL to MapL + 19
'compute the tile to be blt base on the ( x, y)
'blt tile to position based on (x, y)
next
next
To move Left, something like this.
If MapL > 0 then 'if we haven't reached the left edge of the map
MapL = MapL - 1
DrawMap
end if
DrawPlayer
To move right, you would do the opposite, increasing MapL, but not
exceeding a value that would show beyond the edge of the map. (but
perhaps you want the edge of the map to move to the center of the
screen, so the player is always in the center. My assumption is the
player would only be in the center if we haven't reach the edge of the
map, but once an edge is reached, then the player would move. A little
more complicated, but better I think).
After drawing the map, then you draw the characters on it.
|
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
|

01-24-2004, 12:41 PM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Hmm
|
|
Thanks passel. I think I understand It now, the only problem I see is how I should move the screen if I only want to move one pixel. Becomes it not a problem then?
|
|

01-24-2004, 11:35 PM
|
 |
Sinecure Expert
Preferred language: Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 6,748
|
|
For pixel movement, you just offset your tiles, so instead of starting at
(0,0), you would start you blit up to 1 tile width to the left of the window.
Before, MapL was our left tile. This time we'll let it be the left pixel position.
We'll add MapLT to indicate the Left Tile position (make it
a type Long), and perhaps XL which is the pixel offset with in the tile
(where you blt the first tile in a row of tiles. So if you started with MapL = 320,
and you moved 1 pixel to the left, then MapL would be 319. The Tile
would be MapL \ 32 (Integer divide, so the result would be 9 in this case).
Therefore you start with tile (9, 0).
The location of the Left edge of the Left tiles would be XL = -(32 - (MapL mod 32)),
which would be -31 (pixels) in this case, so blit to (-31, 0), so 1 pixel of
tiles (9, y) would be on the left edge of the window.
As MapL moved further left, then more of the tiles would show on the
left edge (all tiles shifted by however many pixels to the right).
Since your tiles are 32 pixels wide (a integer power of 2), instead of
using the mod instruction and subtracting the result from 32, the code
would be quicker by ANDing MapL with 31 (i.e. left offset for 1st column
of tiles would be XL = -(MapL And 31). Since you only need to do this once,
each time before drawing your map, it wouldn't make a real difference.
So the code for looping through and drawing the map would be essentially
the same, but you would blit one more tile horizontally (For x = MapLT to MapLT + 20),
and instead of starting at (0, 0), you would start at (XL, 0)
(assuming you used XL = -(MapL And 31) ).
rpgnewbie has posted some examples in his BitBlt demos thread. I don't
remember looking at the code, but it should be similiar to what I've
described if there is one for pixel based tile background scrolling.
http://www.xtremevbtalk.com/t129548.html
Also BillSoo put together an example of pixel tile scrolling quite awhile ago.
http://www.xtremevbtalk.com/t7965.html
|
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
|

01-24-2004, 11:48 PM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Ok?
Hmm, is it possible for you to post some kind of tile-scrolling-mini-source with nothing more then neccesary?
|
|

01-25-2004, 05:45 PM
|
 |
Sinecure Expert
Preferred language: Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 6,748
|
|
I assume some of the examples given in the other threads are fairly
minimal, but I can give one more, I guess. This code only does a tiled
background scroll. The scrolling is controlled by clicking on the form and
dragging. All you need to do to use this example is:
1. Open a new project
2. Paste this code in the Declarations area in the code window.
3. Add a Picturebox to the form
4. Run the code
If you want to see which tile is the first painted (in the upper left corner)
and what the starting left and top offset's are as you're scrolling, then
add a label, and uncomment the "label1.Caption =" line in the code.
The actual drawing of the map takes little code. The majority of the code
in this example is creating the tiles, the map, and processing the mouse
to set the scroll coordinates.
Code:
Option Explicit
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, _
ByVal dwRop As Long) As Long
Dim map(39, 39) As Byte '40 x 40 map
Dim mapL As Long, mapT As Long 'Top Left corner of Map in pixels
Dim mx As Single, my As Single 'Past history for mouse
Private Sub Form_Load()
Dim dx As Long, dy As Long, t As Long, xo As Long
Dim X As Long, Y As Long
dx = Width - ScaleWidth 'Scale the form to 640 x 480 pixels
dy = Height - ScaleHeight 'in it's client areay
Width = ScaleX(640, vbPixels, ScaleMode) + dx
Height = ScaleY(480, vbPixels, ScaleMode) + dy
ScaleMode = vbPixels
'Generate 4 test tiles, and fill in a 40 x 40 test map
With Picture1
.Width = 200: .Height = 40
.ScaleMode = vbPixels
.Visible = False
.BorderStyle = 0
.AutoRedraw = True
For t = 0 To 3 'create 4 test tiles.
.ForeColor = QBColor(9 + t) 'each tile a different color
xo = t * 32 'offset each tile by 32 pixels
For Y = 0 To 31 'each 32 x 32
For X = 0 To 31
If Rnd > 0.49 Then Picture1.PSet (X + xo, Y) 'fill half the pixels randomly in the tile
Next
Next
Next
End With
For X = 0 To 39 'map 40 wide
For Y = 0 To 39 '40 high too
map(X, Y) = Int(Rnd * 4) 'Pick 1 of 4 different tiles for each map location
Next
Next
mapL = 240 'let's start the map position somewhere middlish
mapT = 240
AutoRedraw = True 'Set the form to AutoRedraw
DrawMap
End Sub
Private Sub DrawMap()
Dim tx As Long, ty As Long, xl As Long, xt As Long, yt As Long
Dim X As Long, Y As Long, t As Long
tx = mapL \ 32: ty = mapT \ 32 'get the starting (upper left corner) map tile coordinate
xl = -(mapL Mod 32): yt = -(mapT Mod 32) 'find how much of the tile should be off the screen
' update label Add a label to the form if you want to see these values as you scroll
' Label1.Caption = "Tile(" & Str$(tx) & "," & Str$(ty) & ") " & Str$(xl) & "," & Str$(yt)
For Y = ty To ty + 20 'For 21 tiles vertically
xt = xl ' Initial where the Left edge starts (-31 to 0)
For X = tx To tx + 20 ' For each tile horizontally
t = map(X, Y) * 32 ' Get the tile's position in the tiles picture
BitBlt Me.hDC, xt, yt, 32, 32, Picture1.hDC, t, 0, vbSrcCopy 'blit the tile
xt = xt + 32 ' The next column, 32 pixels to the right
Next
yt = yt + 32 ' The next row 32 pixels below
Next
Me.Refresh 'Refresh the screen to see our handiwork
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
mx = X: my = Y 'Save the Mouse position to use in the MouseMove
End Sub
Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim dx As Single, dy As Single
If Button = vbLeftButton Then 'If the left button is down
dx = mx - X ' Determine how far the mouse has moved
dy = my - Y ' from the initial click
mapL = mapL + dx ' Add the difference to the Map's Left coordinate
If mapL < 0 Then mapL = 0 ' Limit the left edge between 0 and 639
If mapL > 639 Then mapL = 639
mapT = mapT + dy ' Add the difference to the Map's top coordinate
If mapT < 0 Then mapT = 0 ' Limit the top edge between 0 and 639
If mapT > 639 Then mapT = 639
mx = X ' Update the past histories
my = Y
DrawMap ' Draw the map
End If
End Sub
|
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
|

01-26-2004, 01:13 PM
|
 |
Sinecure Expert
Preferred language: Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 6,748
|
|
Interestingly, the documentation for Pset says this about the color parameter
color Optional. Long integer value indicating the RGB color specified for point. If omitted, the current ForeColor property setting is used .
I'm drawing the tiles in 4 colors, but here at work, all the tiles are showing
up in black. But if I add the Color to the Pset line. i.e.
Code:
Picture1.PSet (X + xo, Y), .ForeColor
Then it draws the 4 colors, as it should have to begin with. It's flakey
things like this, that have to make you wonder.
|
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Last edited by passel; 01-26-2004 at 01:25 PM.
|

01-26-2004, 01:27 PM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Ok
I think I understand the tile tutorial, I think I can make scrolling there one tiles at a time moves, but pixel by pixel? Its seems to hard, but I need to learn it. I have always wanted to do this farming game:'(
Please help me. Could you give me the same source but with keys as steering(instead of mouse) and more simplied(if possible).
|
|

01-26-2004, 01:41 PM
|
 |
Disillusioned Code Poet
Preferred language: Retired Moderator * Guru *
|
|
Join Date: Apr 2002
Location: Tennessee, USA
Posts: 12,808
|
|
Sorry, but this isn't a code handout site. Please show some effort on your own first, then ask specific questions about your code and we can try to help.
|
__________________
Laura
Ita erat quando hic adveni.
|

01-26-2004, 02:48 PM
|
 |
Sinecure Expert
Preferred language: Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 6,748
|
|
Well, I think it is about as simple as it is going to get. You can't just
jump to the end of a process and make a game, you will need to learn
and understand (fairly well) how to do each step. For instance, given the
code above, the work of "scrolling" the map is in the DrawMap sub.
It draws the mapped based on the pixel coordinate of the upper/left
corner, indicated by the variables MapL and MapT. You just have to
change the values of MapL and MapT and call DrawMap, and the map
will be displayed at the new location.
So take the code and start playing with it. Add some code to read a
key and change the value of MapL and MapT and call DrawMap.
Like, if the "A" key is pressed then MapL = MapL - 1.
or if the "D" key is pressed then MapL = MapL + 1.
Maybe use the W key and S key to change MapT, which will move the
map up and down.
Add the label control, and see the values printed in it. Perhaps add to
the readout, the values of MapL and MapT.
You can put a breakpoint in the DrawMap routine and step through the
code as it calculates the values, and draws the tiles. You can look at the
values calculated.
Try reading, and experimenting with things from the debugging tutorial.
Know how to use the debug tools is quite important if you want to be
efficient at getting programs working.
http://www.xtremevbtalk.com/t9415.html
You say you think you understand the tile tutorial, well then that would
be a good place to start. See if you can create your own tiles and blt
them to the screen where you want. Once you can do that, then you can
play around with blting then partly to the left or above the (0,0) point to
implement subtile scrolling.
|
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
|

01-26-2004, 11:32 PM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Here
You want a proof that I have worked with tiles before?
Here you go!
I paused the work with it because of that It went very slow when moving.
|
|

01-27-2004, 05:57 AM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Ok
Here is something, i have used some ideas from you guys. Why does it goes so slow when im blitting to the screen? Please check it out.
|
|

01-27-2004, 06:21 AM
|
 |
Mostly Absent
Preferred language: * Expert *
|
|
Join Date: Jun 2002
Location: Christchurch, New Zealand
Posts: 2,006
|
|
The reason it's running so slow is because you're creating a new DC, loading an image, attaching that image to DC, deleting the image and deleting the dc everytime you blt a tile. That's over 100 times per frame.
The idea is just to load it once at the start, and then unload it at the end. I've done this and it runs considerably faster. Check it out.
|
__________________
Sometimes it happens feelings die, Whole years are lost in the blink of an eye
We once had it all but event conspired, Sometimes
Now that it's over, it is through, It gets me everytime I think of you
Sometimes It happens, feelings die, Sometimes
|

01-27-2004, 06:36 AM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
oh
Haha, oh. So that was the thing that have cause me all pain. Thanks!
|
|

01-27-2004, 11:03 AM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Improved, check it out
 I have improved my testing-tile-source. Please check it out. I also still have a problem with blitting not more tiles then i need. So if i have lets say 30 * 30(32 w&h tiles) with a display of 10 * 10 tiles on the screen i draw all tiles at the same time. How should i do?
|
|

01-27-2004, 04:56 PM
|
 |
Sinecure Expert
Preferred language: Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 6,748
|
|
Look at the code already posted. Here we have a 20 x 15 image from a
40 x 40 map (I notice now, that I treated it as 20 x 20 image , so I've
changed the code below).
Once you find what your starting tile's X and Y index should be (tx and
ty in this example), you then loop from tx to tx + 20 and ty to ty + 15
to cover the 20 x 15 area and not draw any unecessary tiles. In the
original code I also did a "Mod 32" to find the pixel offset so that we
offset by that amount, but doing an "And 31" is more efficient, so I
changed that below as well.
Code:
tx = mapL \ 32: ty = mapT \ 32 'get the starting (upper left corner) map tile coordinate
xl = -(mapL And 31): yt = -(mapT And 31) 'find how much of the tile should be off the screen
' update label Add a label to the form if you want to see these values as you scroll
' Label1.Caption = "Tile(" & Str$(tx) & "," & Str$(ty) & ") " & Str$(xl) & "," & Str$(yt)
For Y = ty To ty + 15 'For 16 tiles vertically
xt = xl ' Initial where the Left edge starts (-31 to 0)
For X = tx To tx + 20 ' For each tile horizontally
|
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
|

01-28-2004, 01:45 AM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
Like this?
I have now looked at your code and adapted it to my. Please check my code and tell me why i get an error when i move up?
|
|

01-28-2004, 06:27 AM
|
 |
Mostly Absent
Preferred language: * Expert *
|
|
Join Date: Jun 2002
Location: Christchurch, New Zealand
Posts: 2,006
|
|
In the DrawMap function, before the line
Code:
For y = ty To ty + 19
Put
Code:
If ty < 0 Then ty = 0
If tx < 0 Then tx = 0
Basically you're trying to get tiles with negative co-ordinates in the map, which obviously don't exist. This just makes sure you can't go negative. If you go too far right and down it will probably have problems, but these can be fixed in a similar way.
|
__________________
Sometimes it happens feelings die, Whole years are lost in the blink of an eye
We once had it all but event conspired, Sometimes
Now that it's over, it is through, It gets me everytime I think of you
Sometimes It happens, feelings die, Sometimes
|

01-29-2004, 07:58 AM
|
|
Regular
|
|
Join Date: Aug 2003
Posts: 69
|
|
No!!!!!!!!!!!!!!!
Why do i get error? I need to fix the problem. Can somebody help me with getting this code working?
'DC function declarations
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
'The function needed to load an image
Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
'Some constants used with LoadImage
Private Const LR_LOADFROMFILE = &H10
Private Const IMAGE_BITMAP = 0
Private MainDC As Long
Private hBitmap As Long
'SelectObject is used to move the loaded image into the DC
'DeleteObject is used to delete the "image buffer"
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Integer
'With BitBlt all the need in copying the bitmap from the DC to the screen(form)
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Map(99, 99) As Byte
Private MapOffset_X As Long
Private MapOffset_Y As Long
Private PlayerX As Long
Private PlayerY As Long
Private Sub Form_Load()
MainDC = CreateCompatibleDC(0)
hBitmap = LoadImage(0, App.Path + "/tileset.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
SelectObject MainDC, hBitmap
DeleteObject hBitmap
MapOffset_X = 0
MapOffset_Y = 0
PlayerX = 5 * 32
PlayerY = 5 * 32
Call CreateMap
Call DrawMap
Call DrawPlayer
End Sub
Private Function CreateMap()
For y = 0 To 93
For x = 0 To 93
Randomize
Map(x, y) = Int(Rnd * 2) * 32
Next x
Next y
End Function
Private Function DrawMap()
Dim tmp
Me.Cls
tx = MapOffset_X \ 32: ty = MapOffset_Y \ 32
xl = -(MapOffset_X And 31): yt = -(MapOffset_Y And 31) 'find how much of the tile should be off the screen
For y = ty To ty + 19
xt = xl ' Initial where the Left edge starts (-31 to 0)
For x = tx To tx + 19
BitBlt Me.hdc, (x * 32) - MapOffset_X, (y * 32) - MapOffset_Y, 32, 32, MainDC, Map(x, y), 0, vbSrcCopy
Next x
Next y
End Function
Private Function DrawPlayer()
BitBlt Me.hdc, PlayerX, PlayerY, 32, 32, MainDC, 64, 0, vbSrcCopy
End Function
Private Sub Form_Unload(Cancel As Integer)
Call DeleteDC(MainDC)
End Sub
Private Sub Timer1_Timer()
If GetAsyncKeyState(vbKeyA) <> 0 Then
MapOffset_X = MapOffset_X - 1
Call DrawMap
Call DrawPlayer
ElseIf GetAsyncKeyState(vbKeyD) <> 0 Then
MapOffset_X = MapOffset_X + 1
Call DrawMap
Call DrawPlayer
ElseIf GetAsyncKeyState(vbKeyW) <> 0 Then
MapOffset_Y = MapOffset_Y - 1
Call DrawMap
Call DrawPlayer
ElseIf GetAsyncKeyState(vbKeyS) <> 0 Then
MapOffset_Y = MapOffset_Y + 1
Call DrawMap
Call DrawPlayer
End If
End Sub
|
|

01-29-2004, 08:16 AM
|
 |
Disillusioned Code Poet
Preferred language: Retired Moderator * Guru *
|
|
Join Date: Apr 2002
Location: Tennessee, USA
Posts: 12,808
|
|
JimCamel's suggestion is correct. Trying to reference Map(-1,...) is generating the error. Take a look at Thinker's debugging tutorial in Tutor's Corner; that will make diagnosing problems like these very simple.
|
__________________
Laura
Ita erat quando hic adveni.
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
| |
|