In this section you'll add level 4 to the game. I saved this level for last because it's different enough from the first three levels that it warrants its own section. In level 4 you'll have to navigate your ship through a tight, twisting "refueling tunnel" in order to earn bonus points:
If you make it through the tunnel successfully, you'll earn 5000 bonus points. But if you touch the sides of the tunnel, your ride ends immediately and you'll start back at level 1. This is a bonus level, so you won't lose a life when you crashbut you won't get any points either.
Let's begin by creating the level 4 section in the Score and then importing the tunnel image.
Create the level4 marker at frame 70. Drag the frame key control behavior from the internal cast and drop it in the Score's behavior channel at frame 85.
You can use the same behavior for this bonus level as you did for the other three levels.
Choose the assets cast and import tunnel.png from the Lesson13\media folder on the CD. Import the image with 32 bits so the alpha channel stays intact. Next, drag the new tunnel member from the cast and drop it into the Score in channel 1, so its span begins at frame 70. After you drop the sprite, adjust the span so it ends at frame 85.
Because the tunnel image is quite large (3222x400) you'll need to move it to the right so that the left edge of the image starts butted up against the left edge of the Stage.
Select the tunnel sprite and make the Property inspector's Sprite tab active. Set the sprite's x position to 1611, which will make the sprite's left edge be at 0:
Click the player's ship sprite in channel 20 of level 3 to select it. Press Ctrl/Command+C to copy it. Click channel 20 of frame 70 and press Ctrl/Command+V to paste the player's ship into level 4.
The ship appears and spans frames 70 to 85.
Select the player's ship in level 4. Choose the Behaviors tab of the Property inspector. Click to select the move_ship behavior, which is attached to the sprite, then press Delete to delete the behavior.
For the bonus level we'll modify the move_ship behavior so that instead of using the enemy list for collision checking it will use the getPixel approach outlined earlier. Also, when you collide with the tunnel wall, you don't want the ship to explode, because this is a bonus level. You simply want to return to level 1.
You'll need to do nearly the same thing with the ground_scroll behavior used to scroll the ground and mountains in the first levels. While nearly the same behavior can be used to scroll the tunnel, the difference is that in level 4 when you reach the end of the tunnel, you don't want it to loop. You want to get your bonus points and then jump to level 1.
In the internal cast, select the move_ship and ground_scroll behaviors by clicking one, and then Ctrl/Command clicking the other. Press Ctrl/Command+C to copy both behaviors. Click an empty member slot and press Ctrl/Command+V to paste in the two behaviors.
You should now rename the two new behaviors in order to distinguish them from their counterparts.
Rename the new move_ship behavior to move_ship_tunnel. Rename the new ground_scroll behavior to tunnel_scroll. Drag move_ship_tunnel from the internal cast and drop it onto the player's ship sprite in level 4. Drag the tunnel_scroll behavior and drop it onto the tunnel sprite. Set the time to scroll to 60000 milliseconds (60 seconds).
You can now modify the two behaviors to make them work within the bonus level. Let's begin by modifying the tunnel_scroll behavior.
Right-click the tunnel sprite, in channel 1, and select Script from the context menu.
The ground scroll and tunnel scroll behaviors are essentially identical. The only thing you need to change is the conditional test within the enterFrame handler that checks to see if the "virtual camera" is beyond the right edge of the bitmap, causing it to loop if it is.
Modify the behavior as follows.
Within the enterFrame handler find the following chunk of Lingo:
if myRect.right > sp.member.rect.right then myRect.right = 800 myRect.left = 0 end if
Change the two lines within the test to read as follows:
if myRect.right > sp.member.rect.right then doScore(5000) _movie.go("level1") end if
Now, if the right edge of the bitmap is reached, 5000 points will be added to the score and the movie will jump to the level1 marker.
That's all the modification the scroll behavior needs. You can now modify the behavior attached to the player's ship so that instead of checking for collisions against the enemy list with the sprite.intersects command, you use the getPixel method.
Right-click the player's ship in level 4 and select Script from the context menu. Modify the script so that it appears as follows:
property sp on beginSprite me sp = sprite(me.spriteNum) _global.shipVelX = 0 _global.shipVelY = 0 end on enterFrame me im = _movie.stage.image a = im.getPixel(sp.loc + point(35,0)) b = im.getPixel(sp.loc + point(0, -17)) c = im.getPixel(sp.loc + point(0, 17)) if a <> rgb(0,0,0) or b <> rgb(0,0,0) or c <> rgb(0,0,0) then sound(2).play(member("boom")) _movie.go("level1") end if sp.loc = sp.loc + point(_global.shipVelX, _global.shipVelY) if sp.locH < 20 then sp.locH = 20 if sp.locH > 500 then sp.locH = 500 if sp.locV < 5 then sp.locV = 5 if sp.locV > 350 then sp.locV = 350 end
You begin by deleting all the property declarations at the top of the script, except the one for sp. Next, the initializations for those properties are removed from the beginSprite handler, and the global variables shipVelX and shipVelY are both set to zero instead. This is done so that at the start of the level there is no initial motion on the ship.
Within the enterFrame handler all that remains of the original script are the five lines that modify the ships loc property, and check to see if it's out of bounds.
The new lines, at the beginning of the enterFrame handler, first store the image of the stage in the local variable im. This is done because the next three lines all use the getPixel method on the stage's image, and it's faster to store the image in a variable first, instead of getting it three times.
The following lines all use the getPixel method to poll the area at the ship's nose and wingtips. Examine the following image to see how the points are set up:
As you can see, the getPixel method returns the color of the three pixels just outside the edges of the ship. If any of those pixels isn't solid black, that is, rgb (0, 0, 0), the boom sound is played and the movie is sent to the level1 marker.
Close the script window. Modify the sprite spans of the two remaining life icons in channels 35 and 36 so that they end at frame 85. Save the movie.
Although you can't lose a life in level 4, it would be disconcerting if the icons suddenly disappeared when you got there.
The game is now finished, but feel free to add any finishing touches you think would be appropriate. You might have the enemy ships start beyond the right edge of the Stage so you don't see them right away. Having the enemy ships fire their own bullets would also be cool. You might even think about adding lives when certain scoring goals are met. You could let your ship drop bombs onto ground targets. You could have the ground cause collisions. The possibilities are endless.
In the next lesson you'll publish the game to the Shockwave format so it can be played online, within your browser.