THOMAS LIVLIG: Okay.
Hej alle sammen.
Jeg er Thomas Lively.
Dette seminar vil være skrive 2D spil i C ved hjælp af SDL.
Så jeg ved, du er alt spørger, yeah, jeg virkelig
ønsker at spille spil og lave spil, men hvad er det SDL virksomhed?
Så SDL er en C-biblioteket.
Det står for Simple DirectMedia Layer.
Og det er en cross-platform, spiludvikling bibliotek.
Det virker på Windows, Mac Linux, selv iOS og Android.
Den håndterer ting som adgang til lydsystemer
for computeren, tastaturet og mus, joysticks, hvis de er tilknyttet.
På mobil, kan det endda gøre det røre input og alt dette.
Og selvfølgelig, det håndterer grafik, tegning ting til skærmen.
>> Så det er meget udbredt, selv om du måske ikke har hørt om det før.
Det er indbygget i, for eksempel, Valves kilde motor,
hvilke beføjelser spil som Portal og Team Fortress 2.
Det er også i et meget stort antal af indie-spil, der kommer ud,
så jeg er spændt på at se, hvad du alle vil være at gøre med det.
>> Seminaret mål er at få dig satte sig for at udvikle med SDL.
Vi kommer til at lære, hvordan at skabe et spil vindue.
Vi kommer til at skabe sprites, som er de billeder i dit spil
der kan bevæge sig rundt.
Vi kommer til at lære, hvordan til og animere de sprites,
så flytte dem rundt, gør dem ændre sig over tid.
Og vi kommer til at lære, hvordan at indfange tastatur og mus
input fra computeren.
Hvad vi vil ikke tale om i dag er 3D-grafik,
fordi det er en meget kompliceret emne, som vi ikke har tid til.
Vi vil ikke lære at afspille lyd på vores spil.
Og vi vil ikke bygge for noget men Linux.
>> Nu forbehold er, at Forhåbentlig ved udgangen seminaret,
vil du være fortrolig med SDL dokumentation,
så du vil være i stand til at gå finde ud hvordan man afspille lyd for dig selv.
Også bygning til Mac eller pc bør arbejde nøjagtig det samme som at bygge til Linux,
men opsætningen kommer til at være lidt anderledes.
Så du bør være i stand til at regne ud af, hvordan at gøre disse ting
ved udgangen af ​​dagens seminar.
>> Så for sat op, vil vi at anvende en virtuel maskine.
Vi ville bruge CS50 IDE, fordi vi bare kommer til at skrive i C.
Men da IDE ikke er en browser, vi kan ikke oprette nye vinduer eller display
grafik i det.
Så vi har brug for en virtuel maskine.
Så du kan følge instruktionerne her på manual.CS50.net/appliance/15
at installere de officielle CS50 apparatet, som blot er en Linux virtuel
maskine.
>> Og så når du har at alle sæt up-- det
kan tage et lille stykke tid, fordi en meget stor download-- du vil
at køre i VM sudo apt-get update.
Og det der virkelig foregår at opdatere al den software
pakker på din virtuelle maskine.
>> Efter dette, er du nødt til at køre sudo apt-get install, libsdl2-2.0-0,
libsdl2-dbg, libsdl2-dev, og derudover libsdl2-image-2,0-0,
libsdl2-image-dbg, og libsdl2-image-dev.
Så hvad betyder det så?
Der blot installerer debug information, dokumentation, overskrifter,
og binære filer til to biblioteker.
Regelmæssig gamle, SDL 2.0, og et andet bibliotek
kaldet SDL Billede, som vi kommer til at bruge
at indlæse billedfiler ind i vores spil.
>> Så når du har der også at, netop når den beder,
du bare skrive ja, tryk Enter at installere disse pakker,
og så skal du være god til at gå.
Så for at få distributionen kode, du can-- oh dear, er denne ikke opdateret.
Medmindre du har en GitHub account-- hvis du har en GitHub-konto,
du kan gøre dette Git klon kommando til repo
og det vil downloade Git repo med al koden i det,
så du har koden.
>> Hvis du ikke har en GitHub konto, hvad du skal gøre er at skrive
wgithttps: //github.com/tlively/sdl seminar-- og her er det different--
/archive/master.zip.
Så igen, det er nøjagtig den samme URL, bortset fra at det vil være
tlively / SDL_seminar / master.zip og du bruger wgit at hente det.
Og så kan du blot unzip at arkivet
og så vil du have alle kildekoden.
Så ked af det.
Og så koden vil også blive vært på det CS50 seminaret webside i et par
dage.
>> Okay.
Så hvordan kommer vi i gang skrive vores eget spil?
Nå, den første ting vi vil ønsker at gøre
er at se på den SDL dokumentation.
Så her er VM.
Og her er websiden.
Jeg har navigeret til at leve libsdl.org.
Hvad jeg har tænkt mig at gøre her er at gå over til indholdsoversigten under dokumentation,
og klik på wikien.
Dette vil bringe mig til wiki, der har de fleste af dokumentationen for SDL.
Over på sidebjælken her, vi er kommer til at klikke på API efter kategori,
fordi der vil give os en dejlig kategorisk visning
af hele API for SDL.
>> Så for eksempel, har vi den grundlæggende initialisering
og lukke ned, alle slags administrativ ting for at bruge SDL,
og så har vi den sektion for vise tingene til skærmen.
Det er video.
Input begivenheder, det er at få input fra tastaturet,
få input fra mus og joysticket, hvis du har det endnu.
Der er force-feedback for ting lignende spil controllere, som
Vi kommer ikke til at tale om.
Og her er lyd.
Og så er der en masse andre ting, som SDL kan gøre for dig.
>> Men i dag vil vi fokusere på initialisering her,
vise billeder i videoen sektionen, og håndtering input begivenheder.
Så dette er det vigtigste sektioner af dokumentation
at du skal bekymre dig om.
Bare for sjov, hvis vi gå over her og klik på API ved navn,
Vi kan se en liste over alle enkelt ting i SDL biblioteket.
Så alle disse funktioner, tællinger, strukturer, en vanvittig mængde ting,
alfabetisk orden.
Og klart, indtil du ved, du laver,
dette kommer ikke til at være alt for hjælpsom, hvilket er grunden til vi gør API efter kategori.
>> Så lad os komme i gang.
Forhåbentlig har du allerede downloadet fordelingen kode.
Og så hvad du kan gøre, er, højre her i CS50 apparatet,
blot åbne en terminal.
Nu sker det.
Så jeg har allerede downloadet den fordeling kode ved hjælp af .zip
metode.
Og jeg har pakket det.
Så her er det i SDL seminar mester.
Så jeg har tænkt mig at gå ind i denne mappe.
Og det, vi ser her er at vi har syv C-filer.
Og det kommer til at koden vi kommer til at se på i dag.
Vi har en makefile.
Og vi har en mappe ressourcer, som blot har et billede
at du vil være at se hurtigt nok.
>> Så lad os åbne disse filer ved hjælp af G-Edit editor.
Så jeg ønsker at åbne alle de filer, begynde med hello og slutte med .c.
Nu sker det.
Så det er et lille vindue, så vi er vil forsøge at gøre det større.
Nej, det gik væk.
>> Okay.
Så her er den allerførste fil vi vil se på.
Det hedder hello1_sdl.c.
Og alt dette gør, er at initialisere SDL bibliotek, så vi kan begynde at bruge det.
Hvordan ville du vide at komme op med denne kode dig selv?
Tja, hvis vi kigge over på dokumentation
og vi går ind initialiseringen og lukke ned afsnittet
det vil fortælle os alle om, hvordan man initialisere SDL.
Så absolut læse denne en anden gang.
Det kommer til at fortælle dig alt om, hvad der foregår her.
Men den vigtigste kerne er, at vi nødt til at kalde denne funktion SDL I Det
og videregive den, hvad slags ting vi ønsker, at biblioteket for at initialisere.
Så i vores tilfælde, vi bare at initialisere video for nu,
så vi kan begynde at vise billeder.
>> Herovre kan man se, om Vi klikker på en SDL i det, vi
kan få endnu mere information, herunder returværdien.
Så vi ser her, at det AFKAST nul på succes.
Så i vores kode, vil vi se, om det ikke vender tilbage til nul,
og hvis det ikke vender tilbage nul, så det var ikke en succes,
så vi vil blot udskrive en fejl ved hjælp af denne anden funktion,
SDL får fejl, der returnerer en streng beskriver den fejl, der opstod.
Vi kommer til at udskrive, at fejl og så er vi bare
kommer til at afslutte programmet med en fejlkode.
>> Så en anden ting, vi har brug for at gøre er, før programmet afsluttes,
hvis vi med succes initialiseret SDL, vi bare nødt til at kalde det SDL holde op.
Og det kommer til at håndtere oprydning alle SDL interne ressourcer til os.
Så dokumentationen there-- igen, her er vi i initialiseringen
og lukke ned sektion af dokumentationen.
Du kan blot klikke på funktion her, SDL holde op,
og du kan læse alt om, at så godt.
Og en masse af disse funktioner dokumentation sider
har fx kode, så det er meget god ressource.
Helt sikkert bruge lidt tid læse dele af denne wiki
hvis du vil gøre dette til et projekt.
>> Okay.
Så det er hele vores program.
Hvad vi kan gøre nu is-- jeg kommer til at åbne makefile her,
så jeg har tænkt mig at tage en se på, hvordan det fungerer.
Og det er en meget enkel makefile, ligner det, du har set før.
En af de væsentligste forskelle er, at her, det
kommer til at indsætte resultatet af driften denne kommando, som du har allerede
installeret, hvis du har installeret SDL.
Og det er en kommando der kommer til at generere
nogle ekstra flag for compileren.
>> Ud over det, vi giver det alle de sædvanlige kommandoer, samt
disse to kommandoer.
Så de -lsdl2-image håndtag forbinder i SDL billedbibliotek.
Og -lm faktisk håndterer linkning i standard C matematik bibliotek.
Så vi ikke vil få brug for dem for alle vores C filer,
men vi bare sætte dem i, så vi kan bruge den samme Makefile til alt
uden ændringer.
>> Herovre i kilder, det er her, du ville
sætte de filer, du var på vej at kompilere til dit projekt.
Men da hver eneste af mine C filer her har en hovedfunktion,
det kommer til at få forvirret hvis vi sætter dem alle i.
Så jeg har tænkt mig at bare sige, for nu, hello1_sdl.c,
som er den, vi bare kiggede på.
Så hvis jeg går tilbage over her, jeg kan gør.
Og hvad det gjorde, er det bare kompileret den første fil.
Og så kan vi skrive ./game, fordi det er den eksekverbare det produceret.
Og alt det gjorde var print initialisering succes.
Så vi gjorde noget rigtigt.
Men det var slags kedelige, fordi vi ikke se et vindue,
intet bevæger sig rundt.
>> Så stor, fik vi SDL initialiseret.
Lad os nu gå videre til noget lidt mere interessant.
Så her har vi hello2_window.c, og dette vil være en lidt mere
komplekse C program, initialiserer SDL ligesom før,
undtagen nu er vi også vil at initialisere SDL timeren.
Og det kommer til at lade os adgang til interne timer
og bruge funktioner vedrørende tid.
>> Og så lad os se hernede.
Det, vi gør, er at vi har denne pointer til en SDL vindue struct, som
vil blive skabt af denne indkaldelse til funktionen, SDL skaber vindue.
Nu, dette tager en masse argumenter, så lad os gå se på dokumentationen.
Så igen, vil jeg API efter kategori, er jeg
gå ned til video her, og den første sektion, viser vinduet ledelse.
Så denne sektion har et ton af ting i det,
men hvis man ser gennem disse funktioner, vil du
se, at nok den, vi ønsker kaldes SDL skabe vinduet,
hvilket sker for at være højre øverst.
>> Og så dette er den dokumentation for denne funktion.
Vinduet kommer til at have en titel, en x og y position på skærmen,
det kommer til at have en bredde, højde, og så det kommer til at tage nogle flag.
Nu behøver vi faktisk ikke bekymrer sig om nogen af ​​disse flag lige nu,
men hvis du ønskede at gøre noget ligesom foretage en fuld skærm vindue,
kunne du tage et kig på det.
For nu er vi bare at anvende disse særlige værdier,
SDL vindue plus centreret for x og y for
bare at lave vinduet i midten af ​​vores skærmen.
>> Så det er, hvad det laver.
Og hvis vinduet sker for at være null, hvilket betyder, der er en fejl,
derefter gang vi bare gå til udskrive fejl ved hjælp af SDL får fejl.
Og så fordi vi initialiseret SDL, vi nu nødt til at lukke den.
Så vi kalder SDL Afslut før returnere en til main.
>> Så vi har dette vindue åbnes forhåbentlig.
Og hvad vi vil at gøre, er vi vil
at kalde SDL for 5.000 millisekunder, hvilket er det samme som fem sekunder.
Og når vi er færdig med det, det kommer til at ødelægge vinduet,
rydde op i SDL-biblioteket, og afslutte programmet.
Så lad os gå videre og give det et skud.
>> Så nu i stedet for at ændre Makefile hver gang,
Jeg kan simpelthen gøre, og derefter på kommandolinjen,
siger kilder lig og derefter den fil, vi kompilere.
Så det er hello2_window.c.
Fantastisk.
Ingen erros.
Nu, hvis vi driver vores eksekverbare, vi ser dette vindue.
Nu er der et par problemer med vinduet.
Vi kan flytte den rundt, men det har denne baggrund junk inde i den.
Så har vi ikke trukket noget, og så det er
bare fuld af skrald, som er temmelig meget, hvad vi forventer.
>> Desuden kan vi ikke lukke vinduet.
Jeg trykker denne X i hjørne og intet sker.
Så vi vil se, hvordan du løser at der i en smule.
Så lad os løse den del, hvor Vinduet er fuld af skrald først.
Så hvis vi går over til hello3_image.c, hvad vi kan se, er, at vi har tilføjet et par
flere ting her.
Vi har tilføjet denne nye overskrift fil for at få de timerfunktioner.
Jeg gætter vi gjorde det i den sidste én, også, og jeg ikke nævne det.
Men nu, fordi vi er arbejder med billeder,
vi er nødt til også at omfatte SDL billede header fil så godt.
Så det er det samme som før, initialiserer SDL her,
samme deal med at skabe vinduer.
Vi har set det før nu.
>> Nu er vi nødt til at skabe noget, der hedder en renderer, hvilken slags går langs
med vinduet.
Men det er en slags abstrakt objekt, der er
ansvaret for at gøre alle disse tegning operationer til vinduet.
Og det faktisk svarer til et program indlæst
ind i grafik hardware i din computer eller din telefon eller hvad.
Så flagene, vi ønsker at videregive det-- og du kan se på dokumentationen
for at få flere detaljer her-- går skal SDL render accelereret, hvilket
betyder, at det vil være ved hjælp grafikhardwaren
og ikke blot emuleret i software.
>> Og vi kommer til at bruge SDL Renderer PRESENTVSYNC.
VSYNC er en ting, der blot gør din grafik se bedre ud og forhindrer
denne ting kaldet skærm terror, hvor halvdelen
af en ramme og halvdelen af ​​den næste rammen bliver trukket på samme tid
og det ser forfærdeligt.
Men igen, kan du gå læse om det på egen hånd.
>> Så vi har nogle flag her.
Og så vi bare vil kalde denne funktion SDL skabe renderer.
Vi vil give det vinduet at associere med denne renderer.
Negativ betyder, at vi er ligeglad med hvad grafikdriver vi kommer til at bruge.
Så det burde temmelig meget altid være negativ,
medmindre du kender om grafikdrivere.
Og så er vi bare at passere det vores flag.
Så hvis der returnerer null, så er vi kommer til at udskrive fejlen som sædvanlig,
men så er vi også vil at ødelægge vinduet
at rydde op disse ressourcer, før kalder SDL holde op og vender tilbage.
>> Nu er den interessante del her er, hvor vi indlæse vores image
ved hjælp af denne funktion IMG_load.
Dette er den eneste funktion, vi skal bruge, på SDL billedbibliotek.
Det er det eneste, vi har brug for.
Det er en funktion, der tager strengen der er stien til et billede ressource.
Og det kan være en .png- en GIF, bitmap, nogen af ​​disse ting.
Og det er derfor, denne funktion er så rart.
Den kan håndtere stort set alle formater.
Belastninger den i hukommelsen og gemmer det som en ting kaldes en SDL overflade.
>> Nu er en SDL overflade er blot en struct der repræsenterer billeddata i hukommelsen.
Så du kan læse mere om at i dokumentationen to.
Og hvis denne fejl, så er vi kommer til at gøre det hele, hvor
vi udskriver fejlen, lukke vores ressourcer, og afslut derefter programmet.
Nu det interessante er, før Vi kan trække billedet til vinduet,
vi er nødt til rent faktisk at gøre det til en tekstur.
Nu en tekstur svarer at billeddata indlæst
ind i grafikken hardware hukommelse.
>> Så en overflade er i main hukommelse, regelmæssig hukommelse
at vi har brugt al semester, og en tekstur er i denne separate VRAM
hukommelse, at de grafikkort kontrol.
Så vi kalder denne funktion SDL_CreateTextureFromSurface.
Vi giver det vores renderer og vores overflade.
Og så er vi faktisk gjort med overfladen,
så vi bare kommer til at frigøre det.
Vi har ikke brug for det længere.
Og derefter så hvis denne indkaldelse errored og returneret null,
så vil vi gøre det hele fejlrapportering ting igen.
>> Okay.
Her vil vi komme ind i nogle faktiske rendering funktioner.
Så kalder SDL_RenderClear og sende den
den renderer forbundet med vores vindue simpelthen gør vinduet gå sort.
Så det fjerner, at junk, som vi så i vores vindue før og gør det sort.
Og så vil vi at kalde SDL_RenderCopy,
give den vores renderer, vores tekstur.
Og vi vil tale om, hvad disse felter er i en smule.
Men det kommer til at tage teksturdataene
og kopiere det ind på vores vinduet for at tegne billedet.
Så efter vi har gjort denne kopi data over på vores vindue,
vi nødt til at gøre denne ekstra funktion kaldet SDL_RenderPresent.
>> Og det er interessant fordi det får
ind i et emne kaldet dobbeltbuffering.
Så dobbeltbuffering er en teknik, gør din grafik se meget bedre.
Igen, det forhindrer, at skærmen tåreflåd Jeg talte om tidligere, hvor
du har to buffere.
Der er en back-buffer i hukommelse og en front buffer.
Den forreste puffer er bogstaveligt talt hvad der er på din skærm i øjeblikket.
Så vi gør alt dette trækker variationer, ligesom SDL gør kopi eller SDL_RenderClear
på bagsiden buffer.
Så de ændrer tingene i ryggen buffer.
Her kan vi trække det grøn firkant på bagsiden bufferen.
>> Så når vi er færdig laver vores gør operationer, som
kan tage rigtig lang gang, hvad vi vil gøre
er skifte buffere.
Så det bogstaveligt talt kun tager forreste puffer og bagsiden puffer
og skifter dem, så at, går,
i én operation i stedet for måske hundreder eller tusinder,
alle vores nyligt gjort objekter på skærmen.
Og det forhindrer tingene ligesom skærmen forfriskende
når vi kun har tegnet en halv af vores objekter til rammen.
Så det er derfor, vi er nødt til at kalde SDL_RenderPresent, samt
som SDL_RenderCopy.
>> Igen, vi bare at vente i fem sekunder.
Så vi kommer til at rydde op vores ressourcer.
Vi har en hel del mere denne gang.
Og så er vi bare at afslutte programmet.
Så lad os gøre det.
Jeg har tænkt mig at skrive make, og derefter kilder lig hello-- dette er nu 3image.c.
Okay, det kompileret nogen fejl.
Og du kan se her har jeg nu trukket ud mit billede, Hej, CS50!
til vores vindue, som forsvinder efter fem sekunder.
>> Nu, dette stadig har problemer, ikke?
Dette er ikke en god ansøgning, fordi når jeg forsøger at lukke vinduet,
der sker ikke noget.
At x er stadig ikke reagerer.
Så lad os tage et kig på den næste fil, hello4animation.
Så dette er den fil der kommer til at indføre
bevægende og bevægelse til vores image.
Så vi kommer til at gøre det samme som før,
initiere SDL, oprette vindue, oprette renderer,
indlæse billedet i hukommelse, skal du oprette tekstur.
Vi har set alt dette før.
Nu, dette er nyt.
Vi kommer til at have en struktur, der kaldes en SDL rekte, som er blot en rektangel.
Hvis vi går over her, vi kan gøre en søgning efter SDL rekt,
og du kan se det er en meget enkel struktur.
Det har en x, y for en stilling, og det
har en bredde og en højde for størrelsen af ​​rektanglet.
>> Så det, vi kommer til at gøre, er at vi er kommer til at definere denne SDL rekte dest,
til destinationen.
Og dette er stedet på skærmen, hvor
Vi kommer til at tegne vores image, lige så
hvis vi vil være flytte billedet rundt,
derefter den destination, hvor vi kommer til at tegne billedet
skal flytte rundt.
Så vi kommer til at kalde denne funktion SDL_QueryTexture.
Og læg mærke til jeg passerer adressen af dest.w, som er bredden,
og dest.h, som er højden.
Og så SDL_QueryTexture går til at gemme på disse områder bredden
og højden af ​​vores tekstur.
>> Og hvad så jeg har tænkt mig at gøre, er jeg har tænkt mig
at indstille dest.x at være vinduet bredde minus dest.w, hvilket er
bredden af ​​sprite, divideret med 2.
Og det kommer til at sætte den op, så at billedet er perfekt centreret
i vores vindue, okay?
Så nu har jeg en Y-positionen.
Og det kommer til at være en variabel, der er
forandring, fordi vi kommer til at være flytte billedet i Y-retningen.
Og nu har vi noget kaldes en animation loop.
>> Så hvordan animationen virker?
Nå, kan menneskelige øje detektere 12 særskilte billeder i hvert sekund, okay?
Så hvis du flash 12 billede kort på mig i en anden, så jeg hver af disse billeder
som sin egen særskilte enkelt billede.
Nu, hvis du flash mere billeder med mig i et sekund,
så mit øje ville begynde at sløre dem sammen
og jeg vil opfatte det som bevægelse, i stedet for en særskilt billede.
Så for eksempel, film og fjernsyn, de flash billeder på dig 24 gange
et sekund.
Så det er 24 billeder i sekundet.
Computerskærme, på den anden side, ofte er på 60 billeder i sekundet.
Det er deres refresh hastighed.
Det er, hvor ofte de opdatere billedet på skærmen.
Så vores mål vil være 60 frames per sekund for vores spil.
>> Så lad os se, at i koden.
Så for hver ramme, er vi først kommer til at fjerne vinduet.
Det er det generelle mønster.
Du har altid rydde vindue hver ramme, og derefter
gøre alle din tegning operationer, og derefter ved udgangen,
do RenderPresent at vise alt i rammen.
Og så er du kommer til at har en ventetid i slutningen
at vente til næste rammen skal begynde.
>> Så hvis jeg gjorde en masse kompleks beregning her
der tog mere end 16 millisekunder, det ville være umuligt for mig
at få denne billedhastighed på 60, ​​der Jeg ønskede, fordi hver ramme er
tager for lang tid at beregne.
Desuden er vi virkelig gøre sortering af en ubetydelig mængde arbejde
her, fordi der er kun én ting, vi tegning.
Så jeg bare vente 1/60 af et sekund, hvilket er længden
af en ramme i mellem rammer.
Så jeg slags foregiver at gøre alt mit arbejde tager tid nul.
Men i et rigtigt spil, du er nødt til at trække
den tid, det tog at gøre alt dette arbejde fra din hviletid.
>> Så alligevel, hvad skal jeg faktisk gør i denne løkke?
Jeg rydder vinduet.
Jeg indstille dest.y, hvilket er en int til min faktiske y position kastet i en int.
Nu, jeg vil flyde opløsning for min y position i mit spil,
men så at faktisk tegne det på skærmen,
den har brug for ints, fordi det er i enheder af pixel, så det er hvad skuespillerne er for.
Jeg har tænkt mig at tegne billedet.
Så det er kilden rektangel.
Og dette er destinationen rektangel.
Så jeg gik null for kilden rektangel
at sige, at jeg ønsker at tegne hele mit tekstur.
Men hvis du havde en masse teksturer i dit spil
og de er alle i én stor tekstur kort der blev indlæst i SDL som ét
tekstur, kunne du bruge en kilde rektangel
at vælge en af ​​de mindre teksturer, en af ​​de mindre sprites,
ud af den store tekstur kort.
>> Så igen, jeg passerer min gengive, min tekstur, og nu destinationen.
Dette vil være, hvor i vindue det kommer til at blive trukket.
Og så, fordi jeg animere noget, jeg har brug for bevægelse,
Jeg har tænkt mig at være en opdatering af sprite position på hver ramme.
Så jeg har denne konstant kaldet rulle hastighed i enheder af pixler per sekund.
Nu hver gang vi gør en bevægelse, rammen er kun 1/60 af et sekund.
Så jeg har tænkt mig at dele det med 60.
Og så, lad os se, jeg er subtrahere det fra Y-positionen.
Hvorfor skal jeg trække?
Vi vil komme til at i et sekund.
Så jeg rydde op i mine ressourcer og programmet er slut.
>> Så lad os gøre det.
Så lad os gå ind i make SRCS = hello4 animation.c, okay?
Spil.
Værsgo.
Så jeg har det rulle op vindue, som er temmelig pæn.
Men hold fast, jeg var at trække fra Y-positionen hver gang.
Hvad sker der der?
Tja, det viser sig, at i SDL, og faktisk i de fleste computergrafik,
oprindelsen for koordinatsystemet er den øverste venstre hjørne af vinduet.
>> Så den positive x-retning går tværs dit vindue til højre.
Og den positive y-retning faktisk går ned.
Så igen, oprindelsen er i øverst til venstre på dit vindue,
positiv y-retning er nede, og positiv x er til højre.
Så når jeg trække fra y position, det er
kommer til at gøre det gå på den negative y-retningen, som er op vinduet.
Så det er, hvad der foregår der.
Afkøle.
>> Lad os se på den næste fil.
Her er den del af viser, hvor vi endelig
få at X i hjørnet af vinduet der er meningen at lukke vinduet
at arbejde.
Så hvad sker der?
Vi initialisere SDL, oprette vinduet, skabe den renderer, indlæse billedet,
skabe tekstur ligesom vi har set før.
Vi har den samme destination rektangel som før, at samme opkald forespørge tekstur.
Men denne gang, vi er så kommer til at opdele bredden
og højden af ​​vores destination med 4.
Dette har kun den virkning, skalering vores image ned, når
vi viser den i vinduet med fire.
Så det er temmelig pæn.
Vi kan bare skalere bare sådan.
Vi kommer til at starte sprite i midten af ​​skærmen.
Og nu har vi x og y hastighed og de er begge kommer til at starte ved nul.
>> Dette er den forkerte fil.
Undskyld.
Så det er alle sande.
Det er alt stadig i denne fil.
Vi har den kløft med 4 og alting.
Så her har vi vores x og y position til midten af ​​vinduet.
Og vi giver det en starthastighed af denne konstant hastighed, som
Jeg tror er 300 pixels per sekund.
Nu har vi denne int kunne lige så godt være en boolesk kaldes tæt anmodet om.
Og i stedet for at gøre en uendelig løkke på en timer her,
Vi kommer til at animere som længe så tæt er ikke anmodet om.
>> Så hvordan kan vi behandler begivenheder?
Nå, SDL køer op hændelser i en bogstavelig kø bag kulisserne.
Og så hver ramme, vi kan dequeue begivenheder
fra køen hjælp denne indkaldelse SDL_PullEvent.
Og igen, helt sikkert gå læse om dette i dokumentationen.
Der er meget mere detaljeret og en masse flere funktioner, du kan bruge med dette.
Vi passerer det adressen af denne ting, SDL_Event
at vi har her på stakken.
>> Nu, hvad er en SDL_event?
Fordi SDL, hvis vi ser på de documentation-- lad os
se, API efter kategori, input begivenheder, håndtering begivenhed,
Vi kan se på antallet af forskellige begivenheder her
og vi kan se, at der er en hel ton af dem.
Så hvad er denne SDL_Event ting?
SDL_Event er en union.
Wow, hvad er en fagforening?
Du har sikkert aldrig hørt om det før.
Og det er OK.
>> En forening er lidt ligesom en struct, undtagen en struct
har en plads til alle sine marker og hukommelse,
mens en fagforening kun har nok plads til at passe den største
en af ​​sine felter, hvilket betyder, at det kan kun gemme en af ​​sine marker
på et tidspunkt, hvilken slags giver mening for arrangementer, ikke?
Vi kan have et tastatur begivenhed eller et vindue omstændigheder
men en enkelt begivenhed kan ikke både være en tastatur begivenhed og et vindue begivenhed,
så det ville være dumt at have plads til både af dem inde i vores begivenhed union.
Så hvis du ønsker at oprette din egen fagforening,
det ser nøjagtig det samme som skaber en struct,
bortset fra at vi bruger fagforeningen søgeord i stedet for struct nøgleordet.
Og husk, for alle de ting inde din fagforening,
den faktiske variabel, der er fagforeningen kan kun have én af disse værdier
på et tidspunkt.
>> Så hvordan kan vi fortælle, hvilken slags begivenhed vi bare dukkede ud af denne kø?
Nå, kan vi teste for event.type.
Og hvis det er lig til SDL_Quit, vi kender
Det er det tilfælde, blev genereret, når vi
skud afsted X i hjørnet af vinduet.
Og vi kan sætte tæt anmodet lig med 1.
Resten er blot nogle animation at du har set før.
Så lad os gå videre og gøre dette og se, hvor godt det virker.
Så jeg har tænkt mig at skrive mærke og derefter SRCS = hello5_events.c.
Der vi går.
Spil.
>> Nu kan vi se, det var faktisk skaleret ned med fire.
Og nu er det hoppen omkring.
Jeg har nogle kollisionsdetektion foregår med siderne af vinduet
at vi kan tage et kig på.
Og hvad sker der, når jeg går til at lukke det?
Det lukker.
Fantastisk.
Vi har modtaget denne begivenhed.
Og vi håndterede det.
>> Så lad os se tilbage på koden.
Så hvordan fik jeg det hoppe rundt sådan?
Husk jeg indstille både x og y indledningsvis til de hastigheder.
Og hastighed er en positiv konstant, så det er
kommer til at få det startet ud gå ned og til højre.
>> Nu, hvor hver ramme, foruden håndtering eventuelle begivenheder, der kan være sket,
Jeg har tænkt mig at afsløre, om min sprite forsøger at gå ud af vinduet.
Så vi kan gøre det ved bare kontrol x_pos med 0, y_pos 0, og derefter
også x_pos og y_pos med vindue bredde og vindue højde.
Bemærk, at jeg har trukket bredden af ​​Sprite.
Og det er fordi, hvis jeg ikke gjorde trække bredden af ​​Sprite,
det ville kun kontrollere, at oprindelsen af ​​sprite
ikke gå uden for vinduet.
Men vi ønsker, at hele bredde af sprite
altid at være inde i vinduet og hele højden af ​​sprite
altid at være inde i vinduet.
Så det er hvad subtraktion er for.
En masse geometri her kan være nyttigt at trække det ud
på papir med koordinatsystemet systemet for at se, hvad der foregår.
>> Så hvis jeg kolliderer, jeg bare blot nulstille stilling
så det ikke vil ud af skærmen.
Og jeg har tænkt mig at, hvis det afvisninger på en af ​​sidevæggene,
Jeg har tænkt mig at negere x hastighed, så at det
begynder hoppende i den anden retning.
Og på samme måde, hvis den rammer toppen eller bunden,
Jeg har tænkt mig at sætte y hastighed lig med den negative y hastighed,
så det vil hoppe tilbage.
Så det er bare, hvordan vi fik den her.
>> Og ajourføring positioner ligesom vi har set før,
dividere med 60, fordi vi er kun håndterer 1/60 af et sekund.
Og derefter rendering, nøjagtigt det samme som før.
Og så det er alt der foregik denne fil.
Så det er, hvordan vi gør begivenheder.
Den vigtigste ting at tage væk her Denne SDL_PullEvent funktion.
Og bør du helt sikkert læse dokumentation mere om SDL_Event
fagforeningen, fordi denne datatype er meget, meget vigtigt, fordi vi bruger det
for alle former for arrangementer.
>> For eksempel, vi bruger det til tastatur begivenheder, som er det, denne fil er for.
Så hvad har vi?
Vi har det samme som før, initialisere SDL, oprette et vindue,
skabe en renderer, indlæse billedet i hukommelsen, skaber tekstur.
Igen, vil vi har denne dest rektangel,
vi kommer til at skalere billedet med fire, gøre det lidt mindre.
Nu skal vi til at starte sprite i midten af ​​skærmen.
Men denne gang, vi kommer til at indstille indledende x- og y-hastigheder til nul,
fordi tastaturet er kommer til at kontrollere dem.
Og desuden vil vi holde styr på disse variabler
op, ned, til venstre og højre.
Og det kommer til at holde styr på, om vi har
trykkede tastaturet knapper, svarer til op, ned, til venstre,
og højre.
>> Nu, dette er slags fancy fordi vi kan bruge W, A, S,
D her, eller den faktiske piletasterne.
Vi vil se, at på bare et sekund.
Så vi kommer til at behandle tilfælde ligesom før.
Vi trækker begivenheden.
Men nu vil vi tænde for begivenheden type.
Hvis det er SDL_Quit, er vi vil sætte tæt
anmodet om at én, ligesom før.
Det håndterer xi hjørnet af vinduet,
så vores vindue faktisk lukker.
>> Ellers, hvis vi får en SDL-tasten nede begivenhed, som betyder, at vi trykker på en tast,
så hvad vi skal gøre, er at vi er kommer til at tænde denne ting her,
som means-- så event.key betyder behandler vores begivenhed union,
gå og få nøglen eventstruktur det.
Så det viser sig, at denne Union er en central begivenhed struktur.
Og derefter gå til nøglen begivenhed struktur sit felt
kaldet keysym og derefter scancode.
Og igen, definitivt læst dokumentationen om dette.
Søgeord indgange ganske interessant.
Du kan få scanne koder eller vigtige koder.
Og det er lidt subtil, men dokumentationen er ganske god.
>> Så hvis vi ser scanningen kode til vores tastetryk bliver W eller op,
vi kommer til at oprette lig med 1.
Og så er vi bryde ud af denne kontakt.
Hvis det er A eller venstre, sæt vi tilbage til 1, et cetera, et cetera, til ned og højre.
Nu i denne ydre kontakt, hvis vi ser en nøgle-up-begivenhed,
det betyder, at vi har udgivet en nøgle og vi ikke længere trykke på den.
Så jeg har tænkt mig at sige op er lig med 0, venstre er lig med 0, ned lig med 0, højre
er lig med 0, et cetera.
>> Og bemærk vi har i hver af disse to tilfælde sat lige ved siden af ​​hinanden
uden særskilt kode for det første tilfælde, hvilket
betyder, at uanset om det er en S eller en ned lige her,
det kommer til at udføre denne kode.
Så det er temmelig praktisk.
Det forhindrer os at skulle gøre mere betingelser og hvis'er og ting
sådan.
>> Så vi kommer til at bestemme hastigheden.
Vi sætter hastigheden til 0.
Så hvis der ikke trykkes op og ikke ned, så vi
indstille y hastighed til negativ hastighed.
Husk negative, fordi negativ y-retning er op.
Og den positive y-retning er nede.
Hvis der trykkes ned og ikke op, så vi er
kommer til at indstille den til positiv hastighed, hvilket betyder at gå ned på skærmen.
Samme ting med venstre og højre.
>> Og så vil vi opdatere positionerne lige som før.
Vi vil gøre kollision detektion med bounds,
men vi kommer ikke til at nulstille hastighed, fordi hastigheden er lige
kontrolleres af tastaturet.
Men vi kommer til at nulstille positioner for at holde den i vinduet.
Og vi kommer til at indstille positioner i struct
og derefter gøre alt rendering ting fra før.
Så lad os se, hvad den gør.
Så gør SRCS-- lad os se, dette er hello6_keyboard.c.
>> Åh nej.
Så vi fik nogle advarsler her.
Og der er simpelthen sige, at vi ikke gjorde kontrollere for hver eneste mulige form
begivenhed.
Det er OK, fordi der er 236 af dem eller deromkring.
Så jeg har tænkt mig at ignorere disse advarsler.
Det er stadig kompileret fint.
Så jeg har tænkt mig at spille spillet.
Det er ikke bevæger sig.
Men nu, når jeg mash på mit tastatur, Jeg kan gøre nogle WASD bevægelse her,
Jeg bruger mine piletasterne så godt.
Og læg mærke til, selvom jeg er trykke lige lige nu,
det kommer ikke til ud af vinduet, fordi jeg nulstille den på hver ramme.
Så det er temmelig pæn.
Du kan forestille dig at flytte rundt Mario med nogle piletasterne eller noget lignende.
Og ja, har X virker.
>> Så endelig fil vi vil at se på, hellow7_mouse.
Det handler om at få mus input.
Så i denne ene, vi importere matematik header,
fordi vi vil have en lille smule af matematik her.
Samme gamle, samme gamle ting, destination, samme gamle, set før.
Nå, det er interessant.
Så vi er tilbage til kun at kontrollere for SDL Afslut begivenhed.
Hvorfor det?
Så du kan få musen input fra begivenheder.
Ligesom når musen flyttes, du får en begivenhed for det.
Når der trykkes på en museknap, du kan få en begivenhed for det.
>> Men der er en anden, lidt enklere måske API til at få mus input.
Og det er simpelthen SDL get mus tilstand.
Så jeg har en int for x og y for markørens position.
Jeg videregive det til SDL_GetMouseState, der sætter disse.
Og det er position i koordinatsystem af vinduet.
Så hvis masse er i øverste venstre af vinduet, ville 0, 0.
>> Nu, hvad jeg har tænkt mig at gøre, er jeg har tænkt mig at gøre en lille smule af vektor matematik.
Jeg vil vædde på, du troede, du ikke ville se, at i CS50, men her er det.
Jeg har tænkt mig at gøre nogle vektor matematik for at få vektoren
fra billedet til markøren.
Og så hvorfor har jeg denne subtraktion her?
Tja, hvis jeg bare brugt dest .-- så Jeg har brug for at oversætte musen x
og y af den halve bredde og højden af ​​billedet,
fordi jeg ønsker i midten af billede, der skal gå mod mus,
ikke oprindelsen af ​​billedet.
>> Så det er bare at sørge for jeg taler omkring midten af ​​billedet her.
Så får vi delta x og y, som er forskellen fra målet
til den faktiske position af billedet.
Og så kan vi få den afstand her, hvilket
bliver pythagoræiske sætning, kvadratroden af ​​x
gange x plus y gange y.
>> Nu for at forhindre jitter, og jeg kan vise dig, hvad det betyder, hvis jeg ikke gør dette,
hvis afstanden mellem markøren og billedet centrum er mindre end fem,
Jeg er bare ikke til at flytte billedet.
Ellers sætter vi hastigheden.
Og vi har sat den, så den hastighed vil altid være konstant.
Og nettoresultatet af alle denne matematik er, at billedet
kommer til at bevæge sig i retning markøren.
>> Nu viser det sig, at SDL_GetMouseState,
Ud over at sætte x- og y-argumenter her,
det også returnerer en int, der svarer til staten af ​​museknapperne.
Så vi kan ikke læse, at direkte, men vi kan
bruge disse makroer, en enkelt bitvis operatør, ikke at skræmmende,
blot en bitvise og.
Så vi siger knapper, der er resultatet vores SDL_GetMouseState, hvis dette
og bitvise og denne makro her, SDL_BUTTON_LEFT.
>> Så dette vil blot løse til bitmap, der svarer
til venstre museknap bliver presset.
Og så hvis den bitvise og forekommer og det er
ikke er nul, hvilket betyder venstre knap blev trykket,
så vi rent faktisk kommer til at negere både x- og y hastigheder,
hvilket vil bare gøre billedet runaway.
Opdater positioner.
Kollisioner opdagelser, set det hele før, rendering, okay.
Lad os gøre det.
Så du fik gøre SRCS = hello7_mouse.c.
Alle tiders.
Ingen fejl.
Og spil.
>> Så her har jeg min mus.
Og billedet er faktisk jagter min mus.
Nu, i et spil, du laver, måske det er som en fjende jagter
din lille karakter eller hvad.
Men her har vi den billede jagter musen.
Og når jeg klikker, musen begynder jagter billedet
og billedet er løbe væk fra musen.
Så det er ret cool.
Og varsel igen, der er stadig kollisionsdetekterings her.
>> Så det er den endelige lille demo jeg har oprettet her.
Og lad os tage et kig på en ting mere.
Så tilbage her, jeg nævnte dette jitter.
Okay.
Så hvis afstanden er mindre end fem pixels, Jeg var ved x og y hastighed til nul.
Hvad sker der, hvis vi slippe af med det?
Så jeg har tænkt mig at bare gøre dette.
Undskyld denne forfærdelige stil, men vi kommenteret den korrekte kode.
Så jeg har tænkt mig at redde denne og gøre det samme kommando fra før for at gøre det.
>> Okay.
Og nu, hvad der sker?
God.
Vi er stadig efter mus ligesom før,
men når vi kommer til musen, vi har fået denne grove jitter.
Hvad sker der der?
Tja, i vores vektor matematik, husker vi var
idet afstanden mellem cursor og centrum af billedet?
Nå, som der nærmer 0, begynder vi at få
som denne slags vanvittige opførsel hvor billedet er slags
Ligesom oscillerende omkring markøren.
Og der er skabe denne jitter.
Og det er virkelig grimt.
Og har du sandsynligvis ikke vil have dine spil at gøre det,
medmindre det er en slags speciel effekt.
>> Så det er derfor, vi har netop dette vilkårlige
afskåret af fem pixels, hvor vi siger hvis det er inden for fem pixels, vi er gode.
Vi behøver ikke at flytte billedet længere.
Så det er, hvad der foregår der.
>> Så det er temmelig meget det.
Nu ved du, hvordan du opretter et vindue, indlæse et billede,
tegne et billede til vinduet, får tastaturinput, får mus input,
der er en masse andre input, som du ikke ville
vide, hvordan du få, hvis du bare bruge en nogle minutter ser på dokumentation.
Så du rent faktisk har en ganske få værktøjer til din rådighed nu
at skrive et fuldgyldigt spil.
>> Nu hvert spil har brug for nogle lyd, men lyden dokumentation
er også temmelig godt.
Og jeg er villig til at vædde på, at hvis du forstår alle de ting,
vi talte om i dag med billederne, og overflader,
vinduerne, og alt, så finde ud audio API er ikke
kommer til at være så slemt.
Så jeg ser frem til at se hvad du opretter med SDL.