Can anyone help me with my scroll code please?

Blitz3D Forums/Blitz3D Programming/Can anyone help me with my scroll code please?

bashc(Posted 2011) [#1]
Long time ago I play a c-64 game very adictive which name I cannot remeber.

But I remeber (o may be it was a dream?) that such game had an scroll up and down and left and right and map border was conected and map seems to be infinite becouse it never finish when scroll.

I am trying to do a map 2D like that, but somehting is is wrong whith my code.
I am unable to sycncro scroll up and down with scroll left to rigth and viceverse.

Can some help me please?

Last edited 2011


Warner(Posted 2011) [#2]
The code looks incomplete?


bashc(Posted 2011) [#3]
Yes Warner, I will place it again, thanks


;Scroll left to rigth and viceversa
;Scroll un to down and viceversa ,but something is wrong 

Graphics 800,600,16,2
Global sprite
Global VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2 ; Zone to view

VistaGrandx1 = 1
VistaGrandy1 = 1
VistaGrandx2 = 640
VistaGrandy2 = 440

Global speedH, speedW

Global imgX, scrW, imgWide
Global imgY, scrH, imgHeight
imgWide =800
imgHeight=480

sprite=CreateImage(imgWide,imgHeight)




SetBuffer BackBuffer()


;imgWide=ImageWidth(sprite)
;imgHeight=ImageHeight(sprite)
Color 100,100,100
Rect 1 , 1 ,imgWide , imgHeight,1
; Draw random rectangles on the screen 
For a=1 To 100
; random color
	Color Rnd(255),Rnd(255),Rnd(255)
; super random rectangles
	Rect Rnd(800),Rnd(600),Rnd(100),Rnd(100),Rnd(1)
	Delay 5
	FlushKeys
Next
Locate 1,1 : Print "Left Up corner"

GrabImage sprite,0,0
Cls
Flip

;DrawImage sprite,0,0


scrW=640
scrH=480

imgX=0 ; X Start positon of the image
imgY=0 ; Y Start positon of the image

speedW=-3 ;Speed in Pixel
speedH=-3
;Print "The image width is: " + ImageWidth(sprite)
;-------------------------------------------------------------------------
;                           inicio
Color 0,250,255
Rect  VistaGrandx1-1 , VistaGrandy1-1 ,VistaGrandx2+2 , VistaGrandy2+2,0
Viewport VistaGrandx1 , VistaGrandy1 ,VistaGrandx2 , VistaGrandy2
DrawImage sprite,imgX, imgY  ; Stats in left Up border.
Color 250,0,0
Locate 1, 400
Print " imgX = "+imgX
Locate 1, 416
Print " imgY = "+imgY
;-------------------------------------------------------------------------

SetBuffer BackBuffer()

While Not KeyDown(1)
	
	
	
	If KeyDown(200) Then ; Scroll of screen up
		
		Cls
		Color 0,250,255
		Rect  VistaGrandx1-1 , VistaGrandy1-1 ,VistaGrandx2+2 , VistaGrandy2+2,0
		Viewport VistaGrandx1 , VistaGrandy1 ,VistaGrandx2 , VistaGrandy2
		
		imgY=imgY+speedH;then current Movemen only in X incremented
		
		If imgY+imgHeight>scrH Then DrawImage sprite,imgX,imgY-scrH ;now the wrap routine
		If imgY>scrH Then imgY=speedH                           
		If imgY<0 Then DrawImage sprite,imgX,scrH+imgY
		If imgY+imgHeight<0 Then imgY=imgY+scrH+speedH  
		DrawImage sprite,imgX, imgY      
		
		
		Color 250,0,0
		Locate 1, 400
		Print " imgY = "+imgY+" up"
		Locate 1, 416
		Print " imgY = "+imgY
		
		Flip
		
	EndIf
	
	If KeyDown(208) Then ; Scroll of screen down
		Cls	
		Color 0,250,4
		Rect  VistaGrandx1-1 , VistaGrandy1-1 ,VistaGrandx2+2 , VistaGrandy2+2,0
		Viewport VistaGrandx1 , VistaGrandy1 ,VistaGrandx2 , VistaGrandy2
		imgY=imgY-speedH;then current Movemen only in X decremented
		
		If imgY+imgHeight>scrH Then DrawImage sprite,imgX,imgY-scrH ;now the wrap routine
		If imgY>scrH Then imgY=speedH 
		If imgY<0 Then DrawImage sprite,imgX, scrH+imgY
		If imgY>scrH Then imgY=imgY-scrH-speedH 
		DrawImage sprite, imgX, imgY      
		
		Color 255,0,0
		Locate 1, 400
		Print " imgX = "+imgX+ " Down"
		Locate 1, 416
		Print " imgY = "+imgY+ "   Vistagrandex1 - Xpos = "+(Xpos-VistaGrandx1)
		
		Flip
		
	EndIf
	
	
	
	
	If KeyDown(205) Then ; Scroll of screen rigth
	Cls
	Color 0,250,255
	Rect  VistaGrandx1-1 , VistaGrandy1-1 ,VistaGrandx2+2 , VistaGrandy2+2,0
	Viewport VistaGrandx1 , VistaGrandy1 ,VistaGrandx2 , VistaGrandy2
	imgX=imgX+speedW;then current Movemen only in X incremented
	
	If imgX+imgWide>scrW Then DrawImage sprite,imgX-scrW,VistaGrandy1 ;now the wrap routine
	If imgX>scrW Then imgX=speedW                           
	If imgX<0 Then DrawImage sprite,scrW+imgX,VistaGrandy1
	If imgX+imgWide<0 Then imgX=imgX-scrW+speedW  
	DrawImage sprite,imgX, VistaGrandy1       
	
	Color 250,0,0
	Locate 1, 400
	Print " imgX = "+imgX+" Rigth  "
	Locate 1, 416
	Print " imgY = "+imgY
	
	Flip
	
EndIf

If KeyDown(203) Then ; Scroll of screen left
	Cls	
	Color 0,250,4
	Rect  VistaGrandx1-1 , VistaGrandy1-1 ,VistaGrandx2+2 , VistaGrandy2+2,0
	Viewport VistaGrandx1 , VistaGrandy1 ,VistaGrandx2 , VistaGrandy2
	imgX=imgX-speedW ;then current Movemen only in X decremented
	
	If imgX+imgWide>scrW Then DrawImage sprite,imgX-scrW,VistaGrandy1 ;now the wrap routine
	If imgX>scrW Then imgX=speedW 
	If imgX<0 Then DrawImage sprite,scrW+imgX,VistaGrandy1
	If imgX>scrW Then imgX=imgX-scrW+speedW 
	DrawImage sprite,imgX, VistaGrandy1       
	
	Color 255,0,0
	Locate 1, 400
	Print " imgX = "+imgX+ " Left"
	Locate 1, 416
	Print " imgY = "+imgY
	
	Flip
	
EndIf







Wend
End 








Warner(Posted 2011) [#4]
When you move upwards or downwards directly, it seems to work correctly.
However, when you scroll sideways, then up or down, it jumps back to it's original x-position.

You could perhaps draw the image 9 times, in a 3x3 grid. Then, scroll the grid and limit the coordinates. Instead of drawing the image 9 times, you could revert to using TileImage instead. It fills an area with an image.


bashc(Posted 2011) [#5]
Warner, it sound interesting idea and I have much time to study how to do what you says.

A rare kind of game would be with such map isn't? lol

If I cannot do with my not-work actually code I will try to do as you says and (if I am able to write and it works) I will post here.

Thank you vey much for your idea that can be a solution to my nightmare-rare-map :)


Jimmy(Posted 2011) [#6]
Something like this perhaps? As you need 8 directional scroll its easiest to do with modulo X and Y to seaprate and so it may be combined, and therefore becomes again as you did it, 4 sprites.
It's just my 2 cents whatever it's worth. It gets quiet shorter this way too. Th total of the 4 sprites visible always adds up to just one screen's worth but its up to hardware to be clever about this via the viewzone.

Inoticed this is the way you tried solve it with abit more code, so it's still just the same, just shorter and abit quicker. But most of all it works 8 directions.

UPDATE Hope this helps you away from your programming nightmares :p, its a great start for a new game not much fat to loose oneself in.




Last edited 2011

Last edited 2011

Last edited 2011

Last edited 2011


bashc(Posted 2011) [#7]
Jimmy, I am not understand still how your code works, but it works fine and it is just I need ! And three days of nighmare trying my routine works has finised!! wow!
Of course, I will be able to adapt it to another start map o array of tiles, etc.

Tomorrow I will examine how your code works, be sure (I like do this) becouse today it is too latter in my country and I have to sleep.

Thank you very much for help, which helps a lot!!


Jimmy(Posted 2011) [#8]
It just draws 4 copies of the screen side by side and side by side on top of eachother.
O O
O O

And these 4 lines is where the magic happens
If KeyDown(200) Then imgY=imgY-speedH : If (imgY+scrH)<0 Then imgY=imgY+scrH                      
If KeyDown(208) Then imgY=imgY+speedH : If imgY>0 Then imgY=imgY-scrH
If KeyDown(203) Then imgX=imgX-speedW : If (imgX+scrW)<0 Then imgX=imgX+scrW
If KeyDown(205) Then imgX=imgX+speedW : If imgX>0 Then imgX=imgx-scrW

Whenever a coordinate goes out of boundry it takes it back a notch eaxctly one screen, making it not noticeble it ever happened.

EDIT I should be at bed too, programming is known to keep people widely awake when not supposed to :s

Last edited 2011


bashc(Posted 2011) [#9]
Yes Jimmy, I can understand it, but I was trying to write an idea,and my idea was not good. Did not work and I waste my time and finally, a magic and hated phrase apperar in my mind "ask to blizt forum".

And I don't like to ask in forum, but if I don't do, I cannot continue.

Seems to be my mind work only with four neurones lol.

However, I learn more and more about progaming but slowly, becouse I am not hurry.

For example, be sure that this I have learned from you, I will adapt in the future to another code if it is necesarry.

And I thank you very much for convert my 180 lines (damn!) of code which does not work in 38 (omg!) which works very well :)


Jimmy(Posted 2011) [#10]
Good to hear! Well we all could need a push sometimes, and its never wasted putting down some effort trying. :)

Sometimes things works sometime they don't, simple as that, same thing goes with brain of mine btw.

Last edited 2011


bashc(Posted 2011) [#11]
To Jimmy

But be sure, that I have learned this lesson :)


Jimmy(Posted 2011) [#12]
Also as Warner mentioned TILEIMAGE might be something worth looking into if it truly gives a hardware boost, as that would probably
mean things gets down to a single draw instead of having do four separate draws. I have never used this myself though.

Note I made an error with wich Width and height I was using, change "ScrW" into "ImgWide" and "ScrH" with "ImgHeight" on the SPRITE line and KEYDOWN lines.

Last edited 2011

Last edited 2011


bashc(Posted 2011) [#13]
Ahh! and There were some that I cannot fix in your code and y resolve so:


Graphics 800,600,16,2

Global sprite, VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2 ; Zone to view
VistaGrandx1 = 1 : VistaGrandy1 = 1 : VistaGrandx2 = 600 : VistaGrandy2 = 430
Global speedH, speedW, imgX, scrW, imgWide, imgY, scrH, imgHeight



sprite=LoadImage("Sprite.png") ; load a image, I used some  of this size 1280*600. Image must be more bigger than what appears on screen.


imgWide=ImageWidth(sprite)
imgHeight=ImageHeight(sprite)

scrW=imgWide : scrH= imgHeight ; <-------I do this solution, even it is was't the best it works for my purpose.

imgX=0 : imgY=0 : speedW=3 : speedH=3
;Color 0,250,255 : Rect VistaGrandx1-1, VistaGrandy1-1, VistaGrandx2+2, VistaGrandy2+2,0
Viewport VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2 
;-------------------------------------------------------------------------
;                           inicio
SetBuffer BackBuffer()

While Not KeyDown(1)
	Cls
	
	If KeyDown(200) Then imgY=imgY-speedH : If (imgY+scrH)<0 Then imgY=imgY+scrH   ; <----- I don`t see error that you write in forum. quote: "...change ScrW into "ImgWide"..."                
	If KeyDown(208) Then imgY=imgY+speedH : If imgY>0 Then imgY=imgY-scrH
	If KeyDown(203) Then imgX=imgX-speedW : If (imgX+scrW)<0 Then imgX=imgX+scrW
	If KeyDown(205) Then imgX=imgX+speedW : If imgX>0 Then imgX=imgX-scrW
	
	Viewport VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2
	DrawImage sprite, imgX, imgY : DrawImage sprite, imgX, imgY+scrH : DrawImage sprite, imgX+scrW, imgY : DrawImage sprite, imgX+scrW, imgY+scrH
	Color 250,0,0 : Locate 1, 400 : Print " imgX = "+imgX : Locate 1, 416 : Print " imgY = "+imgY
	
	Flip
	
Wend


Works even if it is nt a perfecto solntion.


But, of course it is better as you have fixed now!



Global sprite, VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2 ; Zone to view
VistaGrandx1 = 1 : VistaGrandy1 = 1 : VistaGrandx2 = 640 : VistaGrandy2 = 380
Global speedH, speedW, imgX, scrW, imgWide, imgY, scrH, imgHeight

imgWide = 800 : imgHeight = 480
sprite=CreateImage(imgWide,imgHeight) : SetBuffer BackBuffer()
Color 100,100,100 : Rect 1, 1, imgWide, imgHeight,1

; Draw random rectangles
For a=1 To 100 : Color Rnd(255),Rnd(255),Rnd(255) : Rect Rnd(800),Rnd(600),Rnd(100),Rnd(100),Rnd(1) : Delay 5 : FlushKeys : Next

Locate 1,1 : Print "Left Up corner"

GrabImage sprite,0,0 : Cls : Flip
scrW=640 : scrH=480 : imgX=0 : imgY=0 : speedW=3 : speedH=3
Color 0,250,255 : Rect VistaGrandx1-1, VistaGrandy1-1, VistaGrandx2+2, VistaGrandy2+2,0
Viewport VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2 
;-------------------------------------------------------------------------
;                           inicio
SetBuffer BackBuffer()

While Not KeyDown(1)
	Cls
		
	If KeyDown(200) Then imgY=imgY-speedH : If (imgY+imgHeight)<0 Then imgY=imgY+imgHeight                      
	If KeyDown(208) Then imgY=imgY+speedH : If imgY>0 Then imgY=imgY-imgHeight
	If KeyDown(203) Then imgX=imgX-speedW : If (imgX+imgWide)<0 Then imgX=imgX+imgWide
	If KeyDown(205) Then imgX=imgX+speedW : If imgX>0 Then imgX=imgX-imgWide
	
	Viewport VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2
	DrawImage sprite, imgX, imgY : DrawImage sprite, imgX, imgY+imgHeight : DrawImage sprite, imgX+imgWide, imgY : DrawImage sprite, imgX+imgWide, imgY+imgHeight
	Color 250,0,0 : Locate 1, 350 : Print " imgX = "+imgX : Locate 1, 366 : Print " imgY = "+imgY
	
	Flip
	
Wend




And variables "scrW" and "scrH" can be erased.


And I will use this, becouse is better.

Thanks Jimmy for to fix this :)

Warnr idea semms to be good, but start to code this, if code of Jimmy works fine... having account that "my bugged syle of progamning", well, I preffer do not do this idea now, or there is some (too much) risk that I have to ask for help in this forum again lol

I is better yo never view my bugged code and routines, becouse I learn a littel to progamning reading second hand books, not in any school lol

Last edited 2011


Jimmy(Posted 2011) [#14]
You do what makes you feel good :) But you should not feel akward about showing beginners code, we've all been there.

In any case I feel I want at least to show abit how one would use snippet above with absolute coordinates, which is way more useful.

So one may do for things like big circular movements etc, anything really. I recognize it would help making games with it too.

There's two very magical lines here, I roughed my hair few times to come up with this, please don't ask all math and logic behind becuase my mind is not up for it very often and certainly not today :p just came from concert after no sleep. A kingdom for a bed.

But I really want to show how one may use above code with absolute coordinates.

This is the magic line (same goes for Y in source) note that the if is only needed if you want to have both positive/negative world coordinates, if you need only positive, you may throw the IF away

EDIT
imgX = worldx Mod ImgWide : imgX = -imgX : If worldx < 0 Then imgX = imgX - ImgWide


If someone knows how to simplify that please do so.

Enough rambling, here's the code I want to share with you nontheless:

Warners idea of TILEIMAGE was the only thing left now, so I put that into too in a hurry.

Graphics 800,600,16,2

Global sprite, VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2 ; Zone to view
VistaGrandx1 = 1 : VistaGrandy1 = 1 : VistaGrandx2 = 640 : VistaGrandy2 = 440
Global speedH, speedW, imgX, scrW, imgWide, imgY, scrH, imgHeight

imgWide = 800 : imgHeight = 480
sprite=CreateImage(imgWide,imgHeight) : SetBuffer BackBuffer()
Color 100,100,100 : Rect 1, 1, imgWide, imgHeight,1

; Draw random rectangles
For a=1 To 100 : Color Rnd(255),Rnd(255),Rnd(255) : Rect Rnd(800),Rnd(600),Rnd(100),Rnd(100),Rnd(1) : Delay 5 : FlushKeys : Next

Locate 1,1 : Print "Left Up corner"
GrabImage sprite,0,0 : Cls : Flip
scrW=640 : scrH=480 : imgX=0 : imgY=0 : speedW=3 : speedH=3
Color 0,250,255 : Rect VistaGrandx1-1, VistaGrandy1-1, VistaGrandx2+2, VistaGrandy2+2,0
Viewport VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2 
;-------------------------------------------------------------------------
;                           inicio
SetBuffer BackBuffer()

While Not KeyDown(1)
Cls

; WAS THIS

; Using relative coordinates
;If KeyDown(200) Then imgY=imgY-speedH : If (imgY+ImgHeight)<0 Then imgY=imgY+ImgHeight                      
;If KeyDown(208) Then imgY=imgY+speedH : If imgY>0 Then imgY=imgY-ImgHeight
;If KeyDown(203) Then imgX=imgX-speedW : If (imgX+ImgWide)<0 Then imgX=imgX+ImgWide
;If KeyDown(205) Then imgX=imgX+speedW : If imgX>0 Then imgX=imgx-ImgWide

; NOW THIS

; Using world (absolute) coordinates instead
If KeyDown(200) Then worldY=worldY-speedH                  
If KeyDown(208) Then worldY=worldY+speedH
If KeyDown(203) Then worldX=worldX-speedW
If KeyDown(205) Then worldX=WorldX+speedW
; Convert world coordinates into imgX and imgY (the if makes it handles negative world coordinates too)
imgX = worldx Mod ImgWide : imgX = -imgX : If worldx < 0 Then imgX = imgX - ImgWide
imgY = worldy Mod ImgHeight : imgY = -imgY : If worldy < 0 Then imgY = imgY - ImgHeight

Viewport VistaGrandx1, VistaGrandy1, VistaGrandx2, VistaGrandy2
TileImage sprite,imgX,imgY ; or this DrawImage sprite, imgX, imgY : DrawImage sprite, imgX, imgY+ImgHeight : DrawImage sprite, imgX+ImgWide, imgY : DrawImage sprite, imgX+ImgWide, imgY+ImgHeight
Color 250,0,0 : Locate 1, 400 : Print " imgX = "+imgX : Locate 1, 416 : Print " imgY = "+imgY
Color 250,0,0 : Locate 1, 300 : Print " worldX = "+worldX : Locate 1, 316 : Print " worldY = "+worldY

Flip

Wend


Last edited 2011

Last edited 2011

Last edited 2011


Ross C(Posted 2011) [#15]
Defintely, if you need help ask man. You never know, there could be someone reading who gets help or learns something. I have often read threads and saw certain techniques people use to accomplish tasks and used them myself.


bashc(Posted 2011) [#16]
Yes, I will. You are right, Ross C


bashc(Posted 2011) [#17]
Jimmy

It is very interesting to see how to do a scrroll map using World X, Y coordinates.




This is the magic line (same goes for Y in source) note that the if is only needed if you want to have both positive/negative world coordinates, if you need only positive, you may throw the IF away




This code is only to show you as I do to analyze to understand it, becouse so, I will be able to re-write for a future map, idea, etc.
It has not sense only copy an paste a good code without to know how it works!
Code:


Graphics 640,400,16,2
Global imgX, imgY ,imgWide,imgHeight, speedW,SpeedH ; Global only for better display in IDeal editor hehe
imgWide = 800
imgHeight = 480
speedW=-1
SpeedH=-1
CoordTyp=False
While Not KeyDown(1)
	
	; Only to for examine how it works in numbers
	If KeyDown(200) Then worldY=worldY-SpeedH ; down                
	If KeyDown(208) Then worldY=worldY+SpeedH ; Up
	If KeyDown(203) Then worldX=worldX-speedW ; left
	If KeyDown(205) Then worldx=worldX+speedW ; right
	
	imgX = worldx Mod imgWide : imgX = -imgX 
	imgY = worldy Mod imgHeight : imgY = -imgY 
	
	If CoordTyp =True
	If worldX < 0 Then imgX = imgX - imgWide
EndIf
	
	
	
If CoordTyp =True
	If worldy < 0 Then imgY = imgY - imgHeight
EndIf
If CoordTyp =True Then   Locate 1,1: Print "World X = "+WorldX+ "  World X= "+ Worldy + "  World coordenates.  'Z' to change image coordenates"
	
If CoordTyp =False	Locate 1,1 : Print "Img X = "+imgX+ "  Image Y= "+ imgY + "   Image coordenates  'X' to change World coordenates"
	
	If KeyHit(45)=True Then CoordTyp=True   ; z
	If KeyHit(44)=True Then CoordTyp=False  ; x
	
	
	Flip
	Cls
	
Wend



Vey thanks Jimmy for your explanations and exaples wich are very usefull.


mv333(Posted 2011) [#18]
Here's a good example of TileImage for a background :

360° shooter game example code (by WolRon)


bashc(Posted 2011) [#19]
Thank you very much mv333, this example is very good!