2D Shooter game2D Shooter game- Part 1 - University of...
Transcript of 2D Shooter game2D Shooter game- Part 1 - University of...
2D Shooter game- Part 12D Shooter game Part 1
Knowledge in C# fMicrosoft Visual Studio
XNA framework
Expanded as “XNA is Not Acronymed”Hobby ProgrammersMore than APIsNot a 3D Engine!Wraps DirectX in XNA API
Adds to Visual C# Express (free)h d lRequires graphics card supporting pixel
shader model 1.1 or above (at least 2.0, really). Cards later than 2003 should work.really). Cards later than 2003 should work.See http://xnamatrix.com/xnareq.php for a requirements checker.D l XB 360 i CDeploys to XBox 360 -- requires Creators Club membership
XNA Game StudioXNA Game StudioExtends Visual Studio 2005Extends Visual Studio 2005Extends Visual Studio 2005Extends Visual Studio 2005to create games using C#to create games using C#
XNA FrameworkXNA FrameworkCrossCross--Platform gamePlatform gamedevelopment framework anddevelopment framework andruntimeruntime
FrameworkFrameworkruntimeruntime
.NET Framework for Xbox 360.NET Framework for Xbox 360Custom version of the Custom version of the .NET Compact Framework .NET Compact Framework
GamesGamesGamesGames
St t KitSt t KitY C dY C d Y C t tY C t t C tC t
Extended FrameworkExtended FrameworkExtended FrameworkExtended Framework
Starter KitsStarter KitsYour CodeYour Code Your ContentYour Content ComponentsComponents
Core FrameworkCore FrameworkCore FrameworkCore Framework
Application ModelApplication Model Content PipelineContent Pipeline
GraphicsGraphics AudioAudio InputInput MathMath StorageStorage
NetworkingNetworking Gamer ServicesGamer Services
PlatformPlatformPlatformPlatform
DirectXDirectX XDKXDK .NET Framework.NET Framework .NET CF.NET CF
Graphics APIDirectX (Microsoft)OpenGL (Cross-platform)
DirectX more popular for games.Managed DirectX allows use of C# and .NET
h h Crather than C++Still a lot to learn. XNA k i i lXNA makes it simpler.
GameInit
GameMenu
GameExit
Game GameStarting Ending
GameRun
Game class
Initialize- Called onceLoadContent Once each refreshLoadContent - Once each refresh Update - Game logic, called every 1/60 sec.Draw -Renders objects, called every 1/60 sec.j , y /UnloadContent -Called once
Create new myGameCall to constructor myGame()◦ Call to constructor, myGame()
◦ myGame.run() 1. Initializes game, then,2 Runs the main game loop & processes events2. Runs the main game loop & processes events
Initialization phase of run(), ◦ The following methods are called on myGame◦ Initialize()◦ Initialize()
1. call Initialize() on parent class2. Initialize your game state
1 Create player object create enemy objects create1. Create player object, create enemy objects, create object to hold main game state, etc.
◦ LoadGraphicsContent()Method used to load textures, create SpriteBatches
Time elapsed between each clock tick:◦ Fixed:
1/60th of a second (16.6667 milliseconds per tick)myGame.IsFixedTimeStep = trueThe default value
◦ Variable:Adjusts based on the time required to perform previous tickj q p pmyGame.IsFixedTimeStep = false
Each clock tickRun() calls Tick()◦ Run() calls Tick()
◦ Tick() calls Update() then Draw()You supply Update() and Draw()
Update()◦ Update the state of all objectsUpdate the state of all objects◦ Receive input, move player avatar◦ Compute opponent AI, move opponent objects◦ Collision detection & consequences◦ Detect end-of-game or end-of-level conditionDetect end of game or end of level conditionDraw()◦ Re-create the on-screen scene using the up-to-date
positions of player, opponent
Advice◦ Avoid stuffing your entire game into the definition of these
two methodsM th d b t bi !Methods become too big!
◦ Have these methods call out to your player object, opponent objects, etc.
foreach (Opponent o in opponentList) o.update();
Please go to the Riemer’s 2D XNA Tutorial for C# by clicking on http://bit.ly/Riemers2DYou are allowed to progress ahead of me by reading and doing to tutorial yourselfreading and doing to tutorial yourself.I’ll be explaining the tutorial and will be taking things a bit slowtaking things a bit slow.
“Visual C# -> XNA Game Studio 3.1”Windows game (3.1)Go to the Game1.cs and explore the code.What methods do you have there?◦ The constructor◦ Initialize()◦ Initialize()◦ LoadContent()◦ UnloadContent()◦ Update(GameTime gameTime)◦ Draw(GameTime gameTime)
Add the GraphicsDevice variable.GraphicsDevice device;
Initialize the GraphicsDevice variable at the LoadContent() methodLoadContent() method.
device = graphics.GraphicsDevice;
Add the few lines to the Initialize() method. ◦ Setting the Width , Height
graphics.PreferredBackBufferWidth = 500;graphics.PreferredBackBufferHeight = 500;
◦ Setting the fullscreen propertygraphics.IsFullScreen = false;graphics.ApplyChanges();
◦ Altering the window title.Window.Title = "Riemer's 2D XNA Tutorial";
Download the textures from here and here.Go to the Solution Explorer (top-right of your screen)Ri h li k CRight-click on ContentSelect Add -> Existing ItemAdd the background jpgAdd the background.jpg
Add the backgroundTexture variable.Link the texture to the project by adding the Content.Load line to the LoadContent method.Add h Wid h d H i hAdd the screenWidth and screenHeightvariables to store the screen size.Initialize the screen size in theInitialize the screen size in the LoadContent method.
screenWidth = device.PresentationParameters.BackBufferWidth;H i h d i P i P B kB ff H i hscreenHeight = device.PresentationParameters.BackBufferHeight;
Create the empty method DrawScenery()Add the lines to draw the image rectangle
Rectangle screenRectangle = new Rectangle(0, 0, screenWidth, screenHeight);spriteBatch.Draw(backgroundTexture, screenRectangle, Color.White);
Now go to the Draw method and call the DrawScenery() method in the shown manner.
spriteBatch.Begin();spriteBatch.Begin();DrawScenery();spriteBatch.End();
Add the PlayerData struct.Create the players array and numberOfPlayersvariable.C h S U Pl () h dCreate the SetUpPlayers() methodAdd the player positions to the end of the SetUpPlayers() methodSetUpPlayers() method.Call the SetUpPlayers() method at the end of the LoadContent method.the LoadContent method.
Download the carriage image from here and the cannon image from here.Load the images to the game.C h D Pl () h dCreate the DrawPlayers() methodAlter the Draw method.
We need to fix the following problems◦ The carriages are drawn below the terrain, instead
of on top of it.◦ The carriage are far too big.The carriage are far too big.◦ They’re gray.
We need to fix the following problems◦ The carriages are drawn below the terrain, instead
of on top of it.◦ The carriage are far too big.The carriage are far too big.◦ They’re gray.
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The image to drawg
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The target screen pixel positiong p p
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
This argument allows us to specify which part of the image should be drawn This is useful in case you have stored multiple images insidedrawn. This is useful in case you have stored multiple images inside one large image. By specifying null, we indicate we want to render
the whole image.
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The modulation color will be discussed when dealing with the player colors.
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The 5th argument allows us to rotate gthe image before it is rendered to the screen. It will be used to render the
cannon.
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
We’ll use the 6th argument to solve our positioning issue. The 6th argument allows us to specify what XNA calls the ‘origin’ of the image By default thisallows us to specify what XNA calls the origin of the image. By default, this is the top-left corner of the image. XNA will render the image so that this
‘origin’ point of the images is positioned on the screen position specified as 2nd argument.
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The 7th argument allows us to scale the gimage. We specify 1, indicating we
want to render the image at the goriginal size.
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The 8th argument can be used to gmirror the image horizontally of vertically before drawing it to the y g
screen.
The SpriteBatch.Draw() method has a lot of different overloadsspriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new
Vector2(0, carriageTexture.Height), 1, SpriteEffects.None, 0);
The final argument can be used to specify the layer the image should be drawn on. This is useful for advanced games having multiple t t i t k d t f htransparent images stacked on top of each
other.
We need to fix the following problems◦ The carriages are drawn below the terrain, instead
of on top of it.◦ The carriage are far too big.The carriage are far too big.◦ They’re gray.
Add the playerScaling variable and initialize it at the LoadContent method.Alter the SpriteBatch.Draw call of the carriage.
spriteBatch Draw(carriageTexture player Position null Color White 0spriteBatch.Draw(carriageTexture, player.Position, null, Color.White, 0, new Vector2(0, carriageTexture.Height), playerScaling, SpriteEffects.None, 0);
We need to fix the following problems◦ The carriages are drawn below the terrain, instead
of on top of it.◦ The carriage are far too big.The carriage are far too big.◦ They’re gray.
Alter the SpriteBatch.Draw call of the carriage.spriteBatch.Draw(carriageTexture, player.Position, null, player.Color, 0, new Vector2(0, carriageTexture.Height), playerScaling, SpriteEffects.None, 0);
mentioned before, by default XNA takes the top-left corner of the 2D image as origin.◦ XNA will position the image on the screen so the
origin point is at the position you specify in theorigin point is at the position you specify in the SpriteBatch.Draw method.◦ When you rotate the image, XNA rotates the image
d it i i i t Thi i di taround its origin point. This is a direct consequence of the previous one: this way, the origin point stays at the position you specify, no matter what the rotation of the image is.
We need to specify 2 positions:◦ The new origin point of the cannon image.◦ And the screen position indicating where this origin
point should be positioned.point should be positioned.Add the code lines to the DrawPlayers() method.
Add the currentPlayer variable.dd h b d() h dAdd the ProcessKeyboard() method.
private void ProcessKeyboard(){
Ke boardState ke bState Ke board GetState()KeyboardState keybState = Keyboard.GetState();if (keybState.IsKeyDown(Keys.Left))
players[currentPlayer].Angle -= 0.01f;if (keybState.IsKeyDown(Keys.Right))
players[currentPlayer].Angle += 0.01f;players[currentPlayer].Angle + 0.01f;}
Call the ProcessKeyboard() method from the Update() method.Update() et odRun the game and see how the cannon is controlled by the Left and Right keys.
Alter the ProcessKeyboard() method to have limits. (Exchange the +,- signs)
if (players[currentPlayer].Angle > MathHelper.PiOver2)players[currentPlayer].Angle = MathHelper.PiOver2;
if (players[currentPlayer].Angle < -MathHelper.PiOver2)players[currentPlayer].Angle = -MathHelper.PiOver2;
Add the Power modifications to the ProcessKeyboard() method.
Go to the Solution Explorer (top-right of your screen)Right-click on ContentS l Add N ISelect Add -> New ItemSelect “Sprite Font”Name it myFont spritefontName it myFont.spritefontClick the Add button
Open myFont.spritefontFind the FontName entry in the file, and change Segoe UI Mono to Arial. (Or whatever other font you like)other font you like)Add the font variable.Load the spritefont on to the font variableLoad the spritefont on to the font variable.Create the DrawText() method.Cal the DrawText() from the Draw methodCal the DrawText() from the Draw method.
Download the rocket image from here.Add the rocketTexture variable.Link the texture to the project by adding the C L d li h L dC h dContent.Load line to the LoadContent method.Add the variables needed to control the rocketrocket.
bool rocketFlying = false;Vector2 rocketPosition;Vector2 rocketDirection;Vector2 rocketDirection;float rocketAngle;float rocketScaling = 0.1f;
Add the rocket launching keystroke.if (keybState.IsKeyDown(Keys.Enter) || keybState.IsKeyDown(Keys.Space)){
rocketFlying = true;}}
Now set the initial rocket positionrocketPosition = players[currentPlayer].Position;p y y ;rocketPosition.X += 20;rocketPosition.Y -= 10;rocketAngle = players[currentPlayer].Angle;
Now we need to find the angle by applying Cos and Sin.No. XNA k hiXNA makes everything easy.◦ Define the UP direction◦ Create the Rotation MatrixCreate the Rotation Matrix◦ Calculate the rocket direction◦ Scale the direction with powerAdd the DrawRocket method
Remember the Update method gets called every 1/60 th of a second. So we will create a new UpdateRocket method and call it using the Update methodthe Update method.Run the code and see how the rocket fly.It will fly in a straight line Not much of use ifIt will fly in a straight line. Not much of use if you want to shoot the other cannons.
Replace the contents inside the if-block of the UpdateRocket method with this code;
Vector2 gravity = new Vector2(0, 1);rocketDirection += gravity / 10 0f;rocketDirection += gravity / 10.0f;rocketPosition += rocketDirection;
See how the gravity direction is along the positive Y axispositive Y axis.Run it and see.What is the problem now?What is the problem now?
Now we need to rotate the rocket.We know the following direction data;
We can calculate the angle by applying…..◦ Tan-1(Y/X)◦ Tan 1(Y/X)Now add a rocketAngle line to UpdateRocketmethod
Download the smoke texture from here.Add the smokeTexture and import it to the game.C li k h k bjCreate a list to keep the smoke objects.Now add the smoke creation code to the UpdateRocket methodUpdateRocket method.Add the DrawSmoke MethodRun the game and seeRun the game and see.Not enough smoke? Add the loop at the smoke creation point.p
Four series –terrain, flight simulator, higher-level shader language, advanced terrain. I did 2, 1, and 3 in that order.Great intro to 3D games using XNAGreat intro to 3D games using XNAHe answers questions.
Professional XNA Game Programmingf Xb 360 d Wi dfor Xbox 360 and WindowsBenjamin NitschkeWrox (Wiley) 2007Wrox (Wiley) 2007
He created Rocket Commander XNAd R i G b th il bl f Wi dand Racing Game, both available for Windows
and Xbox 360.
Other books to appear.
XNA Team Sitehttp://creators.xna.com/Download XNA, GamesTutorials, Code examples
A Games Class Using XNA Game Studio E bExpress ( http://www.cecs.csulb.edu/~artg/games.ppt) by Prof. Art Gittleman, California State University Long Beachy g3D Game Programming using XNA GSE (http://www.slideshare.net/guest3860287/xna-demoppt) by Sahithya Baskaran PES Institute Ofby Sahithya Baskaran, PES Institute Of Technology2D Graphics in XNA Game Studio Express p p(http://classes.soe.ucsc.edu/cmps020/Winter08/lectures/intro-xna-gse-2d.ppt) by Prof. Jim Whitehead