Programmering datorspel kan vara det mest tekniskt utmanande (och kanske det bäst betalande) jobbet som a programmerare kan ha. Spel på toppnivå kräver det bästa från både programmerare och datorer.
Visual Basic 6 har nu gått förbi som en plattform för spelprogrammering. (Det var aldrig riktigt en. Även under "goda olldagar" skulle seriösa spelprogrammerare aldrig använda ett språk på hög nivå som VB 6 eftersom du bara inte kunde få skärningen kantprestanda som de flesta spel kräver.) Men det enkla "Tic Tac Toe" -spelet är en bra introduktion till programmering som är lite mer avancerad än "Hej världen!"
Detta är en bra introduktion till många av de grundläggande koncepten för programmering eftersom det kombinerar tekniker inklusive:
- Användningen av arrayer. X- och O-markörerna förvaras i separata matriser och hela matriserna skickas mellan funktioner för att hålla reda på spelets framsteg.
- Använda VB 6-nivågrafik: VB 6 erbjuder inte bra grafisk kapacitet, men spelet är en bra introduktion till vad som är tillgängligt. Mycket av resten av denna serie är en utforskning av hur GDI +, nästa generation av Microsoft-grafik, ersätter VB 6-nivågrafiken.
- Använda matematiska beräkningar för programstyrning: Programmet använder smart modulo (Mod) och heltal divisionsberäkningar med hjälp av två-spel markör arrayer för att bestämma när en tre-element "vinna" har inträffade.
Klassen för programmering i denna artikel är kanske bara lite förbi början men det borde vara bra för "mellanliggande" programmerare. Men låt oss börja på en elementär nivå för att illustrera några av koncepten och komma igång med dina Visual Basic spelprogrammeringskarriär. Även studenter mer avancerade än så kan uppleva att det är lite utmanande att få objekten i form precis rätt.
Hur man spelar Tic Tac Toe
Om du aldrig spelat Luffarschack, här är reglerna. Två spelare växlar om varandra när de placerar Xs och Os i 3 x 3 spelplan.
Innan spelet börjar måste båda spelarna komma överens om vem som ska gå först och vem kommer att markera sina drag med vilken symbol. Efter det första draget placerar spelarna växelvis sina märken i någon tom cell. Målet med spelet är att vara den första spelaren med tre markeringar i en horisontell, diagonal eller vertikal linje. Om det inte finns några tomma celler och ingen av spelarna har en vinnande kombination är spelet oavgjort.
Innan du startar någon faktisk kodning är det alltid en bra idé att ändra namnen på alla komponenter du använder. När du börjar kodning, kommer namnet att användas automatiskt av Visual Basic så att du vill att det ska vara rätt namn. Vi använder formulärnamnet frmTicTacToe och vi kommer också att ändra bildtexten till "Om Tic Tac Toe."
Använd formuläret, använd radverktygslådan för att rita ett 3 x 3 rutnät. Klicka på radverktyget och rit sedan en linje där du vill ha den. Du måste skapa fyra rader på detta sätt och justera deras längd och position för att få dem att se rätt ut. Visual Basic har också några praktiska verktyg under Format-menyn som hjälper. Detta är en stor chans att träna med dem.
Förutom det spelande rutnätet behöver vi några objekt för X- och O-symbolerna som kommer att placeras på rutnätet. Eftersom det finns nio utrymmen i rutnätet, skapar vi ett objektuppsättning med nio mellanslag, kallade element i Visual Basic.
Det finns flera sätt att göra nästan allt i Visual Basic-utvecklingsmiljön, och att skapa kontrollmatriser är inget undantag. Förmodligen är det enklaste sättet att skapa den första etiketten (klicka och rita precis som radverktyget), namnge den, ställa in alla attribut (t.ex. Font och ForeColor) och sedan kopiera den. VB 6 frågar om du vill skapa en kontrollgrupp. Använd namnet lblPlayGround för den första etiketten.
För att skapa de andra åtta elementen i rutnätet, välj det första etikettobjektet, ställ in indexegenskapen till noll och tryck på CTRL + C (kopia). Nu kan du trycka på CTRL + V (klistra in) för att skapa ett annat etikettobjekt. När du kopierar objekt som detta kommer varje kopia att ärva alla egenskaper utom Index från den första. Index kommer att öka med en för varje kopia. Detta är en kontrolluppsättning eftersom de alla har samma namn, men olika indexvärden.
Om du skapar matrisen på detta sätt staplas alla kopior ovanpå varandra i det övre vänstra hörnet av formuläret. Dra varje etikett till en av de spelande rutnätspositionerna. Se till att indexvärden är sekventiella i rutnätet. Programmets logik beror på det. Etikettobjektet med indexvärde 0 bör vara i det övre vänstra hörnet och den nedre högra etiketten ska ha index 8. Om etiketterna täcker det spelande rutnätet väljer du varje etikett, högerklickar och väljer Skicka till tillbaka.
Eftersom det finns åtta möjliga sätt att vinna spelet, behöver vi åtta olika linjer för att visa vinsten på det spelande rutnätet. Du kommer att använda samma teknik för att skapa en annan kontrollgrupp. Rita först linjen, namnge den linWin och ställ in indexegenskapen till noll. Använd sedan copy-paste-teknik för att producera sju rader till. Följande illustration visar hur du ställer in indexnumren korrekt.
Förutom etiketten och radobjekten behöver du några kommandoknappar för att spela spelet och fler etiketter för att behålla poängen. Stegen för att skapa dessa är inte detaljerade här, men det är de objekt du behöver.
Två knapp objekt:
- cmdNewGame
- cmdResetScore
Ramobjekt fraPlayFirst som innehåller två alternativsknappar:
- optXPlayer
- optOPlayer
Ramobjekt fraScoreBoard som innehåller sex etiketter. Endast lblXScore och lblOScore ändras i programkoden.
- lblX
- lblXScore
- lblO
- lblOScore
- lblMinus
- lblColon
Slutligen behöver du också etikettobjektet lblStartMsg för att 'maskera' cmdNewGame-knappen när det inte ska klickas. Detta är inte synligt i bilden nedan eftersom det upptar samma utrymme i formen som kommandoknappen. Du kanske måste flytta kommandoknappen tillfälligt för att rita den här etiketten på formuläret.
Hittills har ingen VB-kodning gjorts, men vi är äntligen redo att göra det.
initiering
Nu får du äntligen börja koda programmet. Om du inte redan har gjort det, kanske du vill ladda ner källkoden för att följa med eftersom programmets funktion förklaras.
Ett av de första designbesluten att fatta är hur man kan hålla reda på det aktuella ”läget” i spelet. Med andra ord, vad är de nuvarande Xs och Os på det spelande rutnätet och vem går vidare. Begreppet "tillstånd" är kritiskt i mycket programmering, och särskilt är det viktigt för att programmera ASP och ASP.NET för webben
Det finns flera sätt att göra detta, så det är ett kritiskt steg i analysen. Om du löste detta problem på egen hand, kanske du vill rita ett flödesschema och prova olika alternativ med "repapapper" innan du startar någon kodning.
Vår lösning använder två "tvådimensionella matriser" eftersom det hjälper till att hålla reda på "tillstånd" genom att helt enkelt ändra arrayindex i programslingor. Tillståndet för det övre vänstra hörnet kommer att vara i matriselementet med index (1, 1), det övre högra hörnet är i (1, 3), nederst till höger i (3,3), och så vidare. De två matriserna som gör detta är:
iXPos (x, y)
och
iOPos (x, y)
Det finns många olika sätt detta kan göras och den slutliga VB.NET-lösningen i den här serien visar hur du gör det med bara en enda dimensionell matris.
Programmeringen för att översätta dessa matriser till spelare vinner beslut och synliga skärmar i formuläret finns på nästa sida.
Du behöver också några globala variabler enligt följande. Observera att dessa finns i koden Allmänt och deklarationer för formuläret. Detta gör dem "modulnivå" variabler som kan refereras var som helst i koden för detta formulär. Mer information om detta finns i Förstå omfattningen av variabler i Visual Basic Hjälp.
Det finns två områden där variabler initialiseras i vårt program. Först initialiseras några variabler medan formen frmTicTacToe laddas.
Privat subform_Load ()
För det andra, innan varje nytt spel, tilldelas alla variabler som måste återställas till startvärden i en initialiseringssubutine.
Sub InitPlayGround ()
Observera att initialiseringen av formbelastningen också kallar initiering av lekplatsen.
En av programmerarens kritiska färdigheter är förmågan att använda felsökningsfaciliteter för att förstå vad koden gör. Du kan använda det här programmet för att prova:
- Gå igenom koden med F8-tangenten
- Ställa in en klocka på viktiga variabler, till exempel sPlaySign eller iMove
Ställa in en brytpunkt och fråga om värdet på variabler. Till exempel i den inre slingan för initialiseringen:
lblPlayGround ((i - 1) * 3 + j - 1). Bildtext = ""
Observera att detta program tydligt visar varför det är en bra programmeringspraxis att hålla data i matriser när det är möjligt. Om du inte hade matriser i det här programmet, skulle du behöva skriva kod något liknande:
Line0.Visible = Falsk
Line1.Visible = Falsk
Line2.Visible = Falsk
Line3.Visible = Falsk
Line4.Visible = Falsk
Line5.Visible = Falsk
Line6.Visible = Falsk
Line7.Visible = Falsk
istället för det här:
För i = 0 till 7
linWin (i). Visible = Falsk
Nästa i
Göra ett drag
Om någon del av systemet kan betraktas som 'hjärtat', är det subroutine lblPlayGround_Click. Denna subroutine kallas varje gång en spelare klickar på spelningsnätet. (Klick måste vara inuti ett av de nio lblPlayGround-elementen.) Lägg märke till att denna subrutin har ett argument: (Index som heltal). De flesta andra ”händelsunderrutiner”, som cmdNewGame_Click (), gör det inte. Index indikerar vilket etikettobjekt som har klickats på. Till exempel skulle index innehålla värdet noll för det övre vänstra hörnet av rutnätet och värdet åtta för det nedre högra hörnet.
När en spelare klickar på en kvadrat i spelrutnätet "aktiveras" kommandoknappen för att starta ett annat spel, cmdNewGame, genom att synliggöra det. Tillståndet för den här kommandoknappen gör dubbeltjänst eftersom den också används som en boolesk beslutsvariabel senare i programmet. Att använda ett fastighetsvärde som en beslutsvariabel avlägsnas vanligtvis, om det någonsin blir nödvändigt att ändra programmet (säg till exempel att göra cmdNewGame-kommandoknappen är synlig hela tiden), då kommer programmet oväntat att misslyckas eftersom du kanske inte kommer ihåg att det också används som en del av programmet logik. Av denna anledning är det alltid en bra idé att söka igenom programkoden och kontrollera användningen av allt du ändrar när du gör programunderhåll, även fastighetsvärden. Detta program bryter mot regeln dels för att göra detta och dels för att detta är en relativt enkel kodkod där det är lättare att se vad som görs och undvika problem senare.
Ett spelarval av ett spelkvadrat behandlas genom att kalla GamePlay-underprogrammet med Index som argument.
Bearbetar flytten
Först kontrollerar du om du har klickat på en ledig fyrkant.
Om lblPlayGround (xo_Move) .Caption = "" Sedan
När vi är säker på att det här är ett legitimt drag stegs räknare (iMove). De nästa två raderna är mycket intressanta eftersom de översätter koordinaterna från det en-dimensionella Om lblPlayGround-komponenten array till tvådimensionella index som du kan använda i antingen iXPos eller iOPos. Mod- och heltalsdelning ('backslash') är matematiska operationer som du inte använder varje dag, men här är ett bra exempel som visar hur de kan vara mycket användbara.
Om lblPlayGround (xo_Move) .Caption = "" Sedan
iMove = iMove + 1
x = Int (xo_Move / 3) + 1
y = (xo_Move Mod 3) + 1
Xo_Move-värdet 0 kommer att översättas till (1, 1), 1 till (1, 2)... 3 till (2, 1)... 8 till (3, 3).
Värdet i sPlaySign, en variabel med modulomfång, håller reda på vilken spelare som flyttade. När rörelsearrayerna har uppdaterats kan etikettkomponenterna i det spelande rutnätet uppdateras med rätt tecken.
Om sPlaySign = "O" Sedan
iOPos (x, y) = 1
iWin = CheckWin (iOPos ())
Annan
iXPos (x, y) = 1
iWin = CheckWin (iXPos ())
Sluta om
lblPlayGround (xo_Move) .Caption = sPlaySign
När till exempel X-spelaren klickar i det övre vänstra hörnet av rutnätet har variabler följande värden:
Användarskärmen visar bara ett X i den övre vänstra rutan, medan iXPos har en 1 i den övre vänstra rutan och 0 i alla de andra. IOPos har 0 i varje ruta.
Värdena ändras när O-spelaren klickar på rutans mitt kvadrat. Nu visar iOPos en 1 i mittrutan medan användarskärmen visar ett X i det övre vänstra och ett O i mittrutan. IXPos visar endast 1 i det övre vänstra hörnet, med 0 i alla de andra rutorna.
Nu när du vet var en spelare klickade och vilken spelare som klickade (med värdet i sPlaySign), allt du behöver göra är att ta reda på om någon vann ett spel och ta reda på hur man visar det i visa.
Hitta en vinnare
Efter varje drag kontrollerar CheckWin-funktionen efter den vinnande kombinationen. CheckWin fungerar genom att lägga till varje rad, över varje kolumn och genom varje diagonal. Att spåra stegen genom CheckWin med Visual Basic: s felsökningsfunktion kan vara mycket lärorikt. Att hitta en vinst är en fråga om först, kontrollera om tre 1 hittades i var och en av de enskilda kontrollerna i variabeln iScore, och sedan returnerar ett unikt "signatur" -värde i Checkwin som används som matrisindex för att ändra den synliga egenskapen för ett element i linWin komponentuppsättning. Om det inte finns någon vinnare kommer CheckWin att innehålla värdet -1. Om det finns en vinnare, uppdateras displayen, resultattavlan ändras, ett gratuleringsmeddelande visas och spelet startas om.
Låt oss gå igenom en av kontrollerna i detalj för att se hur det fungerar. De andra är likadana.
"Kontrollera raderna för 3
För i = 1 till 3
iScore = 0
CheckWin = CheckWin + 1
För j = 1 till 3
iScore = iScore + iPos (i, j)
Nästa j
Om iScore = 3 Sedan
Avsluta funktion
Sluta om
Nästa i
Det första att märka är att den första indexräknaren i räknar ner raderna medan den andra j räknar över kolumnerna. Den yttre slingan går sedan helt enkelt från en rad till nästa. Den inre slingan räknar 1: erna i den aktuella raden. Om det finns tre, har du en vinnare.
Lägg märke till att du också håller reda på det totala antalet rutor som testats i variabeln CheckWin, vilket är värdet som returneras när denna funktion avslutas. Varje vinnande kombination slutar med ett unikt värde i CheckWin från 0 till 7 som används för att välja ett av elementen i komponentgruppen linWin (). Detta gör ordningen på koden i funktionen CheckWin också viktig! Om du flyttade ett av blocken av slingkod (som den ovan), skulle fel linje dras på det spelande rutnätet när någon vinner. Prova och se!
Efterbehandlingsdetaljer
Den enda koden som ännu inte diskuterats är subrutinen för ett nytt spel och subrutinen som kommer att återställa poängen. Resten av logiken i systemet gör det lätt att skapa dessa. För att starta ett nytt spel, behöver du bara ringa InitPlayGround-subrutinen. Som en bekvämlighet för spelare eftersom knappen kan klickas i mitten av ett spel ber du om bekräftelse innan du går vidare. Du ber också om bekräftelse innan du startar om resultattavlan.