small medium large xlarge

04 May 2013, 17:58
Leroy Greffin (2 posts)

In section 5.8 you write “Update the enemy spawning code so that we have a 5% chance of spawning seven spaceships in a V-formation as shown on Figure 28, ​7 Ships in a V-formation​” and then show a graphic.

Is the code something that will get added later? I was hoping for an example.

04 May 2013, 19:40
Silvia Domenech (35 posts)

Hi Leroy,

Solutions to the exercises won’t be explained in the book, but my goal is to add some of the key solutions to the book’s downloadable code files.

For now, I’ll write a pseudo-solution here, and then add the final code to one of the future beta updates.

When you’re spawning a V-formation, you’re basically adding several ships spaced out evenly horizontally, but slightly displaced vertically. We can do that by performing a loop when we add them instead of just adding one ship.

To add a V-formation 5% of the time, look for the enemy adding code (in game.lua):

enemies[ #enemies + 1 ] = Enemy( group, spriteSet )

To add a V-formation, it’s easier to add the central ship first, and then use a loop to add the rest in pairs (one to the right, and one to the left). Add the ships following a straight line. In the following example, they’re 60 pixels apart horizontally and 30 vertically, which looks well for these graphics. If you use a loop and add them in pairs, add both ships using the same y coordinate, but change their x value so that it either adds or subtracts from the central x coordinate (i.e. 160 in a screen that is 320 pixels wide).

To add a single enemy 95% of the time and a group 5% of the time, use math.random() to generate a random number.

local formation = math.random( 20 )
if ( formation ~= 1 ) then
	-- Add a single enemy
	enemies[ #enemies + 1 ] = Enemy( group, spriteSet )
	-- Add a formation
	-- First the ship in the centre
	local enemy = Enemy( group, spriteSet )
	enemy:setPosition( 160, -30 )
	enemies[ #enemies + 1 ] = enemy
	-- Now the other ships (2x2)
	for i = 1, 2 do
		-- Left (note that we're changing both x and y positions)
		enemy = Enemy( group, spriteSet )
		enemy:setPosition( 160 - 60 * i, -30 - 30 * i )
		enemies[ #enemies + 1 ] = enemy

		-- Left (note that we're changing both x and y positions)
		enemy = Enemy( group, spriteSet )
		enemy:setPosition( 160 + 60 * i, -30 - 30 * i )
		enemies[ #enemies + 1 ] = enemy

By the way, the Unit:setPosition() function in unit.lua has to be updated for this solution. The final chapter codes will get rid of the redundant x and y properties in this game, but they’re needed (temporarily) for this solution.

-- Set the unit's position
function Unit:setPosition( x, y )
	self.spriteInstance.x = x
	self.spriteInstance.y = y
	self.x = x
	self.y = y

Also, the Unit:toggleDelete() function in unit.lua looks for y values less than -20 in order to delete inactive ships. Update that so that the program does not delete formations as soon as they are added. You can remove the negative y-bounds check or decrease it to anything below the lowest coordinate in the V-formation (-90 in this case).

I hope this helped!