Author Topic: Endless Horizontal Scrolling Code  (Read 6380 times)

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Endless Horizontal Scrolling Code
« on: 2011-Dec-21 »
Hi.

I am using the following code to scroll along a graphic image. What I have is an image that is 6144 pixels by 768 - I am using a screen resolution of 1024x768 fullscreen.
I want to have this large image shown on the screen and to slowly scroll along the screen - once it gets to the end - it loops around smoothly to the beginning again.
To make it loop smoothly - I pasted the first 1024x768 pixels of the image onto the end again. The code below does the rest. Please take a look.

Now my questions...

Although this code works - its crude and I do want to stick to this method of doing it  - i.e. as described above - but can anyone suggest a more efficient way of doing this that perhaps
is Kinder on memory usage or is faster - although this works fine - I do worry about this.. Anyone?
My code is below should anyone want to run it - comments very welcome. Thanks.



// --------------------------------- //
// Project: Testbed: Lullaby TV
// Start: Wednesday, December 20th, 2011
// IDE Version: 10


SETCURRENTDIR("Media") // go to media files

LOADSPRITE "Lullaby-6144x768.png", 0

//PLAYMUSIC "Old MacDonald.wav",TRUE // Loop Music

CONSTANT ScreenWidth = 1024
CONSTANT ScreenHeight = 768

CONSTANT GraphicWidth = 6144

GLOBAL XPos = 0

LIMITFPS 50

CLEARSCREEN RGB(0,0,0) // Set the backbuffer background colour to Black.
SHOWSCREEN // Show it.

REPEAT
   VIEWPORT XPos,0,ScreenWidth+(-XPos),ScreenHeight
   DRAWSPRITE 0,0,0
   SHOWSCREEN
   DEC (XPos)
   IF XPos < -(GraphicWidth-ScreenWidth)
      XPos = 0
   ENDIF
UNTIL FALSE


[attachment deleted by admin]
« Last Edit: 2011-Dec-22 by mrplant »

Offline ampos

  • Prof. Inline
  • *****
  • Posts: 1594
    • View Profile
    • AMpostata Website
Re: Endless Horizontal Scrolling Code
« Reply #1 on: 2011-Dec-21 »
Many devices have sprite lenght limited to 1024x1024 or 2048x2048. Even most of the PCs are at 2048.

So to be safe, you have to be limited to 1024x1024.

BTW, you dont need clearscreen 0, just use clearscreen -1. Why clear the screen if it is going to be overwritten?  :P

also this will work:

Code: GLBasic [Select]
cleascreen -1
repeat
for x=0 to 6144-1024
   drawsprite 0,x,0
   showscreen
next
until exit=true
check my web and/or my blog :D
http://diniplay.blogspot.com (devblog)
http://www.ampostata.org
http://ampostata.blogspot.com
I own PC-Win, MacBook 13", iPhone 3G/3GS/4G and iPAC-WinCE

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #2 on: 2011-Dec-21 »
Thanks for your reply.

The Clearscreen command was an oversight I copied/pasted from my previous project  :-[

Given the size of the graphic file - and this content is just a test - I'd like to have non repeating elements so scrolling parallax layer style prob isn't what I want...

How can I then handle an image of this size - given that its 6000 plus pixels across and I want to display a fullscreen segment of that (1024x768) each frame..

I can't seem to find commands to cut out a rectangles area from a larger graphic image and show that...

I suppose what I am asking is what is the best approach to take to do this?

thanks again.


Offline Moru

  • Administrator
  • Prof. Inline
  • *******
  • Posts: 1781
    • View Profile
    • Homepage
Re: Endless Horizontal Scrolling Code
« Reply #3 on: 2011-Dec-21 »
Get a tilemap editor. Can't say much else without seeing the picture you want to display...

Offline Slydog

  • Prof. Inline
  • *****
  • Posts: 930
  • KodeSource
    • View Profile
    • KodeSource
Re: Endless Horizontal Scrolling Code
« Reply #4 on: 2011-Dec-21 »
You would split your 6144 wide image into 6 (or 3) smaller images.
I'm not sure what platform you are targeting, but if it's PC then you should be good at 2048 wide images.

Then to scroll it you need to determine which two images (of the 3, if they are 2048 wide) you need displayed currently.
To draw the portion of the two images you want, use POLYVECTORs and specify the x, y for each corner vertice of the source image.

Here's something I whipped up (NOT tested) to show you what I mean.
I used my Poly_Draw() function, and TXyXy TYPE to make things simple.

Code: GLBasic [Select]
TYPE TXyXy
        x1%
        y1%
        x2%
        y2%

        FUNCTION Set: x1%, y1%, x2%, y2%
                self.x1 = x1
                self.y1 = y1
                self.x2 = x2
                self.y2 = y2
        ENDFUNCTION
ENDTYPE

CONSTANT ScreenWidth% = 1024
CONSTANT ScreenHeight% = 768
CONSTANT GraphicWidth% = 2048
CONSTANT BackgroundSprites% = 3
CONSTANT BackgroundWidth% = 2048 * 3 // GraphicWidth * BackgroundSprites

GLOBAL sp_background%[]
DIM sp_background[BackgroundSprites]
LOCAL xPos%=0
LOCAL x1%=0 // x Position where the two sprites are joined
LOCAL sp_current% // Current sprite we're working with
LOCAL xy_screen AS TXyXy // Screen x,y TL and BR corner locations
LOCAL xy_sprite AS TXyXy // Sprite x,y TL and BR corner locations

// Load the three images into the 3 sprites IDs
sp_background[0] = GENSPRITE
LOADSPRITE "Lullaby-1.png", sp_background[0]
sp_background[1] = GENSPRITE
LOADSPRITE "Lullaby-2.png", sp_background[1]
sp_background[2] = GENSPRITE
LOADSPRITE "Lullaby-3.png", sp_background[2]

// +---+------+
// |B1 |B2    |
// |   |      |
// +---+------+
// 0  x1     ScreenWidth

REPEAT
        x1 = GraphicWidth - MOD(xPos, GraphicWidth)
        sp_current = xPos / GraphicWidth // Will be either 0, 1, or 2

        // Draw left background sprite
        xy_screen.Set(0, 0, x1, ScreenHeight)
        xy_sprite.Set(GraphicWidth-x1, 0, GraphicWidth, GraphicHeight)
        STARTPOLY sp_current
        Poly_Draw(xy_screen, xy_sprite, RGB(255,255,255))
        ENDPOLY
       
        // Draw right background sprite
        INC sp_current // Use next background sprite
        IF sp_current > BackgroundSprites THEN sp_current = 0  // Cycle to first background sprite when at end
        xy_screen.Set(x1+1, 0, ScreenWidth, ScreenHeight)
        xy_sprite.Set(0, 0, ScreenWidth-x1, GraphicHeight)
        STARTPOLY sp_current
        Poly_Draw(xy_screen, xy_sprite, RGB(255,255,255))
        ENDPOLY
       
        INC xPos
        IF xPos > (BackgroundWidth - ScreenWidth) THEN xPos = 0
UNTIL FALSE

// (uv1) 0___2
//       |  /|
//       | / |
//       |/__|
//       1   3 (uv2)
// xy :: Top-Left and Bottom-Right screen location
// uv :: Top-Left and Bottom-Right texture location
FUNCTION Poly_Draw: xy AS TXyXy, uv AS TXyXy, colour%
        POLYNEWSTRIP
        POLYVECTOR xy.x1, xy.y1, uv.x1, uv.y1, colour           // TL
        POLYVECTOR xy.x1, xy.y2, uv.x1, uv.y2, colour           // BL
        POLYVECTOR xy.x2, xy.y1, uv.x2, uv.y1, colour           // TR
        POLYVECTOR xy.x2, xy.y2, uv.x2, uv.y2, colour           // BR
ENDFUNCTION
« Last Edit: 2011-Dec-21 by Slydog »
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #5 on: 2011-Dec-22 »
Hi thanks.

I will check this new way out and report back..

My target device is probably going to be the iPad in landscape mode 1024x768 - what is the maximum safe size to use for that platform just out of interest - anyone know?

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #6 on: 2011-Dec-22 »
This code is simpler and does work... but as I originally discovered when writing my version - it scrolls the background the wrong direction left to right instead of right to left

cleascreen -1
repeat
for x=0 to 6144-1024
   drawsprite 0,x,0
   showscreen
next
until exit=true

Offline Slydog

  • Prof. Inline
  • *****
  • Posts: 930
  • KodeSource
    • View Profile
    • KodeSource
Re: Endless Horizontal Scrolling Code
« Reply #7 on: 2011-Dec-22 »
I think to just reverse the direction, change the last two lines in the loop to:

Code: GLBasic [Select]
        DEC xPos
        IF xPos < 0 THEN xPos = (BackgroundWidth - ScreenWidth)  // -1 : May need the '-1' at the end if flickers when at end
 
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #8 on: 2011-Dec-23 »
Thanks Slydog - I haven't actually looked at your example code yet but it looks interesting - about to check it out now thanks.

I was still playing about with my own code - on the iPad it is stretching the aspect ratio for some weird reason I can't figure out - perhaps as the texture size is too big??

anyway-  about to test your solution out..

thanks.

Offline chve

  • Mr. Drawsprite
  • **
  • Posts: 65
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #9 on: 2011-Dec-24 »
I should do something so:

Code: GLBasic [Select]
// --------------------------------- //
// Project: Testbed: Lullaby TV
// Start: Wednesday, December 20th, 2011
// IDE Version: 10.209


SETCURRENTDIR("Media") // go to media files

LOADSPRITE "Lullaby-6144x768.png",  map

//PLAYMUSIC "Old MacDonald.wav",TRUE // Loop Music

CONSTANT ScreenWidth = 1024
CONSTANT ScreenHeight = 768

CONSTANT GraphicWidth = 6144

GLOBAL map, exit

GLOBAL speedH, speedW, imgX, scrW, imgWide, imgY, scrH, imgHeight
GLOBAL worldX, worldY ,MundoX, MundoY


GETSPRITESIZE map, imgWide, imgHeight

scrW=imgWide ; scrH= imgHeight


imgX=0 ;imgY=0 ; speedW=1


LIMITFPS 50

SHOWSCREEN // Show it.

CLEARSCREEN -1
REPEAT
imgX=imgX-speedW ; IF (imgX+scrW)<0 THEN imgX=imgX+scrW

        MundoX = MOD (worldX,imgWide) ;MundoX = -imgX ; IF worldX < 0 THEN MundoX = imgX - imgWide
        DRAWSPRITE map, imgX, imgY
        DRAWSPRITE map, imgX, imgY+scrH
    DRAWSPRITE map, imgX+scrW, imgY
        DRAWSPRITE map, imgX+scrW, imgY+scrH

SHOWSCREEN
UNTIL exit=TRUE

 

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #10 on: 2011-Dec-27 »
Hi Slydog.

I have been trying to compile your code but get this error.
Could you possibly run attached file with your code and work out what I have done wrong?
Graphics are cut into 2048 by 768 sizes like you mentioned..

thanks

This is the error I get when compiling for windows.

*** Configuration: WIN32 ***
precompiling:
GPC - GLBasic Precompiler V.10.104 SN:1d5d2793 - 3D, NET
Wordcount:50 commands
compiling:
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp: In function `int __GLBASIC__::__MainGameSub_()':
C:\Users\ADMINI~1\AppData\Local\Temp\glbasic\gpc_temp0.cpp:130: error: `x1' was not declared in this scope
*** FATAL ERROR - Please post this output in the forum
_______________________________________
*** Finished ***

[attachment deleted by admin]

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10723
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Re: Endless Horizontal Scrolling Code
« Reply #11 on: 2012-Jan-02 »
oh! bug.

Either move the TYPE declaration below the "main" function, or don't use the same parameter name "x1" in the Set function as well as a LOCAL in "main". So sorry.

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #12 on: 2012-Jan-02 »
thanks

Offline mrplant

  • Mr. Polyvector
  • ***
  • Posts: 232
    • View Profile
Re: Endless Horizontal Scrolling Code
« Reply #13 on: 2012-Jan-03 »
go code to compile but it locked up machine. I don't know the first thing about polyvectors so I added  a show screen command to main loop and it didn't crash this time!
All it showed though was a scrolling in outline sort of like a moving pyramid single line - no graphic content just outline.. then another pyramid outline, followed by another..
Anyone?
Way over my head now... ;-(

Offline Slydog

  • Prof. Inline
  • *****
  • Posts: 930
  • KodeSource
    • View Profile
    • KodeSource
Re: Endless Horizontal Scrolling Code
« Reply #14 on: 2012-Jan-03 »
Sorry, I've been away all Christmas week.
I ran the code and see there were a few bugs.  (ha, I guess I should have tested it!)

I've fixed them as far as I can see, and it now scrolls continuously and smoothly.
See the attached project.

Oh, for testing, I put a red line at the bottom of the 2nd graphic (and a yellow on the 3rd) to help see where the scroll position is at.

You can switch the direction with the new 'direction' variable.  (-1 for reverse)
You can set the scroll speed with the new 'speed' variable.  (I guess these could be combined into one variable using a negative speed for the reverse direction!)

I'm not 100% sure this is pixel perfect yet.
It may skip the 1st or last pixel in the graphic, and/or overlap the joining pics by a pixel.
More testing would be needed. (ie. I would start and end each graphic file with a one pixel wide line, each file with a different colour, see if you notice both lines where the split is).

[Update] I fixed a bug with detecting the end (or start, depending on scroll direction) of the last/first image.
It looked like it was working, but it happens that the 1st half of the 1st image and 2nd half of the last image were identical so it appeared to connect back to back.

[attachment deleted by admin]
« Last Edit: 2012-Jan-06 by Slydog »
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]