I have been trying to test some things and I have recently run into a bizarre problem with outputting characters in a console application, among other problems. The code is a little long, but I really have no idea what is causing the problem and can not narrow it down so I included the whole code.
Main program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#include <iostream>
#include <ctime>
#include <windows.h>
#include "Coord.h"
//#define debug
using namespace std;
class target {
public:
target();
bool active;
short x, y;
};
target::target() {
active = true;
x = 80;
y = 30;
}
int main() {
//START Initialization
int x = 0;
int y = 0;
int x2 = 0;
int y2 = 0;
long int points = 0;
//Initialize rand
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
//Cursor properties structure
CONSOLE_CURSOR_INFO ConCurInf;
ConCurInf.dwSize = 10;
//Invisible
ConCurInf.bVisible = FALSE;
//Set
SetConsoleCursorInfo(stdOut, &ConCurInf);
SMALL_RECT windowSize = {0, 0, 159, 60}; //Left, top, right, bottom coordinates
// Change the console window size to the values specified in windowsize
SetConsoleWindowInfo(stdOut, TRUE, &windowSize);
//Create a COORD
COORD bufferSize = {160, 61};
// Change the screen buffer size to the values specified in buffersize
SetConsoleScreenBufferSize(stdOut, bufferSize);
SetConsoleTitle( TEXT("MouseTest") );
HWND hWnd = FindWindow(NULL,TEXT("MouseTest"));
ShowWindow(hWnd, SW_SHOWMAXIMIZED);
//Stores cursor position
POINT pos;
//END Initialization
target targets[10];
while(true) {
#ifndef debug
xy(0, 0);//Output points
cout << "Points: " << points;
#endif
for(int i = 0; i <= 10; i++) { //Outputs all targets
xy(targets[i].x, targets[i].y);
cout << "@";
}
//Gets the current cursor position
GetCursorPos(&pos);
#ifdef debug
//x2 and y2 are the raw (x,y) values recieved
x2 = pos.x;
y2 = pos.y;
xy(0, 0);
cout << "x " << x2 << " y " << y2 << endl;
#endif
y = int (pos.y / 13.3); //Calculate approximate x and y positions
x = int (pos.x / 7.99375);
y += 1; //Add 1 to y to compensate for the title bar space
#ifdef debug
//Output the (x,y) coordinate the mouse is calculated to be on
cout << "calculated x " << x << " y " << y << endl;
#endif
//Gives the player some leeway with a three space zone around the target that will count as touching it
for(int i = 0; i <= 3; i++) { //Checks all x values within 3 spaces
for(int n = 0; n <= 10; n++) { //Cycles through all targets
if(x == targets[n].x + i || x == targets[n].x - i) {
//If a target is within three spaces of the cursor on x axis, check y axis
for(int i = 0; i <= 3; i++) { //Checks all y values within 3 spaces
for(int n = 0; n <= 10; n++) { //Cycles through all targets
if(y == targets[n].y + i || y == targets[n].y - i) {
system("cls");
targets[n].active = false;
points += 315;
}
}
}
}
}
}
for(int i = 0; i <= 10; i++) { //Moves each target and checks if they leave the screen or hit something
targets[i].y += 1;
if(targets[i].y >= 60)
targets[i].active = false;
for(int n = 0; n <= 10; n++) {
if(targets[i].active == true && n != i) {
if((targets[i].x == targets[n].x) && (targets[i].y == targets[n].y))
targets[i].active = false;
}
}
}
for(int i = 0; i <= 10; i++) { //Respawns targets
if(targets[i].active == false) {
targets[i].x = rand() % 159;
targets[i].y = rand() % 60;
targets[i].active = true;
}
}
Sleep(10);
system("cls");
}
return 0;
}
|
and Coord.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
#ifndef _COORD_H_
#define _COORD_H_
//COORD Header
//Requires included windows header
//Function xy moves the console application pointer to a specified coordinate
void xy(int column, int row) { //Reads passed in values for where to output text
COORD coord; //COORD structure
coord.X = column; //X coordinate to output at
coord.Y = row; //Y coordinate to output at
SetConsoleCursorPosition( //Sets console application to coordinates
GetStdHandle( STD_OUTPUT_HANDLE ), coord);
}
#endif
|
I have a few things I need help with.
1. I have found that GetCursorPos() will return an (x,y) coordinate of where the cursor is, on the whole screen, whereas I want an(x,y) coordinate of where the cursor is, on the console application screen only. I had bodged it with a quick fix of taking my screen resolution (1280 x 800), and dividing it by the dimensions of the console application. That is why you see
y = int (pos.y / 13.3) and x = int (pos.x / 7.99375)
(And yes I know this is not portable). This does not work all the time, due to the casting to integer, so I had to then fix the fix by checking to see if the cursor is in the general area of the target. I am sure there had to be another better way to do this with the windows API, but I have not found one yet. Does anyone know of a way to do what I want to accomplish?
2.The second problem I faced was that I wanted the screen to start out maximized, which I thought would work with this:
1 2 3
|
SetConsoleTitle( TEXT("MouseTest") );
HWND hWnd = FindWindow(NULL,TEXT("MouseTest"));
ShowWindow(hWnd, SW_SHOWMAXIMIZED);
|
For some reason though, it is not working even though I am manually setting the title and getting a HWND from the exact same title. I was wondering if anyone knows what could be causing that to happen?
3. I at first had wanted each target object to start at a random spot by using rand() in the target::target constructor, but I found that putting a rand initialization outside of main() or another function would result in errors. Do I not need to give the rand initialization a gobal scope to use rand() in a class? Or it is just not possible to do? I have also found a problem in that because the clock is used as a seed, the program executes so fast that I often have multiple rand()s within less than a millisecond of each other, which causes them to produce similar values. Is there any way to prevent this other than using Sleep() to pause for a few milliseconds?
4. This one is just really bizarre. If you actually put this code into a project and run it, you will notice there are two targets(@ signs) that seem to "stick" to each other. They are side by side and move together without separating. I had even gone through twice in debug mode and checked every (x,y) coordinate in the array targets[], and there were no two (x,y) coordinates that were next to each other, yet on the console app. it showed them next to each other. No idea how this is happening at all.
Other than that, I would be glad if anyone would give me feedback on bad practices, ways to achieve better efficiency, etc., as I am still learning.
Thanks!