What do you think of my game I made, strictly in Windows API?
-
Here is the source code:
= "CodeBlocksWindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND+7; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Window's GDI Pixel Game", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The program's width */ 375, -
Here is the source code:
= "CodeBlocksWindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND+7; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Window's GDI Pixel Game", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The program's width */ 375,Well, the first thing that comes to mind is the approach you've taken to do repetitive tasks. The next is the ommision of tags that cause the code to be correctly formatted. (hint: Try 'code block', instead of 'inline code') Take for example, the following exerpt:
SetPixel(hdc, jmpjmp++, 165, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 166, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 167, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 168, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 169, RGB(80, 0, 125)); ... ... ...
Surely, it would make for cleaner/clearer code if it were written as a loop? I.e
x = jmpjmp; for (y=165; y<201; y++) SetPixel(hdc, x++, y, RBG(80,0,125));
I should also probably point out the fact that there are functions available for line drawing.. This may simplify your life somewhat. Try having a look around here[^] Hehe, but you should see some of my original code for a guessing game. Now _that_ code left some er, serious room for improvement. All the best :), good effort.
-
Here is the source code:
= "CodeBlocksWindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND+7; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Window's GDI Pixel Game", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The program's width */ 375,This is the wrong place for your message. This is a technical forum to ask serious questions about problems you may have, not for peer reviews of your code. If you think your program is useful then write an article around it and post in the Articles section. At a quick glance I would say you need to spend some more time with your programming guides (both C/C++ and Windows).
The best things in life are not things.
-
Well, the first thing that comes to mind is the approach you've taken to do repetitive tasks. The next is the ommision of tags that cause the code to be correctly formatted. (hint: Try 'code block', instead of 'inline code') Take for example, the following exerpt:
SetPixel(hdc, jmpjmp++, 165, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 166, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 167, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 168, RGB(80, 0, 125)); SetPixel(hdc, jmpjmp++, 169, RGB(80, 0, 125)); ... ... ...
Surely, it would make for cleaner/clearer code if it were written as a loop? I.e
x = jmpjmp; for (y=165; y<201; y++) SetPixel(hdc, x++, y, RBG(80,0,125));
I should also probably point out the fact that there are functions available for line drawing.. This may simplify your life somewhat. Try having a look around here[^] Hehe, but you should see some of my original code for a guessing game. Now _that_ code left some er, serious room for improvement. All the best :), good effort.
BUT the approach I've taken got the job done, didn't it? All in all, bad coding or not, you still have a working game(assuming someone actually compiled and tested the code).
-
BUT the approach I've taken got the job done, didn't it? All in all, bad coding or not, you still have a working game(assuming someone actually compiled and tested the code).
Okay, let me put this another way - The graphics are horrendous, there is noticeable flicker on a 12 month old pc, the initial window is too small to present the help message provided (instructions for the controls), I can't turn around without making a small movement in the new direction (can't turn around in place). On a different level = nothing changes apart from the diagonal line used to indicate the player's position.. With that in mind, why, oh why would you redraw the whole screen each time, P i x e l b y p a i n f u l l p i x e l? For goodness sake - draw the background once and assign that to the background of the window. Then all you have to do when the player position changes is call for a redraw and show the character in the updated position. As a result of drawing your background once and storing it as a bitmap to be used as the window background, the background can be effectively forgotten about except when it changes AND it's considerably faster to blast a bitmap onto the window than it is to redraw the ground, key and the cactii pixel by pixel for each frame. Add to that the fact that you've a WinMain that's nearly 2000 lines long!! :omg: :wtf: I'm scarred to look at how much redundant code there is in there. You do realize that you can create your own functions, right? Now if you think I'm being harsh, I'm sorry. I intended to offer constructive criticism on the coding style. Sure, of course you have a working game. But it's clearly substandard and unlikely to be much fun to anybody older than about 6 or 7. If you'd like praise for you efforts, perhaps you should ask the opinions of those with skills that are more akin to your own. If you'd like a fair and constructive critique of your work, you might find a thicker skin will leave you feeling more comfortable. Now then, let's see how much smaller this piece of work can be made!! [EDIT:] Jeepers Creepers! What on earth were you thinking - calling BeginPaint while in the code that responds to VK_RIGHT?? You should only ever call BeginPaint (and the corresponding EndPaint) in response to a WM_PAINT message, as seen here[^] Where did I leave the aspirin?
modified on Saturday, June 18, 2011 3:38 AM
-
BUT the approach I've taken got the job done, didn't it? All in all, bad coding or not, you still have a working game(assuming someone actually compiled and tested the code).
I've an answer for the question I posed in my last post - Just how small could I make this thing? (quickly and easily without too much thought) Just 364 lines ;P I avoided the suggestions I made with regards to drawing the background once onto a bitmap and then getting Windows to blast that bitmap onto the application window's background. All I did was remove redundant code and replace it with calls to functions.. By doing this, I am able to see an entire CASE statement inside WinMain on 1 screen now. It sure makes for easier understanding of the program. Here's a couple of small suggested alterations: 1. Replace code that draws your diagonal line - the character - with a call to the following.
void myDrawCharacter(HDC hdc, int xPos, int yPos, bool doesFaceRight)
{
MoveToEx(hdc, xPos, yPos, NULL);
if (doesFaceRight != 0)
LineTo(hdc, xPos+35, yPos+35);
else
LineTo(hdc, xPos-35, yPos+35);
}2. Never, EVER combine the functional code and the drawing code - I.e, in your code the act of drawing the character actually changes his position. :omg: For example, you may find the following achieves the same effect: Moving right
myDrawCharacter(hdc, jmpjmp, 165, true); jmpjmp+=35;
Moving Left
myDrawCharacter(hdc, jmpjmp, 165, false); jmpjmp-=35;
3. Please, please, p l e a s e! Don't repeat the pixel-by-pixel drawing code for the cactii ever-never-again! Much less repeat the entire block of code for each cactus for pretty much every case statement found in WinMain, P L E A S E:rose:
void myDrawCactus(HDC hdc, int xPosBotLeft, int yPosBotLeft, COLORREF col)
{
int curPoint;
HPEN curPen, newPen;
POINT cactusOutline[] =
{
{8,47}, {8,22}, {0,17}, {0,5}, {1,4},
{6,10}, {6,4}, {10,00}, {12,4}, {12,9},
{16,4}, {19,2}, {20,5}, {20,6}, {20,11},
{18,14}, {18,17}, {14,20}, {14,47}, {8,47}
};newPen = CreatePen(PS\_SOLID, 0, col); curPen = (HPEN)SelectObject(hdc, newPen); MoveToEx(hdc, cactusOutline\[0\].x+xPosBotLeft, cactusOutline\[0\].y+yPosBotLeft, NULL); for (curPoint=0; curPoint<20; curPoint++) LineTo(hdc, cactusOutline\[curPoint\].x+xPosBotLeft, cactusOutline\[curPoint\].y+yPosBotLeft); SelectObject(hdc, curPen); DeleteObject(newPen);
}
Replace the code you have with this function, and the following 2 calls:
myDrawCactus(hdc, 22, 108, RGB(0,100,0)); myDrawCactus(hdc, 122, 108, RGB(0,100,0));
Ahh, screw-it! The act of seeing another person's appro
-
Here is the source code:
= "CodeBlocksWindowsApp"; int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND+7; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "Window's GDI Pixel Game", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The program's width */ 375, -
A repost. 5th time.. Very bad.
// ♫ 99 little bugs in the code, // 99 bugs in the code // We fix a bug, compile it again // 101 little bugs in the code ♫
Just cruising through posts to see what I might pick up and saw your siggie. Cool. So true.
Thank you for your time If you work with telemetry, please check this bulletin board: www.irigbb.com