I'm making a little game as a small project but I can't get an if statement to do anything. If I make it !statement it works though. I run this if statement to find which cube on the "grid" (An array or cubes I render in a for loop I didn't show) the mouse clicked on. I use C++ and SDL2 on a Mac. This is my code:
#include <iostream>
#include <SDL2/SDL.h>
void RenderRects(SDL_Renderer *renderer);
void ToggleRect(int MouseX, int MouseY);
struct Grid
{
bool IsActive;
SDL_Rect Rect;
};
Grid grid[228960];
int main()
{
bool IsRunning = true;
bool IsRunningSim;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = SDL_CreateWindow("My Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1000, 780, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
int h, w;
SDL_MaximizeWindow(window);
SDL_GetRendererOutputSize(renderer, &w, &h);
while (IsRunning)
{
// std::cout << w << std::endl;
// std::cout << h << std::endl;
SDL_Event ev;
while (SDL_PollEvent(&ev))
{
if (ev.type == SDL_QUIT)
{
IsRunning = false;
}
if (ev.type == SDL_MOUSEBUTTONDOWN)
{
int x, y;
SDL_GetMouseState(&x, &y);
ToggleRect(x, y);
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
//rendering
RenderRects(renderer);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
void RenderRects(SDL_Renderer *renderer)
{
for (int i = 0; i < 1440; i += 10)
{
for (int j = 0; j < 795; j += 10)
{
SDL_Rect Rect = {i, j, 10, 10};
grid[i].Rect = Rect;
SDL_SetRenderDrawColor(renderer, 100, 100, 100, 225);
SDL_RenderDrawRect(renderer, &grid[i].Rect);
}
}
}
void ToggleRect(int MouseX, int MouseY)
{
SDL_Point MousePos;
MousePos.x = MouseX;
MousePos.y = MouseY;
for (int i = 0; i < 228961; i++)
{
if (SDL_PointInRect(&MousePos, &grid[i].Rect)) //This is the if that doesn't work.
{
std::cout << i << std::endl;
}
}
}
I have fixed this. I had to change my method of drawing since it was drawing over the rect and then showing after I changed its color. There was also an issue with generating the Rects that was probably effect it.
Related
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 7 months ago.
Improve this question
I'm trying to make a game in C++ with SDL2, and I can't even get a texture displaying. SDL_GetError() returns nothing.
I'm on a windows 10 pro using Visual Studio.
Here are my 3 files:
main.cpp
#include "Classes.h"
int MouseX = 0;
int MouseY = 0;
int PlayerX = 0;
int PlayerY = 0;
SDL_Renderer* renderer;
Tile tile = Tile({10, 10, TileTypes::Tile_Grass}, renderer);
EventReturns HandleEvent(SDL_Event* event) {
switch (event->type) {
case SDL_QUIT:
return EventReturns::Event_QUIT;
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
return EventReturns::Event_TryQuit;
default:
return EventReturns::Event_None;
}
default:
return EventReturns::Event_None;
}
}
int mainLoop(EventReturns eventReturn) {
SDL_GetMouseState(&MouseX, &MouseY);
if (eventReturn == EventReturns::Event_QUIT || eventReturn == EventReturns::Event_TryQuit) {
return 1;
}
return 0;
}
void render() {
SDL_SetRenderDrawColor(renderer, 100, 200, 200, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
tile.SetPos(0, 0);
if (tile.Draw(renderer) != 0) {
SDL_ShowSimpleMessageBox(0, "ERROR", "ERROR: Rect in tile has 0x0 size, Please close this with the task manager", NULL);
}
SDL_RenderPresent(renderer);
}
int main(int argc, char* argv[]) {
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 2880, 1600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
bool running = true;
EventReturns eventReturn = EventReturns::Event_None;
SDL_Event event;
int quit = 0;
while (running) {
while (SDL_PollEvent(&event)) {
eventReturn = HandleEvent(&event);
}
quit = mainLoop(eventReturn);
render();
if (quit == 1) {
running = false;
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Classes.h
#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
#define SpriteSizeMult 1
enum class EventReturns {
Event_QUIT,
Event_None,
Event_TryQuit
};
enum class TileTypes {
Tile_Grass
};
struct TileStruct {
int x;
int y;
TileTypes type;
};
class Tile {
public:
Tile(int x, int y, char* TexturePath, SDL_Renderer* renderer);
Tile(TileStruct structure, SDL_Renderer* renderer);
Tile();
int Draw(SDL_Renderer* renderer);
void SetPos(int x, int y);
private:
int x = 0;
int y = 0;
int TextureWidth = 0;
int TextureHeight = 0;
SDL_Texture* texture;
SDL_Rect rect;
};
SDL_Point getsize(SDL_Texture* texture);
Classes.cpp
#include "Classes.h"
SDL_Point getsize(SDL_Texture* texture) {
SDL_Point size;
SDL_QueryTexture(texture, NULL, NULL, &size.x, &size.y);
return size;
}
Tile::Tile(int x, int y, char* TexturePath, SDL_Renderer* renderer)
{
this->x = x;
this->y = y;
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load(TexturePath));
if (this->texture == nullptr) {
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
std::cout << IMG_GetError();
}
SDL_Point point = getsize(this->texture);
this->TextureHeight = point.y;
this->TextureWidth = point.x;
this->rect = {this->x - ((this->TextureWidth * SpriteSizeMult) / 2), this->y - ((this->TextureHeight * SpriteSizeMult) / 2), this->TextureWidth * SpriteSizeMult, this->TextureHeight * SpriteSizeMult};
}
Tile::Tile(TileStruct structure, SDL_Renderer* renderer)
{
this->x = structure.x;
this->y = structure.y;
switch (structure.type) {
case TileTypes::Tile_Grass:
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/Tiles/Grass.png"));
default:
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
}
if (this->texture == NULL) {
this->texture = SDL_CreateTextureFromSurface(renderer, IMG_Load("Assets/MissingTexture.png"));
if (this->texture == NULL) {
SDL_ShowSimpleMessageBox(0, "ERROR", "Failed to load texture", NULL);
SDL_ShowSimpleMessageBox(0, "ERROR", IMG_GetError(), NULL);
}
}
SDL_Point point = getsize(this->texture);
this->TextureHeight = point.y;
this->TextureWidth = point.x;
this->rect = { this->x - ((this->TextureWidth * SpriteSizeMult) / 2), this->y - ((this->TextureHeight * SpriteSizeMult) / 2), this->TextureWidth * SpriteSizeMult, this->TextureHeight * SpriteSizeMult };
}
Tile::Tile()
{
}
int Tile::Draw(SDL_Renderer* renderer)
{
if (rect.w == 0 || rect.h == 0) {
return -1;
}
this->rect.x = 0;
this->rect.y = 0;
SDL_RenderCopy(renderer, this->texture, NULL, &rect);
return 0;
}
void Tile::SetPos(int x, int y)
{
this->x = x;
this->y = y;
}
I'm sorry for the sheer amount of code that is, but I'd really appreciate the help. If there's any more info I need to put here, just let me know.
I'm fully aware that I should make a Minimal Reproducible Example, but as far as I'm aware, all the code listed here is necessary.
Finally, in case I've been unclear, when running the code the Missing Texture image that should appear isn't showing up.
I can't see SDL_INIT function in your code.
You should add this in the beginning of your main function.
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return 1;
You are initialising tile before creating a renderer so the constructor is trying to create a texture without a renderer.
SDL_Renderer* renderer;
Tile tile = Tile({10, 10, TileTypes::Tile_Grass}, renderer);
You should do something like this
#include "Classes.h"
int MouseX = 0;
int MouseY = 0;
int PlayerX = 0;
int PlayerY = 0;
SDL_Renderer* renderer;
EventReturns HandleEvent(SDL_Event* event) {
switch (event->type) {
case SDL_QUIT:
return EventReturns::Event_QUIT;
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_ESCAPE:
return EventReturns::Event_TryQuit;
default:
return EventReturns::Event_None;
}
default:
return EventReturns::Event_None;
}
}
int mainLoop(EventReturns eventReturn) {
SDL_GetMouseState(&MouseX, &MouseY);
if (eventReturn == EventReturns::Event_QUIT || eventReturn == EventReturns::Event_TryQuit) {
return 1;
}
return 0;
}
void render(Tile tile) {
SDL_SetRenderDrawColor(renderer, 100, 200, 200, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
tile.SetPos(0, 0);
if (tile.Draw(renderer) != 0) {
SDL_ShowSimpleMessageBox(0, "ERROR", "ERROR: Rect in tile has 0x0 size, Please close this with the task manager", NULL);
}
SDL_RenderPresent(renderer);
}
int main(int argc, char* argv[]) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
return 1;
SDL_Window* window = SDL_CreateWindow("Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 2880, 1600, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
Tile tile = Tile({ 10, 10, TileTypes::Tile_Grass }, renderer);
bool running = true;
EventReturns eventReturn = EventReturns::Event_None;
SDL_Event event;
int quit = 0;
while (running) {
while (SDL_PollEvent(&event)) {
eventReturn = HandleEvent(&event);
}
quit = mainLoop(eventReturn);
render(tile);
if (quit == 1) {
running = false;
}
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Im following this (https://www.udemy.com/course/free-learn-c-tutorial-beginners/learn/lecture/1838486#announcements ) tutorial and im stuck.
It seem that windows throws that exception and it cant be handled.
I think I try write something to some wrong place but cant see it.
Heres the line that causes the problem.
m_buffer[(y * SCREEN_WIDTH) + x] = color;
And here is everything else
//====================================main.cpp=======================================
#include<iostream>
#include "Screen.h"
#include<SDL.h>
using namespace std;
int main(int argc, char* argv[]) {
Screen screen;
if (!screen.init()) {
cout << "Error initialising SDL." << endl;
}
while (true) {
// update particles
// draw particles
for (int y = 0; y < Screen::SCREEN_HEIGHT; y++) {
for (int x = 0; x < Screen::SCREEN_WIDTH; x++ ){
screen.setPixel(x, y, 128, 0, 255);
}
}
//Draw the screen
screen.update();
// see for messages/events
if (!screen.processEvents()) {
break;
}
}
screen.close();
return 0;
}
//==========================================================================================
screen.h
#ifndef SCREEN_H_
#define SCREEN_H_
#include<SDL.h>
#include<iostream>
class Screen
{
public:
const static int SCREEN_WIDTH = 800;
const static int SCREEN_HEIGHT = 600;
private:
SDL_Window* m_window;
SDL_Renderer* m_renderer;
SDL_Texture* m_texture;
Uint32* m_buffer;
public:
Screen();
bool init();
void update();
void setPixel(int x, int y, Uint8 red, Uint8 green, Uint8 blue);
bool processEvents();
void close();
};
#endif // !SCREEN_H_
//=======================screen.cpp======================================================
#include "Screen.h"
Screen::Screen() : m_window(NULL), m_renderer(NULL), m_texture(NULL), m_buffer(NULL)
{
}
bool Screen::init() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
return false;
}
m_window = SDL_CreateWindow("Particle Fire Explosion",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); //-----------------SDL_WINDOW_HIDDEN SDL_WINDOW_SHOWN
if (m_window == 0) {
SDL_Quit();
return false;
}
m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_PRESENTVSYNC);
m_texture = SDL_CreateTexture(m_renderer,
SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, SCREEN_WIDTH, SCREEN_HEIGHT);
if (m_renderer == NULL) {
SDL_DestroyWindow(m_window);
SDL_Quit();
return false;
}
if (m_texture == NULL) {
SDL_DestroyWindow(m_window);
SDL_DestroyRenderer(m_renderer);
SDL_Quit();
return false;
}
Uint32* buffer = new Uint32[SCREEN_WIDTH * SCREEN_HEIGHT];
memset(buffer, 0xFF, SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(Uint32));
return true;
}
bool Screen::processEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
{
return false;
}
}
return true;
}
void Screen::setPixel(int x, int y, Uint8 red, Uint8 green, Uint8 blue) {
Uint32 color = 0;
color += red;
color <<= 8;
color += green;
color <<= 8;
color += blue;
color <<= 8;
color += 0xFF;
m_buffer[(y * SCREEN_WIDTH) + x] = color;
}
void Screen::update() {
SDL_UpdateTexture(m_texture, NULL, m_buffer, SCREEN_WIDTH * sizeof(Uint32));
SDL_RenderClear(m_renderer);
SDL_RenderCopy(m_renderer, m_texture, NULL, NULL);
SDL_RenderPresent(m_renderer);
}
void Screen::close() {
delete[] m_buffer;
SDL_DestroyRenderer(m_renderer);
SDL_DestroyTexture(m_texture);
SDL_DestroyWindow(m_window);
SDL_Quit();
}
//==========================================================================================
Maybe someone can see what is the broblem?
Your Screen::init() method never sets m_buffer, so when setPixel() tries to dereference it, it is dereferencing a NULL pointer, which invokes undefined behavior.
this line is wrong
Uint32* buffer = new Uint32[SCREEN_WIDTH * SCREEN_HEIGHT];
you mean
m_buffer = new Uint32[SCREEN_WIDTH * SCREEN_HEIGHT];
I recently tried to implement OneLoneCoder's simple 3d Graphics Engine, from his Code-It-Yourself series, on SDL2. So I made some triangles that move on the window, but these triangles would appear to move at a slower framerate when I left my mouse completely still, and then move at their normal framerate if I started to move my mouse.
You see, to animate these triangles I used some while loops, something like this:
while (true) {
// Black Background
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
// Custom function that draws a triangle using SDL_RenderDrawLine()
drawTriangle(renderer, triangle);
SDL_RenderPresent(renderer); // updates the pixels on the renderer
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
goto Exit;
}
}
Pretty standard, right?
Here is an example of some code that has this exact same issue:
#include<iostream>
#include"SDL.h"
struct vec {
float x, y;
vec ( float x, float y)
: x(x), y(y)
{}
vec () {}
};
struct triangle {
vec p[3];
triangle() {}
};
void drawTriangle(SDL_Renderer* r, const triangle& tri) {
SDL_RenderDrawLine(r, tri.p[0].x, tri.p[0].y, tri.p[1].x, tri.p[1].y);
SDL_RenderDrawLine(r, tri.p[1].x, tri.p[1].y, tri.p[2].x, tri.p[2].y);
SDL_RenderDrawLine(r, tri.p[2].x, tri.p[2].y, tri.p[0].x, tri.p[0].y);
}
int main(int argc, char **argv) {
uint16_t width = 400;
uint16_t height = 300;
if (SDL_Init(SDL_INIT_VIDEO) > 0) { std::cout << "SDL_INIT FAILED\nERROR: " << SDL_GetError() << std::endl; }
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Event event;
window = SDL_CreateWindow("SDL Test :)", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN);
if (window == NULL) { std::cout << "SDL_WINDOW FAILED\nERROR: " << SDL_GetError() << std::endl; }
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
triangle myTri;
myTri.p[0] = vec( width * 0.5, 0);
myTri.p[1] = vec( width * 0.333, height * 0.2);
myTri.p[2] = vec( width * 0.666, height * 0.2);
while (true) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
myTri.p[0].y += 0.01f;
myTri.p[1].y += 0.01f;
myTri.p[2].y += 0.01f;
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
drawTriangle(renderer, myTri);
SDL_RenderPresent(renderer);
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
goto Exit;
}
}
Exit:
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I created this easy function and it seems there is something wrong with it that I really don't see what it is...
Evnt.motion.yrel output crazy number.
void EnthropyGenerator::OpenWindow()
{
SDL_Window *EnthropyGeneratorWindow;
SDL_Renderer* Renderer;
SDL_Init(SDL_INIT_VIDEO);
EnthropyGeneratorWindow =
SDL_CreateWindow("Enthropy Generator",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
WindowSizeX,
WindowSizeY,
SDL_WINDOW_SHOWN |
SDL_WINDOW_BORDERLESS |
SDL_WINDOW_INPUT_GRABBED);
if (EnthropyGeneratorWindow == NULL)
{
ServerEngine::FatalError("Could not create window: " +
(std::string)SDL_GetError());
}
Renderer = SDL_CreateRenderer(EnthropyGeneratorWindow, -1, 0);
SDL_SetRenderDrawColor(Renderer, 10, 255, 0, 255);
SDL_RenderClear(Renderer);
SDL_RenderPresent(Renderer);
bool NeedMoreEntropy = true;
SDL_Event Evnt;
while (NeedMoreEntropy)
{
while (SDL_PollEvent(&Evnt))
{
if (Evnt.type == SDL_MOUSEMOTION)
{
std::cout << Evnt.motion.xrel << " and "
<< Evnt.motion.yrel << std::endl;
std::cout << m_EnthropyNeed << std::endl;
UpdateMousePosition(Evnt.motion.xrel, Evnt.motion.yrel);
AddEnthropy(m_MouseX, m_MouseY);
if (m_EnthropyNeed == 256)
{
NeedMoreEntropy = false;
}
}
}
}
SDL_DestroyWindow(EnthropyGeneratorWindow);
SDL_Quit();
}
void EnthropyGenerator::UpdateMousePosition(int deltaX, int deltaY)
{
m_MouseX += deltaX;
m_MouseY += deltaY;
}
void EnthropyGenerator::AddEnthropy(int deltaX, int deltaY)
{
m_EnthropyNeed++;
}
The output in the console is: 0 and 1985359926 and so on.
The output
It seems like something is not initialized or looks like a bad pointer. How can I fix this problem?
The problem I'm having is that when I change an attribute of an Object the change isn't 'saving'. Easier to show you what's happening.
I'm learning c++ and decided to build a small chess app. Each Piece is a seperate Object.
They're stored in a std::vector as such
std::vector<Piece> pieces;
They're initialised like so
for (int i = 0; i < 2; i++)
{
Piece p;
p.Init(i*2+1, 1, renderer, SQUARE_SIZE, "king");
pieces.push_back(p);
}
When I click the mouse I want to select all pieces (temporarily)
for (int i = 0; i < pieces.size(); i++)
{
Piece p = pieces[i];
p.Select();
}
The issue is that while the Select() function is being called, by the time I get to rendering their selected attribute is false. Strangely this does not happen to the piece not contained within in the vector, referred to as k.
Before you ask there is nowhere in my code that I set selected to false :) (Except the constructor :P )
Also if you feel like downvoting, send me a comment first and I'll try fix whatever it is!
Here are the entire files. (not sure if this is the proper way to insert them)
Piece.h
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDl_image.h>
#include <array>
#include <vector>
class Piece
{
public:
Piece();
void Init(int _x, int _y, SDL_Renderer* renderer, int SQUARE_SIZE, std::string type);
void SetPos(int _x, int _y, int _w);
void LoadTexture(SDL_Renderer* renderer, std::string type);
void LoadMovementVector(std::string type);
void Render(SDL_Renderer* renderer);
void Select(){ selected = true; std::cout << "called\n";}
bool isSelected(){ return selected; }
int GetX(){ return x; } // SDL_Point
int GetY(){ return y; }
private:
int x, y;
std::vector<int> move_vector;
bool selected;
SDL_Rect rect;
SDL_Texture* texture;
};
Piece.cpp
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDl_image.h>
#include <vector>
#include "Piece.h"
Piece::Piece()
: x(0)
, y(0)
, selected(false)
{
}
void Piece::Init(int _x, int _y, SDL_Renderer* renderer, int SQUARE_SIZE, std::string type)
{
SetPos(_x, _y, SQUARE_SIZE);
LoadTexture(renderer, type);
LoadMovementVector(type);
}
void Piece::Render(SDL_Renderer* renderer)
{
//selected = true;
//std::cout << selected << std::endl;
if (selected)
{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
}
if (texture != nullptr)
{
SDL_RenderCopy(renderer, texture, nullptr, &rect);
}
else
{
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect);
}
}
void Piece::LoadMovementVector(std::string type)
{
if (type == "king"){ // There literally has to be a better way to init std::vector
int arr[4] = {1,1,1,0};
for (int i = 0; i < 4; i++){ move_vector.push_back(arr[i]); }
}
for (int i = 0; i < move_vector.size(); i++)
{
std::cout << move_vector[i];
}
std::cout << std::endl;
}
void Piece::LoadTexture(SDL_Renderer* renderer, std::string type)
{
std::string source;
if (type == "king"){
source = "wk.png";
}
texture = IMG_LoadTexture(renderer, "res/wk.png");
}
void Piece::SetPos(int _x, int _y, int _w)
{
x = _x;
y = _y;
rect.x = _w*(_x-1);
rect.y = _w*(8-_y);
rect.w = _w;
rect.h = _w;
std::cout << x << y << std::endl;
}
Main.cpp
#include <iostream>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDl_image.h>
#include "Piece.h"
using namespace std::chrono;
// Would be 'const int' but I want to make the board resizeable
int SCREEN_WIDTH = 800;
int SCREEN_HEIGHT = 800;
int BOARD_WIDTH, BOARD_HEIGHT, SQUARE_SIZE;
SDL_Window* window;
SDL_Renderer* renderer;
std::vector<Piece> pieces;
Piece k;
bool InitEverything();
bool InitSDL();
bool CreateWindow();
bool CreateRenderer();
void SetupRenderer();
void Quit();
void RunGame();
void Render();
void HandleInput();
void UpdateDimensions();
double GetDelta();
void RenderGameBoard();
bool loop = true;
auto timePrev = high_resolution_clock::now();
int main(int argc, char* args[])
{
if (!InitEverything())
return -1;
std::cout << "Running Game..." << std::endl;
for (int i = 0; i < 2; i++)
{
Piece p;
p.Init(i*2+1, 1, renderer, SQUARE_SIZE, "king");
pieces.push_back(p);
}
k.Init(5, 1, renderer, SQUARE_SIZE, "king");
RunGame();
Quit();
return 0;
}
void RunGame()
{
while (loop)
{
HandleInput();
Render();
double delta = GetDelta();
}
}
void Render()
{
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
RenderGameBoard();
for (int i = 0; i < pieces.size(); i++)
{
pieces[i].Render(renderer);
}
k.Render(renderer);
SDL_RenderPresent(renderer);
}
void RenderGameBoard()
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if ((j%2==0&&i%2==0)||(j%2!=0&&i%2!=0))
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
else
SDL_SetRenderDrawColor(renderer, 180, 180, 180, 255);
SDL_Rect r = {i*SQUARE_SIZE, j*SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE};
SDL_RenderFillRect(renderer, &r);
}
}
}
void HandleInput()
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
loop = false;
else if (event.type == SDL_KEYDOWN)
{
}
else if (event.type == SDL_MOUSEBUTTONDOWN)
{
if (event.button.button == SDL_BUTTON_LEFT)
{
k.Select();
for (int i = 0; i < pieces.size(); i++)
{
Piece p = pieces[i];
p.Select();
}
int x = floor(event.button.x/SQUARE_SIZE)+1;
int y = 8-floor(event.button.y/SQUARE_SIZE);
for (int i = 0; i < pieces.size(); i++)
{
Piece p = pieces[i];
if (p.GetX() == x && p.GetY() == y)
{
p.Select();
}
}
}
}
}
}
void UpdateDimensions()
{
BOARD_WIDTH = SCREEN_WIDTH;
BOARD_HEIGHT = SCREEN_HEIGHT;
SQUARE_SIZE = BOARD_WIDTH/8;
}
double GetDelta()
{
auto timeCurrent = high_resolution_clock::now();
auto timeDiff = duration_cast< nanoseconds >( timeCurrent - timePrev );
double delta = timeDiff.count();
delta /= 1000000000;
timePrev = timeCurrent;
return delta;
}
bool InitEverything()
{
if (!InitSDL())
return false;
if (!CreateWindow())
return false;
if (!CreateRenderer())
return false;
SetupRenderer();
UpdateDimensions();
return true;
}
bool InitSDL()
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "SDL failed to initialize : " << SDL_GetError() << std::endl;
return false;
}
return true;
}
bool CreateWindow()
{
window = SDL_CreateWindow("Chess", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (!window)
{
std::cout << "Failed to create window : " << SDL_GetError() << std::endl;
return false;
}
return true;
}
bool CreateRenderer()
{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (!renderer)
{
std::cout << "Failed to create renderer : " << SDL_GetError() << std::endl;
return false;
}
return true;
}
void SetupRenderer()
{
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
}
void Quit()
{
SDL_DestroyWindow(window);
SDL_Quit();
}
This:
Piece p = pieces[i];
is creating a copy of the piece at index i in the vector.
Any methods you call after that are operating on the copy, not on the piece in the array.
Instead, take a reference to it:
Piece& p = pieces[i];
After that, p is a reference to element i in the vector and any operations you perform on it are performed on the vector element.