1. Trang chủ
  2. » Công Nghệ Thông Tin

Building XNA 2.0 Games- P7 doc

30 324 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Bringing It To The Game
Trường học Standard University
Chuyên ngành Game Development
Thể loại Luận văn
Năm xuất bản 2023
Thành phố City Name
Định dạng
Số trang 30
Dung lượng 1,05 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

And then we’ll update Land to look like this:private void Land { State = CharState.Grounded; SetAnim"land"; } This means that in our character definition file guy.zmx, we need to creat

Trang 1

Putting Scripting into Practice

Let’s look at how this scripting language actually works in a situation we could be using for

Zombie Smashers XNA

We’ve mapped out all of the important keyframes in the animation second (for secondary

attack) and connected them with gotos in Figure 6-9 We’ve left out frame numbers, opting to

use some attractive lines instead

Figure 6-9 Gotos in “second”

It’s all one animation, but it’s split into two rows that just happen to coincide with the

regular shoot and shoot up animations

At the start of the animation, we’ll check whether Up was pressed If it was, we’ll jump to

the start of the shoot up segment At the ends of both the regular shoot and shoot up

anima-tions, we’ll check for input to send us to the start of the shooting animations If we don’t get

input, we’ll move to the end of the animation and finally idle

Let’s look at a more complicated example for the animation attack, shown in the same

pseudo-format in Figure 6-10

Now we’re getting into the good stuff! We have got a four-hit combo: spanner-whack,

spanner-whack, spanner-whack, flying kick The player just needs to keep mashing those

buttons Of course, if the player doesn’t keep mashing the buttons, each individual attack has

a few back-to-idle frames, so we have a totally legit combo now

The fun part is at the end If the player does an uppercut (Down on the left analog + Y),

we’ll jump to the last row, launching skyward with a nice spanner-uppercut and finishing up in

the fly animation

See how powerful this stuff is? We can really go nuts with these combos—air juggles, complex

ground combos, far-reaching mega slams We’ve just opened up a really fun and exciting part

of this whole design racket!

Trang 2

Figure 6-10 Complex stuff: the “attack” animation

Odds and Ends: Cleanup

Now that we have our script system in place (and gotten all hot and bothered in the process),

we can clean up some placeholder animation code in Character—namely jumping and landing Our character does look a little stiff-legged on the landing, doesn’t he?

In Update(), we’re going to change the key input part to this:

#region Key input

if (animName == "idle" || animName == "run")

Trang 3

And then we’ll update Land() to look like this:

private void Land()

{

State = CharState.Grounded;

SetAnim("land");

}

This means that in our character definition file (guy.zmx), we need to create a jump

anima-tion, which will have our guy crouching and end in a joymove, setjump 600, and setanim fly,

and a land animation, which will end in a setanim idle We’ve basically added an extra

anima-tion between idle/running and flying through the air These animaanima-tions are then responsible

for progressing the character’s motion

Conclusion

We’ve made some terrific headway into our game We created our game solution, moved in all

of the right classes, loaded our content, loaded our data, and set up what is shaping up to be a

very complicated, very expressive Character class, complete with simple movement and

colli-sion detection

Next, we mapped out our scripting language, modified our character editor to allow script

editing, and implemented script parsing and running from our Character class We looked at

how we can use our ultra-simple scripting language to add a lot of depth and expressiveness to

our characters We’ll be building on this quite a bit as we flesh out our game

Our next order of business is going to involve lots of particles: sparks, muzzle flashes,

explosions, and more We’ll call it particle mayhem!

Trang 4

■ ■ ■

Particle Mayhem

Bring Out the Smashing!

Designing particle systems is probably one of the most exciting aspects of independent game

development, yet it also happens to be an area where a lot of aspiring indie developers fall flat

This is another programmer art issue While large teams with big budgets can rely on tools to

better facilitate art direction for particle systems, independent developers must either work the

entire thing out for themselves or try to collaborate with an artist to really nail the feel of it

Furthermore, many developers often take a side road and never come back once they hit

parti-cles After building a basic system, it’s easy to get caught up in adding features to the particle

system and creating an editor, because particles are just so pretty If possible, get someone else

to build the particle system for you and integrate it into the game, so that you have time to work

on more pressing matters However, this book is written with the one-person team in mind, so

we’ll get it done

It’s always nice to have a bit of history under your belt when tackling something new We’re

about to unleash some shiny, explosive particle mayhem, so to prepare ourselves, we’ll take a

brief look at the quintessential rocket contrail, starting in 1993

A Brief History of Rocket Contrails in

First-Person Shooters

Doom introduced rockets without contrails Still, it had rockets, which we all thought was amazing

From the first inception of the rocket, players have been blowing each other up without

actu-ally hitting any rockets! But a rocket is nothing without a sweet trail of smoke and fire spewing

out, attracting everyone’s attention to the destruction that lies ahead and the person who created

it, as you see in Figure 7-1

Marathon (a Doom-like title that was a Mac exclusive for quite awhile) had rockets with

billboarded smoke contrails Unfortunately, something didn’t quite sit right about the contrails

They were drawn “attached” to the rockets, such that each smoke billboard was rendered a

fixed distance from the rocket This created an illusion that the player wasn’t firing a rocket, but

instead launching a giant tube consisting mostly of fluffy gray stuff with a rocket-like protrusion

at the business end

Trang 5

Figure 7-1 Rocket contrail

Quake did it right, albeit cheaply Because the technology was already so taxing on the systems of the day, the Quake developers settled for giant point particles, rather than billboarded quads Each rocket left a trail of yellowish particles and gray particles; the yellow ones slowly fell, while the gray ones slowly rose Still, we all thought it was amazing, and it looked right according to some basic level of physics

Half-Life took another step backward in the name of progress The technique is similar to sword slash effects A contrail is made of a solid polygon with vertex pairs added at each point where a Quake rocket would have dropped some particles The vertex pairs are rotated so that the viewer will get the widest view of each quad section It seemed like a good idea, but in a number of cases, the technique just didn’t look right

Now that technology has caught up with the ubiquitous rocket contrail, it seems the industry has settled on billboarded quads However, for those who look to the future, volumetric rendering could allow for some very gorgeous smoke trails Coupled with a nice haze and fire effect, rockets of the future will look more realistic than ever However, for our purposes (and for much of the industry), volumetric clouds are a bit of overkill

In a nutshell, the modern rocket contrail is made up of billboarded quads, dropped from a fired rocket at regular intervals These quads change colors, fade out, and die after a short life span This modern rocket contrail just looks right More important though, it is realistic enough without creating a huge performance hit

Why is it important to pore over details like this? Much like many other aspects of game development, it is all too easy to get bogged down trying to make good-looking code rather than a good-looking game It’s important to be able to code, build, and run, and to be able to say not only, “this is doing what it’s supposed to,” but also “hey, this looks great!”

Setting Up a Particle System

We’ll start of by setting up the programmatic structure for our particles, and then we’ll make some mayhem We personally think that the first task is the boring part and the second is the fun part, so the attention to detail on each will reflect that Half the fun of particle systems is spent tweaking them to make explosions, splatters, and general effects look both on the money and dramatic enough to draw the player in for some more

A Base Class

We’ll start by defining a base Particle class Particles have fairly limited functionality: they can

be constructed, updated, and rendered They have locations and trajectories, short life spans, and a few other flags that we can play with

Trang 6

The Update() function will decrease the particle life (killing it if necessary) and move the

particle along its trajectory The trajectory works as it did in the Character class, acting as a

consistent velocity to multiply by elapsed time and add onto the current location Update() has

a few parameters that we’ll explain later

public class Particle

{

protected Vector2 location;

protected Vector2 trajectory;

protected float frame;

protected float r, g, b, a;

protected float size;

protected float rotation;

protected int flag;

protected int owner;

public bool Exists;

public bool Background;

public Vector2 GameLocation

Trang 7

public virtual void Draw(SpriteBatch sprite, Texture2D spritesTex)

• owner is typically used to indicate the index of the character that is responsible for this particle

• flag is commonly used for special data, such as which image index a particle uses

• background is used to determine whether the particle is drawn behind all characters or in front of them

To get started, we need some imagery We like to use sprite sheets full of all the neous particle imagery we’ll need Let’s begin by making some fluffy white blobs, as shown in Figure 7-2

miscella-Figure 7-2 Fluffy white blobs (the particle sprite sheet)

Trang 8

We’ll create our Smoke class to extend the Particle base class.

class Smoke : Particle

if (trajectory.Y < -10.0f) trajectory.Y += gameTime * 500.0f;

if (trajectory.X < -10.0f) trajectory.X += gameTime * 150.0f;

if (trajectory.X > 10.0f) trajectory.X -= gameTime * 150.0f;

Trang 9

The constructor is straightforward enough The Draw() and Update() methods show a bit

of life, and ironically enough, take it away!

The Update() method adds a bit of definition to the smoke particle by decelerating its trajectory as it nears death; that is, it will cause smoke to slow down as it fades out, giving it a more natural look (which is what this is all about, no?)

The Draw() method does a few things It determines the source rectangle based on our flag field Then it calculates a scalar, frameAlpha, as a linear function of frame—the particle will quickly fade in and slowly fade out The sprite.Draw() call has a bit of substance to it The color

is calculated such that the RGB values steadily decrease, while the alpha value changes with frameAlpha Also, the size steadily increases

Particle Management

Now we need a class to manage all of these particles Here’s an area where we skimped a bit Traditionally, particle systems are atomic entities, where one system governs its child particles, and each system has its own life cycle We just used a big array, without an emitter-child hier-archy, where particles can act as particle emitters This turns out to be very beneficial, because certain particles can act as particle emitters For example, a spark-like particle that shoots through the air and explodes can be represented as a particle that explodes and emits particles For now, however, we will focus on the more basic particle examples of blood, smoke, and fire.class ParticleManager

{

Particle[] particles = new Particle[1024];

SpriteBatch sprite;

Trang 10

public ParticleManager(SpriteBatch sprite)

Trang 11

To see our smoke in action, we’ll just set up our game so that smoke flies off of our hero’s head, and then get to practical cases later In the Character.Update() method, add the following:

#region Particle Test

for (int i = 0; i < 4; i++)

Let’s do some setup in Game1 At the class level, add this:

Texture2D spritesTex;

ParticleManager pManager;

In LoadContent(), we now can create our ParticleManager with spriteBatch and load our sprites texture:

Trang 12

protected override void LoadContent()

{

spriteBatch = new SpriteBatch(GraphicsDevice);

pManager = new ParticleManager(spriteBatch);

pManager.UpdateParticles(frameTime, map, character);

And finally, draw in (where else?) Draw():

pManager.DrawParticles(spritesTex, true);

character[0].Draw(spriteBatch);

pManager.DrawParticles(spritesTex, false);

Our hot-headed guy in action is shown in Figure 7-3 The picture doesn’t do justice to the

code in action, so give it a try

Figure 7-3 Smoke in action

Trang 13

The parameters we used in AddParticle() were decided after a bit of tweaking Not enough randomness would make the smoke look unnatural; too much randomness would make it look unnatural for other reasons See for yourself the ravages of bad randomization in Figure 7-4.

Figure 7-4 Bad amounts of randomness: too little (left) and too much (right)

Additive Blending: Fire

Additive blending is a cheap way to make flashy (literally) effects, and it’s actually tionally cheaper than plain-old alpha blending The idea of additive blending is that color

computa-values are added to what’s currently on our backbuffer (The backbuffer is what we draw on

each time through the Draw() loop.) When we use vanilla alpha blending, we paint onto the backbuffer with the intensity of the alpha value, so drawing black with an alpha value of 0.5 will darken things a bit Additive blending, on the other hand, adds only color values Additive blending is great for bright, flashy effects—fire, electricity, muzzle flashes, lens flares, and laser blasts, to name a few

We’ll need to make a few structural changes to our ParticleManager and Particle classes

to efficiently render additive particles We want to draw all alpha-blended particles as one batch, and then additive particles as another, simply because we cannot mix the two methods

Trang 14

private bool additive;

public bool Additive

{

get { return additive; }

protected set { additive = value; }

}

In ParticleManager, we modify the Draw() method so it does two draw loops: one for

alpha-blended particles and one for additive particles This is much faster than putting each

sprite in its own batch, especially on the Xbox 360 This is due to how the SpriteBatch works

and, in fact, how rendering in general works It is more efficient to push as many graphics as

possible through the pipeline at once, rather than pushing a small amount at fast intervals You

can liken it to trying to drink a thick milkshake through a straw—a thin straw isn’t going to work

as well as a wider straw

Now we’ll make a Fire class, which can be fairly simple Over time, the color of flames will

transition from white to yellow to red to black Because it will be rendered additively, black is

synonymous with clear The size may diminish slightly over time, and the flame wisps will

rotate as well It’s simple in theory, but the settings and how the particles are morphed over

time matter Here’s the code:

class Fire : Particle

Trang 15

Rectangle sRect = new Rectangle(flag * 64, 64, 64, 64);

float bright = frame * 5.0f;

Ngày đăng: 01/07/2014, 22:20

TỪ KHÓA LIÊN QUAN