I have been designing my c++ console game and I have a question about the game loop. Whenever the game loops, I end up reinitializing my velocity variables in the constructor which sets them to "0". I have a couple ideas on how to solve this but it ends up ruining my game infrastructure and after a while gets confusing.
Can someone please tell me how to prevent my velocity variables from being reinitialized.
BTW I'll find out how to group my headers better later.
FPS.timerMilli(1) is a function that counts 1 millisecond before exiting function. (Trying to control FPS).
rectangle.cpp:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include "rectangle.h"
void rectangle::rectangleDrawPos(int h, int k) {
// Draw top of rectangle
for (int verticle = 1; verticle <= h; verticle += 1) {
std::cout << "\n";
}
for (int horizontal = 1; horizontal <= h; horizontal += 1) {
std::cout << " ";
}
for (int x = 1; x <= width; x += 1) {
std::cout << ".";
}
std::cout << "\n";
//Number of sides
midWidth = width - 2;
for (int y = 1; y <= height; y+=1) {
//Draw sides
for (int x = 1; x <= h; x += 1) {
std::cout << " ";
}
std::cout << ":";
for (int x = 1; x <= midWidth; x+=1) {
std::cout << " ";
}
std::cout << ":\n";
}
//Bottom of rectangle
for (int x = 1; x <= h; x += 1) {
std::cout << " ";
}
for (int x = 1; x <= width; x += 1) {
std::cout << ".";
}
std::cout << "\n";
}
//constructor
rectangle::rectangle(int locHeight, int locWidth) {
width = locWidth;
height = locHeight;
}
rectangle.h:
#ifndef RECTANGLE_H
#define RECTANGLE_H
class rectangle {
//Variables
int height, width, midWidth;
public:
//functions
void rectangleDrawPos(int h, int k);
//constructor
rectangle(int locHeight, int locWidth);
};
#endif
MyGame.cpp:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <ctime>
#include "timer.h"
#include "config.h"
#include "IOMovement.h"
#include "rectangle.h"
int main(){
//object def
timer FPS;
config startupConfig;
IOMovement IO;
//config
startupConfig.Set_Consol_Size(startupConfig.half_screen_Size, GetSystemMetrics(SM_CYSCREEN));
startupConfig.Position_Consol(-6, 0);
//Game Loop
while (1==1) {
FPS.timerMilli(1);
//Game Startup
IO.IOStartup();
//map
//ai
}
//exit
return 0;
}
IOMovement.cpp:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include "IOMovement.h"
#include "rectangle.h"
#define W_KEY 0x57
#define S_KEY 0x53
#define A_KEY 0x41
#define D_KEY 0x44
#define R_KEY 0x52
void IOMovement::IO() {
rectangle player(15, 5);
if (GetAsyncKeyState(W_KEY)) {
system("CLS");
velocityVerticle--;
player.rectangleDrawPos(velocityHorizontal, velocityVerticle);
}
if (GetAsyncKeyState(S_KEY)) {
system("CLS");
velocityVerticle++;
std::cout << "Working\n";
player.rectangleDrawPos(velocityHorizontal, velocityVerticle);
}
if (GetAsyncKeyState(A_KEY)) {
system("CLS");
velocityHorizontal--;
player.rectangleDrawPos(velocityHorizontal, velocityVerticle);
}
if (GetAsyncKeyState(D_KEY)) {
system("CLS");
velocityHorizontal++;
player.rectangleDrawPos(velocityHorizontal, velocityVerticle);
}
}
void IOMovement::IOStartup() {
//Variable decleration
velocityVerticle = 0;
velocityHorizontal = 0;
//Functions
IO();
}
IOMovement.h:
#ifndef IOMOVEMENT_H
#define IOMOVEMENT_H
class IOMovement {
int velocityVerticle, velocityHorizontal;
bool variableInitialization;
void IO();
public:
void IOStartup();
};
#endif
If you need your variable to retain it's value you could turn them into static variables.
Related
I am writing a simple isometric game - simulator of town development. The main classes are Player class and World class. So, the problem is, that when I launching my game, all seems to be going as planned, but when I want to click "X" to close it, at the moment cursor reach place, in which red arrow points, program is being breaked this error.
It is not happening, when Player object is not created, so I think some problem in it.
Player.hpp:
#ifndef PLAYER_HEADER
#define PLAYER_HEADER
#include "Main.hpp"
#include "ToScreenF.hpp"
#include <iostream>
class Player
{
public:
sf::Vector2i MousePos;
sf::Vector2i inCell;
sf::Vector2i cellOffset;
sf::Vector2i cellSelected;
sf::Vector2f cellSelectedInWorldSpace;
sf::Image selectedTileImage;
sf::Texture selectedTileTexture;
sf::Sprite selectedTileSprite;
sf::Image CheatImage;
sf::Color color;
Player(std::string FILE);
~Player();
void Update(sf::RenderWindow* Window, sf::Vector2f TileSize, sf::Vector2f vOrigin, int WorldWidth, int WorldHeight);
};
#endif PLAYER_HEADER
Player.cpp:
#include "Player.hpp"
Player::Player(std::string FILE)
{
selectedTileImage.loadFromFile(FILE);
selectedTileImage.createMaskFromColor(sf::Color::White);
selectedTileTexture.loadFromImage(selectedTileImage);
selectedTileSprite.setTexture(selectedTileTexture);
CheatImage.loadFromFile("tileCheat.png");
}
void Player::Update(sf::RenderWindow* Window, sf::Vector2f TileSize, sf::Vector2f vOrigin, int WorldWidth, int WorldHeight)
{
MousePos = {sf::Mouse::getPosition((*Window))};
inCell = {(int)(MousePos.x / TileSize.x), (int)(MousePos.y / TileSize.y) };
cellOffset = { MousePos.x % (int)TileSize.x, MousePos.y % (int)TileSize.y };
cellSelected = {
(inCell.y - (int)vOrigin.y) + (inCell.x - (int)vOrigin.x),
(inCell.y - (int)vOrigin.y) - (inCell.x - (int)vOrigin.x)
};
color = CheatImage.getPixel(cellOffset.x, cellOffset.y);
if (color == sf::Color::Red) { cellSelected.x += -1; cellSelected.y += 0; };
if (color == sf::Color::Blue) { cellSelected.x += 0; cellSelected.y += -1; };
if (color == sf::Color::Green) { cellSelected.x += 0; cellSelected.y += 1; };
if (color == sf::Color::Yellow) { cellSelected.x += 1; cellSelected.y += 0; };
if (cellSelected.x < 0) cellSelected.x = 0;
if (cellSelected.x > (WorldWidth - 1)) cellSelected.x = 19;
if (cellSelected.y < 0) cellSelected.y = 0;
if (cellSelected.y > (WorldHeight - 1)) cellSelected.y = 19;
cellSelectedInWorldSpace = ToScreen(cellSelected.x, cellSelected.y, TileSize, vOrigin);
selectedTileSprite.setPosition(cellSelectedInWorldSpace);
Window->draw(selectedTileSprite);
std::cout << cellSelected.x << " " << cellSelected.y << std::endl;
}
ToScreenF.cpp:
#include "ToScreenF.hpp"
sf::Vector2f ToScreen(int x, int y, sf::Vector2f TileSize, sf::Vector2f vOrigin)
{
return sf::Vector2f
{
(vOrigin.x * TileSize.x) + (x - y) * (TileSize.x / 2),
(vOrigin.y * TileSize.y) + (x + y) * (TileSize.y / 2)
};
}
TApplication.hpp:
#ifndef TAPPLICATION_HEADER
#define TAPPLICATION_HEADER
#include "Main.hpp"
#include "World.hpp"
#include "Player.hpp"
namespace Application
{
class TApplication
{
protected:
sf::RenderWindow *Window;
World *GameWorld;
Player* _Player;
public:
TApplication();
~TApplication();
void Init();
void Run();
void End();
};
}
TApplication.cpp:
#include "TApplication.hpp"
namespace Application
{
TApplication::TApplication() : Window(nullptr)
{
}
TApplication:: ~TApplication()
{
}
void TApplication::Init()
{
if (Window == nullptr)
Window = new sf::RenderWindow(sf::VideoMode(1200, 800), "Town Builder Simulator");
GameWorld = new World("BasicTile.png", 100, 100);
_Player = new Player("selectedTile.png");
}
void TApplication::Run()
{
sf::Event event;
while (Window->isOpen())
{
while(Window->pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
Window->close();
}
}
Window->clear();
GameWorld->Draw(Window);
_Player->Update(Window, sf::Vector2f(40, 20), sf::Vector2f(10, 10), GameWorld->WorldWidth, GameWorld->WorldHeight);
Window->display();
}
}
void TApplication::End()
{
if (Window != nullptr)
{
delete Window;
delete GameWorld;
Window = nullptr;
}
}
}
**Main.hpp**
#ifndef MAIN_HEADER
#define MAIN_HEADER
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Network.hpp>
#include <SFML/System.hpp>
#endif
Thanks in advance all who helped me, I am very grateful!)
I have a data structure in a header file of a player and a goblin that looks like this:
#ifndef GLOBALVAR_H
#define GLOBALVAR_H
#include <iostream>
#include <windows.h>
struct Player {
int x = 1, y = 1;
int health = 100;
int symbol = '#';
};
struct Goblin {
int x, y;
int health = 100;
int symbol = 'G';
};
#endif
I also have a data structure in a header file for the screen that looks like this:
#ifndef SCREEN_H
#define SCREEN_H
#include <iostream>
#include <windows.h>
struct Screen {
char screen[21][34] = {
"#################################",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#...............................#",
"#################################"
};
};
#endif
Finally, I have the main and generate c++ files that look like this respectively:
// main 'hub' for game
#include <iostream>
#include <windows.h>
#include "screen.h"
#include "generate.h"
#include "globalVar.h"
using namespace std;
bool running = true;
int main() {
struct Player p;
struct Screen s;
while(running) {
system("cls");
s.screen[p.y][p.x] = p.symbol;
draw();
p.health--;
system("pause>nul");
}
return 0;
}
// generates the map and draws the screen
#include <iostream>
#include <windows.h>
#include "screen.h"
#include "globalVar.h"
using namespace std;
int generate() {
return 0;
}
int draw() {
struct Screen s;
struct Player player;
for(int i = 0; i < 20; i++) {
cout << s.screen[i] << endl;
}
for(int i = 0; i < 1; i++) {
cout << "HP: " << player.health << endl;
}
return 0;
}
When I run main.cpp I want it to display a '#' symbol at 1, 1 of the array. When I run the code it instead displays a period in the place of it. What is happening here?
Image of what's being displayed:
https://imgur.com/a/RiWoDJ5
You have created two different Screens. The one in main() is completely different from the one in draw(), because they are in different scopes. You can pass a Screen as an argument to draw() to fix this.
You can also make draw() a function of Screen, as Nathan pointed out in the comments, and then call s.draw() in main().
Also, unlike in C, there is no need to put struct before every use of a struct. Simply put Screen s; instead of struct Screen s;
Example of draw() taking a parameter of type Screen:
int draw(Screen s) {
Player player;
for (int i = 0; i < 20; i++) {
cout << s.screen[i] << endl;
}
for (int i = 0; i < 1; i++) {
cout << "HP: " << player.health << endl;
}
return 0;
}
Example of draw() in Screen:
struct Screen {
static char screen[21][34];
int draw() {
Player player; //think about passing this as a parameter instead, not making one every time, because this one is inaccessible to everyone except this function
for (int i = 0; i < 20; i++) {
cout << screen[i] << endl;
}
for (int i = 0; i < 1; i++) {
cout << "HP: " << player.health << endl;
}
return 0;
}
};
Then, call it like:
s.draw();
I would go a different route and use inheritance and constructors:
struct Item
{
int m_x, m_y; // Every item has a position.
char m_symbol;
Item (char symbol, int x_pos = 1, int y_pos = 1)
: m_symbol(symbol), m_x(x_pos), m_y(y_pos)
{ ; }
};
struct Player : public Item // A player is an item
: Item('#', 1, 1)
{
};
struct Goblin : public Item // A goblin is an item
: Item ('G', 5, 4)
{
};
std::vector<std::vector<Item *>> game_board;
//...
Goblin * p_goblin = new Goblin;
game_board[p_goblin->y][p_goblin->x] = p_goblin;
I am learning the SFML library in C++. I have been trying to implement an efficient method of organizing audio in my game by making an Audio class that contains two separate std::map for the music (sf::Music) and the sound (sf::Sound). However, when I run the program, only the music is able to play but not the sound effects. I believe the sound does load fine since it does not throw the error message. Here is my code and info. (Possibly give tips on my code as well since I am new :D )
Thanks in advance
VS2012, SFML 2.1
SFML_Snake.h (Game header file)
#pragma once
#ifndef GUARD_SFML_SNAKE
#define GUARD_SFML_SNAKE
#include "SFML/Audio.hpp"
#include "SFML/Graphics.hpp"
#include "Snake.h"
#include "Apple.h"
#include "Audio.h"
#include <iostream>
class SFML_Snake{
public:
SFML_Snake();
void run();
private:
void checkBoundary(Snake);
void checkApple(Snake&, Apple&, Audio& );
std::vector<sf::RectangleShape> loadGrid();
private:
bool processEvents();
void update(Audio&);
void render(std::vector<sf::RectangleShape>&);
public:
sf::RenderWindow window;
sf::Text textCount;
Snake snake;
Apple apple;
};
int main(){
SFML_Snake start;
start.run();
}
#endif
SFML_Snake.cpp (Game source file)
/*Import statements*/
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include "Snake.h"
#include "variables.h"
#include "Apple.h"
#include "Audio.h"
#include "SFML_Snake.h"
#include <iostream>
#include <vector>
#include <string>
#include <array>
#include <map>
#include <memory>
SFML_Snake::SFML_Snake():
window(sf::VideoMode(windowWidth, windowHeight), "SFML Application" ),
snake(Snake()), apple(Apple(0,0)), textCount(sf::Text())
{
window.setFramerateLimit(FRAMERATE);
}
void SFML_Snake::checkBoundary(Snake s){
for (int z = dots; z > 0; z--){
if ((s.x[0] == s.x[z]) && (s.y[0] == s.y[z]))
inGame = false;
}
if (s.y[0] >= windowHeight)
inGame = false;
if (s.y[0] < dotSize)
inGame = false;
if (s.x[0] >= windowWidth)
inGame = false;
if (s.x[0] < dotSize)
inGame = false;
}
void SFML_Snake::checkApple(Snake& mA, Apple& mB, Audio& audios){
if ((mA.x[0] == mB.x()) && (mA.y[0] == mB.y())){
audios.getSound("eating").play();
dots += dotInterval;
points++;
if(DEBUG)
std::cout<< points << std::endl;
textCount.setString(std::string("points: ") + std::to_string(points));
mB.locateApple();
for(int i = mA.draw().size() - 1; i >= 0; i--){
while (((mA.x[0] == mB.x()) && (mA.y[0] == mB.y()))
|| (0 == mB.x())
|| (0 == mB.y())
|| (windowWidth - dotSize/2 == mB.x())
|| (windowHeight - dotSize/2 == mB.y()))
{
mB.locateApple();
}
}
}
}
bool SFML_Snake::processEvents(){
sf::Event event;
while (window.pollEvent(event)){
if (event.type == sf::Event::Closed)
window.close();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) {
return true;
}
snake.input();
return false;
}
void SFML_Snake::update(Audio& audios){
snake.checkReals();
snake.moveUpdate();
audios.getSound("moving").play();
checkApple(snake, apple, audios);
checkBoundary(snake);
}
void SFML_Snake::render(std::vector<sf::RectangleShape>& grid){
std::vector<sf::RectangleShape> shapearray = snake.draw();
for (int i = shapearray.size() - 1; i >= 0; i--){
window.draw(shapearray[i]);
}
window.draw(apple.draw());
for(int i = grid.size()-1; i>=0; i--){
window.draw(grid[i]);
}
window.draw(textCount);
window.display();
}
std::vector<sf::RectangleShape> SFML_Snake::loadGrid(){
std::vector<sf::RectangleShape> grid;
for(int k= dotSize/2; k<=windowHeight+dotSize/2; k+=dotSize){
sf::RectangleShape line;
line.setPosition(0, k-dotSize);
line.setSize(sf::Vector2f(windowWidth, 1));
line.setFillColor(sf::Color::Black);
if(k==dotSize/2 || k == windowHeight + dotSize/2){
line.setSize(sf::Vector2f(windowWidth, dotSize));
}
grid.push_back(line);
}
for(int i = dotSize/2; i<=windowWidth+dotSize/2; i+=dotSize){
sf::RectangleShape line;
line.setPosition(i-dotSize, 0);
line.setSize(sf::Vector2f(1, windowHeight));
line.setFillColor(sf::Color::Black);
if(i==dotSize/2 || i == windowWidth+dotSize/2){
line.setSize(sf::Vector2f(dotSize, windowHeight));
}
grid.push_back(line);
}
return grid;
}
void SFML_Snake::run(){
/*Initialize the objects*/
std::vector<sf::RectangleShape> grid = loadGrid();
if(!DEBUG)
std::cout<<"DEBUG MODE: OFF" <<std::endl;
Audio& audios = Audio();
apple.locateApple();
/*Load the audio*/
audios.getMusic("backgroundMusic").setVolume(10);
audios.getMusic("backgroundMusic").setLoop(true);
audios.getMusic("backgroundMusic").setVolume(25);
/*Load the font*/
sf::Font font;
if (!(font.loadFromFile("arial.ttf")))
if(DEBUG)
std::cout << "Error loading fonts" << std::endl;
/*Create the text*/
textCount.setFont(font);
textCount.setString(std::string("points: ") + std::to_string(points));
textCount.setColor(sf::Color::Red);
textCount.setCharacterSize(20);
textCount.setPosition(windowWidth / 2 - (textCount.getString().getSize()*(textCount.getCharacterSize() / 5)), textCount.getCharacterSize() - 10);
textCount.setStyle(sf::Text::Bold);
window.draw(textCount);
/*MAIN GAME LOOP*/
counterTick = 1;
audios.getSound("begin").play();
audios.getMusic("backgroundMusic").play();
while (inGame && !pause)
{
std::string counter = std::to_string(counterTick);
if(DEBUG)
std::cout << "Tick: " + counter << std::endl;
window.clear(sf::Color::White);
if(processEvents()){
break;
}
update(audios);
render(grid);
snake.secInput = false;
counterTick++;
}
audios.getSound("losing").play();
audios.getMusic("backgroundMusic").stop();
std::system("PAUSE");//bad practice, debuggin purposes
}
Audio.h
#pragma once
#ifndef GUARD_AUDIO_H
#define GUARD_AUDIO_H
#include "variables.h"
#include "SFML\Graphics.hpp"
#include "SFML\Audio.hpp"
#include <memory>
struct Audio{
std::map<std::string, sf::Sound> sounds;
std::map<std::string, std::unique_ptr<sf::Music>> musics;
//std::map<std::string, sf::Sound> sounds;
//std::map<std::string, sf::Music> musics;
Audio();
void Audio::addSound(sf::Sound&, sf::SoundBuffer& , const std::string&);
void Audio::addSound(sf::Sound&, const std::string&);
void Audio::addMusic(const std::string&, std::unique_ptr<sf::Music> );
sf::Sound &Audio::getSound(std::string);
sf::Music &Audio::getMusic(std::string);
void Audio::loadAudio();
};
#endif//GUARD_AUDIO_H
Audio.cpp
#include "Audio.h"
#include <iostream>
Audio::Audio(){
loadAudio();
}
void Audio::addSound(sf::Sound& s, sf::SoundBuffer& sb, const std::string &key){
s.setBuffer(sb);
sounds.insert(std::pair<std::string, sf::Sound>(key, std::move(s)));
}
void Audio::addSound(sf::Sound& s, const std::string &key){
sounds.insert(std::pair<std::string, sf::Sound>(key, s));
}
void Audio::addMusic(const std::string &key, std::unique_ptr<sf::Music> value){
musics.insert(std::pair<std::string, std::unique_ptr<sf::Music> >(key, std::move(value)));
}
sf::Sound &Audio::getSound(std::string key){
return sounds.at(key);
}
sf::Music &Audio::getMusic(std::string key){
return *musics.at(key);
}
void Audio::loadAudio(){
//sf::Music backgroundMusic;
sf::Sound s_eating;
sf::SoundBuffer sb_eating;
sf::Sound s_moving;
sf::SoundBuffer sb_moving;
sf::Sound s_losing;
sf::SoundBuffer sb_losing;
sf::Sound s_begin;
sf::SoundBuffer sb_begin;
auto backgroundMusic = std::unique_ptr<sf::Music>(new sf::Music());
if (!backgroundMusic->openFromFile("backgroundmusic.wav"))
if(DEBUG)
std::cerr << "Error opening \"backgroundmusic.wav\"" << std::endl;
if (!sb_eating.loadFromFile("eatingsfx.wav"))
if(DEBUG)
std::cerr << "Error opening \"eatingsfx.wav\"" << std::endl;
if (!sb_moving.loadFromFile("movingsfx.wav"))
if(DEBUG)
std::cerr << "Error opening \"movingsfx.wav\"" << std::endl;
if (!sb_losing.loadFromFile("losingsfx.wav"))
if(DEBUG)
std::cerr << "Error opening \"losingsfx.wav\"" << std::endl;
if (!sb_begin.loadFromFile("beginsfx.wav"))
if(DEBUG)
std::cerr << "Error opening \"beginsfx.wav\"" << std::endl;
//s_eating.setBuffer(sb_eating);
//s_moving.setBuffer(sb_moving);
//s_losing.setBuffer(sb_losing);
//s_begin.setBuffer(sb_begin);
addMusic(std::string("backgroundMusic"), std::move(backgroundMusic));
addSound(s_eating, sb_eating, std::string("eating"));
addSound(s_moving, sb_moving, std::string("moving"));
addSound(s_losing, sb_losing, std::string("losing"));
addSound(s_begin, sb_begin, std::string("begin"));
}
You basically need a sound manager, this is what I use to manager my sounds.
Header file
#pragma once
#include "SFML/Audio.hpp"
#include "Enums.h"
#include <map>
#include <vector>
#include <iostream>
class SoundLoader
{
public:
//SoundNames is an enum
SoundLoader();
~SoundLoader();
void LoadSounds();
void PlaySound(SoundNames soundName);
std::map<SoundNames, sf::SoundBuffer> Sounds;
std::vector<sf::Sound> playingSounds;
};
Source file
#include "SoundLoader.h"
SoundLoader::SoundLoader()
{
}
SoundLoader::~SoundLoader()
{
}
void SoundLoader::LoadSounds()
{
Sounds[SoundNames::sound1].loadFromFile("Assets/Sounds/sound1.wav");
}
void SoundLoader::PlaySound(SoundNames soundName)
{
if (playingSounds.size() == 0)
{
playingSounds.push_back(sf::Sound());
playingSounds.at(0).setBuffer(Sounds[soundName]);
playingSounds.at(0).play();
}
else
{
int location = -1;
for (int i = 0; i < playingSounds.size(); i++)
{
if (playingSounds.at(i).getStatus() != sf::Sound::Playing && location == -1)
{
location = i;
}
}
if (location != -1)
{
playingSounds.at(location).setBuffer(Sounds[soundName]);
playingSounds.at(location).play();
}
else
{
playingSounds.push_back(sf::Sound());
playingSounds.at(playingSounds.size()-1).setBuffer(Sounds[soundName]);
playingSounds.at(playingSounds.size() - 1).play();
}
}
}
Now you have yourself a SoundManager, you can load sounds like so and play sounds like so.
SoundLoader sl;
sl.LoadSounds();
sl.Play(SoundNames::sound1);
Hope this helps you out, if you need any more help just let me know.
The sf::SoundBuffer effectively holds the audio data you want to playback. To do so the data needs to exist as long as you're playing it. In your code however, you load the buffers in Audio::loadAudio() but as soon as you leave that function, the buffer will get destroyed and your sf::Sound object don't have any kind of data to playback.
You rather want to store the sf::SoundBuffer objects instead of the sf::Sound objects.
Hi I made a level generator with a 3D Buzz tutorial called Evil Monkeys.
I generated a level but I can't get it to draw on the screen.
My code:
Level.cpp
#include "Level.h"
#include <stdlib.h>
#include "Sprite.h"
Level::Level(drawEngine *de, int w, int h)
{
drawArea = de;
width = w;
height = h;
gamer = 0;
//create memory for our level
level = new char *[width];
for(int x = 0; x < width; x++)
{
level[x] = new char[height];
}
//create the level
createLevel();
drawArea->setMap(level);
}
Level::~Level()
{
for(x = 0; x < width; x++)
delete []level[x];
delete [] level;
}
void Level::createLevel(void)
{
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
int random = rand() % 100;
if (y == 0 || y == height - 1 || x == 0 || x == width - 1)
{
level[x][y] = TILE_WALL;
}
else
{
if (random < 90 || (x < 3 && y < 3))
level[x][y] = TILE_EMPTY;
else
level[x][y] = TILE_WALL;
}
}
}
}
void Level::draw(void)
{
// level to be drawn here
drawArea->drawBackground();
}
Level.h
#ifndef LEVEL_H
#define LEVEL_H
enum
{
TILE_EMPTY,
TILE_WALL
};
#include "drawEngine.h"
class Character;
class Level
{
public:
Level(drawEngine *de, int width = 30, int height = 20);
~Level();
int x;
int y;
void addPlayer(Character *p);
void update(void);
void draw(void);
bool keyPress(char c);
protected:
void createLevel(void);
private:
int width;
int height;
char **level;
Character *gamer;
drawEngine *drawArea;
};
#endif
Game.cpp
#include "Game.h"
#include <conio.h>
#include <iostream>
#include "drawEngine.h"
#include "Character.h"
#include <windows.h>
using namespace std;
//this will give ME 32 fps
#define GAME_SPEED 25.33
bool Runner::run()
{
level = new Level(&drawArea, 30, 20);
drawArea.createBackgroundTile(TILE_EMPTY, ' ');
drawArea.createBackgroundTile(TILE_WALL, '+');
drawArea.createSprite(0, '$');
gamer = new Character(&drawArea, 0);
level->draw();
char key = ' ';
startTime = timeGetTime();
frameCount = 0;
lastTime = 0;
posX = 0;
while (key != 'q')
{
while(!getInput(&key))
{
timerUpdate();
}
//gamer->keyPress(key);
//cout << "Here's what you pressed: " << key << endl;
}
delete gamer;
cout << frameCount / ((timeGetTime() - startTime) / 100) << " fps " << endl;
cout << "Game Over" << endl;
return true;
}
bool Runner::getInput(char *c)
{
if (kbhit())
{
*c = getch();
return true;
}
}
void Runner::timerUpdate()
{
double currentTime = timeGetTime() - lastTime;
if (currentTime < GAME_SPEED)
return;
frameCount++;
lastTime = timeGetTime();
}
game.h
#ifndef GAME_H
#define GAME_H
#include "drawEngine.h"
#include "Sprite.h"
#include "Character.h"
#include "level.h"
class Runner
{
public:
bool run();
Runner(){};
protected:
bool getInput(char *c);
void timerUpdate();
private:
Level *level;
Character* gamer;
double frameCount;
double startTime;
double lastTime;
int posX;
drawEngine drawArea;
};
#endif
drawEngine.cpp
#include <iostream>
#include "drawEngine.h"
#include <windows.h>
using namespace std;
drawEngine::drawEngine(int index, int xSize, int ySize, int x, int y)
{
screenWidth = x;
screenHeight = y;
map = 0;
//set cursor visibility to false
//cursorVisibility(false);
}
drawEngine::~drawEngine()
{
cursorVisibility(true);
//set cursor visibility to true
}
int drawEngine::createSprite(int index, char c)
{
if (index >= 0 && index < 16)
{
spriteImage[index] = c;
return index;
}
return -1;
}
void drawEngine::deleteSprite(int index)
{
// in this implemantation we don't need it
}
void drawEngine::drawSprite(int index, int posX, int posY)
{
//go to the correct location
gotoxy (index, posX, posY);
// draw the sprite
cout << spriteImage[index];
cursorVisibility(false);
}
void drawEngine::eraseSprite(int index, int posX, int posY)
{
gotoxy (index, posX, posY);
cout << ' ';
}
void drawEngine::setMap(char **data)
{
map = data;
}
void drawEngine::createBackgroundTile(int index, char c)
{
if (index >= 0 && index < 16)
{
tileImage[index] = c;
}
}
void drawEngine::drawBackground(void)
{
if(map)
{
for(int y = 0; y < screenHeight; y++)
{
gotoxy(0,y, 0);
for(int x = 0; x < screenWidth; x++)
cout << tileImage[map[x][y]];
}
}
}
void drawEngine::gotoxy(int index, int x, int y)
{
HANDLE output_handle;
COORD pos;
pos.X = x;
pos.Y = y;
output_handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output_handle, pos);
}
void drawEngine::cursorVisibility(bool visibility)
{
HANDLE output_handle;
CONSOLE_CURSOR_INFO cciInfo;
cciInfo.dwSize = 1;
cciInfo.bVisible = visibility;
output_handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(output_handle, &cciInfo);
}
drawEngine.h
#ifndef DRAWENGINE_H
#define DRAWENGINE_H
class drawEngine
{
public:
drawEngine(int index, int xSize = 30, int ySize = 20, int x = 0, int y = 0);
~drawEngine();
drawEngine(){};
int createSprite(int index, char c);
void deleteSprite(int index);
void eraseSprite(int index, int posX, int posY);
void createBackgroundTile(int index, char c);
void drawSprite(int index, int posX, int posY);
void drawBackground(void);
void setMap(char **);
protected:
char **map;
int screenWidth, screenHeight;
char spriteImage[16];
char tileImage[16];
private:
void gotoxy(int index, int x, int y);
void cursorVisibility(bool visibility);
};
#endif
I've also got Sprite.cpp, Sprite.h, Character.h,Character.cpp and main.cpp if you need them
Ok, I made it through the code and found one issue. The Runner class encapsulates a drawEngine object. At the constructor of Runner, the default c'tor of drawEngine is called, which doesn't set values for sceenWidth and screenHeight (or any other member). Luckily in debug mode, they are defaulted to 0xcccccccc which is negative so you're drawBackground returns immediately (Visual Studio 2010).
You should change that c'tor (or even remove it) and corretly initialize the engine in runner's constructor, e.g.:
class Runner {
public:
Runner() : drawArea(0, width, height, ?, ?){};
[...]
};
Further, the x and y members are used in the loops in drawBackground. You should use screenWidth and screenWidth, resp. BTW, I don't know what x and y should be in drawEngine
UPDATE: The x and y coordinates at the gotoxy call in drawBackground are mixed up, so you draw everything on the same line. BTW: what is index used for?
Hi I am having trouble with my code. I got error C2227.
My code:
Game.h
#ifndef GAME_H
#define GAME_H
#include "drawEngine.h"
#include "Sprite.h"
class Runner
{
public:
bool run();
Runner(){};
protected:
bool getInput(char *c);
void timerUpdate();
private:
int *gamer;
double frameCount;
double startTime;
double lastTime;
int posX;
drawEngine drawArea;
};
#endif
Game.cpp
#include "Game.h"
#include <conio.h>
#include <iostream>
#include "drawEngine.h"
#include "Character.h"
#include <windows.h>
using namespace std;
//this will give ME 32 fps
#define GAME_SPEED 25.33
bool Runner::run()
{
drawArea.createSprite(0, '$');
gamer; new Character(&drawArea, 0);
char key = ' ';
startTime = timeGetTime();
frameCount = 0;
lastTime = 0;
posX = 0;
while (key != 'q')
{
while(!getInput(&key))
{
timerUpdate();
}
gamer->keyPress(key);
//cout << "Here's what you pressed: " << key << endl;
}
delete gamer;
cout << frameCount / ((timeGetTime() - startTime) / 100) << " fps " << endl;
cout << "Game Over" << endl;
return true;
}
bool Runner::getInput(char *c)
{
if (kbhit())
{
*c = getch();
return true;
}
}
void Runner::timerUpdate()
{
double currentTime = timeGetTime() - lastTime;
if (currentTime < GAME_SPEED)
return;
frameCount++;
lastTime = timeGetTime();
}
I've never seen this before.
I've looked everywhere for an answer but they don't work with my code. I've got other code too that belongs to the same project which I didn't post.
I think the problem is that you've defined gamer as
int *gamer;
So when you write
gamer->keyPress(key);
You're trying to call a member function on an int, which is not legal.
Are you sure you want gamer to be an int *? That seems incorrect.
Change
int *gamer;
to
Character* gamer;
and
gamer; new Character(&drawArea, 0);
to
gamer = new Character(&drawArea, 0);