Moin.
Ich hab mich die letzten tage mal etwas intensiver mit c++ beschäftigt, und da wollte ich gestern gleich mal was brauchbares Code.
Was dabei rausgkam ist ein kleines Snake, gesteuert wird mit den Pfeiltasten, der rest dürfte klar sein.
"Main.cpp"
C
#include <stdio.h>
#include <windows.h>
#include <TCHAR.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include "Main.h"
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
bool AddSnakePeace() ;
void AddFood() ;
void DrawMenu (HWND hwnd) ;
void RestSnake () ;
void ResetMap () ;
int TimerInit () ;
int TimerDiff (int Timestamp) ;
const int cxGUI = 400, cyGUI = 400 ;
const int cxMenu = cxGUI, cyMenu = 100 ;
const int iMapRaster = 10 ;
int curren_dir ;
int fps = 10 ;
int iScreen ;
int iLevelUp = 5 ;
// The Map
struct Map
{
// 0 = Free Way, 1 = Wall, 2 Food
int MapArray[cxGUI / iMapRaster][(cyGUI - cyMenu) / iMapRaster] ;
}
MainMap ;
// Informations about the player
struct
{
int iLevel ;
int iScore ;
int iSnakeSize ;
}
Player ;
//Peaces of the Snake
#define MAXSNAKEPEACES 100
struct
{
int Visible ;
int xPos ;
int yPos ;
}
Snake[MAXSNAKEPEACES] =
{
1,0,10,
};
void CreateMap (int iLevel, struct Map MyMap)
{
// DO some mor stuff with the level (create walls and so on)
int iUboundX = cxGUI / iMapRaster ;
int iUboundY = (cyGUI - cyMenu) / iMapRaster ;
int x, y ;
for (x = 0 ; x < iUboundX ; x++)
{
for (y = 0 ; y < iUboundY ; y++)
{
MyMap.MapArray[x][y] = 0 ;
}
}
}
// If Snake Peaces Full, return True, else False
bool AddSnakePeace()
{
bool bFull = false ;
int i ;
for (i = 0 ; i < MAXSNAKEPEACES ; i++)
{
if (Snake[i].Visible == 0)
{
Player.iSnakeSize = i + 1 ;
Snake[i].Visible = 1 ;
Snake[i].xPos = Snake[i-1].xPos ;
Snake[i].yPos = Snake[i-1].yPos ;
if (Player.iSnakeSize == (Player.iLevel * 10))
bFull = true ;
// Delete the Pos of the food and add a new food !
MainMap.MapArray[Snake[0].xPos][Snake[0].yPos] = 0 ;
AddFood() ;
break ;
}
}
if (bFull)
return true ;
else
return false ;
}
void AddFood()
{
int iUboundX = cxGUI / iMapRaster ;
int iUboundY = (cyGUI - cyMenu) / iMapRaster ;
int iRandX, iRandY ;
while (TRUE)
{
iRandX = rand () % (iUboundX - 1) ;
iRandY = rand () % (iUboundY - 1) ;
if (MainMap.MapArray[iRandX][iRandY] == 0)
{
MainMap.MapArray[iRandX][iRandY] = 2 ;
break ;
}
}
}
void DrawMenu (HWND hwnd)
{
RECT rect ;
TCHAR szBuffer[100] ;
HBRUSH hbrush = CreateSolidBrush(RGB(80,80,80)) ;
SetRect (&rect, 0, cyGUI - cyMenu, cxGUI, cyGUI) ;
HDC hdc = GetDC (hwnd) ;
FillRect (hdc,&rect, hbrush) ;
SetBkMode (hdc, TRANSPARENT) ;
SetTextColor (hdc, RGB (255,255,255)) ;
_stprintf(szBuffer, _T ("%s%d"), TEXT ("Level: "), Player.iLevel) ;
TextOut (hdc, 10, (cyGUI - cyMenu) + 10 , szBuffer, lstrlen (szBuffer)) ;
_stprintf(szBuffer, _T ("Snake size (%d/%d)"), Player.iSnakeSize, (Player.iLevel * 10)) ;
TextOut (hdc, 100, (cyGUI - cyMenu) + 10 , szBuffer, lstrlen (szBuffer)) ;
ReleaseDC (hwnd, hdc) ;
}
void RestSnake ()
{
int i ;
for (i = 1 ; i < MAXSNAKEPEACES ; i++)
{
Snake[i].Visible = 0 ;
Snake[i].xPos = 0 ;
Snake[i].yPos = 0 ;
}
Player.iSnakeSize = 1 ;
Snake[0].xPos = ((cxGUI / iMapRaster) / 2) ;
Snake[0].yPos = (((cyGUI - cyMenu) / iMapRaster) / 2) ;
}
void ResetMap ()
{
int x, y ;
int iUboundX = cxGUI / iMapRaster ;
int iUboundY = (cyGUI - cyMenu) / iMapRaster ;
for (x = 0 ; x < iUboundX ; x++)
{
for (y = 0 ; y < iUboundY ; y++)
{
MainMap.MapArray[x][y] = 0 ;
}
}
}
int TimerInit ()
{
clock_t Stamp = clock () ;
return (int)Stamp ;
}
int TimerDiff (int Timestamp)
{
clock_t Stamp = clock () ;
return (int)((Stamp - Timestamp) / (CLOCKS_PER_SEC / 1000)) ;
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Snake By Darter") ;
HWND hwnd ;
MSG msg ;
WNDCLASS wndclass ;
TCHAR szBuffer[100] ;
HBRUSH hbrush = CreateSolidBrush(RGB(200,200,200)) ;
int Stamp = TimerInit () ;
int x, y, i;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = hbrush ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{ // Unicode Compilierung kann nur ein fehler sein !
MessageBox (NULL, TEXT("Fehler"), szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, //Name der Fensterklasse
TEXT ("Snake By Darter"), //Fenstertitel
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, //Styles
CW_USEDEFAULT, //X-Pos
CW_USEDEFAULT, //Y-Pos
cxGUI, //Breite
cyGUI, //Höhe
NULL, //Parent Fenster
NULL, //Menü
hInstance, //Programm-Kopiezähler
NULL) ; //Sonstige Parameter
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
// Loop witch alloywed me to to something else !
while (TRUE)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break ;
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
else
{
if (TimerDiff (Stamp) > (1000 / fps) && iScreen == PLAYINGSCREEN)
{
switch (curren_dir)
{
case 1:
x = 0 ;
y = -1 ;
break ;
case 2 :
x = 1 ;
y = 0 ;
break;
case 3 :
x = 0 ;
y = 1 ;
break ;
case 4 :
x = -1 ;
y = 0 ;
break ;
}
for (i = MAXSNAKEPEACES ; i > 0 ; i--)
{
Snake[i].xPos = Snake[i-1].xPos ;
Snake[i].yPos = Snake[i-1].yPos ;
}
Snake[0].xPos = Snake[0].xPos + x ;
Snake[0].yPos = Snake[0].yPos + y ;
// Check if Head pos == Food Pos
if (MainMap.MapArray[Snake[0].xPos][Snake[0].yPos] == 2)
{
if (AddSnakePeace())
{
Player.iLevel++ ;
fps = fps + (Player.iLevel) ;
}
}
// Check if Head pos <> Map size
if (Snake[0].xPos < 0 || Snake[0].yPos < 0 ||
Snake[0].xPos > (cxGUI / iMapRaster -2) || Snake[0].yPos > ((cyGUI - cyMenu) / iMapRaster) -1)
iScreen = LOOSESCREEN ;
// Check if Head Pos = Body Pos
for (i = 2 ; i < MAXSNAKEPEACES ; i++)
{
if (Snake[i].Visible && Snake[0].xPos == Snake[i].xPos && Snake[0].yPos == Snake[i].yPos)
{
iScreen = LOOSESCREEN ;
break;
}
}
InvalidateRect (hwnd, NULL, TRUE) ;
Stamp = TimerInit () ;
}
Sleep(20) ;
}
};
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
static int cxChar, cyChar ;
static int cxClient, cyClient ;
static int iStartButtonW, iStartButtonH ;
static int iStartCounter, iShowLevelCounter ;
int i ;
TCHAR szBuffer[100] ;
switch (message)
{
case WM_CREATE :
int iDesktW, iDesktH ;
RECT rect ;
// Set the Act Screen to Startscreen
iScreen = STARTSCREEN ;
// Set the start dir witch the snake should go
curren_dir = 3 ;
iDesktW = GetSystemMetrics(SM_CXSCREEN) ;
iDesktH = GetSystemMetrics(SM_CYSCREEN) ;
// Get Char width and height
cxChar = LOWORD (GetDialogBaseUnits()) ;
cyChar = HIWORD (GetDialogBaseUnits()) ;
iStartButtonW = 20 * cxChar ;
iStartButtonH = 7 * cyChar / 4 ;
GetClientRect (hwnd, &rect) ;
// Move the WIndow in the Center of the Screen
MoveWindow(hwnd, (iDesktW / 2) - (cxGUI / 2), (iDesktH / 2) - (cyGUI / 2), rect.right, rect.bottom, FALSE) ;
CreateWindow ( TEXT ("Button"), // Classenname
TEXT ("Start"), // Beschriftung
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, // Style
(cxGUI / 2) - (iStartButtonW / 2), // xPos
(cyGUI / 2) - (iStartButtonH / 2), // yPos
iStartButtonW, // Breite
iStartButtonH, // Höhe
hwnd, // Parent
(HMENU) BUTTONSTART, // Ist hier die ID, hat nichts mit einem Menü zu tun !
((LPCREATESTRUCT) lParam) -> hInstance, NULL ) ;
return 0 ;
case WM_PAINT :
RECT Map, RasterPeace ;
HBRUSH hbrushBG, hbrushMenu ;
HBRUSH hbrushSnake, hbrushWall, hbrushFood ;
HFONT hFont ;
int iUboundX, iUboundY, x, y ;
hbrushBG = CreateSolidBrush(RGB(200,200,200)) ;
SetRect (&Map, 0, 0, cxGUI, cyGUI - cyMenu) ;
hdc = BeginPaint (hwnd, &ps) ;
switch (iScreen)
{
case STARTSCREEN :
break ;
case PLAYINGSCREEN :
hbrushSnake = CreateSolidBrush(RGB(10,10,10)) ;
hbrushWall = CreateSolidBrush(RGB(0,0,0)) ;
hbrushFood = CreateSolidBrush(RGB(10,200,10)) ;
FillRect(hdc, &Map, hbrushBG) ;
//Draw Walls, Food
iUboundX = cxGUI / iMapRaster ;
iUboundY = (cyGUI - cyMenu) / iMapRaster ;
for (x = 0 ; x < iUboundX ; x++)
{
for (y = 0 ; y < iUboundY ; y++)
{
switch (MainMap.MapArray[x][y])
{
case 1 : //Wall
SetRect(&RasterPeace, (x * iMapRaster), (y * iMapRaster),
(x * iMapRaster) + iMapRaster, (y * iMapRaster) + iMapRaster) ;
FillRect(hdc, &RasterPeace, hbrushWall) ;
break;
case 2 : //Food
SetRect(&RasterPeace, (x * iMapRaster), (y * iMapRaster),
(x * iMapRaster) + iMapRaster, (y * iMapRaster) + iMapRaster) ;
FillRect(hdc, &RasterPeace, hbrushFood) ;
break ;
}
}
}
// Draw Snake
for (i = 0 ; i < MAXSNAKEPEACES ; i++)
{
if (Snake[i].Visible == 1)
{
SetRect(&RasterPeace, (Snake[i].xPos * iMapRaster), (Snake[i].yPos * iMapRaster),
(Snake[i].xPos * iMapRaster) + iMapRaster, (Snake[i].yPos * iMapRaster) + iMapRaster) ;
FillRect(hdc, &RasterPeace, hbrushSnake) ;
}
}
DrawMenu (hwnd) ;
DeleteObject (hbrushSnake) ;
DeleteObject (hbrushWall) ;
DeleteObject (hbrushFood) ;
break ;
case LOOSESCREEN :
hFont = CreateFont(24, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Aral"));
SelectObject(hdc, hFont) ;
SetBkMode (hdc, TRANSPARENT) ;
DrawText (hdc, TEXT("Game Over! Press Space to try again!"), -1, &Map, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
DrawMenu (hwnd) ;
break ;
case STARTCOUNTDOWN :
FillRect(hdc, &Map, hbrushBG) ;
hFont = CreateFont(24, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Aral"));
SelectObject(hdc, hFont) ;
SetBkMode (hdc, TRANSPARENT) ;
SetTextColor (hdc, RGB (255, 0, 0)) ;
_stprintf(szBuffer, _T ("%s%d"), TEXT ("Game starts in : "), iStartCounter);
DrawText (hdc, szBuffer, -1, &Map, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
DrawMenu (hwnd) ;
break ;
}
EndPaint (hwnd, &ps) ;
DeleteObject (hbrushBG) ;
return 0 ;
case WM_SIZE :
return 0 ;
case WM_COMMAND :
switch (wParam)
{
case BUTTONSTART :
InvalidateRect (hwnd, NULL, TRUE) ;
Player.iLevel = 1 ;
iScreen = STARTCOUNTDOWN ;
DestroyWindow((HWND)lParam) ;
SetTimer(hwnd, TIMER_STARTCOUNT, 1000, NULL) ;
iStartCounter = 3;
fps = 10 ;
RestSnake () ;
break ;
}
return 0 ;
case WM_TIMER :
switch (wParam)
{
case TIMER_STARTCOUNT :
iStartCounter-- ;
InvalidateRect (hwnd, NULL, TRUE) ;
if (iStartCounter == 0)
{
KillTimer(hwnd, TIMER_STARTCOUNT) ;
iScreen = PLAYINGSCREEN ;
ResetMap () ;
CreateMap (Player.iLevel, MainMap) ;
AddFood() ;
}
break ;
}
return 0 ;
case WM_KEYDOWN :
switch (wParam)
{
case VK_LEFT :
curren_dir = 4 ;
break ;
case VK_RIGHT :
curren_dir = 2 ;
break ;
case VK_UP :
curren_dir = 1 ;
break ;
case VK_DOWN :
curren_dir = 3 ;
break ;
case VK_SPACE :
if (iScreen == LOOSESCREEN)
PostMessage (hwnd, WM_COMMAND, BUTTONSTART, NULL) ;
break ;
}
break ;
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
Alles anzeigen
"Main.h"
Ich wollte eig. den Kompletten VS Projektordner anhängen, leider ist dieser etwas zu groß xD, deshalb nur die Exe in nem Rar verpackt.
mfg