iOS 7 之 Sprites

話不多說 直接上圖 懶得翻譯了 會點英語的應該都能看個八九不離十了Chapter 1: SpritesBy Ray Wenderlich

Now that you know what Sprite Kit is and why you should use it, it’s time to try itout for yourself!

The first minigame you will build in this book is called Zombie Conga. Here’s what itwill look like when you’re finished:

In Zombie Conga, you take the role of a happy-go-lucky zombie who just wants toparty!

Luckily, the beach town you occupy has an overly abundant cat population. All youneed to do is bite them and they’ll join your zombie conga line.

But watch out for the crazy cat ladies! They won’t take kindly to anyone stealingtheir beloved cats, and will do their best to make the player rest in peace –permanently.

You will build this game across the next five chapters, in stages:



1. Chapter 1, Sprites:You are here! You will get started by adding your first

sprites to the game: the background and the zombie.

2.Chapter 2, Manual Movement:You will make the zombie move around thescreen following your touches, getting a crash-course in basic 2D vector math inthe process.

3.Chapter 3, Actions:You will add the cats and crazy cat ladies to the game, aswell as some basic collision detection and gameplay.

4. Chapter 4, Scenes:You will add a main menu to the game, and a win and losescenes.

5. Chapter 5, Scrolling:You will make the game scroll from left to right, andfinally add the conga line itself.

Let’s get this party started!

Getting started

Start Xcode and selectFile\New\Project...from the main menu. Select theiOS\Application\SpriteKit Game template and clickNext.

Enter ZombieCongafor the Product Name, chooseiPhonefor Devices, leave theClass Prefixblank and clickNext.

Choose somewhere on your hard drive to save your project and clickCreate. Atthis point Xcode will generate a simple Sprite Kit starter project for you.

Take a look at what Sprite Kit made. In Xcode’s toolbar, select theiPhone Retina(4-inch) Simulatorand click Play.


You’ll see a single label that says “Hello, World!” and when you click on the screen,a rotating space ship will appear.

In Sprite Kit, a single object called ascenecontrols each “screen” of your app. Asceneis a subclass of Sprite Kit’sSKSceneclass.

Right now this app just has a single scene,MyScene. OpenMyScene.mand you’llsee the code that displays the label and rotating space ship. It’s not important tounderstand this code quite yet – you’re going to remove it all and build up yourgame one step at a time.

For now, delete everything inMyScene.mand replace it with the following:

#import"MyScene.h"@implementationMyScene

-(id)initWithSize:(CGSize)size{

if(self= [superinitWithSize:size]) {self.backgroundColor= [SKColorwhiteColor];

}

return self;}

@end

initWithSize:is the method that gets called when the scene is first created. Here,you simply set the background color to white.


Zombie Conga is designed to run in landscape mode, so let’s configure the app tolaunch in landscape. To do this, select theZombieCongaproject in the ProjectNavigator and then select theZombieCongatarget. Go to theGeneraltab anduncheck Portrait so that onlyLandscape LeftandLandscape Rightare checked.


Since you changed the device orientation to landscape, you have to make a chanceto the code as well. At the time of writing, the Sprite Kit template uses the ViewController’s main view’s size as the size to create the scene in viewDidLoad, butthis size is not guaranteed to be correct at viewDidLoadtime.

There are many ways to fix this, but it’s easiest to openViewController.m,renameviewDidLoadtoviewWillLayoutSubviews:, and make a few minorchanges as highlighted below:


{

[superviewWillLayoutSubviews];

// Configure the view.

SKView* skView = (SKView*)self.view;if(!skView.scene) {

skView.showsFPS=YES;skView.showsNodeCount=YES;

// Create and configure the scene.

SKScene* scene = [MyScenesceneWithSize:skView.bounds.size];

scene.scaleMode=SKSceneScaleModeAspectFill;

- (void)viewWillLayoutSubviews


// Present the scene.

[skViewpresentScene:scene];}

}

This works becauseself.view.frame.sizeis guaranteed to be correct atviewWillLayoutSubviewstime, so it will properly use the landscape size. Thereason you now check to see ifskView.sceneexists before creating it is to avoidcreating the scene twice (this method can be called more than once).

There’s two last things: to get this game started on the right foot, you shoulddisable the status bar and set up an app icon. To disable the status bar, openViewController.mand add this to the bottom:

And to set up an app icon, openImages.xassetsand select theAppIconentry.Then in the resources for this chapter, drag all of the files from the “App Icon”folder into the area on the right. You should see the following when you’re done:

Build and run your app again. This time you should see a (mostly) blank, whitescreen:

-(BOOL)prefersStatusBarHidden{

return YES;}

This may not look like much, but you now have a starting point upon which to buildyour first Sprite Kit game.

Let’s move on to the simplest possible task, which also happens to be one of themost important and common tasks when making games – getting an image toappear on the screen.

Displaying a sprite

When making 2D games, you usually put images on the screen representing yourgame’s hero, monsters, bullets, and so on. Each of these images is called a sprite.


Sprite Kit has a special class that makes it easy to create and work with sprites,calledSKSpriteNode. This is what you’ll use to add all your sprites to the game.Let’s give it a try.

Adding the resources

First things first – before you can add sprites to the game, you need some imagesto work with.

In the resources for this chapter, you will find a folder calledArtthat includes allthe images and sounds you need for Zombie Conga. Drag this folder into yourproject and make sure thatCopy items into destination group’s folder (ifneeded),Create groups for any added folders, and the ZombieCongatargetare all checked.

You should now see the list of files in your Xcode project. Feel free to look throughthe art to get familiar with it.

In particular, look for an image calledbackground.pngas shown above. Thisrepresents the beach town the zombie lives in – and this is what you’re going touse to create your first sprite!

Creating a sprite

OpenMyScene.m, and add this line to initWithSize:, right after setting thebackground color:

Note that you do not need to pass the image’s extension, as Sprite Kit willautomatically determine that for you.

Build and run. Ah, you thought it was simple, but at this point you still see a blankwhite screen – what gives?

Adding a sprite to the scene

It actually is simple. It’s just that a sprite will not show up onscreen until you add itas a child of the scene, or one of the scene’s descendentnodes.

To do this, add this line of code right after the previous line:

[selfaddChild:bg];

You’ll learn about nodes and scenes later. For now, build and run again, and you’llsee part of the background appear in the bottom left of the screen:

SKSpriteNode*bg =
[
SKSpriteNodespriteNodeWithImageNamed:@"background"];


Obviously that’s not quite what you want. To get the background in the correctspot, you have to set its position.

Positioning a sprite

By default, a sprite is positioned at (0, 0), which in Sprite Kit represents the bottomleft. Note that this is different from the UIKit coordinate system in iOS, where (0, 0)represents the top left.

Try positioning the zombie somewhere else by setting thepositionproperty. Addthis line of code right before calling[self addChild:bg]:

Here you are setting the background to the center of the screen. Even though thisis just one line of code, there are four important things to understand:

1. The type of thepositionproperty isCGPoint, which is a simple structure thathas xandycomponents:

2. You can easily create a newCGPointwith the macro shown above,CGPointMake.

3. Since you are writing this code in anSKScenesubclass, you can access the sizeof the scene at any time with theself.sizeproperty. Theself.sizeproperty’stype isCGSize, which is a simple structure like CGPointthat haswidthandheightcomponents.

bg.position=
CGPointMake(self.size.width/2,self.size.height/2);

structCGPoint {CGFloatx;CGFloaty;

};

structCGSize {CGFloatwidth;CGFloatheight;

};

4. Note that a sprite’s position is within the coordinate space of its parent node,which in this case is the scene itself. You’ll learn more about what this means inChapter 5, “Scrolling”.

Build and run, and now your background will be fully visible:

Setting a sprite’s anchor point

Note that when you set the position of the background sprite, you’re actuallysetting thecenterof the background sprite to that position. This means two things:

1. Since this background image is bigger than the size of the screen, you areactually looking at the center part of the image right now. Look at the originalimage to see for yourself.

2. This also explains why you could only see the upper half of the sprite earlier.Before you set the position, the position defaulted to (0, 0). This was placing thecenter of the sprite at the lower left corner of the screen – so you could only seethe top half.

You can change this behavior by setting a sprite’s anchor point. Think of the anchorpoint as “the spot within a sprite that you pin to a particular position.” For example,here is an illustration showing a sprite positioned at the center of the screen, butwith different anchor points:

To see how this works, replace the line that set the background’s position to thecenter of the screen with the following:

bg.anchorPoint= CGPointZero;bg.position= CGPointZero;

CGPointZerois a handy shortcut for (0, 0). Here you set the anchor point of thesprite to (0, 0) to pin the lower-left corner of the sprite to wherever you set theposition – in this case also (0, 0).

Build and run, and this time you’ll see a different portion of the background image –the far left half. Notice how the surf boards are now in the middle of the screen?

This works because now you are pinning the lower left corner of the backgroundimage to the lower left of the screen.

Here you changed the anchor point for the background for learning purposes.However, usually you can leave the anchor point at its default of (0.5, 0.5), unlessyou have a specific need to rotate the sprite around a particular point – an exampleof which is described in the next section.

So in short: when you set the position of a sprite, by default it’s the center of thesprite that you’re positioning.

Rotating a sprite

To rotate a sprite, simply set itszRotationproperty. Try it out on the backgroundsprite by adding this line right before calling[self addChild:bg]:

bg.zRotation=M_PI/8;

Rotation values are in radians, which are a method of measuring angles. Thisexample rotates the sprite pi / 8 radians, which is equal to 22.5 degrees.

I don’t know about you, but I find it easier to think about rotations in degrees,rather than in radians. Later on, you’ll create helper routines to convert betweendegrees and radians.

Build and run, and you’ll notice the background sprite has now been rotated:

This brings up an interesting point. Sprites are rotated about their anchor points.Since you set the anchor point to (0, 0), this sprite rotates around the bottom-leftcorner.

Try rotating it around the center instead. Replace the lines that set the position andanchor point with these:

Build and run, and this time the background sprite will have rotated around thecenter instead:

bg.position=
CGPointMake(self.size.width/ 2,self.size.height/ 2);

bg.anchorPoint= CGPointMake(0.5,0.5);// same as default

That’s good to know! But for this game you don’t want a rotated background, socomment out that line:

//bg.zRotation = M_PI / 8;

If you’re wondering when you might want to change the anchor point in a realgame, consider the case where you’re creating a character’s body out of differentsprites – one for the head, torso, left arm, right arm, left leg and right leg:

If you wanted to rotate these body parts at their joints, you’d have to modify theanchor point for each sprite, as shown in the diagram above.

But again, usually you should leave the anchor point at default unless you have aspecific need like shown here.

Getting the size of a sprite

Sometimes when you’re working with a sprite, you want to know how big it is. Asprite’s size defaults to the size of the image. The class representing this image iscalled a texturein Sprite Kit.

Add these lines after the call to[self addChild:bg]to get the size of thebackground and log it out:

Build and run, and in your console output you should see something like this:

ZombieConga[5316:70b] Size: {1136, 320}

Sometimes it’s useful to programmatically get the size of sprites like this instead ofhard-coding numbers. This makes your code much more robust and adaptable inthe future.

Sprites and nodes

Earlier you learned that that if you want to make a sprite to appear onscreen, youneed to add it as a child of the scene, or as one of its descendentnodes. Thissection will delve more deeply into the concept of nodes.

Everything that appears on the screen in Sprite Kit derives from a class calledSKNode. The scene class (SKScene)derives fromSKNode, and the sprite class(SKSpriteNode) also derives from SKNode.

SKSpriteNodeinherits a lot of its capabilities fromSKNode. It turns out the positionand rotation properties are derived from SKNode, not something particular toSKSpriteNode. This means that, just as you can set the position or rotation of a

CGSizemySize = bg.size;
NSLog(@"Size: %@", NSStringFromCGSize(mySize));

sprite, you can do the same thing with the scene itself, or anything else that

derives fromSKNode.

You can think of everything that appears on the screen as a graph of nodes, oftenreferred to as ascene graph. Here’s an example of what such a graph might looklike for Zombie Conga if there was one zombie, two cats and one crazy cat lady inthe game:

You’ll learn more about nodes and the neat things you can do with them inChapter5, Scrolling. For now, you will be adding your sprites as direct children of the sceneitself.

Finishing Touches

And that’s it! As you can see, adding a sprite to a scene takes only three lines ofcode:

1. Create the sprite.

2. Position the sprite.

3. Add it to the scene graph.

Now it’s time for you to test your new-found knowledge by adding the zombie tothe scene. 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章