Spritebatch explanation

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
zugamifk
Prole
Posts: 28
Joined: Sun Jul 26, 2009 4:01 pm

Spritebatch explanation

Post by zugamifk » Mon Mar 15, 2010 12:43 am

I was reading over info on quads in the wiki and it all makes good sense with examples and such, but I don't understand the spritebatch at all. From what I understand, quads are simply a collection of coordinates you can apply to any image to get a subsprite from that image, and that sounds extremely useful for a tile based game, which is exactly what I'm working on.

However, it seems like spritebatch is made even more specifically for this purpose, but I don't understand how it works. Is it a table that stores images as values?

Here's an example of the table I store all of my images in:

Code: Select all

images = {
	world = {
		tiles = {
			earth = {
				love.graphics.newImage("tiles/earth/1.png"),
				love.graphics.newImage("tiles/earth/2.png"),
				love.graphics.newImage("tiles/earth/3.png"),
				love.graphics.newImage("tiles/earth/4.png"),
				love.graphics.newImage("tiles/earth/loam.png"),
				},
			grass = {
				meadow_foxtail = love.graphics.newImage("tiles/grass/meadow_foxtail.png"),
				},
			flowers = {
				wild_lupin = love.graphics.newImage("tiles/flowers/wild_lupin.png"),
				field_poppy = love.graphics.newImage("tiles/flowers/field_poppy.png"),
				},
			trees = {
				red_maple = {love.graphics.newImage("tiles/trees/saplings/red_maple.png"),
							love.graphics.newImage("tiles/trees/trunks/red_maple.png"),
							love.graphics.newImage("tiles/trees/leaf cover/red_maple.png"),	},
				}
			},
		items = {
			natural = {
				seeds = {
					--grass
					meadow_foxtail = love.graphics.newImage("tiles/items/seed_meadowfoxtail.png"),
					--flowers
					wild_lupin = love.graphics.newImage("tiles/items/seed_wildlupin.png"),
					field_poppy = love.graphics.newImage("tiles/items/seed_fieldpoppy.png"),
					--trees
					red_maple = love.graphics.newImage("tiles/items/seed_redmaple.png"),
					},
				},
			},
		player = {
			idle = {
				down = newAnimation(love.graphics.newImage( "tiles/character/idle_down.png" ), 25, 50, 0.1, 0),
				up = newAnimation(love.graphics.newImage( "tiles/character/idle_up.png" ), 25, 50, 0.1, 0),
				right = newAnimation(love.graphics.newImage( "tiles/character/idle_right.png" ), 25, 50, 0.1, 0),
				left = newAnimation(love.graphics.newImage( "tiles/character/idle_left.png" ), 25, 50, 0.1, 0),
			},
			walk = {
				right = newAnimation(love.graphics.newImage( "tiles/character/walk_right.png" ), 25, 50, 0.1, 0),
				left = newAnimation(love.graphics.newImage( "tiles/character/walk_left.png" ), 25, 50, 0.1, 0),
				up = newAnimation(love.graphics.newImage( "tiles/character/walk_up.png" ), 25, 50, 0.1, 0),
				down = newAnimation(love.graphics.newImage( "tiles/character/walk_down.png" ), 25, 50, 0.1, 0),
			},
		},
	},

	hud = {
		main = {
			bar = love.graphics.newImage("tiles/hud/hud_bar.png"),
		},
		windows = {
			context_window = love.graphics.newImage("tiles/hud/hud_context.png"),

			examine_window = love.graphics.newImage("tiles/hud/hud_examine.png"),

			help_window = love.graphics.newImage("tiles/hud/help_window.png"),

			inventory_window = love.graphics.newImage("tiles/hud/inventory_window_2.png"),
			inventory_window_info = love.graphics.newImage("tiles/hud/hud_inventory_info.png"),

		},
		buttons = {
			examine = love.graphics.newImage("tiles/hud/button_examine.png"),
			inventory = love.graphics.newImage("tiles/hud/button_inventory.png"),
			help = love.graphics.newImage("tiles/hud/button_help.png"),
			nextgen = love.graphics.newImage("tiles/hud/hud_newgen.png"),
			close = love.graphics.newImage("tiles/hud/close.png"),

			inventory_slot = love.graphics.newImage("tiles/hud/inventory_slot_1.png"),
			inventory_action = love.graphics.newImage("tiles/hud/hud_inventory_action.png"),
			context_item = love.graphics.newImage("tiles/hud/hud_context_itemslot.png"),
			context_action = love.graphics.newImage("tiles/hud/hud_action_itemslot.png"),
		},
		boxes = {
			inventory_main = love.graphics.newImage("tiles/hud/hud_inventorytextbox.png"),
			inventory_grid = love.graphics.newImage("tiles/hud/hud_inventorygrid.png"),
		},
		menus = {
			menu_action = love.graphics.newImage("tiles/hud/menu_actions.png"),

		},
		items = {
			natural = {
				seeds = {
					--grass
					meadow_foxtail = love.graphics.newImage("tiles/grass/icons/seed_meadowfoxtail.png"),
					--flowers
					wild_lupin = love.graphics.newImage("tiles/flowers/icons/seed_wildlupin.png"),
					field_poppy = love.graphics.newImage("tiles/flowers/icons/seed_fieldpoppy.png"),
					--trees
					red_maple = love.graphics.newImage("tiles/trees/icons/seed_redmaple.png"),
				},
			},
		},
	},
	cursors = {
		default = love.graphics.newImage("tiles/cursors/crs_default.png"),
		tileselect = love.graphics.newImage("tiles/cursors/crs_tileselect.png"),
	},

}
Is there some way this would better work out as a sprite batch? Can I take an image from a spritebatch and apply a quad to it?

pekka
Party member
Posts: 206
Joined: Thu Jan 07, 2010 6:48 am
Location: Oulu, Finland
Contact:

Re: Spritebatch explanation

Post by pekka » Mon Mar 15, 2010 8:58 am

Every time you create a SpriteBatch with the newSpriteBatch function, you need to specify an image. Since the SpriteBatch object methods don't provide a way of adding new images, this means that for each batch, you only get one image. It seems to be limiting, but the solution for drawing different things with one batch is to make a mosaic of images and store it as one image, and to then use Quads to pick the right subimages to draw.

SpriteBatches are good for storing drawing operations that will often be repeated but which don't vary between frames. You can use them, for example, to draw a section of the background. Assuming the background does not change, its tiles will all be the same and in the same relative positions to each other. Then you need only provide the location of the whole section (that is, the batch) when drawing it, and the SpriteBatch code in LÖVE will take care of placing all the tiles in the right positions. You only need to specify these positions once, when creating the SPriteBatch and adding the Quads into it.

SpriteBatches use a special internal representaiton for the drawing commands, and thus should be faster that doing the same drawing by one call to draw or drawq at a time. You can try measuring this difference by writing a program that times a lot of drawing operations done in both ways and compares the results. (The difference is probably slight if you draw only a few images.) You can also read the LÖVE sources to see how they're implemented, if you are familiar with C++ and OpenGL.

User avatar
zugamifk
Prole
Posts: 28
Joined: Sun Jul 26, 2009 4:01 pm

Re: Spritebatch explanation

Post by zugamifk » Mon Mar 15, 2010 7:26 pm

Thank you, that was extremely helpful.

This is like a godsend for my tile based RPG project. Do I draw spritebatches with love.graphics.draw? Also, can I remove a specific image from a spritebatch and replace it with something else?

Mamny thanks for the answer by the way, that explained it to me perfectly.

pekka
Party member
Posts: 206
Joined: Thu Jan 07, 2010 6:48 am
Location: Oulu, Finland
Contact:

Re: Spritebatch explanation

Post by pekka » Tue Mar 16, 2010 5:36 am

SpriteBatch is a Drawable object, so you call love.graphics.draw to draw it. Unfortunately, there is no method for removing data from a batch, but only a way to remove all the sprites: SpriteBatch:clear.

Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests