OK.
I'm in essense trying to make my own interpretation of the NES hardware, so I can make a game that ideally would resemble what a NES game would look like. I'm currently stuck with how to adjust how to draw the playfield to the video memory (back buffer).
BACKBUFFER
The NES had restrictions on the nametable, or backbuffer. For my example, the backbuffer is 256x240pixels big, or the size of one screen. If I drew this to the TV, it would fill up the screen perfectly. Now, if I drew this to the screen with an offset of X=5, the entire image would be shifted and would wrap around the screen.
For example.....
ORIGINAL, NO OFFSET: DRAWN WITH OFFSET OF X=5:
ABCDEFGHIJK GHIJKABCDEF
DRAWN WITH OFFSET OF X=-5:
FGHIJKABCDE
The screen is split up into squares 8x8 pixels each, totalling 32x30 rows and columns. (256x240 pixels). The offset is represented in pixels - not columns; so in theory, I could offset the screen by 5 pixels and every column would be shifted to the right by five pixels.
LEVEL DESIGN
My stages are made up of screens, containing data that is represented in 16x15 rows and columns, each by 16x16 pixels. This is to emulate how many NES games stored level data - each tile holds info about what should be in each 8x8 block.
E.g.:
AA
BC with A,B,C,D representing what 8x8 graphic should go where
Level design is represented by this as well, with each number being a different screen and - meaning nothing, null.
-----
-123-
---4-
--54-
-----
CHARACTER PLACEMENT
This is easy. I already know how I can determine which table, row, and column my characters are on based on their absolute positioning. I can also determine the relative positioning within the screen.
With this info, I can easily figure out which columns are to the left and right of the character, if any (if the character is at the left side of screen 1, thered be no more level left)
SO HERE'S THE QUESTION DUN DUN DUN
How do I draw my levels to the screen, so that they scroll from one to the next.
It would be relatively easy to draw one full screen at a time, and when the character gets to the edge just flip to another screen.
However, the problem I'm conceptually having is that I need to 'stream' the level data onto the screen. That, lets say the character moves 24 pixels to the right. The BG needs to move as well.
So, I need to adjust the scrolling of the backbuffer by 24 pixels. However, just scrolling alone will cause the screen to wrap over, diplsaying old portion of the level. So, while scrolling I need to make sure to draw new pieces of the level to the back buffer. But before I can do that, I need to figure out which tiles need to get drawn first. And if the person goes 24 pixels to the left, I need to redraw tiles onto the backbuffer and change the offset accordingly as well.
And let's not forget that if the character moves right and there's no more level data to be drawn, there should be no offset but instead the character gets closer to the side of the screen (instead of being centered in the middle of the screen via the X axis).
Basically, I just have a lot of different numbers and values stuck in my mind right now - trying to wrap my head around many concepts and they caused my brain to turn into goo. Anyone have any perspective on how I can approach this?
EDIT: Using VB.Net. C# is applicable as well ( I program in both)
The way the NES did it was with 4 name tables, each 256x240. When you scrolled one off the screen, the adjacent one would scroll on. To get "worlds" bigger than 512x480, you update the name table at the positions that are offscreen.
Generally, a cartridge would have a giant table in ROM with all of the level data, and would track the overall position with 1 or 2 RAM variables. Then when the game scrolled, it would update the RAM variables, use those to lookup the level data table and copy in the new level data into the parts of the name table that were offscreen.
So actually your back buffer should be 512x480, and you only show a 256x240 portion of it.
Have you looked at the disassembly for any NES games that have large scrolling worlds? I think a partial disassembly of Metroid is out there somewhere...
...yeah, found some docs at romhacking.net
Metroid disassembly; not real well commented but with a little effort it shouldn't be too hard to figure it out.
Another disassembly that is commented better.
EDIT: In the 2nd disassembly posted above, look in MetroidGameEnginePage.txt at the "SetupRoom" routine and the "DrawRoom" routine; also the routine at label LEB4D shows how the name table is updated in one case. Also look at the extensive comments above the "GetNameTable" routine. In general, a text search for "name table" throughout the document will get you lots more.
EDIT EDIT: Also at romhacking.net; the memory map for SMB might be useful.
I would set up a grid of image controls and load the levels from a database that stores what column and row each picture is relative to the level. Once the image that represents the game's character gets far enough to the right (you would have to store its location in some module level variables) of the screen you would load the next column of images (while shifting all of the other images one to the left and removing the first column).
Related
I got a tiled map and I want to make lava lakes. I wish to have some kind of lava texture image on the background looping diagonally slowly. I could make it with four 960x640 images and move all of them diagonally etc. But when I do, a black/white line appears between each...
... and someone suggested me "CCParallax". I have never used it and am not sure if it really can achieve the effect I am seeking.
Also note that as the player moves on the map, the parallax will need to simulate that as well etc.
So my question is, what would you do for this effect? Four looping images or "CCParallax"?
CCParallaxNode is pretty limited because you can't specify endless parallax scrolling without modifying the class. It also doesn't quite fit your use case.
Using four 960x640 images is wasteful. Just to make some lakes underneath the background this is overkill and will negatively affect performance.
The solution depends a bit on how big the lakes are. For example, if these are just 1 or 3x3 tiles in size you could add a textured sprite underneath each lake. If on the other hand your tilemap consists mostly of a few narrow pathways while the rest is lava lakes, then you need a different approach.
You might want to try GL_REPEAT to repeat a single sprite's texture over a defined area. That allows you to use a relatively small texture, for example 64x64, that will be repeated over the rectangle you specified.
You can then modify the sprite's position each frame to scroll the texture. Every time the sprite has moved 64 pixels in horizontal or vertical direction, you subtract 64 pixels (sprite.contentSize.width) from the sprite's position to reset it back to its original state. That means the sprite will never move further than 64 pixels from its initial position in any direction but you still get smooth scrolling.
This question is very similar to that posed here.
My problem is that I have a map, something like this:
This map is made using 2D Perlin noise, and then running through the created heightmap assigning types and color values to each element in the terrain based on the height or the slope of the corresponding element, so pretty standard. The map array is two dimensional and the exact dimensions of the screen size (pixel-per-pixel), so at 1200 by 800 generation takes about 2 seconds on my rig.
Now zooming in on the highlighted rectangle:
Obviously with increased size comes lost detail. And herein lies the problem. I want to create additional detail on the fly, and then write it to disk as the player moves around (the player would simply be a dot restricted to movement along the grid). I see two approaches for doing this, and the first one that came to mind I quickly implemented:
This is a zoomed-in view of a new biased local terrain created from a sampled element of the old terrain, which is highlighted by the yellow grid space (to the left of center) in the previous image. However this system would require a great deal of modification, as, for example, if you move one unit left and up of the yellow grid space, onto the beach tile, the terrain changes completely:
So for that to work properly you'd need to do an excessive amount of, I guess the word would be interpolation, to create a smooth transition as the player moved the 40 or so grid-spaces in the local world required to reach the next tile over in the over world. That seems complicated and very inelegant.
The second approach would be to break up the grid of the original map into smaller bits, maybe dividing each square by 4? I haven't implemented this and I'm not sure how I would in a way that would actually increase detail, but I think that would probably end up being the best solution.
Any ideas on how I could approach this? Keep in mind it has to be local and on-the-fly. Just increasing the resolution of the map is something I want to avoid at all costs.
Rewrite your Perlin noise to be a function of position. Then you can increase the octaves (and thus the detail level) and resample the area at a higher resolution.
For a university term project, I'm working on a graphical roguelike (I'm aware of the contradiction in terms :P) that uses an isometric display. What I'm trying to figure out is, since drawing all the tiles is stupidly expensive and unnecessary, I'm wanting to figure out a relatively fast algorithm to determine which tiles should be drawn to fit within an NxMpx window, given that the tile graphics are XxYpx.
I'm not doing smooth scrolling for this, so that's not an issue. I'm also not worried about being perfect - a little unnecessary draw is fine, I just don't want to draw a huge amount of unnecessary tiles that won't show up in-game.
You need to think about two concepts: Screen space and world space. These are very important in 3d engines, but they apply to all but the very simplest games. In the isometric engine your world-space is a 2d array of tiles.
So you are looking first of all at a way to covert between these two co-ordinate spaces. Once you've done that, it'll be obvious that screen space maps onto the world as a rectange that's turned at 45 degrees. You can determine a formula for that, but it's only important if you are trying to determine which part of the world space is visible so you only simulate monsters in that area (an efficiency necessary on 8 bit consoles, probably not on a modern PC!). When it comes to actual rendering you don't really need to determine this visible region of the world, because it's implicit in the way you render the tiles onto the screen:-
You work out which tile location is at the top-left of the screen, call this O (for origin) - that's going to be a fixed offset from your point of interest, usually the player, that you want to keep in the centre of the screen.
Once you have that you paint the tiles in the top row of the screen, stepping +1X and -1Y in world space for each tile (if you are looking north-east).
Then you paint the row below. That is offset minus one half a tile width in screen space and starts at O -1X in world space.
You repeat steps 2 and 3, modifying your starting position in world space by -1 in X and Y from what you used in the previous stage 2 until you reach the top of the screen.
Other tips:-
Obviously you don't draw any tiles that are outside the map. You might also, depending on game design, not draw any tiles outside a particular room the player is in.
There's not just floor tiles to draw, theres also players, monsters, scenary, etc. The rule is you draw everything in a paricular world location in the same pass. That way objects closest to the 'camera' will obscure stuff behind them (which is why you start drawing at the top of the screen).
Also, you don't just have floor tiles in most iso engines, you would also have furniture and wall segments. You might designate areas of the map as belonging to a particular room, when the focus is on that room (because the player is in it for example), you don't draw the wall segments for the side of the room closest to the camera.
Anyway, that's enough to be getting on with, hope it's helpful and your project goes well.
I am in the process of making my 2D engine for a Beat'em Up game (Castle Crashers is what I call Beat'em Up or Brawler kind of game ).
I will support 2D sprites and 2D particle emitters. This is all done in the engine now. But I have come to an issue that I would like to ask for advice:
It's about "space" management, what I thought was to do something as this image shows:
alt text http://img337.imageshack.us/img337/9162/spacingprototype1.png
My idea is to make a grid ( Spatial Hash or Grid ), of the ground where my Particle Emitters / 2D sprites will live. In my picture, I have enumerated this slots from 1 to N, (don't have to be 35, it's just for showing purposes ). My idea is to draw the "GameElements" (Sprites/Emitters) in order from 0 to N , ( going from bucket 0 to bucket N ) , so then I will get them to display correctly overlapped on screen (back to forward).
I know this could be done by just comparing the lower Y axis of each Element and performing a "quicksort" too, but having the Grid could allow me to perform Collision Detection in a better way , and if I do something like A* to implement some kind of AI, it could help me too.
If you want to have some sort of optimization for the number of objects you need to test against each other, you might want to think about using a Quadtree
http://en.wikipedia.org/wiki/Quadtree
The idea is to divide the screen up in 4 nodes, placing all items in the node they belong, then divide the nodes you just created up in another 4 if there are sprites/items/whatever in there that need to be tested. Keep doing this until a certain size or amount of items in a node has been reached.
You can then ask the top-node if it contains the item you want to test. This node will then ask the child-nodes if it contains the item, which in their turn will ask their children. This way a large part of the screen can be skipped already (if it's located in child 00, you can skip child 01, 10 and 11). Then you get a list of items you perform more specific collision detection on when it's desired to do so.
If you were to make it visual, it would look a bit like this:
alt text http://geodata.ethz.ch/geovite/tutorials/L2GeodataStructuresAndDataModels/en/images/quadtree.gif
Fire them out to the Z buffer and let that worry about it.
If you find that in the future it is too slow (via profiling obviously) then look at optimizing it.
Take the simplest solution and move on.
Your method fails if you have two sprites occupying the same box in the grid. Suppose you have two enemies both standing in the same box. One stands slightly in front of the other. Which do you draw first? You would need two algorithms - one which divides the sprites into the grid, and the second which looks at the z co-ordinates of all the sprites in a given grid box and draws them based on that value.
A far simpler method is to have a single collection of all sprites. It should store all sprites sorted by their z co-ordinates (from the back of the screen at the head of the list to the front of the screen at the back). Loop through the collection and draw each sprite as it appears. When a sprite moves into or out of the screen (ie. its z co-ordinate changes) you can perform a very simple sort to move that single sprite within the collection. Keep swapping it with the next sprite in the list until the next sprite's z co-ordinate is greater than/less than (as appropriate) the changed sprite's co-ordinate.
Well, i was thinking of making a Tetravex solving program in order to practice my code writing skills (language will propably be Visual Basic) and I need help finding an algorithm for solving it. For those that don't know what tetravex is see this http://en.wikipedia.org/wiki/TetraVex . The only algorithm I can come up with is the brute force way, place a tile randomly in one corner and try every possible tile next to it and continue the same process, if it reaches a dead end revert to a previous state and place a different tile. So can anyone come up with a better algorithm? Thank you for your time.
here some ideas.
A vanilla brute force algorithm would try to fill out the grid recursively by enumerating the grid positions in a fixed order (e.g. row major) and always trying to fit every possible piece in the current position and then recursing. This is what you mentioned and it is very inefficient.
An improvement is to always count for every free position the number of pieces that fit there, and then recurse on the position that has least fits; if one has zero fitting pieces, backtrack immediately; if there is one where only one piece fits fill that and continue (no branch created); otherwise select the one that has least fitting pieces (≥ 2) and continue from there.
Once you have this algorithm in place, the next question is how you can prune the search space more. If have, say, A pieces with "1" on the top position and B pieces with "1" on the bottom position, and A > B, then you know that at least A - B of the "1 at top position" pieces must be actually placed on the top row, so you can exclude them from any other position. This helps to reduce the branching factor and to spot dead-ends earlier.
You should also check at every recursion step that every piece has at least one spot where it fits (do this check after verifying that there is no piece that fits in only one place for speed). If there is a piece that doesn't fit anywhere you need to backtrack immediately. You can extend this to checking that every pair of pieces fits for a potentially better earlier dead-lock checking capability.
There is a also a strategy called "non-chronological backtracking" or "backjumping" which originates from research into SAT solving. This helps you to backtrack more than one level at a time when you reach a dead-end; if you want, you can google for these terms to find more, but you need to do some mental work to map the concept into your problem space.
A first improvement would be counting how many matching pairs of numbers there are, and if, say, there are 5 "1"'s on the top of squares, but only 4 on the bottom, then there must be a "1" pointing off the top of the grid.
At any given partly solved board I would
look for a place where none of the remaining tiles could be played. If found, the board must be unwound to the last place a tile was played randomly.
Look for a place where only 1 of the remaining tiles can legally be played. If found, place that tile.
Place a tile randomly at the spot on the board where the fewest number of remaining tiles can legally be played. Remember this board layout before I lay the tile, I may want to unwind back to this board and play a different tile.
In pseudocode it would be
top:
evaluate # of tiles that match at each empty square
if any square has 0 matches, unwind to <prev>
if any square has 1 match, lay tile, goto top
save current board as <prev>
play randomly at square with minimum number of matches, goto top
As an optimization, you can ignore evaluating squares that don't touch any squares that have tiles, since they will always allow all remaining tiles.
It looks like Tetravex is a Constraint Satisfaction Problem, so you want to limit your options as quickly as possible. It should be possible to do better than random placement. How about?:
Create links between all tile faces with their possible matches.
Any tile with an unlinked face must be an edge tile.
Any tile with two adjacent unlinked faces must be a corner tile.
Center tiles must have four active links.
Now, place a tile in a valid location and invalidate links that are used. If any un-placed tile contains three unlinked faces or unlinked faces on opposite sides, the move is invalid and you can backtrack.
You should be able to use tile face links to look for the next possible tile versus searching through all tiles. If there isn't one, backtrack.
I wrote a solver for Tetravex and used a different approach and it seems very efficient. I built up possible valid relationships increasing the size. So each iteration gives me larger puzzle pieces to work with while reducing the number of puzzle of pieces, so to speak.
I start by creating a list of all possible connections between tiles from bottom to top and a list of all possible connections between tiles from right to left.
From these two lists, I build a list of all possible valid 2x2 combinations.
Using the 2x2 list, I build a list of all possible valid 3x3 combinations.
From there I can go 4x4 by using the 2x2 and 3x3 lists, or do 5x5 by just using the 3x3 list.
Right now my code does each iteration separately, but should be able to be cleaned up to handle each iteration with the same code which would allow for larger grid sizes.
This also seems like a great situation for using a neural net, and I might give that a try next.