Platformer tile engine--advice on what to do with long tiles - xna-4.0

I'm looking for advice more than direct help.
I am working on an 8 bit platformer game in XNA. I've probably sunk 160 hours into it already, and I'm starting to get into issues with the engine I have. It is basically an adapted/modified version of the XNA platformer demo. All or most of my tiles are 32x32, but some are 64 wide and 32 px tall, like a desk. Some are 32 wide and 64 tall, like a plant.
I am shipping them to the gpu just one .png at a time similar to the way that the XNA tutorial's author does tile mapping. For animated sprites I do use a tile map of different frames of the character. For the tile map data, I read in a text file just like the XNA tutorial.
How should I accommodate for the wide and tall tiles? Should I make a two layered tile system (I figured I should abide by the keep-it-simple-stupid rule)?
Right now I'm using transparent tiles to extend the wide tiles.
Desk with chair:
chair http://dl.dropbox.com/u/8446900/game_screen_desk.png
.....
...h.
..d".
#####
Plant and chair:
desk http://dl.dropbox.com/u/8446900/game_screen_plant.png
..p...h.
..,...,.
########
The chair is 'h', 'd' is for desk, 'p' is plant, and ',' is for a transparent background tile (no interaction with the user). '"' is for a transparent tile that the user can stand on (extending the desk). The problem is, as you can see, the background appears to have a hole in it.
Should I make an actual tile map and combine everything into one large png? Another option I could take is to actually cut each wide or tall tile into two different tiles. How would a pro do this? I'm not looking for a quick and dirty fix, just how a modern day platformer would run.
UPDATE: After reviewing the answer, I found a very useful tool that packs sprites into a sheet.
http://spritesheetpacker.codeplex.com/
UPDATE: My newly upgraded tile engine is much faster and almost just as simple. The advice below was great. Strongly recommended.

First off - don't introduce special-width/height tiles. Make the artist slice up large objects into single tiles (and hence re-compose them on the map editor). Every tile should be a PNG with an alpha channel so they can be correctly composed.
Keeping that in mind, my recommendations are:
Your tiles should comprise of only single tiles that have pre-composed parts of different objects, for example the left part of the desk is a single tile, the right part without a chair is another and one more with the chair behind it. (tilevalue = "dc", perhaps?)
You can define multiple layers of single tiles and render them back-to-front. You can also define a parallax factor for multiple layers and thus get a nice parallax effect between two layers quite easily. Of course, the player must "exist" in one layer at a time or you won't know what collision geometry to use for his/her current position.
You should also not create one texture per tile - but a compiled tilesheet (exactly like a spritesheet) so that the number of renderstate changes you make are minimized. Making many changes per draw call is bad because each time you make a change (current texture, drawing color or something else that affects that draw call) the API, the driver and possibly the GPU itself has to do work to update its state - this adds up quick.
Note that this doesn't mean you should put characters and levels into a HUGE spritesheet - this is bad for other reasons. You could, for example: put all level-related tiles in one tilesheet, the hero's animation tiles on another and all enemies on one (together) or something similar.
Hope that helps, otherwise I'd be glad to explain things further.

Related

Best way to create a 2D scrolling map

I am writing a program in visual basic 2010 to create a 2D scrolling map. I am using Pictureboxes at the moment, all 50 by 70 in size. It starts with 1, and depending on what is needed may easily end up with 1000 - 2000 of them. They all need to be clickable. I am concerned it might use too many resources and run too slow. Can anyone tell me what the best approach to make something like would be.
Thankyou.
A common method is to only draw the tiles (or pictureboxes in your case) when they can be seen by the player's camera. So you should first determine how many boxes fill the screen and then calculate whether or not they are within the bounds of the player camera as represented by a rectangle. Additionally, you should draw boxes slightly outside the player's view (1 or 2 additional boxes per edge, this is explained below).
When the player moves, move the position of the world, not the player. So if the player moves left, scroll all of the tiles to the right while the player sprite remains stationary. Now when a player's position changes you should check again which tiles are visible in the player's screen. Since you are drawing additional rows slightly outside the view of the player, the edges will smoothly scroll in and will not 'pop' in as is a common problem when starting out.
Since you are only drawing tiles which are visible to the player, your game should run a lot more efficiently. It is OK to store this data in a 2D array in memory for now. In the future when you have huge maps, it may be a good idea to load sections of your map which are far outside of the player's view from disk to memory. You don't want to load in map data from disk which the player can navigate to before it is fully loaded.
Exactly how much map data to store in memory is up to you and depends on what platforms you want to release on and other constraints.
Additionally, you may want to look into different rendering libraries. Common low-level libraries are DirectX and OpenGL. These libraries work directly with your graphics card to dramatically speed up rendering. There are libraries built on top of those for various languages, but I don't know any for Visual Basic. An example for JavaScript is PixiJS. Additionally, there are full featured game creation libraries such as Unity or the Unreal Engine 3.

Player-Sprite with hat/robe/staff for each direction?

Some friends and I started to create a game, in which a mage will be in the center of the screen, being able to run in all 4 directions (as it is a 2D game)+diagonals, so 8 directions total (so the level below the player is moving).
The mage should wear a hat, a robe, and a staff for now, of which there should be a hole lot more than just one.
Additionally the mage should have a walking animation of let's say 3 pictures.
So overall it would be:
8(directions)*3(walking animation)*k(hats)*n(robes)*m(staffs) = 24*k*n*m sprites
(Which are currently BufferedImages as PNG with alphachannel drawn on a canvas), which is like waaaay too much for my designer (because we want a hole lot of staffs, robes and hats, maybe later even add boots and stuff)
So my idea was to make a "naked" playersprite and have separate sprites for staffs, robes and hats, which I then just render on top of the player.
Is that a good idea, or am I missing anything that would make all that a hole lot easier?
Combining sprites to draw the player is the way to go. You can reduce the amount of work more if you sacrifice some details.
You can mirror the animation for left and right. The weapon is always in the players hand facing you (instead of e.g. always in the player's right hand)
You can omit diagonal walking animations. Just reuse the horizontal or vertical animations.
Some games even omit the vertical walking animations, meaning you always see the player from the side even though you can walk up. It may interferes with the game mechanics if you can't attack up or down.
If the sprites are high res enough, you can keep static items as one single sprite and move/rotate them with the player's animation. So every weapon (or weapon type) has the same animation for walking, attacking etc. Probably doesn't look to good in retro style games because it won't be pixel perfect.
Reuse sprites. Not every robe needs a new design, just change some colors.
If you plan on finishing the game, detailed sprites and animations should be the last thing you implement. Make an ugly prototype first and if it is fun, then you can still add more details and make it look good.

I need help drawing sunrays, glimmers, bursts, sparkles, etc in C

I am in the process of learning how to create a lens flare application. I've got most of the basic components figured out and now I'm moving on to the more complicated ones such as the glimmers / glints / spikeball as seen here: http://wiki.nuaj.net/images/e/e1/OpticalFlaresLensObjects.png
Or these: http://ak3.picdn.net/shutterstock/videos/1996229/preview/stock-footage-blue-flare-rotate.jpg
Some have suggested creating particles that emanate outwards from the center while fading out and either increasing or decreasing in size but I've tried this and there are just too many nested loops which makes performance awful.
Someone else suggested drawing a circular gradient from center white to radius black and using some algorithms to lighten and darken areas thus producing rays.
Does anyone have any ideas? I'm really stuck on this one.
I am using a limited compiler that is similar to C but I don't have any access to antialiasing, predefined shapes, etc. Everything has to be hand-coded.
Any help would be greatly appreciated!
I would create large circle selections, then use a radial gradient. Each side of the gradient is white, but one side has 100% alpha and the other 0%. Once you have used the gradient tool to draw that gradient inside the circle. Deselect it and use the transform tool to Skew or in a sense smash it. Then duplicate it several times and turn each one creating a spiral or circle holding Ctrl to constrain when needed. Then once those several layers are in the rotation or design that you want. Group them in a folder and then you can further effect them all at once with another transform or skew. WHen you use these real smal, they are like little stars. But you can do many different things when creating each one to make them different. Like making each one lower in opacity than the last etc...
I found a few examples of how to do lens-flare 'via code'. Ideally you'd want to do this as a post-process - meaning after you're done with your regular render, you process the image further.
Fragment shaders are apt for this step. The easiest version I found is this one. The basic idea is to
Identify really bright spots in your image and potentially down sample it.
Shoot rays from the fragment to the center of the image and sample some pixels along the way.
Accumalate the samples and apply further processing - chromatic distortion etc - on it.
And you get a whole range of options to play with.
Another more common alternative seems to be
Have a set of basic images (circles, hexes) and render them as a bunch of bright objects, along the path from the camera to the light(s).
Composite this image on top of the regular render of you scene.
The problem is in determining when to turn on lens flare, since it is dependant on whether a light is visible/occluded from a camera. GPU Gems comes to rescue, with better options.
A more serious, physically based implementation is listed in this paper. This is a real-time version of making lens-flares, but you need a hardware that can support both vertex and geometry shaders.

Rendering very large image from scratch then splitting it into tiles (for Google Maps)

I have a large set of google maps api v3 polylines and markers that need to be rendered as transparent PNG's (implemented as ImageMapType). I've done all the math/geometry regarding transformations from latLng to pixel and tile coordinates.
The problem is: at the maximum allowable zoom for my app, that is 18, the compound image would span at least 80000 pixels both in width and height. So rendering it in one piece, then splitting it into tiles becomes impossible.
I tried the method of splitting polylines beforehand and placing the parts into tiles, then rendering each tile alone, which up until now works almost fine. But it will become very difficult when I will need to draw stylized markers / text and other fancy stuff, etc.
So far I used C# GDI+ as the drawing methods (the ol' Bitmap / Graphics pair).
Many questions here are about splitting an already existing image, storing, and linking it to the API. I already know how to do that.
My problem is how do I draw the initial very large image then split it up? It doesn't really need to be a true image/bitmap/call it whatever you want solution. A friend suggested me to use SVG but I don't know any good rendering solutions to suit my needs.
To make it a little easier to comprehend, think it in terms of input/output. My input is the data that I need to draw (lines, circles, text, etc) that spreads across tens of thousands of pixels, and the output must be the tiles. I really don't care what the 'magic box' is, and I don't even care what the platform is.
I ran into the same problem when creating custom tiles, and you are on the right track with your solution of creating one tile at a time. You just need to add some strategy to the process. What I do is like this:
Pseudo code:
for each tile {
- determine the lat/lon corners of the tile.
- query the database and load the objects that are within this tile.
for each object{
- calculate the tile pixels on which the object should be painted. [*A*]
- draw the object on the tile.
- Save the tile. (you're done with this tile).
}
}
alternatively:
Pseudo code:
- for each object to be drawn {
- determine what tile the object should be painted on.
- calculate the tile pixels on which the object should be painted.[*A*]
- get that tile, if it doesn't yet exist create a new one.
- draw the object on the tile.
- Save the tile. (you might need to draw more on this tile later)
}
I do this with Perl and the GD library.
[*A*] When painting objects that span more than one tile, if the object begins on the current tile then part of it will be left out automatically because you'll be attempting to paint outside the tile, while if the object began on the previous tile and you're drawing the second part then the pixel numbers should be negative, meaning that it began on the neighbor tile.
This is a bit hard to explain in a written post so please feel free to ask for further clarification if you need it and I'll edit the answer.
I'd recommend getting to know GDAL (http://gdal.org) and it's libraries. It has libraries for rasterization, tiling, data conversion, projections, warping, and much more.

Best approach for "game" problematic

I have to tell you, I'm completely NEW to XNA, and I know NOTHING about vertex, multisampling, etc etc..
However, I love so much programming and windows phone that I wanted to start an immense challenge... create a XNA game! :D
ok, let's stop the story and start explaining..
I'm making a big game... which I've worked for it for almost 1 month, now it's almost over..
I've just a big issue, which is the central point of the game... think about it as a 1024x800 puzzle, each point of puzzle can be clicked, and when it's clicked it must change color..
so we have 2 hard point to do,
1) UNDERSTAND WHICH PIECE I'VE CLICKED
2) COLOR THIS PIECE
I thought about 2 approaches
FIRST APPROACH
1 PNG big puzzle background 1024x800
N PNG for each puzzle piece, with transparent layer around the piece ( each piece is 1024x800, in the correct position )
by merging the N+1 PNGS we have the complete puzzle, now, it's REALLY easy to understand which piece I've clicked, because I just have to cycle the N textures, and when I got the one which havent the transparent pixel in the point clicked, I've the piece!
then, for color it, I've just to color the texture in the draw part.
it's easy, the problem is that if I have to drag, zoom, 50*4 pngs, it's really slow :(
SECOND APPROACH
1 PNG big puzzle 1024x800 with all pieces merged, EACH piece will have a different color fill, example, 1) 250,250,250 2) 245,245,245 etc
After the PNG has been loaded, I calculate the pixel indexes by using GetData for each piece and store it in an array for each piece
for getting the piece selected, it's easy.. I've just to calculate the y*width+x and get the piece with that value on the array.
problem is that when I've to color.. I've to iterate the array and change the RGB and then finally do a SetData.. it takes 1 second to colorate that piece.. it MAY be acceptable.. but I want better ...
second approach is way MUCH MUCH MUCH faster when dragging and zooming, because it's only 1 PNG, and I can use bigger resolutions thanks to this, this far way best approach
any suggestions??
Thanks,
Luca
So you have a 1024x800 puzzle, with each pixel being a piece? You are not going to want to make 819200 image files or define 819200 individual behaviors for each pixel.
You need to (well, should) use object-oriented concepts for this. Here is a basic idea of the path I think you should take:
Define a "Piece" class. This Piece represents a game piece.
In the Piece class, define a rectangle which represents this piece on the board. If your piece is an irregular shape (like an S tetronimo, etc), define multiple rectangles. If you have multiple different types of pieces (and different shapes), you will want to use inheritance and make each different type of piece inherit from the Piece class, but define its own rectangles. However, if your 'pieces' are just pixels on the screen, just make a 1x1 Rectangle.
Fill the rectangles with a color using SpriteBatch. You can use a single white pixel png and stretch it to fill the rectangle(s) as well as specify the color.
Use the rectangles to hit-test your pieces with touch. If a touch falls within your rectangle, you have selected that piece. If your pieces are only 1 pixel in size, it's even easier: simply lookup the piece at the touch position's X and Y values.
Now for the game board: depending on the shape and possible positions of the pieces, you will need to select a way to store them. If all your pieces were squares, you could store them in a 2D array. Otherwise you might use a map, where the key is the piece's position and the value is the piece itself.
A basic summary of this approach: don't try to store your board in a single texture. Writing/reading texture data is slow and textures are not made to act as data structures. Instead, store your pieces as individual objects. Iterate through each piece and draw it to the screen.

Resources