a few questions about a tilemap and a camera

BlitzMax Forums/BlitzMax Beginners Area/a few questions about a tilemap and a camera

delbar(Posted 2005) [#1]
Hello.

I have been struggling with trying to implement a " camera " like functionality in my game I am making. More like I am struggling on how to implement it. Here is my code so far. The types are in seperate files and also my main loop is.





My questions are probly simple or obvious but I am new to this and am not sure which I should do and don't want to code it one way and find out I should have done it another way.

With my Maps type code, is the tiled map larger then my screen x,y and I just cant see it because of no camera type yet? I know its not wider because I don't want it to be, but is the Y height go beyond the upper or lower portion of my viewing area? And if it does go beyond my screen how do I move my player along it to make a camera in 2D, should I use the tiled map index somehow or should I use the screen X&Y to somehow do it? I don't want to code it one way and then later on find out I should have done it another way. The map sizes in my game will remain the same size for all levels.
If I do need to use the arrays index could someone be so kind as to show how you index the array because the help files doesn't show much on how to do it.


Another question related to this is I used another image to draw some foliage on the map using a .bmp and didn't put it into the array, just used drawtext and drew over my tiled map or on top of it.This slowed my game down terribly, the bullets out of my players gun looked like slow motion..LoL , is there a better way to do this or a reason why it slowed it down?

Being a newbie to this I will appreciate any help in this and any criticism of my code sofar, such as making the array part of the list in the create function( i think it is anyhow). I am copying the structure as best as possible from the "make asteroids in an hour" tutorial posted by Wave in the tutorial section. Also I already know the trig is wrong for the 2D vectoring but I needed it to face north or up at the start as this is going to be a top down viewed shooter that Yscrolls only.Nonetheless let me know what you all think of the structure and such please. Thank You in advance.


RiK(Posted 2005) [#2]
Might help if you post a link to a zipped version of the project so that people can try it out rather than trying to decypher your code...


delbar(Posted 2005) [#3]
Hello

I don't have a place to upload a zip file to otherwise I would. The code is fairly straight forward and all types are a seperate file, the first part of the code till the first "end " is the main file with the loop.Really the game has no great look or anything, the sprites and map tile are all just standins until I get all the game mechanics down. It looks pitiful atm but will focus on artwork after mechanics. Its just a project to learn from for me.


REDi(Posted 2005) [#4]
I think there are some examples in the tutorials forum, might be of some use to you.
[EDIT] http://www.blitzmax.com/Community/posts.php?topic=45336


delbar(Posted 2005) [#5]
Hello again.

Thanks Papa. Wow is that some heavy coding in that example! Hopefully There is an easier way of doing it, or a shorter more simple way. At a quick glance at his code I think he is using the maps index and the viewport to make it scroll and not just a screen coordinate. That helps me out by answering which way I should code it. I will certainly have to study that awhile to get to understand it. Thanks for pointing me to it .


To the other question, I guess I will need to load an animImage with different tiles in it to get the foliage I want without(hopefully) the slow down that a regular .bmp image being drawn over the tiled map caused.


SoggyP(Posted 2005) [#6]
Hello.

With tilemaps one advantage is that you don't have to output all of them, only the ones that are on screen at a particular time. This means that instead of your loop going:
for y= 0 to 50
  for x = 0 to 50
    drawimage tile,x,y ' Just pseudo, obviously
  next
next


with a bit of thought you can do something like
for y = current_top to current_top + screen_height
  for x = current_left to current_left _ screen_width
    drawimage tile,x,y
  next
next


whilst you keep track of the current top and leftmost tiles. This means you can have tilemaps of enormous sizes and only draw those that you can see. This should give you enough time to display all the anims you want.

Does that make sense to you?

Goodbye.


delbar(Posted 2005) [#7]
Hello

Sorry have some troubles last night so couldn't get on to answer.Thanks for answering SoggyP. It kinda makes some sense, I am sure its alot easier then Papa's linked example which is abit more then what I need atm, or can understand without studying it alot. I don't quite get arrays too well yet but am learning.I just need to dig in and start playing with them alot and the scrolling code and hopefully that will turn the light on alittle more for me. I am guessing in your example that the current top is the currently drawn top, then the " to current top " is the next top to be drawn and thus the first current top would be down screen 1 row? Same with the left also I take it? My game is going to be a Yscrolling game so I think the current left wouldn't be needed because the sides will be in a constant width and always in view/onscreen. If anyone remembers the arcade version of Ikari Warriors thats the kind of game I am trying to make.


If I wanted to make a tile of the bush I was drawing over the map with, and added it to my animImage so I could use it in my tiled map. How would I draw that bush on the map where I wanted it drawn? I have seen some examples of filling the map randomly with your different tiles, but how would you put that bush frame at a certain X,Y spot on your tiled map?


The r0nin(Posted 2005) [#8]
If I wanted to make a tile of the bush I was drawing over the map with, and added it to my animImage so I could use it in my tiled map. How would I draw that bush on the map where I wanted it drawn? I have seen some examples of filling the map randomly with your different tiles, but how would you put that bush frame at a certain X,Y spot on your tiled map?


OK. Let's look at it this way. Are your tiles going to be of equal size (i.e. all tiles 64x64 or something)? If so, then you can do your scrolling and positioning very easily.

For example, in my tilemap, I create an animated image of all of the possible tiles (so the first part of the png from x=0 to x=63 and y=0 to y=63 is the grassy plains. Then from x=64 to x=127, with y being the same as before, I have a horizontal road, etc.) So I'm not actually animating the tiles, but I'm storing all of the tiles in one image. Then I create an array of the number of tiles I have wide by the number deep (i.e. Tilemap_Tiles [40,40]... though I actually do it as a field in a custom type). Then, I store the corresponding number for each tile (what frame it is in the image) in the array. For example, if I have two open plains tiles followed by a road tile at the top left of my tilemap, the array would look like Tilemap_Tiles [0,0]=0, Tilemap_Tiles [1,0] = 0, Tilemap_Tiles [2,0] = 1.

Then all you do is store the map offset (this is where the actual top left corner of the whole tilemap is in relation to the screen). Since I never want my screen to show a place where my map isn't (blank space), the offset will always be negative (I'll only be able to move my map up and left at the start... because if I had my top-left tile in the top-left corner and moved the map down I'd get blank space). So when the map is at the top-left corner, I'd initialize my offset type like this:
Type MapOffset
     Field x#=0.0,y#=0.0
End Type

Then, as I moved the map up, I'd subtract from my MapOffset.y (because the map origin is now above the top of the screen). Same for moving right. Add for down and left (but limit it to <= 0) When you render, run two for-next loops (one for x and one for y) and don't draw any tiles that aren't onscreen (multiply the x by the width of each tile, 64 here, and add the offset, then check to see if it is greater than -63 and less than the screen width... ditto that for the y). Voila, a scrolling tilemap!

Now, when you want to place objects, give them an x and y coordinate based on the offset (I wrote my own map editor so I can just point and click to set tiles and set objects, but this is what the editor is doing in code). So, if the first tree was in the middle of the first tile (32 pixels right and 32 pixels down), it's coordinates would be 31,31. If it was inside the 3rd tile on the top-left, and 10 pixels above the bottom and 20 pixels from the left side of that tile, it would be at 147,53 ( you calculate that: 3 X 64[ which is the size of each tile] - 45[first tile starts at pixel 0], 1 X 64[size of tile] - 11[first tile starts at pixel 0]). At render, you run 2 for-nexts just like with the tilemap and render at the x + MapOffset.x and y + MapOffset.y, if they are onscreen. Now you have a scrolling tilemap with objects attached.


Cruis.In(Posted 2005) [#9]
You can put those commands there for input in a GetInput method of the same type. And put a player1.getinput() in your main loop. Because what you do with the values of x and y when you pressing the keys, x and y changes, and in your update function you can use the sin and cosin,

vx=sin(angle)*speed
vy=cosin(angle)*speed

x:+vx
y:+vy

and use your getInput function to updates the rotation and speed variables. So as you rotate with left and right, move up with up, up will change your speed, and rotating changes your angle or direction as you call it...
then your update function uses the code up there
then the update is applied to x and y, in the second set of code, and as you know already your image is being drawn to x and y.

Its a little weird to be having when you press up to have the maths doing it there. You have it so when you press up it does the calculations.

This will cause problems later on if you try to put other conditions underneath the input buttons like max speed and can be very confusing.

here is another example if you don't understand what I mean.

Method updatePhysics()
'move ship in angle facing
vx :+ Sin(angle)*thrust
vy :- Cos(angle)*thrust 'thrust/speed same

'add the calculation done above to x and y positions
x :+ vx
y :+ vy

vx :* 0.98
vy :* 0.98
End Method


If KeyDown(KEY_UP)
'if thrust is lower than the max thrust, then it will increase, otherwise in my other code i have limitations for it, this is a rough example... just to give you the jist of what I mean

If thrust < Max_Thrust
thrust :+ accel
End If




So as the thrust (speed) achanges when you push up that gives sin and cosin a new value to work with, and they work out a different value, a value WHICH, will move you forward in the direction facing like you're doing so far.

This code is for rotating in a direction to want to go in then thrusting in that direction, looking at the code you have for your turn left and turning right, it doesn't seem that is your intent, or is it?

What are you making btw?


delbar(Posted 2005) [#10]
Hello

Thanks for all your replies everyone and for the great help your all giving me to try to understand arrays better. I think I am going to be able to work it out now to get my map scrolling following my players movements and be able to draw different tiles in areas I want them.

To answer your question Cruis.In I am making a game somewhat based off of the arcade version of " Ikari Warriors " . If your not familiar with the game it is a top down viewed shooter/army guy type game that only scrolled on the Y axis and had some very good play that unfortunately wasn't copied too well to the home computer i.e. commador64 and other older type game systems. The arcade version sure was fun to play though.

My left and right code for the player is first a strafe with the right mouse button added, it just rotates the player to a new direction if only the arrow key is used. The strafe function wasn't a part of the original game but I thought I would add it because my version will be much faster then the arcade one and dodging bullets and such will be alittle easier with it.


Once again I really thank you all for helping me out with arrays, soon as I get some code together and test it I will post it and see what you all think of it. Originally I was stuck between coding the scrolling with either the array or the screen X/Y, but thanks to you all I now know I have to do it with both in order to do it correctly. And now I hope to be able to use more tiles to draw different features of the map without using drawimage to draw over my map and get that huge slow down I was experiencing. Thanks again for the great help everyone!


delbar(Posted 2005) [#11]
Hello Again.

Well I have been working on my scrolling map for some time now and have made progress and have come to this problem. I added an OffSetY to my map and have my player at the bottom of the map where I want him to be so I will move up the map decreasing my Y and my OffSetY as I move along. I have the up movement down good except messing with the scroll speed which is no problem. My problem occurs when I want to move down the map which increases my Y and my OffSetY. I have tried it many different ways using an if statement along with the direction variable to either increase or decrease my OffSetY depending on my direction. If my direction is > 90 but < 270 I need it to increase OffSetY , or if my direction is >270 but < 90 I need my OffSetY to decrease to scroll the other way. It works fine by my first line of code in the if statement but when I rotate my player to go the other way the map still scrolls in the original direction( if I am making any sense ). For the life of me I can't understand why its doing it either, if I rem out the second line of my if statement it still does the same thing. I suspect that somehow I have my if statement wrong and it isn't reading the parameters of the Direction Variable or something that is probably easy or obvious such as that .

If anyone has any insight as to what I am doing wrong or what needs to be done to get the scrolling correct with using my Direction variable I would really appreciate the advice/help. Thanks in advance.

Here is a copy of my players type and the input with the if statement in the up arrow key is the part I am refering to.




Edited : forgot to add my Tmaps type in the code box.