xna game studio
DESCRIPTION
Az xna játék készítésére találálták ki ebben a pdf-ben egyszerű példák alapján megismerhetjük a program környezetet.TRANSCRIPT
XNA GAME STUDIO Ebben a kis jegyzetben, minden fontos dolgot próbáltam összegyűjteni, amire szükséged lehet, ha
teljesen elölről kezdesz a játékfejlesztéssel és az XNA-val foglalkozni.
Megpróbáltam összegyűjteni a legfontosabb kérdéseket, hogy tényleg csak a játék írásával teljen az
idő.
Az XNA Game Studio , egy Cross-platform fejlesztőkörnyezet, aminek a segítségével olyan dolgokat
csinálhatunk meg otthon ,amiről eddig csak ábrándoztunk. A legtöbb embernek eszébe jutott már,
hogy milyen jó lenne összedobni pl. egy régi játéknak az új remakejét.
Sokan szerettek volna mindig is játékfejlesztők lenni ,de valamiért nem léptek erre az útra, mert túl
sok időt ,energiát vagy épp túl nagy tudást igényelt.
Lehet egyedül is játékot fejleszteni viszont a fennakadások elkerülése miatt jobb egy laza közösség.
Ilyen az XNA Creators Club , aminek a magyar változataként felfoghatjuk a devportal szakmai
közösségét
Négy nagyon fontos szempontot fogalmaztak meg a közösségi játékfejlesztéssel kapcsolatban:
1. bárki fejleszthessen játékokat,akinek van egy jó ötlete
2. könnyen megoszthassuk egymással
3. értékelni is lehessen őket
4. akár el is lehessen adni
Az XNA Framework a .NET része, és egy nagyon egyszerűen használható, de mégis nagyon hatékony
fejlesztő eszköz.
A recept egyszerű:
-fejlesszünk játékot
-nem érdekel senkit miért bonyolult konzolra fejleszteni
-legyen olyan mint a .NET , lehetőleg problémamentes a hasonló megoldásokkal szemben
-ugyan az a kód fusson mindenhol. PONT.
-ne kelljen mindenféle segédprogramot írkálnunk ahoz, mert összeakarunk dobni egy supermariot,
vagy egy gyors hálózati játékot.
-managelt kód használatával sokkal könnyebb a fejlesztés
Rendszerkövetelmények:
Software
Visual Studio 2008 Express Edition
Visual Studio 2008 Standard Edition
Visual Studio 2008 Professional Edition
Visual Studio 2008 Team Edition
Hardware:
minimum:
shader model 1.1
ajánlott:
shader model 2.0
A legmagasabb shader model verzió amit az XNA támogat, az a shader model 3.0
Ennek egyszerű az oka, az Xbox 360ban található videokártya is ezt tudja, és a kompatibilitás miatt
van ez a korlátozás.
Xbox 360 GPU ( Xenos ) rövid leírás
Xbox 360 GPU ( Xenos ) részletes leírás
XNA Game Studio 3.1
Letöltés
megjegyzés:
a 3.1 abban tér el a 3.0tól, hogy már wmv formátumú videókat is tudunk importálni )
Tipp: ha nagyon gyenge a géped a fejlesztéshez, akkor jobb választás lehet egy Xbox 360 konzol,
mivel lassan egy közepes videokártya áráért kapható.
A tutorialban szereplő anyagok Visual Studio 2008 Professional Edition alatt lettek fejlesztve.
Támogatott platformok:
Ttámogatott operációs rendszerek: Windows Vista , Windows 7 , Windows Xp)
Zune (jelenleg csak 2d támogatás)
Vágjunk bele!
Ha Zune-ra vagy Xbox 360-ra szeretnénk fejleszteni, akkor ki kell engednünk a tűzfalon a Game
Studio-t, amit alapesetben a telepítő elvégez helyettünk.
Azért, hogy elkerült a későbbi kellemetlenségeket itt a port lista, hogy melyik portokat kell
kiengedned a tűzfalon, hogy minden szépen működjön
Ellenőrizzük még egyszer, hogy mindent feltelepítettünk, ami a fejlesztéshez szükséges.
Visual Studio
XNA Game Studio 3.0
a videokártya driverek fenn vannak
az Xbox / Zune csatlakoztatva van a hálózatra
Xbox,illetve Zune párosítása
Konzolt a device centerben tudunk párosítani. Ha megnyitunk egy új windows game projectet,
alapból nem fog megjelenni a device center gombja, csak ha létrehozunk egy Xbox vagy Zune
példányt a projectünkből.
Akár több eszközt is hozzáadhatunk, ilyenkor mindig ki kell választani azt, amire fordítani szeretnénk.
Fontos:
Ha nem pc-re fejlesztünk, akkor mindenképp kell egy Live id. Sajnos a Live Magyarországon jelenleg
nem elérhető. Ezt a problémát úgy tudjuk áthidalni, hogy egy másik országba regisztráljuk be az
azonosítónkat, mintha ott laknánk. Ennek a hátrányai közé tartozik, hogy az adott nyelvűre fog
változni a menü, illetve az ott hivatalos pénznemben tudunk fizetni a szolgáltatások használatáért.
A konzol neve mindegy, azt írunk be amit akarunk. Arra szolgál csak, hogy el tudjuk dönteni, melyik
gépet adtuk hozzá.
A Connection Key-t az Xbox generálja, ezt onnan kell beírnunk, és kész is vagyunk!
Előnyök a konkurens megoldásokkal szemben:
A legtöbb gyártó, mivel a különböző konzolokat mindenki veszteségesen állítja elő, nem szeretne
mindenkit a mézes bödön közelébe engedni, ezért elég komoly összegekhez szokta kötni a fejlesztést.
Azaz aki be akar törni a piacra, annak bizony kemény összegeket kell letennie az asztalra, és általában
elég kevés támogatást kap hozzá.
A konkurens megoldásoknál gyakran egy külső hardware is szükséges a fejlesztéshez, ami
feleslegesen bonyolítja és nehezíti a fejlesztést, aminek hiányában vagy nem kapunk teljes körű
tesztelési lehetőségeket, vagy egyáltalán nem tudunk fejlesztést végezni.
Ezeknek az eszközöknek a célközönsége a profi játékstudiók. Az XNA célközönsége teljesen más, a
hobbifejlesztőket és a játékosokat célozza meg. Pont ezért Pcre teljesen ingyenes!
Xbox és Zune consolera oktatási céllal ingyenes(tehát mindenki elérhet MSDNAA programból egy
prepaid kódot, amivel 1éves trial előfizetést kap) egyébként évente 99$ az előfizetés.
A 99$ persze nem csak arra jogosít fel minket, hogy használjuk a szolgáltatást, hanem lehetőséget
biztosít a játékaink ingyenes publikálására és eladására, a Microsoft Xbox Live szolgáltatásán
keresztül.
Egészen pontosan a bevétel 70%-a jut a fejlesztő kezébe, amivel a cél a hobbifejlesztők és hallgatók
ösztönzése.
Egy nagyon fontos célkitűzés:
Végre bárki fejleszthet játékot, aki érez magában kellő bátorságot, és a programozói tudása is adott
ehhez. Ez azért fontos, mert a nagy csapatok megjelenésével eltűntek a kis hobbifejlesztők a
köztudatból.
Mióta megjelent az XNA , a Dream Build Play sikere is bizonyítja, hogy nem csak sok milliós
költségvetéssel rendelkező csapat készíthet jó játékot.
ISMERKEDÉS AZ XNA-VAL
Először barátkozzunk meg pár alapfogalommal, és az XNA működésével.
„Hello XNA” Project Először is készítsük el a legelső projectünket, az úgy nevezett „Hello World” projectet.
1. Kattintsunk a Visual Studio 2008-ban File menüpontra, majd a New Project…-re.
2. Válasszuk ki a bal oldali Project Types listából a Visual C#-ot, és azon belül az
XNA Game Studio 3.0 elemet.
3. Győződjünk meg arról, hogy a jobb felső sarokban a .NET Framework 3.5 van kiválasztva!
Tegyünk egy kis kitérőt a Template-ek miatt:
A New Project ablakunkban template-ek kavalkádjával találkozhatunk. Ezzel segítenek minket a
fejlesztők. Természetesen kezdhetünk egy teljesen üres C# projectet is, és csak azokat a
referenciákat, namespace-eket, stb. adjuk a projectünkhöz hozzá, amire pontosan szükségünk van,
ám sokkal egyszerűbb (és célszerűbb), ha a kezünkbe adott meglévő üres XNA Game Template-ket
kezjük el használni.
Az Xbox 360 projectet akkor célszerű választanunk, ha például a PC-nkben olyan „gyenge” a
videokártya, hogy esélyünk sincs arra, hogy először normális Windows alkalmazásként futassuk a
játékunkat,de rendelkezünk egy konzollal.
Fontos tudnivaló:
Általánosságban az mondható el, hogy azon játékaink, amik futnak a PC-nken, azok futnak az
Xbox-on is. (A 2D, illetve a 3D egyaránt!)
Néhány esetben viszont lassabb lehet az Xboxon futtatható kód, ez akkor fordulhat elő,ha
valami olyasmit műveltünk amit a Compact Framework „nem szeret”.
A New Project ablakban a Templatek közt láthatunk még egy Platformer Starter Kit 3.0 nevű
templatet is. Ez gyakorlatilag egy egyszerű „Super Mario szintű” játék, amiben a 2D grafika alapjaival
ismerkedhetünk meg, egy szép rendezett és objektumorientált kódon keresztül.
(Természetesen nem ez az egyetlen Starter Kit, ami létezik, mivel a Microsoft folyamatosan ad ki
Starter Kit-eket az XNA-hoz! Erre a későbbiekben fogunk kitérni részletesen!)
4. A jobb oldali Templates listából válasszuk ki a Windows Game (3.0) -t .
5. Írjuk be a Name mezőbe azt, hogy XNATutorial.
6. Legyen a Create directory for solution checkbox kipipálva.
7. Kattintsunk az OK gombra!
Nézzünk bele a kódunkba! (Game1.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
Ha megnézzük az első néhány „using”-ot, mi jut eszünkbe?
Használhatjuk a C# 3.0 nyelvi elemeket, ami nagyszerű hír, hiszen rendelkezésünkre áll
rengeteg új kényelmes szolgáltatás, mint például a Linq.
Miért fogjuk szeretni az XNA-t?
Mert mindent megkapunk, amire szükségünk lehet egy jó játék elkészítéséhez! Minden olyan
eszközt megkapunk,amit sok esetben nekünk kéne megírni, illetve problémás lenne a
használata pl.:hálózati modul
Nagyban leegyszerűsödik a multi-platform fejlesztés, és kezdőknek szintén előnyös, hogy a
kód szinte „beszél” .
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
...
}
Az első fontos osztály amivel találkozunk, a GraphicsDeviceManager. Ezen keresztül tudjuk a
videokártyát vezérelni.
Ilyen vezérlés alatt értjük például azt, hogy:
a felbontást változtathatjuk,
bekapcsolhatjuk az élsimítást,
illetve utasítjuk a videokártyát a kép kirajzolására.
Nyugodtan mondhatjuk, hogy ez a „legfontosabb” osztályunk, hiszen ha nem szólunk a
videokártyának, akkor bizony nem fog semmit sem kirajzolni a képernyőre!
A második dolog amivel találkozunk, az a SpriteBatch osztály lesz.
Fontos tudnivaló:
Sprite alatt a számítógépes grafikában, egy nagyobb scenebe foglalt 2D, vagy 3D képet
értünk.
A 2D játékoknál Sprite-okat fogunk rajzolni. (Ilyen például a játékos, az ellenség, a terep, a
háttér, stb.)
Nézzük meg, hogy épül fel a játékciklusunk:
Tehát, a következő kódrészlet az inicializálás, az Initialize metódusba kerül minden nem grafikus
tartalom.
Például:
AI
a képernyő fejlécébe írt szöveg
legyen látható az egér ( mert fejlesztéskor zavaró lehet, hogy az ablakba húzott kurzor eltűnik)
protected override void Initialize()
{
Window.Title = ("Hello XNA");
IsMouseVisible = true;
base.Initialize();
}
A LoadContent metódussal töltjük be az összes grafikus elemet.
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}
Grafikus elemnek számítanak a Shader fileok, a képek, a modellek (fbx formátum), az audio fileok, az
X fileok, és az XML fileok.
A templateünkben létrehozott egy SpriteBatch példányt arra használjuk, hogy ki tudjuk rajzolni a
Content Manager segítségével betöltött fileokat.
Ha nem állítottuk át, akkor a Content Pipeline root directorya a ”Content” mappa lesz,ami az
alapbeállítás.
Az itt található grafikus tartalmakra, elég a relatív elérési utat kiírni.
Ennek a menete:
1. Betöltjük a grafikus tartalmakat.
2. Visszatérünk a játékciklushoz a betöltött grafikus tartalmakkal.
3. Ha már nincs szükség valamire, akkor az UnloadContent metódusban kidobhatjuk.
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
Az üres templateünkben, csupán a képernyő hátérrszínét állítottuk be. Ha
kiakarunk rajzolni egy spriteot, akkor a SpriteBatch osztály
SpritaBatch.Begin és SpriteBatch.End függvényére lesz szükségünk.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
base.Draw(gameTime);
}
Összegzés röviden:
-az új XNA projectünk a kötvekezőképp épül fel:
-update / draw cikikusan fut
-initialize a különböző beállításokat érvényesítjük
-load graphics betöltjük a képeket és egyéb
dolgokat(modellek,hangok stb)
-unload content felszabadítjuk a memóriát
VISUAL STUDIO
Mielőtt komolyabb dolgokkal kezdünk foglalkozni, tegyünk egy kis kitérőt. Ez a fejezet mindenkinek
szól aki, aki még nem rég kezdett. NET technológiákkal foglalkozni, esetleg eddig Turbo Cvel kínozták
az egyetemen, és vagy csak nem tudják megfelelően a Visual Studiot használni, esetleg az összes jó
tanács annyi volt számukra, hogy „használt Visual Studiot, mert az neked jó”
Folytassuk ott, ahol az előbb abbahagytuk. Van egy üres templateünk, amit tovább szeretnénk írni.
Hogy néz ki a Game1 osztályunk?
Mindenki látott már ilyen szép ábrákat, de sokan nem tudják, honnan vannak, vagy hogy lehet őket
generálni…sokan külső programra gyanakodnak ,de nem így van.
Fontos információ:
Ha valaki Visual Studio 2008 Express-t használ, akkor ez az osztálynézet funkció sajnos nem elérhető
számára, csak a Professional Editiontől része a Visual Studionak a Class Viewer.
Természetesen minden egyetemista számára, a saját egyeteme MSDNAA rendszeréből ingyen
hozzáférhet a komolyabb verzióhoz.
Tipp: ha nem vagy jártas az objektumorientált programozásban, vagy csak nem szeretnél sokat írni,
esetleg nem tudod, hogy adhatsz hozzá pl. egy Eventet akkor hagyd, hogy segítsen a Visual Studio.
1.lépés
Hozzuk be a ClassViewert.
2.Lépés rajzoltassunk osztálydiagramot.
A következőt látjuk:
Pl. hozzunk létre új osztályt
(természetesen még nagyon sok dolgot csinálhatnánk hasonló módon)
Egyszerűen húzzunk át egy új osztályt a toolboxból és adjuk meg a nevét.
Ha rákattintottunk az OK-ra, létrejön az új osztályunk, és ez a ClassVierben is szépen megjelenik.
Amint látjuk, ez az osztályunk még teljesen üres.
Adjunk hozzá egy új property-t!
Most már rengeteg diagramot és egyéb ábrát láttunk, nézzük meg mit írt helyettünk a Visual Studio.
Az eredmény:
1.Létrejött a player osztály, egy player.cs file-ban.
2. megjelent az osztálydiagram file-unk.
Mi van a player.cs-ben?
namespace WindowsGame2
{
public class player
{
public int player
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
}
}
A másik jó barátunk az IntelliSense.
Ha valamit nemtudunk, bátran csapkodjuk a CTRL+SPACE-t
Ha valahol nem vagyunk biztosak mit írjunk, csak vigyük fölé az egeret, a Visual Studio majd segít, és
megmondja mit vár tőlünk.
Biztosan mindenkivel előfordult már tanfolyamon, vagy előadáson olyat, hogy amíg lepillantott a
billentyűzetre, addig hirtelen felkerült a kivetítőre egy tonna kód. Ebben természetesen semmi
ördöngösség nincs, valószínűleg csak az oktató jól ismeri a Visual Studiot, és kicsit gyorsított a
folyamatokon.
Most megnézünk pár egyszerű dolgot, hogy tehetjük gyorsabbá és hatékonyabbá a fejlesztést.
Pl.
Elfelejtettünk egy névteret usingolni, akkor nem az a megoldás, hogy bepötyögjük! A visual studio
jelezni fogja, hogy amit használni szeretnénk, az ugyan létezik, de nincs usingolva névtér. Ha fölé
visszük az egeret, lehetőséget fog adni arra, hogy ezt most megtegyük, de még gyorsabb ha a CTRL + .
kombinációt használjuk.
Persze az is lehet, hogy pont olyan dolgok vannak benn amire nincs szükségünk, viszont egyáltalán
nincs kedvünk és időnk arra, hogy kiválogassuk ezeket egyesével. Ekkor a megoldás, hogy szintén egy
gomb kombinációt használunk. Az unused namespacek eltávolítására default nincs gomb beállítva,
ezért ezt nekünk kell megtennünk.
A Tools -> Options -> Keyboard menüben keressük meg az Edit.RemoveUnusedUsing opciót, és
adjunk hozzá egy gyorsbillentyűt. Ilyen egyszerű az egész.
További gyorsbillentyűket is használhatunk természetesen ezeken kívül. A legtöbb hasznos funkciót a
készítők előre egy gyorsbillentyűre tették. Célszerű a gyakran használtakat megjegyezni.
Visual Studio 2008 Hotkeys
Edit
Edit.CollapseTo-Definitions CTRL + M, O
Edit.ToggleAllOutlining CTRL + M, L
Edit.ToggleOutliningExpansion CTRL + M, M
Edit.StopOutlining CTRL + M, P
Edit.CommentSelection CTRL + K, C or CTRL + E, C
Edit.UncommentSelection CTRL + K, U or CTRL + E, U
Edit.FormatDocument CTRL + K, D or CTRL + E, D
Edit.FormatSelection CTRL + K, F or CTRL + E, F
Edit.InsertSnippet CTRL + K, X
Edit.SurroundWith CTRL + K, S
Edit.InvokeSnippetFromShortcut TAB
Edit.CycleClipboardRing CTRL + SHIFT + V
Edit.Replace CTRL + H
Edit.ReplaceInFiles CTRL + SHIFT + H
View.ShowSmartTag CTRL + . Or SHIFT + ALT + F10
File
File.NewProject CTRL + SHIFT + N
File.OpenProject CTRL + SHIFT + O
Project.AddClass SHIFT + ALT + C
Project.AddExistingItemSHIFT + ALT + A
Project.AddNewItem CTRL + SHIFT + A
Window.ShowEzMDIFileList CTRL + ALT + DOWN ARROW
Edit.OpenFile CTRL + O
Intellisense ( ha közben lenyomjuk a CTRL gombot, átlátszóvá válik a lenyíló ablak )
Edit.CompleteWord CTRL + SPACE or CTRL + K, W
Edit.ListMembers CTRL + J or CTRL + K, L
Edit.QuickInfo CTRL + K, I
Edit.ParameterInfo CTRL + SHIFT + SPACE or CTRL K, P
Make Completion List Transparent CTRL
Navigation
Edit.FindAllReferences SHIFT + F12 or CTRL + K, R
Edit.GoToBrace CTRL + ]
Edit.GoToDefinition F12
Edit.GoToNextLocation F8
Edit.IncrementalSearch CTRL + I
View.ClassViewGo-ToSearch, Combo CTRL + K, CTRL + V
View.ForwardBrowseContext CTRL + SHIFT + 7
View.PopBrowseContext CTRL + SHIFT + 8
View.NavigateBackward CTRL + MINUS SIGN (-)
View.NavigateForward CTRL + SHIFT + MINUS SIGN (-)
Edit.FindInFiles CTRL + SHIFT + F
Edit.FindSymbol ALT + F12
View.ViewCode F7
View.ViewDesigner SHIFT + F7
View.ViewMarkup SHIFT + F7
Window.MoveToNavigationBar CTRL + F2
Edit.Find CTRL + F
Edit.GoTo CTRL + G
Edit.GoToFindCombo CTRL + /
Window
View.ClassView CTRL + W, C
View.CodeDefinitionWindow CTRL + W, D
View.Command-Window CTRL + W, A
View.ErrorList CTRL + W, E
View.ObjectBrowser CTRL + W, J
View.Output CTRL + W, O
View.PropertiesWindow CTRL + W, P
View.SolutionExplorer CTRL + W, S
View.TaskList CTRL + W, T
View.Toolbox CTRL + W, X
View.ServerExplorer CTRL + W, L
Window.CloseToolWindow SHIFT + ESC
Data.ShowDataSources SHIFT + ALT + D
Window.CloseDocument, Window CTRL + F4
Window.NextDocument, WindowNav CTRL + TAB
Refactor
Refactor.EncapsulateField CTRL + R, E
Refactor.ExtractInterface CTRL + R, I
Refactor.ExtractMethod CTRL + R, M
Refactor.PromoteLocalVariabletoParameter CTRL + R, P
Refactor.RemoveParameters CTRL + R, V
Refactor.Rename CTRL + R, R or F2
Refactor.ReorderParameters CTRL + R, O
Debugging
Debug.Autos CTRL + D, A
Debug.CallStack CTRL + D, C
Debug.Immediate CTRL + D, I
Debug.Locals CTRL + D, L
Debug.QuickWatch CTRL + D, Q
Debug.Start F5
Debug.StartWithoutDebugging CTRL + F5
Debug.StepInto F11
Debug.StepOut SHIFT + F11
Debug.StepOver F10
Debug.StopDebugging SHIFT + F5
Debug.ToggleBreakpoint F9
Debug.Watch CTRL + D, W
Debug.EnableBreakpoint CTRL + F9
Make Datatip Transparent [CTRL]
Build
Build.BuildSolution F6 or CTRL + SHIFT + B
Build.BuildSelection SHIFT + F6
A következő linkről tudjuk letölteni a Visual Studio 2008 Hotkey Postert ahol minden hotkey szerepel.
Érdemes kitapétázni vele a szobát
Visual Studio 2008 Hotkey Poster
SPRITE
Most, hogy már tudjuk mi mit csinál, kicsit nyúljunk mélyebben a kódunkba. A feladat a következő lenne. Fogjunk egy spriteot, és rajzoljuk ki a képernyőre. Pár alapvető dologra lesz szükségünk ehez: A sprite az egy egyszerű kép, amit egy nagyobb 2d vagy 3d scenebe rakunk. Szóval csak fogunk egy képet, kirajzoljuk tologatjuk.. elforgatjuk.Ilyesmik Mi a frame, és a framerate? Mikor meghívjuk a draw függvényt, akkor kirajzolunk valamit a képernyőre.Ha egyszer fut le akkor egy framet. Ha sokszor egymás után rajzolunk ki dolgokat,és mindig egy kicsit mást,akkor úgy fog kinézni, mint mikor kisgyerekként egy füzetbe animációt rajzoltunk és végigpörgettük Ez lesz a framerate. Mikor másodpercenként 60szor töröljük le és rajzoljuk újra a képet, a framerate 60fps, amit már szép folyamatos képnek lát a szemünk. Így keltjük azt az illúziót, hogy a karakterünk mozog a képernyőn. Mivel tárolni szeretnénk a képet, mondjuk azt, hogy ez egy 2D textura. Adjuk hozzá a képet a projectünkhöz. Szerencsére nincs szükség semmiféle varázslatra, csak a Content Managgerre..:) és néhány kattintásra. Ennyi az egész. Ha a Content mappán belül,nemcsinálunk külön könyvtárstruktúrát, akkor egyszerűen a file nevével hivatkozhatunk a betöltött tartalomra, egyébként pedig a Content Root directorynál megadott úthoz való relatív elérési utat kell beírnunk.
Ha ezzel megvagyunk, és sikeresen hozzáadtuk a képet, akkor a következőt kell látnunk.
Egykis előretekintésként megnézhetjük a tulajdonságait a fileunknak.Ha esetleg rosszul ismerné fel a file típusát, kézzel is nyugodtan átállíthatjuk.
Nagyszerű, már van egy 2D texturánk, de hol is fog ez megjelenni? és hogy ? Természetesen ha Windows alatt vagyunk, vagy Xboxra fejlesztünk, elfog térni egymástól az ablak és a képernyő koordinátáinak széle. Xboxon és Zune konzolon ez megegyezik, tehát az ablak széle megegyezik a képernyő szélével.
A következő amit még megkell írnunk, a sprite kirajzolása. A SpriteBatch osztályt használjuk, ami a framework része, úgyhogy ezzel sem lesz problémánk. Mindent amit rajzolunk, Begin() és End() közé teszünk.
spriteBatch.Begin()
…
spriteBatch.End()
Ha eközött meghívjuk simán a kép kirajzolását, és nemrendelünk hozzá semmiféle koordinátát, akkor a képernyő bal felső sarkába fogja tenni a spriteunkat.
Most azt szeretnénk, hogy középre rajzolja ki, viszont nemtudjuk mekkora az ablak, meg egyébként is..lehet más felbontásban fogja valaki más megnézni, úgyhogy használjunk arányokat. Ha elkezdjük írni a kódot, a visual studio írni is fogja, ,hogy a spriteBatch.Draw milyen paramétereket vár. Ide írjuk be a 2d texturánk nevét, és a pozícióját is.
spriteBatch.Begin();
spriteBatch.Draw(mehecske,new Vector2((Window.ClientBounds.Width / 2)
- (mehecske.Width / 2),(Window.ClientBounds.Height / 2) -
(mehecske.Height / 2)),Color.White);
spriteBatch.End();
megjegyzés:fehér esetén nem színezünk semmit.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace newgame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D mehecske;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
mehecske = Content.Load<Texture2D>("mehecske");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed) this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.GreenYellow);
spriteBatch.Begin();
spriteBatch.Draw(mehecske,new
Vector2((Window.ClientBounds.Width / 2) - (mehecske.Width /
2),(Window.ClientBounds.Height / 2) - (mehecske.Height / 2)),Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
INPUTKEZELÉS
Billentyűzet:
Az inputkezeléshez, az XNA Keyboard osztályát fogjuk használni, ami a
Microsoft.XNA.Framework.Input névtérben található meg.
A Keyboard osztály egy statikus methódusán (GetState) keresztül tudhatjuk meg a billentyűk
állapotát.
Pl. ha arra vagyunk kíváncsiak, hogy egy adott betűt lenyomtak e , akkor a következőt tehetjük:
if (Keyboard.GetState().IsKeyDown(Keys.A))
// és erre reagálunk valamit, pl kilépünk az alkalmazásunkból
this.Exit();
Feladat: írjunk egy kicsit összetettebb inputkezelő függvényt, és módosítsuk úgy az előző
kódunkat, hogy a spriteot irányítani tudjuk a képernyőn, de továbbra se hagyja el az ablakot!
Ehhez egy kis segítség:
public void inputhandler() {
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.Left))
beePosition.X -= beeSpeed;
if (keyboardState.IsKeyDown(Keys.Right))
beePosition.X += beeSpeed;
if (keyboardState.IsKeyDown(Keys.Up))
beePosition.Y -= beeSpeed;
if (keyboardState.IsKeyDown(Keys.Down))
beePosition.Y += beeSpeed;
}
Ne felejtsük el meghívni
Egér:
Az egér kezelése, nem túl meglepő módon még sokkal egyszerűbb, mint a billentyűzetkezelés. Mivel
a képernyőn kell mozognunk, ezért csak két koordinátánk lesz, ami a kurzor aktuális helyzetét
mutatja.
void SetPosition(int x, int y)
Ezen kívül természetesen tudunk kattintani, tehát az egér gombjait is kezelnünk kell valamilyen
formában.
Feladat: módosítsuk az előző kódunkat úgy, hogy az egérrel is irányítani tudjuk a spriteunkat.
Egy kis segítség:
MouseState mouseState = Mouse.GetState( );
if(mouseState.X != prevMouseState.X ||
mouseState.Y != prevMouseState.Y)
beePosition = new Vector2(mouseState.X, mouseState.Y);
prevMouseState = mouseState;
Gamepad:
Biztosan mindenki kitalálta, ha egér és billentyűzet kezelő osztály is volt már, akkor lesz egy a
gamepadhoz is.
Ha veszünk egy kontrollert a PC-hez, akkor nemcsak Xboxon, hanem rögtön a gépen is tesztelhetjük
az irányítást. Azért is érdemes beszerezni egyet, mert autós játékkal sokkal élvezetesebb így játszani,
ugyanis amíg a billenyűzet az egy digitális eszköz a kontroller anológ, és a stickel könnyebb az
irányítás, mert vannak fokozatok és nem csak két végállapot.
Ami megbonyolítja a dolgot picit, az hogy ilyennel találkoztunk, mint PlayerIndex. Egy játékkal egyszerre egy Xboxon 4ember játszhat, 4 kontrollerrel. Ezeket jelöljük sorba Nézzük a kódot. Először megvizsgáljuk, hogy az A gombot lenyomták , vagy sem. Ha igen, akkor a méhecskénk hirtelen zümmögni kezd, a kontroller rezeg és 2szer olyan gyorsan halad tovább… ha elengedjük, akkor kikapcsolódik a vibráció, és újra normál sebességgel fog repülni. GamePadState gamepadState = GamePad.GetState(PlayerIndex.One); if (gamepadState.Buttons.A == ButtonState.Pressed) { beePosition.X += beeSpeed * 2 * gamepadState.ThumbSticks.Left.X; ringsPosition.Y -= ringsSpeed * 2 * gamepadState.ThumbSticks.Left.Y; GamePad.SetVibration(PlayerIndex.One, 1f, 1f); } else { ringsPosition.X += ringsSpeed * gamepadState.ThumbSticks.Left.X; ringsPosition.Y -= ringsSpeed * gamepadState.ThumbSticks.Left.Y; GamePad.SetVibration(PlayerIndex.One, 0, 0); } TouchPad A Zune , az egy keményebb tészta, ugyanis két lehetőségünk van. Egy nehezebb, és egy könnyebb.A könnyebb lehetőség, hogy a touchpadot hagyományos gombként használjuk, ekkor ugyan úgy viselkedik mintha a GamePadot használnánk. A másik lehetőség, ami játékélmény szempontjából sokkal előnyösebb, ha TouchPadként használjuk. Ebben az esetben persze sokkal több problémát kell megoldanunk, és rengeteg állapotot kell kezelnünk.
ANIMÁLT SPRITEOK
A recept egyszerű, attól függően, hogy mi történik, le kell játszanunk valami egyszerű animációt. Az
itt látható képen, pl. a Prince of Persia főhősének mozdulatai láthatók. Még egy egyszerű 2d játéknál,
is rengeteg dolgot kell, animálunk. Szerencsére annyira nem vészes a helyzet, mint ahogy látszik, és
viszonylag szépen megtudjuk oldani ezt a problémát.
Két fajta animált spriteot tudunk elképzelni, az egyiket a játékos irányítása alatt áll, az egyik pedig
tőle független. Pl. a pályán található Healing/Mana italok.
Mi most egy nagyon egyszerű példát fogunk venni, és közben felhasználjuk azt, amit már eddig
megtanultunk.
Vegyünk egy 2D Texturát, ami ebben az esetben olyan mint egy dia film, amit leszeretnénk játszani.
Ez egy nem a játékos által kontrollálható sprite lesz.
Felveszünk még mellé egy timert, ami az időt számolja. Ennek függvényében fogunk „lapozni” és
másik képkockára lépni. Most ez azt jelenti, hogy 25fpsel történik az animáció lejátszása.
Texture2D spriteSheet;
float timer = 0f;
float interval = 1000f / 25f;
A frameCount az összes frame számát jelöli, azaz most 16 frameből áll az animációnk, a currentFrame
pedig azt mutatja, hányadik framenél tartunk.
int frameCount = 16; int currentFrame = 0;
A frame szélességét és magasságát jelöljük, és a pozícióit.
int spriteWidth = 64;
int spriteHeight = 64;
Rectangle sourceRect;
Rectangle destinationRect;
Létrehozunk egy új SpriteBatch példányt,és betöltjük a Content mappába az explosion.tif filet. Kiterjesztést nem szükséges írnunk,az XNA magától fel fogja ismerni mivel van dolga.
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spriteSheet = Content.Load<Texture2D>("sprite_sheet");
destinationRect = new Rectangle(0, 0, spriteWidth,
spriteHeight);
}
Az update függvényt pedig egészítsük ki egy kicsit, az eltelt idő mérésével.
protected override void Update(GameTime gameTime)
{
float deltaTime =
(float)gameTime.ElapsedGameTime.TotalMilliseconds;
timer += deltaTime;
animate();
base.Update(gameTime);
}
Ellenőrizzük, hogy az épp aktuális frame, az utolsó frame vagy sem. Ha az utolsó, akkor reseteljük az
animációt és elölről kezdünk számolni , és kiírjuk a
public void animate()
{
if (timer > interval)
{
currentFrame++;
if (currentFrame > frameCount - 1)
{
currentFrame = 0;
}
timer = 0f;
}
sourceRect = new Rectangle(currentFrame * spriteWidth, 0,
spriteWidth, spriteHeight);
Window.Title = "Current Frame: " + currentFrame.ToString();
}
Végül az egészet kirajzoljuk a képernyőre.
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.Black);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(spriteSheet, destinationRect, sourceRect,
Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
ÜTKÖZÉSVIZSGÁLAT A 2d ütközésvizsgálat elég egyszerűen megoldható a 3Dhez képest.
Mi most csak az egyszerű eseteket fogjuk nézni, tehát vagy „Bounding box” vagy „Per pixel”
ütközésvizsgálatot fogunk végezni.
A spriteunkat mindig egy négyszög veszi körbe,mert egy képről van szó, úgyhogy ha azt vizsgáljuk,
hogy két objektum ütközött e, ez a legegyszerűbb eset,de annyira nem szerencsés megoldás ha pl két
kört szeretnénk ütköztetni.
Pl: A és B valójában még nem ütközött,de a programunk aztmonndja, hogy igen.
Itt két bitmapot nézünk, és ha átfedés van a két kép között akkor ütköztek egymással.
Ennél persze ügyesebb megoldást is kitalálhatunk.
Ha apróbb részletekben vizsgálnánk meg, hogy tényleg történt e ütközés, az már pont megfelelne.
Mivel a pixel a legkisebb dolog ami a képernyőn megjelenik, így adott a megoldás. Nézzük meg
pixelenként, hogy a két objektumunk mikor találkozott igazból.
Ez azért jó nekünk, mert sokszor apró dolgokat vizsgálunk, pl.(egy rakéta eltalálta a hajót), és ebben
az esetben az előző megoldás nem túl szerencsés,mert mindenki kifogja szúrni,hogy még egymáshoz
sem ért a két objektum de már ütközés történt.
Mi az alpha csatorna?
Egy kép átlátszóságát tartalmazó fekete-fehér (általában 8 bit-es) "szín"-csatorna.
Így már könnyen összehasonlíthatunk két spriteot, és elvégezhetjük az ütközésvizsgálatot, hogy
tudjuk melyik a kép melyik része átlátszó.
Ugyan ezt lekódolva,itt találjátok(vagy a csatolt projectek közt használat közben):
Per Pixel Collision
Ez az írás hamarosan kiegészül a következő témákkal:
- XACT audio tool
- egyszerű játéklogika
- szöveg kiiratása
- részletes leírás a content pipelineról
- grafikus fogalmak
- játékfejlesztés Zune-ra.
- illetve a már meglévő témák közül néhány bővülni fog részletesebb leírásokkal
Felkerül több kis játék forráskódja
Mivel ez még nem egy végleges anyag, arra szeretnélek kérni, ha hibát találsz benne, kérlek, jelezd
e-mailbe, hogy a következő verzióban javíthassam.
Pellek Krisztián
Microsoft-SP
2009.04.26