First commit!

master
q3k 2012-10-08 16:00:59 +02:00
commit 69fe3a4307
26 changed files with 887 additions and 0 deletions

BIN
0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

BIN
1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

BIN
2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

BIN
3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

BIN
4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

BIN
5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

BIN
6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 B

BIN
7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

BIN
8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

70
GFXframework.cpp Normal file
View File

@ -0,0 +1,70 @@
#include "GFXframework.h"
#include <iostream>
GFXframework* GFXframework::m_GFXframework= NULL;
GFXframework::GFXframework()
{
}
GFXframework::~GFXframework()
{
m_Window->close();
delete m_Window;
}
GFXframework* GFXframework::GetInstance()
{
if (m_GFXframework== NULL)
{
m_GFXframework = new GFXframework();
}
return m_GFXframework;
}
void GFXframework::ResetInstance()
{
delete m_GFXframework; // REM : it works even if the pointer is NULL (does nothing then)
m_GFXframework = NULL; // so GetInstance will still work.
}
bool GFXframework::InitWindow(int sizeX, int sizeY, char* name)
{
m_Window = new sf::RenderWindow(sf::VideoMode(sizeX, sizeY), name);
return true;
}
sf::RenderWindow* GFXframework::GetWindow()
{
return m_Window;
}
void GFXframework::LoadSprites()
{
m_TileTexture[0].loadFromFile("0.png");
m_TileTexture[1].loadFromFile("1.png");
m_TileTexture[2].loadFromFile("2.png");
m_TileTexture[3].loadFromFile("3.png");
m_TileTexture[4].loadFromFile("4.png");
m_TileTexture[5].loadFromFile("5.png");
m_TileTexture[6].loadFromFile("6.png");
m_TileTexture[7].loadFromFile("7.png");
m_TileTexture[8].loadFromFile("8.png");
m_TileTexture[9].loadFromFile("bomb.png");
m_TileTexture[10].loadFromFile("happy.png");
m_TileTexture[11].loadFromFile("ground.png");
m_TileTexture[12].loadFromFile("flag.png");
for (int i = 0; i < 13; i++)
{
m_Sprite[i] =sf::Sprite(m_TileTexture[i]);
}
}
void GFXframework::DisplaySpriteAt(int spriteType, int x, int y)
{
m_Sprite[spriteType].setPosition((float)x, (float)y);
m_Window->draw(m_Sprite[spriteType]);
}

34
GFXframework.h Normal file
View File

@ -0,0 +1,34 @@
// GFX FRAMEWORK SINGLETON
#ifndef GFXFRAMEWORK_H
#define GFXFRAMEWORK_H
#include <SFML/Graphics.hpp>
class GFXframework
{
// Singleton mechanics
protected:
GFXframework();
static GFXframework* m_GFXframework;
public:
static GFXframework* GetInstance();
static void ResetInstance(); // we don't want any leaks!
// GFX system methods and member variables
protected:
sf::RenderWindow* m_Window;
public:
~GFXframework();
bool InitWindow(int sizeX, int sizeY, char* name);
sf::RenderWindow* GetWindow();
sf::Texture m_TileTexture[13];
sf::Sprite m_Sprite[13];
void LoadSprites();
void DisplaySpriteAt(int spriteType, int x, int y);
};
#endif

9
README.txt Normal file
View File

@ -0,0 +1,9 @@
// A game of minesweeper, written in one day.
//
// CONTROLS:
// Left mouse click - test tile for mine
// Right mouse click - mark tile with a flag or remove a flag
// 'R' key - reset the game
// Esc - exit game
// Depends on SFML (and VLC in debug)

BIN
bar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

BIN
bomb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
flag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

172
game.cpp Normal file
View File

@ -0,0 +1,172 @@
#include "game.h"
#include "general.h"
#include "tile.h"
#include "map.h"
#include "GFXframework.h"
#include <SFML\Window\Mouse.hpp>
#include <iostream>
Game::Game()
{
Init();
}
Game::~Game()
{
delete m_LevelMap;
GFXframework::ResetInstance();
}
void Game::Init()
{
m_Finished = false;
m_numOfBombs = SMALL_MAP_BOMBS;
m_SizeX = SMALL_MAP_SIZE_X;
m_SizeY = SMALL_MAP_SIZE_Y;
int window_width = m_SizeX * TILE_SIZE_X;
int window_height = m_SizeY * TILE_SIZE_Y + TILE_SIZE_Y/2;
GFXframework::GetInstance()->InitWindow(window_width, window_height, "Don't Explode!");
GFXframework::GetInstance()->LoadSprites();
// bottom bar, part of GUI
m_GUITexture.loadFromFile("bar.png");
m_GUISprite =sf::Sprite(m_GUITexture);
// create basic map
m_LevelMap = new Map(m_SizeX, m_SizeY, m_numOfBombs);
m_FirstClick = true;
}
void Game::Shutdown(int returnCode)
{
(void)returnCode;
}
void Game::MainLoop()
{
while (GFXframework::GetInstance()->GetWindow()->isOpen())
{
sf::Event event;
// main events processing
while (GFXframework::GetInstance()->GetWindow()->pollEvent(event))
{
if (event.type == sf::Event::Closed)
GFXframework::GetInstance()->GetWindow()->close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::R))
{
m_FirstClick = true;
m_LevelMap->Generate();
m_Finished = false;
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape ))
{
GFXframework::GetInstance()->GetWindow()->close();
}
// if the game isn't finished yet, allow all mechanics to work
if ( !m_Finished)
{
if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if ( m_LeftMouseDown != true)
{
m_LeftMouseDown = true;
sf::Vector2i localPosition = sf::Mouse::getPosition(*(GFXframework::GetInstance()->GetWindow()));
if (m_FirstClick)
{
if (m_LevelMap->GenerateFromClick(localPosition.x, localPosition.y))
{
m_FirstClick = false;
HandleLeftMouse(localPosition);
}
}
else
{
HandleLeftMouse(localPosition);
}
}
}
else
{
// prevent repeating signals of mousedown (SFML only has MouseDown, so we have to work around it)
m_LeftMouseDown = false;
}
if (sf::Mouse::isButtonPressed(sf::Mouse::Right) && !m_FirstClick)
{
if ( m_RightMouseDown != true)
{
m_RightMouseDown = true;
sf::Vector2i localPosition = sf::Mouse::getPosition(*(GFXframework::GetInstance()->GetWindow()));
HandleRightMouse(localPosition);
}
}
else
{
// prevent repeating signals of mousedown (SFML only has MouseDown, so we have to work around it)
m_RightMouseDown = false;
}
if (m_LevelMap->IsMapDone())
{
m_Finished = true;
if (m_LevelMap->IsMapWon())
{
m_LevelMap->WinMap();
}
else
{
m_LevelMap->LoseMap();
}
}
}
GFXframework::GetInstance()->GetWindow()->clear();
Render();
GFXframework::GetInstance()->GetWindow()->display();
}
}
bool Game::HandleLeftMouse(sf::Vector2i localPosition)
{
m_LevelMap->ClickAt(localPosition.x, localPosition.y);
return true;
}
bool Game::HandleRightMouse(sf::Vector2i localPosition)
{
m_LevelMap->RightClickAt(localPosition.x, localPosition.y);
return true;
}
void Game::HandleGame()
{
}
void Game::DrawGui()
{
// draw bottom bar, for MORE BLING!
for (int x = 0; x < m_SizeX; x++)
{
m_GUISprite.setPosition((float)(x * TILE_SIZE_X), (float)(m_SizeY * TILE_SIZE_Y));
GFXframework::GetInstance()->GetWindow()->draw(m_GUISprite);
}
}
void Game::Render()
{
DrawGui();
m_LevelMap->Render();
}

46
game.h Normal file
View File

@ -0,0 +1,46 @@
// MAIN GAME CLASS
#ifndef GAME_H
#define GAME_H
class Map;
#include <SFML/Window/Mouse.hpp>
#include <SFML/Graphics.hpp>
class Game
{
private:
bool m_Finished;
int m_SizeX;
int m_SizeY;
int m_numOfBombs;
bool m_FirstClick;
bool m_LeftMouseDown;
bool m_RightMouseDown;
sf::Texture m_GUITexture;
sf::Sprite m_GUISprite;
Map* m_LevelMap;
public:
Game();
~Game();
void Init();
void Shutdown(int exitCode); // init and shutdown methods, woo
void MainLoop(); // main loop, call that from the MAIN file and you have a game
bool HandleLeftMouse(sf::Vector2i localPosition);
bool HandleRightMouse(sf::Vector2i localPosition);
void HandleGame(); // some cool stuff may go here, eventually
void DrawGui(); // draw gui... pretty stuff
void Render(); // render our game. we call this every frame
};
#endif

16
general.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef GENERAL_H
#define GENERAL_H
const int BOMB = 9;
const int HAPPY = 10;
const int GROUND = 11;
const int FLAG = 12;
const int TILE_SIZE_X = 64;
const int TILE_SIZE_Y = 64;
const int SMALL_MAP_SIZE_X = 9;
const int SMALL_MAP_SIZE_Y = 9;
const int SMALL_MAP_BOMBS = 10;
#endif

BIN
ground.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
happy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

31
main.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <SFML/Graphics.hpp>
/*
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML works!");
sf::Texture texture;
if (!texture.loadFromFile("happy.png"))
{
return -1;
}
sf::Sprite sprite(texture);
sprite.setPosition(100,100);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.draw(sprite);
window.display();
}
return 0;
}*/

326
map.cpp Normal file
View File

@ -0,0 +1,326 @@
#include "map.h"
#include "general.h"
#include "tile.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
Map::Map(int sizeX, int sizeY, int numBombs)
{
srand((unsigned int)time(NULL));
m_SizeX = sizeX;
m_SizeY = sizeY;
m_numOfBombs = numBombs;
m_PlacesLeft = m_SizeX * m_SizeY - m_numOfBombs;
m_MapDone = false;
m_Layout = NULL;
Generate();
}
Map::~Map()
{
delete[] m_Layout;
}
void Map::GenerateFrom(int fromX, int fromY)
{
if (m_Layout != NULL)
{
delete[] m_Layout;
m_Layout = NULL;
}
m_PlacesLeft = m_SizeX * m_SizeY - m_numOfBombs;
m_Layout = new Tile[m_SizeX * m_SizeY];
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].SetType(0);
}
}
int bombCount = m_numOfBombs;
while (bombCount != 0)
{
int posX = rand() % m_SizeX;
int posY = rand() % m_SizeY;
if ( posX > fromX + 1 || posX < fromX -1 || posY > fromY + 1 || posY < fromY - 1)
{
if (m_Layout[posX+posY*m_SizeX].GetType() == 0)
{
m_Layout[posX+posY*m_SizeX].SetType(BOMB);
bombCount--;
}
}
}
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
if (m_Layout[x+y*m_SizeX].GetType() != 9)
{
int bombInNeighbours = 0;
// CHECK LEFT THREE NEIGHBOURS
if (x > 0)
{
if (y > 0)
{
if (m_Layout[x-1+(y-1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (y < m_SizeY - 1)
{
if (m_Layout[x-1+(y+1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (m_Layout[x-1+y*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
// CHECK RIGHT THREE NEIGHBOURS
if (x < m_SizeX - 1)
{
if (y > 0)
{
if (m_Layout[x+1+(y-1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (y < m_SizeY - 1)
{
if (m_Layout[x+1+(y+1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (m_Layout[x+1+y*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
// CHECK MIDDLE TWO NEIGHBOURS
if (y > 0)
{
if (m_Layout[x+(y-1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
if (y < m_SizeY - 1)
{
if (m_Layout[x+(y+1)*m_SizeX].GetType() == 9)
{
bombInNeighbours++;
}
}
m_Layout[x+y*m_SizeX].SetType(bombInNeighbours);
}
//m_Layout[x+y*m_SizeX].SetSprite();
m_Layout[x+y*m_SizeX].SetSpritePosition(x*TILE_SIZE_X, y*TILE_SIZE_Y);
}
}
}
void Map::Generate()
{
m_MapDone = false;
GenerateFrom(rand() % m_SizeX, rand() % m_SizeY);
}
bool Map::GenerateFromClick(int mouseX, int mouseY)
{
bool found = false;
int currentX = 0;
int currentY = 0;
m_MapDone = false;
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
bool revealed = m_Layout[x+y*m_SizeX].TestPosition(mouseX, mouseY);
if (revealed)
{
currentX = x;
currentY = y;
found = true;
DecrementFreePlaces();
}
}
}
GenerateFrom(currentX, currentY);
return found;
}
void Map::Render()
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].Render();
}
}
}
void Map::ClickAt(int mouseX, int mouseY)
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
bool revealed = m_Layout[x+y*m_SizeX].TestClick(mouseX, mouseY);
if (revealed)
{
if (m_Layout[x+y*m_SizeX].GetType() == 0)
{
Reveal(x, y);
}
else
{
DecrementFreePlaces();
if (m_Layout[x+y*m_SizeX].GetType() == 9)
{
m_MapDone = true;
}
}
}
}
}
}
void Map::RightClickAt(int mouseX, int mouseY)
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
bool revealed = m_Layout[x+y*m_SizeX].TestRightClick(mouseX, mouseY);
if (revealed)
{
}
}
}
}
void Map::Reveal(int indexX, int indexY)
{
m_Layout[indexX+indexY*m_SizeX].Reveal();
DecrementFreePlaces();
if (m_Layout[indexX+indexY*m_SizeX].GetType() == 0)
{
if (indexX > 0)
{
if (indexY > 0)
{
if(m_Layout[indexX - 1 + (indexY - 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX - 1, indexY - 1);
}
}
if (indexY < m_SizeY - 1)
{
if(m_Layout[indexX - 1 + (indexY + 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX - 1, indexY + 1);
}
}
if(m_Layout[indexX - 1 + indexY * m_SizeX].IsRevealed() != true)
{
Reveal(indexX - 1, indexY);
}
}
if (indexX < m_SizeX - 1)
{
if (indexY > 0)
{
if(m_Layout[indexX + 1 + (indexY - 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX + 1, indexY - 1);
}
}
if (indexY < m_SizeY - 1)
{
if(m_Layout[indexX + 1 + (indexY + 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX + 1, indexY + 1);
}
}
if(m_Layout[indexX + 1 + indexY * m_SizeX].IsRevealed() != true)
{
Reveal(indexX + 1, indexY);
}
}
if (indexY > 0)
{
if(m_Layout[indexX + (indexY - 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX, indexY - 1);
}
}
if (indexY < m_SizeY - 1)
{
if(m_Layout[indexX + (indexY + 1) * m_SizeX].IsRevealed() != true)
{
Reveal(indexX, indexY + 1);
}
}
}
}
void Map::DecrementFreePlaces()
{
m_PlacesLeft--;
if (m_PlacesLeft == 0)
{
m_MapDone = true;
}
}
void Map::WinMap()
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].SetType(10);
m_Layout[x+y*m_SizeX].SetSpritePosition(x*TILE_SIZE_X, y*TILE_SIZE_Y);
m_Layout[x+y*m_SizeX].Finish();
}
}
}
void Map::LoseMap()
{
for (int x = 0; x < m_SizeX; x++)
{
for (int y = 0; y < m_SizeY; y++)
{
m_Layout[x+y*m_SizeX].Finish();
}
}
}

44
map.h Normal file
View File

@ -0,0 +1,44 @@
// MAP CLASS, CONTAINS ALL LOGIC AND WINNING/LOSING TESTS
#ifndef MAP_H
#define MAP_H
class Tile;
class Map
{
private:
Tile* m_Layout;
int m_SizeX;
int m_SizeY;
int m_numOfBombs;
int m_PlacesLeft;
bool m_MapDone;
void DecrementFreePlaces();
public:
Map(int sizeX, int sizeY, int numBombs);
~Map();
void Render(); // render to window
inline bool IsMapWon() { return m_PlacesLeft == 0; }
inline bool IsMapDone() { return m_MapDone; }
void WinMap();
void LoseMap();
// generate map depending on amount of parameters
void Generate();
void GenerateFrom(int x, int y);
bool GenerateFromClick(int mouseX, int mouseY);
// process input
void ClickAt(int mouseX, int mouseY);
void RightClickAt(int mouseX, int mouseY);
void Reveal(int indexX, int indexY);
};
#endif

21
minesweeper.cpp Normal file
View File

@ -0,0 +1,21 @@
// A game of minesweeper, written in one day.
//
// CONTROLS:
// Left mouse click - test tile for mine
// Right mouse click - mark tile with a flag or remove a flag
// 'R' key - reset the game
// Esc - exit game
#include "game.h"
#ifdef _DEBUG
#include <vld.h> // Visual Leak Detector
#endif
int main()
{
Game *game = new Game();
game->MainLoop();
delete game;
return 0;
}

79
tile.cpp Normal file
View File

@ -0,0 +1,79 @@
#include "tile.h"
#include "general.h"
#include "GFXframework.h"
Tile::Tile()
{
m_Revealed = false;
m_Flagged = false;
}
Tile::~Tile()
{
}
void Tile::SetSpritePosition(int x, int y)
{
m_PosX = x;
m_PosY = y;
}
void Tile::Render()
{
if (!m_Flagged)
{
if (m_Revealed)
{
GFXframework::GetInstance()->DisplaySpriteAt(m_Type, m_PosX, m_PosY);
}
else
{
GFXframework::GetInstance()->DisplaySpriteAt(GROUND, m_PosX, m_PosY);
}
}
else
{
GFXframework::GetInstance()->DisplaySpriteAt(FLAG, m_PosX, m_PosY);
}
}
bool Tile::TestClick(int x, int y)
{
if ( x > m_PosX && x <= m_PosX + TILE_SIZE_X &&
y > m_PosY && y <= m_PosY + TILE_SIZE_Y)
{
if (!m_Revealed && !m_Flagged)
{
m_Revealed = true;
return true;
}
}
return false;
}
bool Tile::TestRightClick(int x, int y)
{
if ( x > m_PosX && x <= m_PosX + TILE_SIZE_X &&
y > m_PosY && y <= m_PosY + TILE_SIZE_Y)
{
if (!m_Revealed)
{
m_Flagged = !m_Flagged;
return true;
}
}
return false;
}
bool Tile::TestPosition(int x, int y)
{
if ( x > m_PosX && x <= m_PosX + TILE_SIZE_X &&
y > m_PosY && y <= m_PosY + TILE_SIZE_Y)
{
return true;
}
return false;
}

39
tile.h Normal file
View File

@ -0,0 +1,39 @@
// TILE CLASS, CONTAINS GRAPHICS AND COLLISION TESTS
#ifndef TILE_H
#define TILE_H
#include <SFML/Graphics.hpp>
class Tile
{
private:
int m_Type;
bool m_Revealed;
bool m_Flagged;
int m_PosX;
int m_PosY;
public:
Tile();
~Tile();
inline int GetType() { return m_Type; }
inline void SetType(int type) { m_Type = type; }
void SetSpritePosition(int x, int y);
bool IsRevealed() { return m_Revealed; }
inline void Reveal() { m_Revealed = true; }
// used to fully reveal the tile once the game is done
inline void Finish() { m_Revealed = true; m_Flagged = false; }
// tests for collision and mechanics for processing the input
bool TestPosition(int x, int y);
bool TestClick(int x, int y);
bool TestRightClick(int x, int y);
void Render();
};
#endif