I am in the progress of making a game which uses SDL_TTF and SDL_Image. I have one function called browseinventory which allows you to check out the stats of an item once you hover over it. That's where the memory leak occurs. Baically once you've hovered over an item slot the program check if there's anything in said slot and if there is, Text class objects are set with the item's parameters and then rendered.
I am pretty sure that the fault lies within the Text class, as memory usage rapidly increases once I've hovered over an item.
Text class:
class Text
{
public:
Text() {w = 0; h = 0; saying = ""; Textthing = NULL;}
~Text(){destroy();}
void destroy(){SDL_DestroyTexture(Textthing); Textthing = 0; saying = "", w = 0, h = 0;}
void render(int, int, int, SDL_Renderer*);
void settext(string, SDL_Color);
void rendertest(int, int, SDL_Renderer*);
int rows;
private:
string saying;
SDL_Texture *Textthing;
int w, h;
unsigned int flag1 = 0, flag2, loops = 0;
string saying1;
unsigned int counter;
bool spaceflag = 0;
};
render():
void Text::render(int x, int y, int maxchars = 100, SDL_Renderer *Temp = Saviour)
{
rows = 0;
flag1 = 0, flag2 = maxchars, loops = 0;
int increment = maxchars;
if (resolution == "800x600")
{
flag2 = maxchars*0.8;
increment = maxchars*0.8;
}
spaceflag = 0;
do
{
spaceflag = 0;
for (counter = flag1; counter < flag2 && counter < saying.length(); counter++)
{
if (counter > flag2-10 && saying[counter] == ' ')
{
spaceflag = 1;
break;
}
saying1 += saying[counter];
}
asdfgfa1.settext(saying1);
asdfgfa1.rendertest(x, y + loops*(SCREEN_HEIGHT/19), Temp);
saying1 = "";
loops++;
rows++;
if (flag2 > saying.length())
break;
if (spaceflag == 0)
{
flag1 = flag2;
flag2 += increment;
}
else
{
flag1 = counter;
flag2 = counter + increment;
}
}while (1);
asdfgfa1.destroy();
SDL_DestroyTexture(Textthing);
Textthing = 0;
}
setText():
void Text::settext(string stuff, SDL_Color Colour = {255, 255, 255})
{
saying = stuff;
SDL_Surface *Surf = TTF_RenderText_Solid(Arial, stuff.c_str(), Colour);
w = Surf->w;
h = Surf->h;
Textthing = SDL_CreateTextureFromSurface(Saviour, Surf);
SDL_FreeSurface(Surf);
Surf = 0;
}
Related
I managed with some help to know how when two rectangles are intersecting each other, from there it should be easy to make what i just said in the title but ...
So, short story of what i just did below:
Created a for loop from 1 to Number_of_Obstacles
In that for an random obstacle (rectangle/square) is created and it will be checked if it is overlaped with all other obstacles created from 0 to the loop contor (or in other words every obstacle stored in the vector)
Again, the doOverLap function works. Tested it with a square which i made a controller and other random rectangle created on the screen. It outputs in chat when i'm overlaping it and trust me, i overlaped it from all angles.
Here is a picture with the overlaping issue: https://imgur.com/a/ZzorOcD
bool doOverlap(A a, B b)
{
if (a.x1 > b.x2 || b.x1 > a.x2)
return false;
if (a.y1 > b.y2 || b.y1 > a.y2)
return false;
return true;
}
struct Obstacles {
int X, Y;
void Create_Random_Obstacles(Obstacles Obj[], int Numar_Obstacole)
{
srand(time(NULL));
A Rectangle_1;
B Rectangle_2;
/* To avoid rendering outside of the screen */
int X_Axis = X_RESOLUTION - 40;
int Y_Axis = Y_RESOLUTION - 40;
int obstacolX = rand() % X_Axis + 1;
int obstacolY = rand() % Y_Axis + 1;
Obj[0].X = obstacolX;
Obj[0].Y = obstacolY;
for (int i = 1; i < Numar_Obstacole; i++)
{
obstacolX = rand() % X_Axis + 1;
obstacolY = rand() % Y_Axis + 1;
Rectangle_1.x1 = obstacolX;
Rectangle_1.x2 = obstacolX + 40;
Rectangle_1.y1 = obstacolY;
Rectangle_1.y2 = obstacolY + 40;
for (int j = 0; j < i; j++) {
Rectangle_2.x1 = Obj[j].X;
Rectangle_2.x2 = Obj[j].X + 40;
Rectangle_2.y1 = Obj[j].Y;
Rectangle_2.y2 = Obj[j].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2))
{
std::cout << "Overlap\n";
}
else
{
Obj[i].X = obstacolX;
Obj[i].Y = obstacolY;
}
}
}
}
void Render(SDL_Renderer* renderer, Obstacles Obj[], int Numar_Obstacole) {
for (int i = 0; i < Numar_Obstacole; i++)
{
SDL_Rect r{ Obj[i].X, Obj[i].Y, 40, 40 };
SDL_SetRenderDrawColor(renderer, 255, 160, 15, 255);
SDL_RenderFillRect(renderer, &r);
}
}
};
Restart selection when collision occurs, something like:
bool Has_Overlap(const Obstacles& obj, const Obstacles* Objs, int Size)
{
B Rectangle_2;
Rectangle_2.x1 = obs.X;
Rectangle_2.x2 = obs.X + 40;
Rectangle_2.y1 = obs.Y;
Rectangle_2.y2 = obs.Y + 40;
for (int i = 0; i != Size; ++i) {
A Rectangle_1;
Rectangle_1.x1 = Obs[i].X;
Rectangle_1.x2 = Obs[i].X + 40;
Rectangle_1.y1 = Obs[i].Y;
Rectangle_1.y2 = Obs[i].Y + 40;
if (doOverlap(Rectangle_1, Rectangle_2)) {
return true;
}
}
return false;
}
void Create_Random_Obstacles(Obstacles* Objs, int Size)
{
/* To avoid rendering outside of the screen */
const int X_Axis = X_RESOLUTION - 40;
const int Y_Axis = Y_RESOLUTION - 40;
for (int i = 0; i < Size; i++)
{
do {
Objs[i].X = rand() % X_Axis + 1;
Objs[i].Y = rand() % Y_Axis + 1;
} while (Has_Overlap(Objs[i], Objs, i));
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
So I used to use Code::Blocks IDE, and like it a lot. Recently I switched to Visual Studio. I downloaded VS Express, it was 600mb and I can only use 1gb data per day, I don't have Wi-Fi, so I that was my only option.I inserted the same code that compiled properly in Code::Blocks in it , it took a few tweaks to make it work in VS, but when I finally check it, the output was totally different, Instead of a command line Tetris, it glitched and filled the command prompt with strange characters.
This is the code I tweaked a bit to make it work in VS:
#include <iostream>
#include <time.h>
#include <string>
#include <windows.h>
using namespace std;
int nScreenHeight = 30;
int nScreenWidth = 80;
int nFieldWidth = 10;
int nFieldHeight = 25;
unsigned char *pField = NULL;
wstring tetromine[7];
int currentPiece = 0;
int currentRotation = 0;
int currentX = (nFieldWidth/2);
int currentY = 0;
unsigned int score = 0;
int pieceCounter = 0;
int speed = 20;
int speedCounter = 0;
bool forcePieceDown =false;
bool key[4];
bool shiftGridDown = false;
int rotate(int px,int py,int r)
{
switch(r/90)
{
case 0:
return py*4+px;//0 degs
case 1:
return 12+py - (px*4);//90 degs
case 2:
return 15 - (py*4) - px;//180 degs
case 3:
return 3 - py + (px*4);//270 degs
}
return 0;
}
int doesPieceFit(int id,int rot, int x, int y)
{
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
int pi = rotate(px,py,rot);
int fi = (y+py) * nFieldWidth + (x+px);
if(x + px>= 0 && x+px < nFieldWidth){
if(tetromine[id][pi] == L'X' && pField[fi]!=0){
return false;
}
}
}
}
return true;
}
void lineCheck(){
bool line = true;
int lines = 0;
for(int y = 0; y<= nFieldHeight-1;y++){
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(y)*nFieldWidth+x]!=0){
line &= true;
} else line &= false;
}
if(line) lines++;
if(line){
for(int x = 1; x< nFieldWidth-1;x++){
pField[(y)*nFieldWidth+x] = 8;
}
}
}
}
int main()
{
//assets
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[1].append(L"..X.");
tetromine[1].append(L".XX.");
tetromine[1].append(L".X..");
tetromine[1].append(L"....");
tetromine[2].append(L".X..");
tetromine[2].append(L".XX.");
tetromine[2].append(L"..X.");
tetromine[2].append(L"....");
tetromine[3].append(L"....");
tetromine[3].append(L".XX.");
tetromine[3].append(L".XX.");
tetromine[3].append(L"....");
tetromine[4].append(L"..X.");
tetromine[4].append(L".XX.");
tetromine[4].append(L"..X.");
tetromine[4].append(L"....");
tetromine[5].append(L"....");
tetromine[5].append(L".XX.");
tetromine[5].append(L"..X.");
tetromine[5].append(L"..X.");
tetromine[6].append(L"....");
tetromine[6].append(L".XX.");
tetromine[6].append(L".X..");
tetromine[6].append(L".X..");
pField = new unsigned char[nFieldWidth*nFieldHeight];
for(int x = 0; x<nFieldWidth; x++)
{
for(int y = 0; y<nFieldHeight; y++)
{
pField[y*nFieldWidth + x] = (x==0||x==nFieldWidth -1 || y == nFieldHeight - 1) ? 9 : 0;
}
}
char *screen = new char [nScreenWidth * nScreenHeight];
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole);
DWORD dwBytesWritten = 0;
//Display frame
COORD here;
here.X = 0;
here.Y = 0;
WriteConsoleOutputCharacter(hConsole, (LPCWSTR)screen, nScreenWidth * nScreenHeight,here, &dwBytesWritten);
bool gameOver = false;
while(!gameOver)
{
Sleep(100);
speedCounter++;
if(speedCounter>=speed){
forcePieceDown = true;
speedCounter = 0;
} else {
forcePieceDown = false;
}
if(shiftGridDown){
score++;
for(int y = nFieldHeight-2;y > 0;y--){
for(int x = 1;x<nFieldWidth -1;x++){
if((pField[(y)*nFieldWidth+x]) != 0){
pField[(y+1)*nFieldWidth+x] = pField[(y)*nFieldWidth+x];
pField[(y)*nFieldWidth+x] = 0;
}
}
}
shiftGridDown = false;
lineCheck();
}
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(nFieldHeight-2)*nFieldWidth+x]==8){
pField[(nFieldHeight-2)*nFieldWidth+x]=0;
if(x==nFieldWidth-2){
shiftGridDown = true;
score+=100;
}
}
}
for(int k = 0;k<4;k++){ // R L D Z
key[k] = (0x8000 & GetAsyncKeyState((unsigned char)("DASZ"[k]))) != 0;
}
if(key[1]){
if(doesPieceFit(currentPiece,currentRotation,currentX-1,currentY)){
currentX = currentX-1;
}
}else if(key[0]){
if(doesPieceFit(currentPiece,currentRotation,currentX+1,currentY)){
currentX = currentX+1;
}
}if(key[2]){
speedCounter = speed;
}
if(key[3]&&doesPieceFit(currentPiece,currentRotation+90,currentX,currentY)){
(currentRotation+90<=270)?currentRotation+=90:currentRotation=0;
}
if(forcePieceDown){
if(doesPieceFit(currentPiece,currentRotation,currentX,currentY+1))
currentY++;
else {
//lock piece
pieceCounter++;
if(pieceCounter%5==0){
speed-=1;
}
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)]==L'X'){
pField[(currentY+py)*nFieldWidth+(currentX+px)] = currentPiece+1;
}
}
}
score+=20;
//check lines
lineCheck();
//get next piece
currentX = nFieldWidth/2;
currentY = 0;
currentRotation = 0;
srand(time(0));
currentPiece = rand() % 7;
//check game over
gameOver = !doesPieceFit(currentPiece,currentRotation,currentX,currentY);
}
}
//draw field
for(int x = 0; x < nFieldWidth; x++)
{
for(int y = 0; y < nFieldHeight; y++)
{
screen[(y+2)*nScreenWidth + (x+ 2)] = L" xxxxxxx=#"[pField[y*nFieldWidth + x]];
}
}
//draw piece
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)] == L'X'){
screen[(currentY+py+2)*nScreenWidth+(currentX+px+2)] = '+';
}
}
}
string s("Score -> ");
string num;
int tmp = score;
while(tmp!=0){
int rem = tmp%10;
tmp /= 10;
num = ((char)(48+rem)) + num;
}
s+=num;
for(int i = 0; i<s.size();i++){
screen[i] = s[i];
}
//display frame
WriteConsoleOutputCharacter(hConsole, (LPCWSTR)screen, nScreenWidth * nScreenHeight,here, &dwBytesWritten);
}
return 0;
}
This is the origional code :
#include <iostream>
#include <time.h>
#include <string>
#include <windows.h>
using namespace std;
int nScreenHeight = 30;
int nScreenWidth = 80;
int nFieldWidth = 10;
int nFieldHeight = 25;
unsigned char *pField = NULL;
wstring tetromine[7];
int currentPiece = 0;
int currentRotation = 0;
int currentX = (nFieldWidth/2);
int currentY = 0;
unsigned int score = 0;
int pieceCounter = 0;
int speed = 20;
int speedCounter = 0;
bool forcePieceDown =false;
bool key[4];
bool shiftGridDown = false;
int rotate(int px,int py,int r)
{
switch(r/90)
{
case 0:
return py*4+px;//0 degs
case 1:
return 12+py - (px*4);//90 degs
case 2:
return 15 - (py*4) - px;//180 degs
case 3:
return 3 - py + (px*4);//270 degs
}
return 0;
}
int doesPieceFit(int id,int rot, int x, int y)
{
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
int pi = rotate(px,py,rot);
int fi = (y+py) * nFieldWidth + (x+px);
if(x + px>= 0 && x+px < nFieldWidth){
if(tetromine[id][pi] == L'X' && pField[fi]!=0){
return false;
}
}
}
}
return true;
}
void lineCheck(){
bool line = true;
int lines = 0;
for(int y = 0; y<= nFieldHeight-1;y++){
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(y)*nFieldWidth+x]!=0){
line &= true;
} else line &= false;
}
if(line) lines++;
if(line){
for(int x = 1; x< nFieldWidth-1;x++){
pField[(y)*nFieldWidth+x] = 8;
}
}
}
}
int main()
{
//assets
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[0].append(L"..X.");
tetromine[1].append(L"..X.");
tetromine[1].append(L".XX.");
tetromine[1].append(L".X..");
tetromine[1].append(L"....");
tetromine[2].append(L".X..");
tetromine[2].append(L".XX.");
tetromine[2].append(L"..X.");
tetromine[2].append(L"....");
tetromine[3].append(L"....");
tetromine[3].append(L".XX.");
tetromine[3].append(L".XX.");
tetromine[3].append(L"....");
tetromine[4].append(L"..X.");
tetromine[4].append(L".XX.");
tetromine[4].append(L"..X.");
tetromine[4].append(L"....");
tetromine[5].append(L"....");
tetromine[5].append(L".XX.");
tetromine[5].append(L"..X.");
tetromine[5].append(L"..X.");
tetromine[6].append(L"....");
tetromine[6].append(L".XX.");
tetromine[6].append(L".X..");
tetromine[6].append(L".X..");
pField = new unsigned char[nFieldWidth*nFieldHeight];
for(int x = 0; x<nFieldWidth; x++)
{
for(int y = 0; y<nFieldHeight; y++)
{
pField[y*nFieldWidth + x] = (x==0||x==nFieldWidth -1 || y == nFieldHeight - 1) ? 9 : 0;
}
}
char *screen = new char [nScreenWidth * nScreenHeight];
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole);
DWORD dwBytesWritten = 0;
//Display frame
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, {0,0}, &dwBytesWritten);
bool gameOver = false;
while(!gameOver)
{
Sleep(100);
speedCounter++;
if(speedCounter>=speed){
forcePieceDown = true;
speedCounter = 0;
} else {
forcePieceDown = false;
}
if(shiftGridDown){
score++;
for(int y = nFieldHeight-2;y > 0;y--){
for(int x = 1;x<nFieldWidth -1;x++){
if((pField[(y)*nFieldWidth+x]) != 0){
pField[(y+1)*nFieldWidth+x] = pField[(y)*nFieldWidth+x];
pField[(y)*nFieldWidth+x] = 0;
}
}
}
shiftGridDown = false;
lineCheck();
}
for(int x = 1; x< nFieldWidth-1;x++){
if(pField[(nFieldHeight-2)*nFieldWidth+x]==8){
pField[(nFieldHeight-2)*nFieldWidth+x]=0;
if(x==nFieldWidth-2){
shiftGridDown = true;
score+=100;
}
}
}
for(int k = 0;k<4;k++){ // R L D Z
key[k] = (0x8000 & GetAsyncKeyState((unsigned char)("DASZ"[k]))) != 0;
}
if(key[1]){
if(doesPieceFit(currentPiece,currentRotation,currentX-1,currentY)){
currentX = currentX-1;
}
}else if(key[0]){
if(doesPieceFit(currentPiece,currentRotation,currentX+1,currentY)){
currentX = currentX+1;
}
}if(key[2]){
speedCounter = speed;
}
if(key[3]&&doesPieceFit(currentPiece,currentRotation+90,currentX,currentY)){
(currentRotation+90<=270)?currentRotation+=90:currentRotation=0;
}
if(forcePieceDown){
if(doesPieceFit(currentPiece,currentRotation,currentX,currentY+1))
currentY++;
else {
//lock piece
pieceCounter++;
if(pieceCounter%5==0){
speed-=1;
}
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)]==L'X'){
pField[(currentY+py)*nFieldWidth+(currentX+px)] = currentPiece+1;
}
}
}
score+=20;
//check lines
lineCheck();
//get next piece
currentX = nFieldWidth/2;
currentY = 0;
currentRotation = 0;
srand(time(0));
currentPiece = rand() % 7;
//check game over
gameOver = !doesPieceFit(currentPiece,currentRotation,currentX,currentY);
}
}
//draw field
for(int x = 0; x < nFieldWidth; x++)
{
for(int y = 0; y < nFieldHeight; y++)
{
screen[(y+2)*nScreenWidth + (x+ 2)] = L" xxxxxxx=#"[pField[y*nFieldWidth + x]];
}
}
//draw piece
for(int px = 0;px<4;px++){
for(int py = 0;py<4;py++){
if(tetromine[currentPiece][rotate(px,py,currentRotation)] == L'X'){
screen[(currentY+py+2)*nScreenWidth+(currentX+px+2)] = '+';
}
}
}
string s("Score -> ");
string num;
int tmp = score;
while(tmp!=0){
int rem = tmp%10;
tmp /= 10;
num = ((char)(48+rem)) + num;
}
s+=num;
for(int i = 0; i<s.size();i++){
screen[i] = s[i];
}
//display frame
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0, 0}, &dwBytesWritten);
}
return 0;
}
You have a mix of narrow and wide characters. The cast (LPCWSTR)screen in your call to WriteConsoleOutputCharacter is an indication something isn't right.
In this case, screen is a char but you want it to be wchar_t instead. You're already using wstring for tetromine, and L prefixed character strings. You just need to ensure the rest of the code is also using wide characters.
I am trying to write a program that simulates a chess game with the FLTK library.
My problem is that I want to do two callbacks on an two dimension array of buttons, I want to click a button, then click another button and when the second button is clicked have the label of the first button switch to the label of the second button and then delete the label of the first button.
I feel like I need someway of storing the value of the the first button that is clicked, for example if I click FBoard[1][2] the i have a variable that is equal to FBoard[1][2] and open the second click replace the label of FBoard[1][2] to blank (assuming FBoard[1][2] is a cell on the board that has a piece on it. But I'm not sure how or even if this is the right approach.
Here is the cpp file:
#include"Window.h"
#include"ChessBoard.h"
const char * DisplayWindow::LastLabel;
bool DisplayWindow::flag;
DisplayWindow::DisplayWindow(int width, int height, const char*)
:Fl_Window(800, 650, "Chess"){
for (int X = 0; X <= 7; ++X){
for (int Y = 0; Y <= 7; ++Y){
// Leaves all positions that arent occupied by
// a figure at the start of the game blank
FBoard[X][Y] = new Fl_Button(10 + 50*Y, 100 + 50*X, 50, 50,"");
FBoard[X][Y]->callback((Fl_Callback*)DisplayWindow::ChangeButton);
}
}
flag = false;
MakeLabel();
LabelButton();
show();
}
DisplayWindow::~DisplayWindow(){}
void DisplayWindow::MakeLabel(){
for (int X = 0; X <= 7; ++X){
for (int Y = 0; Y <= 7; ++Y){
LBoard[X][Y] = (" ");
}
}
for (int X = 0; X <= 7; ++X){
LBoard[1][X] = ("WP");
// Occupies second row with white pawns
}
LBoard[0][0] = ("WR");
LBoard[0][1] = ("WH");
LBoard[0][2] = ("WB");
LBoard[0][3] = ("WQ");
LBoard[0][4] = ("WK");
LBoard[0][5] = ("WB");
LBoard[0][6] = ("WH");
LBoard[0][7] = ("WR");
for (int X = 0; X <= 7; ++X){
LBoard[6][X] = ("BP");
}
LBoard[7][0] = ("BR");
LBoard[7][1] = ("BH");
LBoard[7][2] = ("BB");
LBoard[7][3] = ("BQ");
LBoard[7][4] = ("BK");
LBoard[7][5] = ("BB");
LBoard[7][6] = ("BH");
LBoard[7][7] = ("BR");
}
void DisplayWindow::LabelButton(){
for (int X = 0; X <= 7; ++X){
FBoard[1][X]->label(LBoard[1][X]);
// Occupies second row with white pawns
}
FBoard[0][0]->label(LBoard[0][0]);
FBoard[0][1]->label(LBoard[0][1]);
FBoard[0][2]->label(LBoard[0][2]);
FBoard[0][3]->label(LBoard[0][3]);
FBoard[0][4]->label(LBoard[0][4]);
FBoard[0][5]->label(LBoard[0][5]);
FBoard[0][6]->label(LBoard[0][6]);
FBoard[0][7]->label(LBoard[0][7]);
for (int X = 0; X <= 7; ++X){
FBoard[6][X]->label(LBoard[6][X]);
}
FBoard[7][0] ->label(LBoard[7][0]);
FBoard[7][1] ->label(LBoard[7][1]);
FBoard[7][2] ->label(LBoard[7][2]);
FBoard[7][3] ->label(LBoard[7][3]);
FBoard[7][4] ->label(LBoard[7][4]);
FBoard[7][5] ->label(LBoard[7][5]);
FBoard[7][6] ->label(LBoard[7][6]);
FBoard[7][7] ->label(LBoard[7][7]);
for(int i=0 ; i<=7 ; i++)
{
for(int j=0 ; j<=7 ; j++)
{
int k=i+j;
if(k % 2 != 0 ){
FBoard[i][j]->color(FL_WHITE);
}
else if (k % 2 ==0 ){
FBoard[i][j]->color(FL_YELLOW);
}
}
}
}
void DisplayWindow::ChangeButton(Fl_Widget * o, void * v){
DisplayWindow* Win = (DisplayWindow *) v;
Fl_Button * NewBoard = (Fl_Button*) o;
if (Win->flag == false){
DisplayWindow::LastLabel = NewBoard->label();
NewBoard->label(" ");
Win->flag = true;
}
else{
NewBoard->label(DisplayWindow::LastLabel);
Win->flag = false;
}
}
And the Header file:
class DisplayWindow: public Fl_Window {
public:
DisplayWindow(int width, int height, const char* title=0);
virtual ~DisplayWindow();
void MakeLabel();
void LabelButton();
static void ChangeButton(Fl_Button * o, void * );
static bool flag;
bool flag1;
static const char * LastLabel;
private:
Fl_Button * FBoard[8][8];
char * LBoard[8][8];
};
#endif
cpp:
#include"Window.h"
#include"ChessBoard.h"
const char * DisplayWindow::LastLabel;
bool DisplayWindow::flag;
DisplayWindow::DisplayWindow(int width, int height, const char*)
:Fl_Window(800, 650, "Chess"){
for (int X = 0; X <= 7; ++X){
for (int Y = 0; Y <= 7; ++Y){
// Leaves all positions that arent occupied by
// a figure at the start of the game blank
FBoard[X][Y] = new Fl_Button(10 + 50*Y, 100 + 50*X, 50, 50,"");
FBoard[X][Y]->callback((Fl_Callback*)DisplayWindow::ChangeButton);
//FBoard[X][Y]->callback(ChangeButton);
}
}
flag = false;
MakeLabel();
LabelButton();
show();
}
DisplayWindow::~DisplayWindow(){}
void DisplayWindow::MakeLabel(){
for (int X = 0; X <= 7; ++X){
for (int Y = 0; Y <= 7; ++Y){
LBoard[X][Y] = (" ");
}
}
for (int X = 0; X <= 7; ++X){
LBoard[1][X] = ("WP");
// Occupies second row with white pawns
}
LBoard[0][0] = ("WR");
LBoard[0][1] = ("WH");
LBoard[0][2] = ("WB");
LBoard[0][3] = ("WQ");
LBoard[0][4] = ("WK");
LBoard[0][5] = ("WB");
LBoard[0][6] = ("WH");
LBoard[0][7] = ("WR");
for (int X = 0; X <= 7; ++X){
LBoard[6][X] = ("BP");
}
LBoard[7][0] = ("BR");
LBoard[7][1] = ("BH");
LBoard[7][2] = ("BB");
LBoard[7][3] = ("BQ");
LBoard[7][4] = ("BK");
LBoard[7][5] = ("BB");
LBoard[7][6] = ("BH");
LBoard[7][7] = ("BR");
}
void DisplayWindow::LabelButton(){
for (int X = 0; X <= 7; ++X){
FBoard[1][X]->label(LBoard[1][X]);
// Occupies second row with white pawns
}
FBoard[0][0]->label(LBoard[0][0]);
FBoard[0][1]->label(LBoard[0][1]);
FBoard[0][2]->label(LBoard[0][2]);
FBoard[0][3]->label(LBoard[0][3]);
FBoard[0][4]->label(LBoard[0][4]);
FBoard[0][5]->label(LBoard[0][5]);
FBoard[0][6]->label(LBoard[0][6]);
FBoard[0][7]->label(LBoard[0][7]);
for (int X = 0; X <= 7; ++X){
FBoard[6][X]->label(LBoard[6][X]);
}
FBoard[7][0] ->label(LBoard[7][0]);
FBoard[7][1] ->label(LBoard[7][1]);
FBoard[7][2] ->label(LBoard[7][2]);
FBoard[7][3] ->label(LBoard[7][3]);
FBoard[7][4] ->label(LBoard[7][4]);
FBoard[7][5] ->label(LBoard[7][5]);
FBoard[7][6] ->label(LBoard[7][6]);
FBoard[7][7] ->label(LBoard[7][7]);
for(int i=0 ; i<=7 ; i++)
{
for(int j=0 ; j<=7 ; j++)
{
int k=i+j;
if(k % 2 != 0 ){
FBoard[i][j]->color(FL_WHITE);
}
else if (k % 2 ==0 ){
FBoard[i][j]->color(FL_YELLOW);
}
}
}
}
void DisplayWindow::ChangeButton(Fl_Widget * o, void * v){
DisplayWindow* Win = (DisplayWindow *) v;
Fl_Button * NewBoard = (Fl_Button*) o;
if (Win->flag == false){
DisplayWindow::LastLabel = NewBoard->label();
NewBoard->label(" ");
Win->flag = true;
}
else{
NewBoard->label(DisplayWindow::LastLabel);
Win->flag = false;
}
}
h:
#ifndef WINDOW_H_
#define WINDOW_H_
#include<vector>
#include<limits>
#include<string>
#include<iostream>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
class DisplayWindow: public Fl_Window {
public:
DisplayWindow(int width, int height, const char* title=0);
virtual ~DisplayWindow();
void MakeLabel();
void LabelButton();
static void ChangeButton(Fl_Widget * o, void * );
static bool flag;
bool flag1;
static const char * LastLabel;
private:
Fl_Button * FBoard[8][8];
char * LBoard[8][8];
};
#endif
Okay so I am a college student and our professor gave us this code to examine, and I was wondering if there was another way to do this but for OS X. My professor is using a HANDLE which I barely understand what that is, the professor was telling me he create the HANDLE as a pointer to the output stream so what would be the equivalent to it for mac since we don't have #include Windows.h obviously. Everything you see in this code is my professor's, including the comments.
//This is an example of a simple platformer made in the console. This
//makes no claims as the best way of doing things as I created this
//live before a class (while taking suggestions from them).
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
using namespace std;
const int MAX_ROWS = 20;
const int MAX_COLS = 60;
//this is a reference to cout (we got this when we changed the output color)
//we can use this to setCursorPosition
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
//this is the place that we can set the cursor to when we are not using it
COORD zero;
//basic cardinal directions
enum Direction
{
UP = 8,
DOWN = 2,
RIGHT = 6,
LEFT = 4,
NORTH = UP,
SOUTH = DOWN,
EAST = RIGHT,
WEST = LEFT
};
//each place on the gameboard is a tile (tiles in this game are 1 character in length, though they do not have to be)
class Tile
{
public:
char display;
bool isPassible;
COORD pos;
Tile(char d, bool b, int y, int x)
{
display = d;
isPassible = b;
pos.X = x;
pos.Y = y;
}
void Display()
{
SetConsoleCursorPosition(output, pos);
cout << display;
SetConsoleCursorPosition(output, zero);
}
};
class Player
{
public:
COORD pos;
char display;
int JumpAmt;
//player constructor (x and y are starting location)
Player(int x, int y)
{
pos.X = x;
pos.Y = y;
display = 'C';
JumpAmt = 0;
}
//This gets the input and decides how to use it (this should be called in the main game loop)
bool Act(vector<vector<Tile>> GameBoard)
{
bool didMove = false;
COORD oldPos;
oldPos.X = pos.X;
oldPos.Y = pos.Y;
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
{
//make sure the movement is not off the game board and that there is not a wall in the way
if (pos.X + 1 < MAX_COLS && GameBoard[pos.Y][pos.X + 1].isPassible)
{
//actually move the character
pos.X += 1;
didMove = true;
}
}
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
if (pos.X - 1 > 0 && GameBoard[pos.Y][pos.X - 1].isPassible)
{
pos.X -= 1;
didMove = true;
}
}
//You can only jump if you are on the ground
if (pos.Y + 1 < MAX_ROWS && !(GameBoard[pos.Y + 1][pos.X].isPassible))
{
if (GetAsyncKeyState(VK_UP) & 0x8000)
{
if (pos.Y - 1 > 0 && GameBoard[pos.Y - 1][pos.X].isPassible)
{
pos.Y -= 1;
didMove = true;
JumpAmt = 4;
}
}
}
//When you are not jumping fall (gravity)
if (JumpAmt == 0)
{
if (pos.Y + 1 < MAX_ROWS && GameBoard[pos.Y + 1][pos.X].isPassible)
{
pos.Y += 1;
didMove = true;
}
}
//This is what happens during your jump
if (JumpAmt > 0)
{
JumpAmt--;
if (pos.Y - 1 > 0 && GameBoard[pos.Y - 1][pos.X].isPassible)
{
pos.Y -= 1;
didMove = true;
}
}
//If you did move anywhere then update the board
if (didMove)
{
Display(oldPos, GameBoard);
}
return didMove;
}
void Display()
{
//draw myself at my position
SetConsoleCursorPosition(output, pos);
cout << display;
SetConsoleCursorPosition(output, zero);
}
void Display(COORD fix, vector<vector<Tile>> GameBoard)
{
//clear my old position
GameBoard[fix.Y][fix.X].Display();
Display();
}
};
int main()
{
//zero is used after anything is drawn to reset the cursor (this should never be changed after this)
zero.X = 0;
zero.Y = 0;
//this is a 2 dimentional array of tiles
vector<vector<Tile>> GameBoard;
//init all the tiles to blank (we will later add in platforms and stuff over top of these)
for (int row = 0; row < MAX_ROWS; row++)
{
vector<Tile> thisRow;
for (int col = 0; col < MAX_COLS; col++)
{
thisRow.push_back(Tile(' ', true, row, col));
}
GameBoard.push_back(thisRow);
}
//Build the game specific tiles (in a perfect world these would be read in from a file)
GameBoard[4][2] = Tile('-', false,4,2);
GameBoard[4][3] = Tile('-', false, 4,3);
GameBoard[4][4] = Tile('-', false, 4,4);
GameBoard[4][5] = Tile('-', false, 4,5);
GameBoard[4][6] = Tile('-', false, 4,6);
GameBoard[7][9] = Tile('-', false, 7,9);
GameBoard[7][10] = Tile('-', false, 7,10);
GameBoard[5][10] = Tile('-', false, 5,10);
GameBoard[8][14] = Tile('*', false, 8, 14); //this marks the win square
//display the board once
for (int row = 0; row < MAX_ROWS; row++)
{
for (int col = 0; col < MAX_COLS; col++)
{
GameBoard[row][col].Display();
}
}
//Bob is our hero
Player bob = Player(3, 3);
while (true)
{
bob.Act(GameBoard);
bob.Display();
Sleep(50);
//if bob falls down he dies
if (bob.pos.Y > 18)
{
bob.pos.X = 3;
bob.pos.Y = 3;
//bob.display = 65 + rand() % 26;
}
//if bob gets here he wins
if (bob.pos.Y == 7 && bob.pos.X == 14)
{
COORD pos;
pos.Y = 20;
pos.X = 0;
SetConsoleCursorPosition(output, pos);
cout << "You are Awesome";
break;
}
}
COORD pos;
pos.Y = 21;
pos.X = 0;
SetConsoleCursorPosition(output, pos);
system("Pause");
return 0;
}
I have multiple SDL_Rects creating a snake that is supposed to stay in a specific area. Sometimes when the "snake" reaches the boundaries a part disappears.
void Snake::update(SDL_Surface *screen, int level)
{
old_pos.first = snake_rect[0];
if(x_axis)
snake_rect[0].x += snake_speed * level * direction_multiplier;
else if(!x_axis)
snake_rect[0].y += snake_speed * level * direction_multiplier;
for(unsigned int i = 1; i < snake_rect.size(); ++i)
{
old_pos.second = snake_rect[i];
snake_rect[i] = old_pos.first;
old_pos.first = old_pos.second;
}
boundariesCheck(screen);
/// Making the enemy move randomly
if(rand() % 100 < 10)
{
if(x_axis)
{
x_axis = false;
direction.second = rand() % 2;
if(direction.second)
direction_multiplier = 1;
else if(!direction.second)
direction_multiplier = -1;
}
else if(!x_axis)
{
x_axis = true;
direction.first = rand() % 2;
if(direction.first)
direction_multiplier = 1;
else if(!direction.first)
direction_multiplier = -1;
}
}
}
void Snake::draw(SDL_Surface *screen)
{
for(unsigned int i = 1; i < snake_rect.size(); ++i)
{
SDL_FillRect(screen, &snake_rect[i], 0xFF0000);
}
SDL_FillRect(screen, &snake_rect[0], 0xFF5500);
}