Small problem with level editor scroll?

Blitz3D Forums/Blitz3D Programming/Small problem with level editor scroll?

Guy Fawkes(Posted 2012) [#1]
Hi all, ok, my level editor is working fine with the keys. (At least I think), for scrolling... (Correct the scrolling code if I'm wrong). BUT... I for some reason can't get the tile to draw in the exact correct spot UNLESS I haven't scrolled on the map. But that's a problem, because I NEED to scroll, in order to create a full map...


Here's the code:






I need to create maps the SAME size in the game, as the editor...


Here's the CURRENT level editor AND game with media AND source:


http://www.mediafire.com/?wpcx1uufi0x13f5


Thank you for the help! :)

Last edited 2012


Guy Fawkes(Posted 2012) [#2]
Ugh. I'm SO close. What could be wrong? :/


Midimaster(Posted 2012) [#3]
You have a lot of code, that does nearly the same.. Why not put this into a function and call it?

If mode=1
For x=0 To mapx
	For Y=0 To mapy
		DrawImage tiles,X1+x*32,Y1+y*32,map(x,y)	
	Next	
Next
....
If mode=2
For x=0 To mapx
	For Y=0 To mapy
	DrawImage tiles,x*32,y*32,map(x,y)	
	If mapcol(x,y)=1
	Color 0,0,0
    Rect x*32,y*32,32,32,0
    EndIf
....	


better:
If mode=1
     DrawTiles
....
If mode=2
    DrawTiles
    Grid
   For x=0 To mapx
	For Y=0 To mapy
	If mapcol(x,y)=1
	Color 0,0,0
    Rect x*32,y*32,32,32,0
    EndIf
....	

Function DrawTiles()
   For x=0 To mapx
	For Y=0 To mapy
		DrawImage tiles,X1+x*32,Y1+y*32,map(x,y)	
	Next	
   Next
End Function




even better:
If mode=MODE_TILE_PLACE
     DrawTiles
....
If mode=MODE_KOLLISION
    DrawTiles
    Grid
   For x=0 To mapx
	For Y=0 To mapy
	If mapcol(x,y)=WITH_COLLISION
	    SetColor WHITE 
    Rect x*TILE_SIZE,y*TILE_SIZE,TILE_SIZE,TILE_SIZE,0
    EndIf
....	

Function DrawTiles()
   For x=0 To mapx
	For Y=0 To mapy
		DrawImage tiles,X_Off+x*TILE_SIZE,Y_Off+y*TILE_SIZE,map(x,y)	
	Next	
   Next
End Function





I can see some line which are responsible for Drawing Tiles on the Screen. Sometime you use a Scrolling-Offset X1, sometimes not. Why?

Next problem is to understand your code. You use a lot of numbers. This is no good style. Third persons can not understand what this code is good for.

sample:

If KeyHit(12) And mode=2 Then coltype=coltype-1


it would be better to define CONST at the beginning of the programm, the nto use this keywords instead of direct numbers:
CONST KEY_QUEST=12
CONST MODE_TILE_PLACE=1 , MODE_KOLLISION=2
If KeyHit(KEY_QUEST) And mode=MODE_KOLLISION Then coltype=coltype-1


.....
    gy=MouseY()/32
	Color 256,0,0
	Line MouseX()-10,MouseY(),MouseX()+10,MouseY()
	Line MouseX(),MouseY()-10,MouseX(),MouseY()+10
	If MouseDown(1) And gx < 32 And gy < 24 Then map(gx,gy)=currenttile
.....


better:
 .....
    gy=MouseY()/32
    Color 256,0,0
    ShowCursor
    If MouseDown(1) And gx < 32 And gy < 24 Then map(gx,gy)=currenttile
.....
Function ShowCursor()
	Line MouseX()-10,MouseY(),MouseX()+10,MouseY()
	Line MouseX(),MouseY()-10,MouseX(),MouseY()+10
End Function


even better:
CONST TILE_SIZE=32 
CONST RED=1, LEFT_MOUSE=1
 .....
    actCursorY=MouseY()/TILE_SIZE
    SetColor Red
    ShowCursor
    If MouseDown(LEFT_MOUSE) And actCursorX < TILE_SIZE And actCursorY < 24 Then map(gx,gy)=currenttile
.....
Function ShowCursor()
	Line MouseX()-10,MouseY(),MouseX()+10,MouseY()
	Line MouseX(),MouseY()-10,MouseX(),MouseY()+10
End Function

Function SetColor (ColorNumber%)
     Select ColorNumber
        Case RED
                 Color 255,0,0
    .....
End Function




A variable name like X1% says not much about, why it is necessary, it would be better to name it Xoff%

Also your Grid() Function could handle all these RECT commands in one function...


Guy Fawkes(Posted 2012) [#4]
Ok, I redid it so it's more conventional, but for some reason, it's still drawing tiles in the incorrect places. Also, what does "WITH_COLLISION" equal?


Here's my code:




Last edited 2012


Midimaster(Posted 2012) [#5]
if you now use only the DrawTiles() function to draw any tile it is not longer possible, that the tiles are drawn in "incorrect places"!

The error must be in storing the tile-information in Map[] or in finding out the tile position before storing the map[]. Have a look on the Mouse() related functions. Also the problem could be caused by the Load functions?

Try to reduce the code to one remaining function GetTile(), which calculates the current tilepos X and Y by MouseX() and MouseY().

In a scrolled map window the cursor should also be shown considering the OffX and OffY. maybe this is better:

Function ShowCursor()
     GetTile()
 	Line X1+X,Y1+Y+16,X1+X+32,Y1#Y+16
	Line X1+X+16,Y1+Y,X1+X+16,Y1+Y+32
End Function




Also all RECT-command should care about the OffX/OffY:
		For x=0 To mapx
			For Y=0 To mapy
				If mapcol(x,y)=WITH_COLLISION
					SetColor WHITE
					Rect X1+x*TILE_SIZE,Y1+y*TILE_SIZE,TILE_SIZE,TILE_SIZE,0
				EndIf
			Next
		Next


Also you should replace A L L Color commands with the new solution!

And of course my "+16" in the sample above with a HALF_TILE_SIZE const!!!

And I would exchange all "X1" with the name "Xoff"


Guy Fawkes(Posted 2012) [#6]
Ok, EXCEPT for the Xoff thing, NOW im confused... Here is what I have:





Also, I sorta don't understand what you mean by it's drawing in incorrect places... :/ Sorry ><

Last edited 2012


Midimaster(Posted 2012) [#7]
Ok... Now I had the time to have a deeper look on your code.

As I can see, you planned to set the scrolling not pixel by pixel but grid by grid. I found this line:
	If X1 < -mapx Then X1 = -mapx

this says, that the scrolling should finish, when X1 is bigger then mapx, but mapx is 32. This cannot be pixels but rows or columns.

So you have to calculate the real scrolling by multiplicating the X1 with TILE_SIZE. So let us add this line:
OffX=X1*TILESIZE
and use this OffX in all drawing commands:
Rect OffX+x*TILE_SIZE,OffY+y*TILE_SIZE,TILE_SIZE,TILE_SIZE,0
of course the same with Y1 and OffY

Now I cleaned up your Update() Function. Now it looks like this:
Function update()

		DrawTiles()
		
  		DrawGrid()
				
		DrawCurrentTile()

End Function


it contains only three call of function, which take care about drawing tiles, the grid and a box which shows the current tile.

Here is the first:
Function DrawTiles()
		For x=0 To mapx
			For Y=0 To mapy
				DrawImage tiles,OffX+x*TILE_SIZE,OffY+y*TILE_SIZE,map(x,y)	
			Next	
		Next

End Function 

i think you understand what happens. Nothing special. The drawing uses the new OffX parameter.


here is the second:

Function DrawGrid()
	If GridOn=True
		For x=0 To mapx
			For y=o To mapy
				If mapcol(x,y)=1
						SetColor BLACK
				ElseIf mapcol(x,y)=2
						Setcolor RED
				EndIf
					Rect OffX+X*TILE_SIZE , OffY+Y*TILE_SIZE , TILE_SIZE , TILE_SIZE ,0
			Next
		Next
	EndIf
End Function

this paints the rects arounf the tiles and shows now all the time the status of the Collision at each tile

Now the third is a gift of me. It shows a box (like a window) that is always above the others and gives the user informations about the ccurrent tile and the current selected collision state
Function DrawCurrentTile()
	; draws a window to show all possible Tiles and the current:
		Local OffX%=15 , OffY%=715 , Border%=3
		
		; first a box
		SetColor BLACK
			Rect OffX-2*Border,OffY-2*Border,10*(TILE_SIZE+5)+4*Border,TILE_SIZE+4*Border
			SetColor GREY
			Rect OffX-Border, OffY-Border,10*(TILE_SIZE+5)+2*Border,TILE_SIZE+2*Border
		
		; then all tiles:
			For i=0 To 9
				DrawImage tiles,OffX+i*(TILE_SIZE+5),OffY,i
			Next
	
		; then the current:
		If coltype=2 
				SetColor RED
		Else
				Setcolor WHITE
		EndIf
			Rect OffX+CurrentTile*(TILE_SIZE+5) , OffY , TILE_SIZE , TILE_SIZE ,0
End Function



Now you should remove all drawing commands from the control() function. And there is no need for dividing the function into a mode=1 and a mode=2 part!

Remove the cursor cross code to a function ShowCursor()

Use 4 different key for the Collisions and the tile selection. So you can both the same time. After that a mouse click would move the current tile and the current collision to a certain map position!

Bundle all key press commands into the control() function.


Your last problem now is the calculation of the map position from mouse coordinates:

Global AktCursorX%,AktCursorY% 
.....

Function CalculateCursor()
	AktCursorX=MouseX()/TILE_SIZE-X1
	AktCursorY=MouseY()/TILE_SIZE-Y1
End Function


Now you can write the code for ShowCursor() function:

Function ShowCursor()
	CalculateCursor()
	locX=OffX+AktCursorX * TILE_SIZE
	locY=OffY+AktCursorY * TILE_SIZE
	
 	Line locX , locY+TILE_SIZE/2 , locX+TILE_SIZE , locY+TILE_SIZE/2
	Line locX+TILE_SIZE/2 , locY , locX+TILE_SIZE/2 , locY+TILE_SIZE
End Function


will be continued....


here is the whole code (attention: i temp. removed the save/load functions()



Last edited 2012


Guy Fawkes(Posted 2012) [#8]
Ok, it sorta works.. When I use mousedown(), and move it with the arrows, then move it back to the left, it glitches for some reason, and draws tiles in the wrong place. I need to use mousedown so I don't have to draw something that needs to be drawn more than once, one by one.







Thanks, MidiMaster! :)


Midimaster(Posted 2012) [#9]
shouldn't you pack all key commands into the control() function?

Do you want grid scrolling or pixel scrolling?

I could not repeat the bug you told me!

MouseDown is also OK! But i think the grid scrolling is too fast in combination with the MouseDown(), or?

Perhaps you should permit scrolling keys while mouse is pressed?


Guy Fawkes(Posted 2012) [#10]
Ok, what I need, is when you hold down the left mousebutton, then 1 of the cursor keys, it draws the selected tile in the correct area, no matter what speed, no matter how big the map is. :)


Thanks, MidiMaster! :)