I'm trying to swap to objects of class. It's a puzzle game something like http://www.neos-guide.org/sites/default/files/Fifteen_puzzle.png. I'm using std::swap but it doesn't work. Here's code:
if (puzzle[i-1][j].getNum() == 16) {
std::swap(puzzle[i][j], puzzle[i-1][j]);
}
else if (puzzle[i+1][j].getNum() == 16) {
std::swap(puzzle[i+1][j], puzzle[i][j]);
}
else if (puzzle[i][j+1].getNum() == 16 && j != 3) {
std::swap(puzzle[i][j+1], puzzle[i][j]);
}
else if (puzzle[i][j-1].getNum() == 16 && j != 0) {
std::swap(puzzle[i][j-1], puzzle[i][j]);
}
And here's my puzzle class:
class Puzzle {
private:
int x;
int y;
int num;
ALLEGRO_FONT *font;
public:
Puzzle();
~Puzzle();
void init(int posx, int posy, ALLEGRO_FONT *font);
void setNum(int num);
void draw();
void setXY(int x, int y);
int getX();
int getY();
int getNum();
bool click(int mx, int my);
};
I have tried std::swap on 2D array of integers, on two objects of same class, on 1D object array and 2D object array. It worked. It just doesn't work in this implementation. I also tried to comment out ALLEGRO_FONT as I thought that there is the problem. But nothing has changed. cplusplus.com says that I need to include <algorithm> or <utility>. I tried both (not at the same time) but it didn't work. Any suggestions? Thank you :)
Related
I am currently trying to make a 2d vector representing pixels.
The problem is that when I try to set a value at a specific index the program crash.
The compilation is good.
Here is the .h :
#include "../include/graphics.h"
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <vector>
#include <string>
using namespace rgb_matrix;
class Viewport
{
public:
Viewport(std::string id,int xMn,int yMn,int xMx,int yMx,Canvas *c)
{
canvas_=c;
_id = id;
_x = xMn;
_y = yMn;
width=xMx-xMn;
height=yMx-yMn;
}
void SetPixel(int x_vport,int y_vport,rgb_matrix::Color c);
int getXMax(){
return _x + height;
}
int getHeight(){
return height;
}
int getWidth(){
return width;
}
int getX(){
return _x;
}
void clear();
std::string getId(){return _id;}
void show();
void fill(int r,int g,int b);
private :
Canvas *canvas_;
int width,height;
int _x,_y;
std::string _id;
std::vector<std::vector<rgb_matrix::Color> > colors;
};
The weird point is that I can access to the values into the .h but not into the .cpp :
void Viewport::SetPixel(int x, int y, rgb_matrix::Color c) {
if(x>=0 && y>= 0 && x< width && y < height) {//if in rectangle
colors.at(x).at(y) = c;
}
}
This is not how you fill values in the vector:
void Viewport::SetPixel(int x, int y, rgb_matrix::Color c) {
if(x>=0 && y>= 0 && x< width && y < height) {//if in rectangle
colors.at(x).at(y) = c;
}
}
Before you visit an element of the vector colors.at(x) you must assure that the size of the vector colors.size() is bigger than x. So, maybe you call colors.resize() somewhere in other place, before filling vector with values.
The crash is intended, that's an exception thrown due to the out-of-bounds access.
I would question the choice of the data structure:
std::vector<rgb_matrix::Color> can be chosen if you need the continuous block of memory (just remember to either resize it or construct it with width*height parameter =)
vector of vectors implies a dense nonrectangular structure - normally it's used for something like triangle matrices to save the memory.
using x = unsigned; using y = unsigned;vector::<std::tuple<x, y, rgb::matrix::Color> can be used for a sparse structure with a few pixels in random places.
Also x>=0 && y>= 0 can be avoided if you switch to unsigned instead of int=)
I have a sample of code for some framework that I am using. For ease of reading I have separated blocks of code from different files.
Tile.h
class Tile
{
public:
Tile(int row, int column);
~Tile();
void Draw();
void Update(double delta);
void SetValue(int value);
int GetValue();
private:
//Member variables
Label* m_ValueLabel;
int m_Value = 0;
int m_Row;
int m_Column;
float duration = 0.0f;
float xScale = 0;
float yScale = 0;
};
Tile.cpp
void Tile::SetValue(int value)
{
//Set the Tile's value
m_Value = value;
//if (m_Value != EMPTY_TILE)
{
//Update the Tile's Label
m_ValueLabel->SetText(to_string(m_Value));
}
/*else
{
m_ValueLabel->SetText("");
}*/
}
Game.h
class Game
{
public:
Game(); //Constructor
~Game(); //Destructor
void Update(double delta);
void Draw();
void HandleLeftMouseClick(float mouseX, float mouseY);
void HandleRightMouseClick(float mouseX, float mouseY);
void HandleKeyPress(Keyboard::Key key);
bool isBoardFull();
int GetEmptyTileIndex();
void SpawnTile();
void RandomizeSeed();
int RandomRange(int min, int max);
private:
//Member variables should go here
Tile* m_Tiles[NUM_TILES];
bool isTileFull[16] = {};
int TileValueArray[5] = { 2,2,2,4,4 };
};
Game.cpp
void Game::SpawnTile()
{
RandomizeSeed();
int meaningfulVariableName = GetEmptyTileIndex();
if (meaningfulVariableName != -1)
{
int RandomNumber = RandomRange(0,4);
int TileValue = TileValueArray[RandomNumber];
}
else if (meaningfulVariableName == -1)
{
//Does nothing
}
}
What I need to do with this is make it so that the TileValue created in Game.cpp can be passed to the SetValue function in Tile.cpp because the value created is required for m_Value in SetValue.
The majority of code present can probably be ignored, and anything commented out should not effect how I need the code to function at the moment. There is nothing wrong with the framework outside of these files, as I have used it several times before.
I know there are easier ways to do this, but this is how I am required to do it. I would really appreciate if someone could help me with this because anything that I have found online has not helped. If you think that you may need more code for clarification on something, please do not hesitate to ask. Also, in case it helps I am using this to create a 2048 clone.
You have a function Game::GetEmptyTileIndex which will return an index. You can use that index to set Game::m_Tiles by changing the Game::SpawnTile function like so:
// Game.cpp
void Game::SpawnTile()
{
RandomizeSeed();
// Returns a tile index.
int meaningfulVariableName = GetEmptyTileIndex();
if (meaningfulVariableName != -1)
{
int RandomNumber = RandomRange(0,4);
int TileValue = TileValueArray[RandomNumber];
// Set the value for the tile at the required index.
m_Tiles[meaningfulVariableName]->SetValue(TileValue);
}
else if (meaningfulVariableName == -1)
{
//Does nothing
}
}
Hi im doing little project tomy school and keep getting weird for me error.
While calling one of methods in my object this pointer is set to 0xcdcdcdcd. i googled it and found some info about erasing memory or destroing objects before calling, but i make sure no destructors are called before.
World.h
class Organism;
class Human;
class World
{
private:
vector <Organism*> organisms;
vector <Organism*> organismsToAdd;
vector <string> logs;
int turn_;
void initializeWorld();
void drawInterface();
void drawInfo();
void drawOrganisms();
void nextTurn();
bool isPositionTaken(int x, int y);
Organism* getOrganism(int x, int y);
void queueOrganismToAdd(Organism* newOrganism);
void addQueuedOrganisms();
void generateStartOrganisms();
bool isPlayerAlive();
public:
void executeMove(Organism* moving, int toX, int toY); //here's the problem
bool isPositionValid(int x, int y);
World(int x, int y);
struct
{
int x_, y_;
} worldSize;
void startGame();
~World();
};
executeMove
void World::executeMove(Organism* moving, int toX, int toY)
{
cout << moving->getSign();
getch();
if (!isPositionTaken(toX, toY)) // <- here it brake
{
moving->setPosition(toX, toY);
}
else if (moving->getSign() == getOrganism(toX, toY)->getSign())
{
//multiply
//make log
}
else {
if (!moving->specialCollision((getOrganism(toX, toY)))) return;
if (!getOrganism(toX, toY)->specialCollision(moving)) return;
if (moving->getPower() >= getOrganism(toX, toY)->getPower())
{
//log
//delete losser
}
else
{
//log
//delete losser
}
moving->setPosition(toX, toY);
}
}
isPositioinTaken
bool World::isPositionTaken(int x, int y)
{
for (int i = 0; i < this->organisms.size(); ++i) // here this is set to 0xcdcdcdcd
{
if (organisms[i]->getPositionX() == x && organisms[i]->getPositionY() == y) return true;
}
return false;
}
Method isPositionTaken is worlking well in other parts of project so im totally lost if finding whats wrong, i aprreciate any help
Since the organisms member has a default constructor, the only way to see this behavior at the line you indicated is if the call to executeMove() was using a pointer which was uninitialized.
Something like:
World *ptr; // not initialized on stack
...
ptr->executeMove();
Or this method was called from another method with the same problem.
Hey I am trying to make this space game. Now I have developed my ship, and am able to display it. However I would like to be able to use the class for more than one object. I can do this with a constructor but have no clue how to get a constructor working, what changes would I need to make to my code to make the object take an int value as a constructor and allow me to make multiple ships with the code by calling the object.
Here is my header file.
//
// Ship.hpp
// Zerg_Invasion
//
// Created by Flik Wolf on 11/9/15.
//
//
#ifndef Ship_h
#define Ship_h
#include <stdio.h>
#include "ofMain.h"
class Ship {
public:
// Constructor
Ship();
// Methods
void moveLeft();
void moveRight();
void load();
void draw();
void fire();
void keyPressed();
// Properties
int x;
int y;
ofColor color;
ofImage cat;
};
#endif
and here is my CPP file.
//
// Ship.cpp
// Zerg_Invasion
//
// Created by Flik Wolf on 11/9/15.
//
//
#include "Ship.h"
Ship::Ship() {
// Set the initial color
//color.set( ofRandom(255), ofRandom(255), ofRandom(255));
// Initial x position of the ball
x = 450;
// Initial y position of the ball
y = 200;
}
void Ship::moveLeft() {
x -= 10;
}
void Ship::moveRight() {
x += 10;
}
void Ship::load() {
cat.load("spaceShip.png");
}
void Ship::draw() {
cat.draw(x, y);
// ofCircle(x, y, 30);
}
void Ship::fire() {
ofSetColor(255, 255, 255);
ofCircle(x, 200, 2);
}
Also here is the .h and .cpp files for Openframeworks which I am using for graphics.
#pragma once
#include "ofMain.h"
#include "Ship.h"
class ofApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y);
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
Ship theShip;
};
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup() {
// Smooth edges
ofEnableSmoothing();
// Fixed framerate
ofSetFrameRate(120);
theShip.load();
// No need to define the initial position of the ball
// because the Ball constructor does it for you
}
//--------------------------------------------------------------
void ofApp::update() {
// theShip.move();
}
//--------------------------------------------------------------
void ofApp::draw() {
ofBackground(0);
std::vector <int> nums;
nums.push_back(0);
nums.push_back(1);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
nums.push_back(6);
nums.push_back(7);
nums.push_back(8);
cout << nums[0] << endl;
cout << nums[1] << endl;
theShip.draw();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key) {
if (key == 'a')
{
theShip.moveLeft();
}
if (key == 'd')
{
theShip.moveRight();
}
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key) {
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button) {
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button) {
theShip.fire();
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button) {
}
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h) {
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg) {
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo) {
}
As mentioned, the constructor in your case should only produce one ship, and this should be the case with all object constructors.
However, it's still easy enough to create and maintain multiple ships (as you've implemented them) if you use a container like std::vector.
Containing multiple ships:
To create a container for your ships, you can use a vector like so:
std::vector<Ship> Ships;
Adding new ships:
To add additional ships to it, you can use std::vector::push_back():
Ships.push_back(Ship()); //Adds a new ship to 'Ships'
Updating the ships:
There are a couple of ways to cycle through your ships:
for (auto& i : Ships)
i.Update(); //Some updating function for each ship
Or, if you need to keep track of the specific position of each ship inside the vector:
for (unsigned int i = 0; i < Ships.size(); ++i)
Ships[i].Update() //The same updating function
How about to get the x and y as constructor argument?
in the .h file:
struct Ship {
// Constructor
Ship(int _x = 450, int _y = 200);
// ...
in the cpp file:
Ship::Ship(int _x, int _y) : x{_x}, y{_y} {
// Set the initial color
//color.set( ofRandom(255), ofRandom(255), ofRandom(255));
}
So, i decided to create a collision detection function in my game and i put it into the class of enemies. Then i put it to "enemy.cpp" and i used "this" pointer.
The code:
if(((this->sprite.getPosition().y + this->sprite.getTextureRect().height) >= blocklist[i].sprite.getPosition().y) &&
(this->sprite.getPosition().y <= blocklist[i].sprite.getPosition().y))
This gives me SIGSEGV segmentation error. I can't find what could be the problem in this line, here is the enemyclass for reference.
class enemyclass
{
public:
sf::Sprite sprite;
sf::Sprite bubble;
//PROPERTIES
float xspeed, yspeed;
int x, y;
float health;
bool colR, colL, colU, colD;
int skin;
void detectCollisions(int blocksize);
};
and the blockclass that i made a vector of to use as a list of enemies:
class blockclass
{
public:
sf::Sprite sprite;
int x, y;
};
I would be very thankfull for an answer since i can't find out what's wrong.
As others have said, if some complicated instruction causes an error, split it into smaller parts and see, in which part the error arises:
if( this->x == 0) // changes nothing
x = 0; // but validates 'this'
int thisy = sprite.getPosition().y;
int thish = sprite.getTextureRect().height;
sf::Sprite &that = blocklist[i].sprite;
if( that.x == 0) // validate 'that'
that.x = 0;
int thaty = that.getPosition().y;
if(thisy + thish >= thaty && thisy <= thaty) {
// ......
}