Help me, about 2D x,y
Blitz3D Forums/Blitz3D Beginners Area/Help me, about 2D x,y
| ||
Well, if you make somekind of game and ask to draw and image to 5000,5000 Does it start from the top left corner? And how can u move ur screen to move down,up,left,right and get to that image? or does the image move with the corner of ur screen... i dunno if u can follow me :| and example would be nice, like how to make ur screen move... |
| ||
Your screen is 0,0 in the top left corner, and GraphicsWidth()-1, GraphicsHeight()-1 in the lower right corner. If you want to scroll an image onto the screen, then you need to move the images, not the screen. Luckilly, this is fairly easy to do. Let's assume Screen_X, Screen_Y is where you would like the screen to be in the 2D plane that extends both to -5000,-5000 and to 5000, 5000. As the screen itself cannot move, you need to instead offset the images to simulate the effect. All you need to do then is subtract Screen_X and Screen_Y from the image's location in the world, and then blit the image to that new location. Ie, if your image is at 5000,5000, and your screen is at 4000, 4000, then you would blit the image at 1000,1000. Note though that this is very likely to be off the screen, because most 2D games do not run at 1280x1024. They run at more like 640x480, or 800x600. Can't scroll graphics at a high framerate in really high resolutions. |
| ||
You should avoid actually drawing an image of that size to the screen though. Use DrawImageRect to draw only the area of the image which is onscreen. |
| ||
What I meant was, example I place a circle at x5000,y5000 and the screen appears at x0,y0 if I press up the screen moves up, down the screen moves down(like scrolling,left the screen moves left and right the screen moves right, but the circle doesn't move the screen does :P Another question, if I added a space background and like my spaceship goes right, so the background scrolls left at a certain speed, how would I do that? is that doable? |
| ||
You MUST move the images. You CANNOT move "the screen". The screen is not a camera providing a view into a larger world, it is a collection of pixels a certan width and height fixed in place. Moving the images in the way I describe will make the screen APPEAR to move. It will be the effect you want. The screen only APPEARS to be a window into a larger area when you offset the images before you draw them. So in my example above, add 10 to Screne_X every tiem the user hits right arrow, and that will make the images move to the left... which will make the screen viewport appear to move to the right. Blitting big images though is not the best way to make a scrolling engine. The best way is to scroll is to use small tiles. You may be thinking of how one used to scroll graphics in the sayd of DOS. Back then you could make the graphics buffer bigger than the screen, and scroll parts of it into view, then when one whole tile was revealed you could build some more off the edge waiting to scroll onto the screen, and continue to scroll. But as far as I know, this method of scrolling is no longer possible. That method isn't that useful anyhow, because noawadays most 2D games have parralax. And the fastest way to do parralax is just to redraw the whole screen every time. "Another question, if I added a space background and like my spaceship goes right," Yes, you can do this. All you need to do is change the spaceship position in the world. So as you are changing screen_X, and subtracting that from the space ship and background tile positions just before you draw them, you also are adding some value to ship_X so that it is moving to the right faster than the screen is scrolling to the left. Of course, in MOST shooters, they are not realistic, so if you move the ship to the right, it stays there even though the screen scrolls. In that case, you simply position the ship in screen space, and don't subtract screen_X, Screen_Y from it's location every frame. Then it'll stay at Ship_X, Ship_Y on the screen where you left it. |
| ||
Again to reiterate: Image_X, Image_Y = Image location in WORLD space. Screen_X, Screen_Y = Screen location in WORLD space. Ship_X, ShipY = Ship location in SCREEN space. During each loop: To scroll background left: Screen_X = Screen_X - 10 Draw background Image at: Image_X-Screen_X, ImageY-Screen_Y. Draw Ship at: Ship_X, Ship_Y If you want the ship to move back when the screen scrolls left, then instead draw it at Ship_X-Screen_X, Ship_Y-Screen_Y. But remember that you will have to move it to the right at the same speed as the screen is scrolling left if you want to keep it on the screen. |
| ||
I tryed something which is not working, what am i doing wrong: ; Graphic Mode Graphics 800,600,32 ; Global Variables While Not KeyDown(1) Cls ; Always clear screen first Rect 40,40,20,20,1 ; Draw the box in the current x,y location Rect 40,100,20,20,1 ; Draw the box in the current x,y location If KeyHit(208) Then ch=GraphicsHeight() - 1 EndIf Flip ; Flip it into view Wend |
| ||
You're doing a lot wrong. I'm not even sure what you intended with that bit that gets activated when you press a key. Here is the simplest 2d scrolling system I could muster up for you. Graphics 800,600,32 SetBuffer BackBuffer() Type Sprite Field Image Field XPos Field YPos End Type Dim Image(20) ; Create 20 random images to use for sprites cause we don't have any bitmaps to load. For Loop = 0 To 19 Image(Loop) = CreateImage(32, 32) SetBuffer ImageBuffer(Image(Loop)) Color Rand(0,255), Rand(0,255), Rand(0,255) Shape = Rand(0, 1) Select Shape Case 0 Rect 0, 0, 32, 32, Rand(0, 1) Case 1 Oval 0, 0, 32, 32, Rand(0, 1) End Select Next ; Reset the graphics to draw to the backbuffer. ; Don't need to do this if you load the images instead of create them manually. SetBuffer BackBuffer() ; Create 2000 random sprites in the world. For Loop = 1 To 2000 ; Add a new sprite to the list of sprites. ThisSprite.Sprite = New Sprite ; Pick a random image for this sprite. ThisSprite\Image = Image(Rand(0, 19)) ; Place the sprite at a random location in world space. ThisSprite\XPos = Rand(0, 10000) ThisSprite\YPos = Rand(0, 10000) Next ; Set the initial position of the "camera". Screen_X = 5000 Screen_Y = 5000 While Not KeyDown(1) Cls ; Use arrow keys to "scroll". If KeyDown(203) Then Screen_X = Screen_X - 1 If KeyDown(205) Then Screen_X = Screen_X + 1 If KeyDown(200) Then Screen_Y = Screen_Y - 1 If KeyDown(208) Then Screen_Y = Screen_Y + 1 ; Draw all objects in the world. For ThisSprite.Sprite = Each Sprite DrawImage ThisSprite\Image, ThisSprite\XPos-Screen_X, ThisSprite\YPos-Screen_Y Next Flip Wend |
| ||
#1 - Everytime the user presses down, you're just saying "ch=599"... what's ch? It doesn't do anything. #2 - It looks like you're trying to "move" the screen. Try assigning variables to the x,y positions of the rectangles (before the While loop) instead of 40,40 and 40,100, then when the user presses an arrow, alter the x,y variables. |
| ||
Btw, Drawimage draws any areas of an image that have color 0,0,0 as transparent. For your backgrounds you may want to use drawblock instead, unless you have multiple layers scrolling on top of one another. |
| ||
Kaisuo.... Your signature says that you have Blitz Plus. If that is the case then you can indeed move the screen without having to draw your graphics all of the time. All you do is create a canvas that is larger than the window area then use SetGadgetShape on your canvas to reposition the canvas. Ideal for scrolling shoot em ups etc. |
| ||
"All you do is create a canvas that is larger than the window area then use SetGadgetShape on your canvas to reposition the canvas. Ideal for scrolling shoot em ups etc." I'd be surprised if that was anything other than much slower than the method I described. :-) |
| ||
You can scroll without moveing Image objects, use the command Origin x,y; this sets a new point for all subsequent drawing commands. Origin x,y can be negative or positive. This is if you don't use canvas. |
| ||
But then your HUD will draw out of place, and your ship will scroll with the screen. :-) |
| ||
sswift: Yes they will follow the scroll, but you can set origin to 0,0 before drawing HUD and ship's, then they will stand still. :-\ |
| ||
In a nutshell then, Kaisuo, what you need is OFFSET coordinates. An OFFSET is a value which will alter the co-ordinates of an object in order to draw it onscreen. So, taking your example, if you had an object at 5000, 5000 you would offset that by subtracting the offset values from the x and y co-ordinates. Here is a more practical example:; Define our objects Global OFFSET_X = 0 ; Set to zero (it is by default anyway) Global OFFSET_Y = 0 Global MAN_X = 5000 ; Set the co-ordinates of our character Global MAN_Y = 5000 Repeat If KeyDown(KEY_UP) MAN_Y = MAN_Y - SPEED If KeyDown(KEY_DOWN) MAN_Y = MAN_Y + SPEED If KeyDown(KEY_LEFT) MAN_X = MAN_X - SPEED If KeyDown(KEY_RIGHT) MAN_X = MAN_X + SPEED ; Draw the area of the background which is onscreen DrawBlockRect mybackground, 0, 0, OFFSET_X, OFFSET_Y, GraphicsWidth(), GraphicsHeight() ; If the character is onscreen then draw him TEST_X = MAN_X - OFFSET_X If TEST_X < GraphicsWidth() And TEST_X > -ImageWidth( MAN_IMAGE ) TEST_Y = MAN_Y - OFFSET_Y If TEST_Y < GraphicsHeight() And TEST_Y > -ImageHeight(MAN_IMAGE) DrawImage MAN_IMAGE, TEST_X, TEST_Y EndIf EndIf Flip Until KeyHit(1)Notice that the values OFFSET_X are subtracted from the characters X and Y coordinates when checking to see if he is onscreen. In this example, the cursor keys would move the character but not scroll the map. To achieve this, you could set the keys to change the OFFSET_X and OFFSET_Y values instead. |
| ||
SSwift.... I'd be surprised if that was anything other than much slower than the method I described. :-) Prove it! |
| ||
Easy enough for you to test yourself if you're that interested in the results. :-) |
| ||
Try this,the block you see is the main man,there is a block down below the screen.Press down to walk to it. ;I tryed something which is Not working, what am i doing wrong: ; Graphic Mode Graphics 800,600,32 ; Global Variables Global x=40,x1=40,y=40,y2=640 While Not KeyDown(1) Cls ; Always clear screen first Rect x,y,20,20,1 ; Draw the box in the current x,y location Rect x1,y2,20,20,1 ; Draw the box in the current x,y location If KeyHit(208) Then y2=y2-40 EndIf Flip ; Flip it into view Wend Is this what ur asking? |