The Incredible TextMan (Spel, C++)

Permalänk
Medlem

The Incredible TextMan (Spel, C++)

Detta är bara ett simpelt spel gjort i C++.
Syftet med detta är för nybörjare att se hur ett spel fungerar i grund och botten

Är en del text men har ingen filehost så fick blå såhära.

För att komma igång:
* Klistra in koden i din editor
* Kör du UNIX eller liknande, ändra raden 'char *OS = "WIN";' till 'char *OS = "UNIX";'
* Compilera och Kör

Innehåller:
* Förflyttning av en spelare
* Simpel Kollisionshantering

/* * The Incredible TextMan * (C) Andreas Lindström, 2008 * * You are allowed to use this source code for public purpose * as long as this original copyright text remains. * * //Andreas */ #include <iostream> #include <string> #include <conio.h> using namespace std; char *OS = "WIN"; // OS Version, Usage: char *OS = 'WIN' or 'UNIX' char player; void clrscr(); void show_help(); void GameLoop(string pName); void DrawGameField(string pName, int pX, int pY); int main() { string pName; show_help(); cout << "Enter your initials (3 Letters): "; cin >> pName; pName.resize(3); cout << "Enter a character (Only 1): "; cin >> player; clrscr(); GameLoop(pName); cout << "Goodbye!" << endl; //system("PAUSE"); // Using Visual Studio 2008, // so this line is not really // needed. But im adding it // for other people using other // compilers. return 0; } void GameLoop(string pName) { bool GameEnd; int pX = 0, pY = 0; GameEnd = false; DrawGameField(pName, pX, pY); do { int keyDown = 0; if(_kbhit()) { keyDown=_getch(); if(keyDown == 119) // W Key { if(pY >= 1) pY -= 1; } else if(keyDown == 97) // A Key { if(pX >= 1) pX -= 1; } else if(keyDown == 100) // D Key { if(pX <= 75) pX += 1; } else if(keyDown == 115) // S Key { if(pY <= 19) pY += 1; } else if(keyDown == 27) // ESC Key { GameEnd = true; } DrawGameField(pName, pX, pY); } } while (GameEnd == false); } void clrscr() { if(strcmp(OS, "WIN") == 0) { system("cls"); } else if(strcmp(OS, "UNIX") == 0) { system("clear"); } return; } void DrawGameField(string pName, int pX, int pY) { clrscr(); cout << " Name: " << pName << " Position: (" << (pX + 1) << ", " << (pY + 1) << ")" << endl; cout << "+-----------------------------------------------------------------------------+" << endl; for(int y = 0; y <= 20; y++) { cout << "|"; for(int x = 0; x < 77; x++) { if((y == pY) && (x == pX)) { cout << player; } else { cout << " "; } } cout << "|" << endl; } cout << "+-----------------------------------------------------------------------------+" << endl; } void show_help() { cout << "\tThe Incredible TextMan" << endl << "Copyright (C) Andreas Lindstrom, 2008" << endl << endl; cout << "\t\t!!! How To Play !!!" << endl << endl; cout << "\tKeys:" << endl; cout << "\t W = Move Up" << endl; cout << "\t A = Move Left" << endl; cout << "\t S = Move Down" << endl; cout << "\t D = Move Right" << endl << endl; cout << "\t ESC = Exit Game" << endl << endl << "Now Enjoy! (PS. The flickering is supposed to be there. DS.)" << endl << endl; }

EDIT:
Ändrade lite i koden och tog bort lite onödiga saker

//AJL

Visa signatur

C#/MonoGame Fanatiker.
Pixel Artist & Game Developer

Permalänk
Hedersmedlem

Re: The Incredible TextMan (Spel, C++)

Citat:

Ursprungligen inskrivet av AJL
* Kör du UNIX eller liknande, ändra raden 'char *OS = "WIN";' till 'char *OS = "UNIX";

Ett annat gammalt trick är att använda flaggan _WIN32 för att avgöra huruvida man kör windows. Man kan då skippa OS-fältet och istället skriva följande i clrscr():

#ifdef _WIN32 system("cls"); #else system("clear"); #endif

Permalänk
Medlem

Fast conio är ju inte en standardheader, så programmet kompilerar inte i Unix ändå (inte med gcc i alla fall).

Men här är lite tips på saker som du kan göra bättre:

  • char *OS = "WIN"; gör inte vad du tror att det gör. Du kan nämligen inte skapa en pekare till char som pekar på en strängkonstant, och du borde få en varning för den raden. Det du vill ha är const char *OS = "WIN";. Vad som händer nu vet jag inte riktigt, men skulle gissa att det är odefinierat beteende som gäller, dvs. precis vad som helst kan hända. Egentligen så är det nog förresten bättre att definiera den som const string OS = "WIN"; istället, så blir det enklare att handskas med den. Fast egentligen så behöver du ju inte OS alls, om du använder _WIN32 som Elgot sa.

  • För att kunna använda strcmp på OS så borde du egentligen behöva inkludera headern cstring som definierar c-strängfunktionerna. Jag vet inte riktigt varför du inte behövde göra det, kanske conio.h inkluderade den, men ska det vara riktigt så borde du göra det. Som det är nu så kompilerar koden inte i GCC, fast det gör den ändå inte eftersom conio.h saknas. På samma sätt så borde du behöva inkludera cstdlib för att kunna använda system.

  • Globala variabler är ondskefulla av många orsaker, och ju snabbare du inser det desto bättre. Fundera t.ex. på om player egentligen behöver vara en global variabel, eller om det kanske finns bättre sätt att designa spelet på. Det kanske inte gör någon skillnad i just ditt spel, och blir säkerligen bara mer komplicerat, men i större projekt så märker man snabbt att det inte fungerar så bra med massor av globala variabler.

  • Något du ska vara medveten om är att cout är buffrad, och texten skrivs inte ut på skärmen förrän du anropar endl för att tömma buffern. Detta medför att varje gång du anropar endl så töms buffern och innehållet skrivs ut på skärmen. Något som är mycket effektivare är att använda \n för att få en ny rad, och sedan endl när du ritat klart t.ex. spelplanen. Nu märks det förmodligen inte i ditt spel, men det är en god vana att ta till sig.

  • Du skickar strängar "by-value" som det kallas, dvs. varje gång du skickar t.ex. pName till DrawGameField så kommer en kopia av pName att skapas som sedan skickas till funktionen. Något som är mycket effektivare är att skicka strängen som en referens, eftersom ingen kopia då behöver skapas. För att inte funktionen ska kunna ändra på strängen så vill du även att den ska vara konstant, så vad du vill ha istället för "string pName" är alltså "const string &pName".

  • I DrawGameField så loopar du t.ex. från 0 till 20. Undvik gärna så kallade "magiska siffror" som 20 och 77, och definiera istället två konstanter som t.ex.

    const int PLAYFIELD_Y = 20; const int PLAYFIELD_X = 77;

    Då kan du använda dem på andra ställen, och skulle du vilja ändra spelplanens storlek så behöver du bara göra det på ett ställe. Men behöver heller inte fundera på vad 20 och 77 är, utan namnet på konstanterna talar direkt om vad det handlar om.

  • char förvandlas automatiskt till int när så behövs, så i din if-sats där du kollar vilken knapp som tryckts ner så kan du använda 'W' istället för 119 t.ex., så slipper du skriva en kommentar om vilken knapp det är.

Ok, det får räcka för nu tror jag Hoppas att mina tips är till någon hjälp för dig.

Permalänk
Medlem

nice
bra att nån håller kolla på sakerna man tabbar sig med
men jo globala variable brukar jag bara använda om jag absolut måste men gick fortare nu att köra en global på så lite kod ^^

ska prova ändra lite kod senare ikväll se om det blir nån skillnad

edit:
angående 'conio.h' etc så antog jag att det fanns med i gcc men tydligen inte :<

Visa signatur

C#/MonoGame Fanatiker.
Pixel Artist & Game Developer

Permalänk
Medlem

Skriv gärna hur man kompilerar koden. Jag antar att det endast är "gcc <filnamn>" som behövs.

Visa signatur

Archlinux, Sway och Rust, vad mer behövs?

Permalänk

Du bör kanske fixa så att man kan byta tangenter, antingen via en config-fil eller via omkompilering och konstanter.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av hagbarddenstore
Du bör kanske fixa så att man kan byta tangenter, antingen via en config-fil eller via omkompilering och konstanter.

omkompilering är ju bara att ändra tangenterna i källkoden

ps. utvecklar för tillfället till ett större och lite mer finare så kommer väl en uppdatering inom kort förhoppningsvis

Visa signatur

C#/MonoGame Fanatiker.
Pixel Artist & Game Developer

Permalänk
Medlem

Finns det något knep för att få den att dra mindre CPU-kraft? Min är uppe i 20% när jag kör programmet.

Permalänk
Hedersmedlem
Citat:

Ursprungligen inskrivet av Dythzer
Finns det något knep för att få den att dra mindre CPU-kraft? Min är uppe i 20% när jag kör programmet.

Problemet är att do-loopen kör onödigt många gånger om man inte trycker på någon tangent. Ett sätt att lindra problemet är att till exempel lägga till

Sleep(200);

före

} while (GameEnd == false);

Detta kräver dock att man inkluderar windows.h