This question already has answers here:
How do I use arrays in C++?
(5 answers)
Closed 7 years ago.
I have been trying to make a simulator which involves ants randomly running around (for now...) I want to make a array of "Ant" to contain all my ant information and later functions. How would I do that?? (example with my code if possible)(I know java fairly well so if you could relate it to java that would be nice
//inclusions
#include <GLUT/glut.h>
#include <OpenGL/glu.h>
#include <OpenGL/gl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//declarations
//class declarations
void keyboard (unsigned char key, int x, int y);
void keyboardUp (unsigned char key, int x, int y);
void mouseLocation(int,int);
int onMouse;
int rightClick;
int a = 0;
int mx;
int my;
float red=1.0, blue=0, green=0;
class Ant {
int x;
int y;
int type;
Ant() { } // private default constructor
public:
Ant(int nx, int ny, int ntype)
{
x = nx;
y = ny;
type = ntype;
}
void SetX(int swagger)
{
x = swagger;
}
void SetY(int ny)
{
y = ny;
}
void SetType(int ntype)
{
type = ntype;
}
int GetX() { return x; }
int GetY() { return y; }
};
//mouse listener methods
void mouseLocation(int x,int y) {
mx = x;
my = y;
}
void mouseClicks(int button, int state, int x, int y) {
mx = x;
my = y;
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
onMouse = 1;
}
if(button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
onMouse = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) {
rightClick = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
rightClick = 1;
}
}
//keylistner methods
void keyboard (unsigned char key, int x, int y)
{
if (key == 'a')
{
a = 1;
}
}
void keyboardUp (unsigned char key, int x, int y)
{
if(key == 'a')
{
a = 0;
}
}
//ant methods
int randommove(int position,int speed)
{
speed++;
int random = rand() %speed - speed/2 ;
position = position + random;
return position;
}
//drawing methods
Ant ant1(100,100,1);
Ant ant2(50,500,1);
//Here is the where I want to try the ant array something like
//Ant ants[x] and then I would fill in the values with the SetX, SetY... methods
void ant()
{
int a2 = randommove(ant1.GetX(),2);
ant1.SetX(a2);
glLineWidth(1);
glBegin(GL_LINES);
glColor4f(1, 0, 0, 1);
glVertex2i(ant1.GetX(),ant1.GetY());
glVertex2i(ant1.GetX()+5,ant1.GetY()+5);
glEnd();
}
void line1()
{
if(a == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(80,20);
glVertex2i(100,400);
glEnd();
}
}
void line2()
{
if(onMouse == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(200,20);
glVertex2i(100,400);
glEnd();
}
}
void rect1()
{
if(mx >= 50 && my >= 50)
{
int x = 100;
int y = 100;
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(x,y,0);
glVertex3f(x+w,y,0);
glVertex3f(x+w,y+h,0);
glVertex3f(x,y+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
void rect2()
{
if(rightClick == 1)
{
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(mx,my,0);
glVertex3f(mx+w,my,0);
glVertex3f(mx+w,my+h,0);
glVertex3f(mx,my+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
//render drawing methods
void renderScence(void){
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(red, green, blue);
ant();
line1();
line2();
rect1();
rect2();
glFlush();
}
//graphics init method
void init(void)
{
glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB);
glutInitWindowSize (500,500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Testing");
glClearColor (0, 0, 0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
}
//main/graphics calls
int main(int argc,char** argv)
{
glutInit(&argc, argv);
init();
glutDisplayFunc(renderScence);
glutIdleFunc(renderScence);
glutMouseFunc(mouseClicks);
glutPassiveMotionFunc(mouseLocation);
glutKeyboardUpFunc (keyboardUp);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
You could create the array of Ant objects inside main, and it's the same way you'd create any other array except it's of type Ant:
Ant ants[25]; // 25 Ant objects
/* to set them all the same, as an example */
for(i=0; i<25; i++)
{
ants[i].SetX(1); // x = 1
ants[i].SetY(2); // y = 2
ants[i].SetType(3); // type = 3
}
Related
As a school project, I've made the classic snake game using SDL2 and C++.
I've already implemented the growing, moving features for the Snake but it was required to make the movement based on a grid, but when I implemented the grid feature, the self-collision was always triggering whenever grow one part, so every time I start the game, and eat the first fruit, the snake dies.
I've been trying for a while now, from placing a delay to the adding of the tail and delaying the collision check, but to no avail, it's always colliding with itself even though it is not.
I can't see what is wrong with the self collision, I would gladly appreciate it if someone can point out what's wrong.
Snake.h
#include "GameObject.h"
#include "common.h"
#include "draw.h"
#include "Food.h"
#include "util.h"
#include <vector>
struct Segment {
int x;
int y;
Segment(int posx, int posy) {
x = posx;
y = posy;
}
};
class Snake :
public GameObject
{
public:
~Snake();
void start();
void update();
void draw();
void outOfBoundsCheck();
void move();
void addSegment(int x, int y);
void selfCollisionCheck(bool hasEaten);
void setHasMoved(bool a);
void setIsAlive(bool a);
int getX();
int getY();
int getWidth();
int getHeight();
bool getIsAlive();
bool getHasMoved();
std::vector<Segment*> const& getV() const;
private:
std::vector<Segment*> body;
SDL_Texture* headTexture;
SDL_Texture* bodyTexture;
int x;
int y;
int width;
int height;
int dx;
int dy;
int tempX;
int tempY;
bool isAlive;
bool hasMoved;
};
Snake.cpp
Snake::~Snake()
{
}
void Snake::start()
{
// Load Texture
headTexture = loadTexture("gfx/player.png");
bodyTexture = loadTexture("gfx/body.png");
tempX = 0;
tempY = 0;
x = 0;
y = 0;
dx = 0;
dy = 0;
isAlive = true;
hasMoved = false;
width = 0;
height = 0;
SDL_QueryTexture(headTexture, NULL, NULL, &width, &height);
addSegment(x, y);
}
void Snake::update()
{
std::cout << "Head" << body[0]->x << std::endl;
if (body.size() > 1) {
std::cout << "2nd Segment" << body[1]->x << std::endl;
if (body.size() > 2) {
std::cout << "3nd Segment" << body[2]->x << std::endl;
}
}
move();
outOfBoundsCheck();
}
void Snake::draw()
{
if (!isAlive) return; // Cancel the render if player dies
for (int i = 0; i < body.size(); i++) {
blit(headTexture, body[i]->x, body[i]->y);
}
}
void Snake::outOfBoundsCheck()
{
for (int i = 0; i < body.size(); i++) {
if (body[i]->x > SCREEN_WIDTH) {
body[i]->x = 0;
}
if (body[i]->x < 0) {
body[i]->x = SCREEN_WIDTH;
}
if (body[i]->y > SCREEN_HEIGHT) {
body[i]->y = 0;
}
if (body[i]->y < 0) {
body[i]->y = SCREEN_HEIGHT;
}
}
}
void Snake::move()
{
if (app.keyboard[SDL_SCANCODE_W] && dy != 5) {
dx = 0;
dy = -5;
}
if (app.keyboard[SDL_SCANCODE_A] && dx != 5) {
dx = -5;
dy = 0;
}
if (app.keyboard[SDL_SCANCODE_S] && dy != -5) {
dx = 0;
dy = 5;
}
if (app.keyboard[SDL_SCANCODE_D] && dx != -5) {
dx = 5;
dy = 0;
}
Segment* snakeHead = *(body.begin()); //Grid
tempX += dx;
tempY += dy;
if (tempX % 25 == 0) {
snakeHead->x += tempX;
tempX = 0;
}
if (tempY % 25 == 0) {
snakeHead->y += tempY;
tempY = 0;
}
for (int i = body.size() - 1; i > 0; i--) { //For the other parts to follow
body[i]->x = body[i - 1]->x;
body[i]->y = body[i - 1]->y;
}
}
void Snake::addSegment(int x, int y)
{
Segment* seg = new Segment(x, y );
body.push_back(seg);
}
void Snake::selfCollisionCheck(bool hasEaten) // Fail
{
Segment* head = body[0];
if (hasEaten == false) {
for (int i = 1; i < body.size(); i++) {
if (head->x == body[i]->x && head->y == body[i]->y) {
isAlive = false;
break;
}
}
}
else {
return;
}
}
void Snake::setHasMoved(bool a)
{
hasMoved = a;
}
void Snake::setIsAlive(bool a)
{
isAlive = a;
}
int Snake::getX()
{
return x;
}
int Snake::getY()
{
return y;
}
int Snake::getWidth()
{
return width;
}
int Snake::getHeight()
{
return height;
}
bool Snake::getIsAlive()
{
return isAlive;
}
bool Snake::getHasMoved()
{
return hasMoved;
}
std::vector<Segment*> const& Snake::getV() const
{
// TODO: insert return statement here
return body;
}
GameScene.h
#include "Scene.h"
#include "GameObject.h"
#include "Snake.h"
#include "Food.h"
#include "util.h"
#include "text.h"
#include "SoundManager.h"
class GameScene : public Scene
{
public:
GameScene();
~GameScene();
void start();
void draw();
void update();
void spawnFood();
void collisionLogic();
void selfCollision();
void despawnFood(Food* food);
private:
Snake* snake;
Food* food;
int points;
std::vector<Food*> spawnedFood;
};
GameScene.cpp
#include "GameScene.h"
GameScene::GameScene()
{
// Register and add game objects on constructor
snake = new Snake();
this->addGameObject(snake);
points = 0;
}
GameScene::~GameScene()
{
delete snake;
delete food;
}
void GameScene::start()
{
Scene::start();
// Initialize any scene logic here
initFonts();
spawnFood();
}
void GameScene::draw()
{
Scene::draw();
drawText(110, 20, 255, 255, 255, TEXT_CENTER, "POINTS: %03d", points);
if (snake->getIsAlive() == false) {
drawText(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 255, 255, 255, TEXT_CENTER, "GAME OVER!");
}
}
void GameScene::update()
{
Scene::update();
if (spawnedFood.size() == 0 && spawnedFood.size() != 1) {
spawnFood();
}
collisionLogic();
selfCollision();
}
void GameScene::spawnFood()
{
int random = rand() % 720;
if (random % 25 != 0) {
random = rand() % 720;
}
else {
Food* food = new Food();
this->addGameObject(food);
food->setPosition(rand() % SCREEN_WIDTH, rand() % SCREEN_HEIGHT);
spawnedFood.push_back(food);
}
}
void GameScene::collisionLogic()
{
Segment* head = snake->getV()[0];
std::vector<Segment*> snakeBody = snake->getV();
for (int i = 0; i < objects.size(); i++) {
Food* food = dynamic_cast<Food*>(objects[i]);
if (food != NULL) {
int collision = checkCollision(
head->x, head->y, snake->getWidth(), snake->getHeight(),
food->getX(), food->getY(), food->getWidth(), food->getHeight()
);
if (collision == 1) {
despawnFood(food);
snake->addSegment(snakeBody[snakeBody.size() - 1]->x, snakeBody[snakeBody.size() - 1]->y); //Adds a part to the snake
points++;
break;
}
}
}
}
void GameScene::selfCollision()
{
std::vector<Segment*> body = snake->getV();
Segment* head = snake->getV()[0];
for (int i = 1; i < snake->getV().size(); i++) {
if (head->x == body[i]->x && head->y == body[i]->y) {
snake->setIsAlive(false);
break;
}
}
}
void GameScene::despawnFood(Food* food)
{
int index = -1;
for (int i = 0; i < spawnedFood.size(); i++) {
if (food == spawnedFood[i]) {
index = i;
break;
}
}
if (index != -1) {
spawnedFood.erase(spawnedFood.begin() + index);
delete food;
}
}
It seems that I had some logical errors when it comes to the grid movement because when I re-coded everything and changed the grid movement into cell based instead of using modulo condition by dividing the screen width and height to the pixel size of my snake and using that as the coordinates for my movement, everything went back to normal and the collision bug disappeared.
Instead of doing this for the grid movement
Old Grid Movement Code
tempX += dx;
tempY += dy;
if (tempX % 25 == 0) {
snakeHead->x += tempX;
tempX = 0;
}
if (tempY % 25 == 0) {
snakeHead->y += tempY;
tempY = 0;
}
I defined this as a permanent value in my defs.h
defs.h
#define CELL_SIZE 25 // Size of the segment
#define CELL_WIDTH SCREEN_WIDTH / CELL_SIZE
#define CELL_HEIGHT SCREEN_HEIGHT / CELL_SIZE
After that, since I'm still going to render the picture with the default resolution, I multiplied CELL_SIZE to the dest variable of my blit function
draw.cpp
void blit(SDL_Texture* texture, int x, int y)
{
SDL_Rect dest;
dest.x = x * CELL_SIZE;
dest.y = y * CELL_SIZE;
SDL_QueryTexture(texture, NULL, NULL, &dest.w, &dest.h);
SDL_RenderCopy(app.renderer, texture, NULL, &dest);
}
This results to the snake and any other thing that I'm going to render to follow a grid and by assigning the x and y values with the CELL_WIDTH and CELL_HEIGHT as substitution to the resolution, I accomplished the grid movement with no conflict with my collision check.
I'm writing the program that continuously draws a polygon until the user clicks right-click, but when I continue to draw something else on the screen the polygon disappears, how can I avoid this? This is my program:
float mouseX, mouseY;
vector<float> vecX(40);
vector<float> vecY(40);
int numPoints = 0;
int closed = 0;
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
if (closed || numPoints > 40)
numPoints = 0;
closed = 0;
vecX[numPoints] = mouseX;
vecY[numPoints] = mouseY;
numPoints++;
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
closed = 1;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
if (numPoints)
{
glBegin(GL_LINE_STRIP);
for (int i = 0; i < numPoints; ++i)
glVertex2f(vecX[i], vecY[i]);
if (closed)
glVertex2f(vecX[0], vecY[0]);
else
glVertex2f(mouseX, mouseY);
glEnd();
}
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(600, 400);
glutInitWindowPosition(0, 0);
glutCreateWindow("Testing");
gluOrtho2D(0, 600, 400, 0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
}
The vecX and vecY are used to store the coordinate of the mouse click.
Once a polyline is finished, you need to store it to a container. Use a std::vector of polylines. The type of a polyline is std::vector<float>. At the begin, just 1 empty polyline is in the container:
std::vector<std::vector<float>> polylines(1);
When you left-click, a new vertex coordinate is added to the last polyline in the container. When you right-click, a new polyline is added to the container:
void mouse(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
polylines.back().push_back(mouseX);
polylines.back().push_back(mouseY);
}
if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
{
polylines.push_back(std::vector<float>());
}
}
Draw the polylines in nested loops:
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
for (auto i=0; i < polylines.size(); ++ i)
{
bool is_last = i == polylines.size() - 1;
const auto& polyline = polylines[i];
glBegin(is_last ? GL_LINE_STRIP : GL_LINE_LOOP);
for (auto j = 0; j < polyline.size(); j += 2)
glVertex2f(polyline[j], polyline[j+1]);
if (is_last)
glVertex2f(mouseX, mouseY);
glEnd();
}
glutSwapBuffers();
}
I have a base class cGameObject which has a virtual update function. I wish to have many derived game objects each with their own specific update function.
I want to add the derived gameobjects to a vector and iterate through them to call each of their update methods.
What is wrong with my iterator?
//In Header file
std::vector <cGameObject*> vGameObjs;
std::vector <cGameObject*>::iterator Iter;
cGameObject *AGameObj;
/In cpp file - add object pointer to vector
AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
vGameObjs.push_back(AGameObj);
AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
vGameObjs.push_back(AGameObj);
//Iterator Crashing??
for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
{
//Call Each Objects Update() method here?
}
When I run this, it throws an exception: read access violation. _Mycont was nullptr.
Not sure what to do.
error thrown
Header of Class App Class:
#ifndef _H_AGK_TEMPLATE_
#define _H_AGK_TEMPLATE_
// Link to GDK libraries
#include "AGK.h"
#include "Brickbat.h"
#include "BrickBall.h"
#include "cGameObject.h"
#include <vector>
#define DEVICE_WIDTH 1024
#define DEVICE_HEIGHT 768
#define DEVICE_POS_X 32
#define DEVICE_POS_Y 32
#define FULLSCREEN false
// used to make a more unique folder for the write path
#define COMPANY_NAME "BitMaNip:Play"
// Global values for the app
class app
{
public:
// constructor
app() { memset ( this, 0, sizeof(app)); }
// main app functions - mike to experiment with a derived class for this..
void Begin( void );
int Loop( void );
void End( void );
private:
//Vector of GameObject Pointers;
std::vector <cGameObject*> vGameObjs;
//Iterator of GameObjects
std::vector <cGameObject*>::iterator Iter;
BrickBat *MyBat;
BrickBall *MyBall;
cGameObject *AGameObj;
};
extern app App;
#endif
// Allow us to use the LoadImage function name
#ifdef LoadImage
#undef LoadImage
#endif
cpp file for Header
// Includes
#include "template.h"
#include "cGameObject.h"
#include
// Namespace
using namespace AGK;
app App;
void app::Begin(void)
{
agk::SetVirtualResolution (DEVICE_WIDTH, DEVICE_HEIGHT);
agk::SetClearColor( 151,170,204 ); // light blue
agk::SetSyncRate(60,0);
agk::SetScissor(0,0,0,0);
//Test
/*BrickBall = agk::CreateSprite(0);
agk::SetSpriteSize(BrickBall, 64, 64);
agk::SetSpriteColor(BrickBall, 255, 255, 255, 255);
xPos = (DEVICE_WIDTH - 64) / 2;
yPos = (DEVICE_HEIGHT - 64) / 2;
agk::SetSpritePosition(BrickBall, xPos , yPos );
xDir = 1;
yDir = 1;
iSpeed = 8;*/
MyBat = new BrickBat(128, 32, (1024-128)/2, 768-64, 0);
AGameObj = new BrickBat(128, 32, (1024 - 128) / 2, 768 - 64, 0);
vGameObjs.push_back(AGameObj);
MyBall = new BrickBall(64, 512, 384, 1, 1, 0);
AGameObj = new BrickBall(64, 512, 384, 1, 1, 0);
vGameObjs.push_back(AGameObj);
}
int app::Loop (void)
{
agk::Print( agk::ScreenFPS() );
if (agk::GetRawKeyState(37) == 1)
{
MyBat->MoveLeft();
}
if (agk::GetRawKeyState(39) == 1)
{
MyBat->MoveRight();
}
MyBat->Update();
MyBall->Update();
MyBall->Collided(MyBat->iGetBatID());
for (Iter = vGameObjs.begin(); Iter != vGameObjs.end(); ++Iter)
{
//(*Iter)->Update();
//(*Iter)->Collided(MyBat->iGetBatID());
}
Derived class
include "cGameObject.h"
class BrickBall: public cGameObject
{
private:
bool bHoriDir;
bool bVertDir;
int iSpeed;
bool bPause; //in case game is paused
public:
BrickBall(int iSize, int xPos, int yPos, bool bHori, bool bVert, int ImageID);
virtual void Update() override;
virtual void Collided(int OtherSpriteToCheck) override;
};
agk::Sync();
return 0; // return 1 to close app
}
void app::End (void)
{
}
Base Class:
#pragma once
class cGameObject
{
protected:
bool bInit = false;
int iSprID;
int iImageID;
int iXPos;
int iYPos;
int iAngle;
int iAlpha;
int iWidth;
int iHeight;
int iColour;
//Movement
float fDeltaX;
float fDeltaY;
//Animation
int iAniType; //Type of animation
//0 = No Animation
//1 = Repeating Loop of Frames (All image is animation)
//2 =
int iFrameW; //Width of Animation Frame
int iFrameH; //Height of Animation frame
int iFPS; //Animation Delay
int iNumFrames; //Number of animation frames
int iAniCount; //Frame Counter
public:
// set up default for constructor
cGameObject(int width = 16, int height = 16, int xPos = 0, int yPos = 0, int ImageID = 0);
void SetPosition(int ixPos, int iyPos);
void SetSize(int iWidth, int iHeight);
void SetWidth(int Width);
void SetAngle(int iAngle);
void SetTransparency(int iAlpha);
void SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames);
virtual void Collided(int OtherSpriteToCheck) {};
virtual void Update() {};
int iGetWidth();
int iGetHeight();
int iGetX();
int iGetY();
int iGetSprID();
~cGameObject();
};
Base Class cpp
#include "cGameObject.h"
#include "agk.h"
void cGameObject::SetAngle(int iAngle)
{
if (bInit == true)
{
if (iAngle > 0 && iAngle < 359)
{
agk::SetSpriteAngle(iSprID, iAngle);
}
}
}
//cGameObject::cGameObject(int width, int height, int xPos, int yPos, const char * szImageFile)
cGameObject::cGameObject(int width, int height, int xPos, int yPos, int ImageID)
{
bInit = true;
iImageID = 0;
/*if (std::strlen(szImageFile) > 0)
{
iImageID = agk::LoadImage(szImageFile);
if (iImageID < 1)
{
bInit = false;
}
}*/
iColour = agk::MakeColor(255, 255, 255);
//init animation code
iAniType = 0; //Type of animation
iFrameW = 64; //Width of Animation Frame
iFrameH = 64; //Height of Animation frame
iFPS = 10; //Animation Delay
iNumFrames = 1; //Number of animation frames
iAniCount = 0; //Frame Counter
iSprID = agk::CreateSprite(iImageID);
if (iSprID < 1)
{
bInit = false;
}
else
{
agk::SetSpriteSize(iSprID, width, height);
agk::SetSpritePosition(iSprID, xPos, yPos);
fDeltaX = 4.0;
fDeltaY = 4.0;
}
}
void cGameObject::SetPosition(int ixPos, int iyPos)
{
if (bInit == true)
{
agk::SetSpritePosition(iSprID, ixPos, iyPos);
}
}
void cGameObject::SetSize(int iWidth, int iHeight)
{
if (bInit == true)
{
if (iWidth > 0 && iWidth < 1024 && iHeight > 0 && iHeight < 1024)
{
agk::SetSpriteSize(iSprID, iWidth, iHeight);
}
}
}
void cGameObject::SetWidth(int Width)
{
if (bInit == true)
{
agk::GetSpriteWidth(Width);
}
}
void cGameObject::SetTransparency(int iAlpha)
{
if (bInit == true)
{
if (iAlpha > 0 && iAlpha < 256)
{
agk::SetSpriteTransparency(iSprID, iAlpha);
}
}
}
void cGameObject::SetAnimation(int Type, int FrameW, int FrameH, int FPS, int NumFrames)
{
//Animation
iAniType = Type;
iFrameW = FrameW; //Width of Animation Frame
iFrameH = FrameH; //Height of Animation frame
iFPS = FPS; //Animation Delay
iNumFrames = NumFrames; //Number of animation frames
iAniCount = 0; //Frame Counter
agk::SetSpriteAnimation(iSprID, iFrameW, iFrameH, iNumFrames);
if (iAniType > 0)
{
agk::PlaySprite(iSprID, iFPS);
}
}
int cGameObject::iGetWidth()
{
if (bInit == true)
{
return agk::GetSpriteWidth(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetHeight()
{
if (bInit == true)
{
return agk::GetSpriteHeight(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetX()
{
if (bInit == true)
{
return agk::GetSpriteX(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetY()
{
if (bInit == true)
{
return agk::GetSpriteY(iSprID);
}
else
{
return 0;
}
}
int cGameObject::iGetSprID()
{
if (bInit == true)
{
return iSprID;
}
else
{
return 0;
}
}
cGameObject::~cGameObject()
{
if (bInit == true)
{
agk::DeleteSprite(iSprID);
}
}
Derived Class Header:
#include "cGameObject.h"
class BrickBall: public cGameObject
{
private:
bool bHoriDir;
bool bVertDir;
int iSpeed;
bool bPause; //in case game is paused
public:
BrickBall(int iSize, int xPos, int yPos, bool bHori, bool bVert, int ImageID);
virtual void Update() override;
virtual void Collided(int OtherSpriteToCheck) override;
};
Derived Class cpp
#include "BrickBall.h"
BrickBall::BrickBall(int Size, int xPos, int yPos, bool bHori, bool bVert, int ImageID):cGameObject(Size, Size, xPos, yPos, ImageID)
{
iWidth = Size;
iHeight = Size;
iXPos = xPos;
iYPos = yPos;
bHoriDir = bHori;
bVertDir = bVert;
/*iSprID = agk::CreateSprite(0);
agk::SetSpriteColor(iSprIdx, 255, 255, 255, 255);
//agk::SetSpriteSize(iSprIdx, iSize, iSize);
agk::SetSpriteSize(iSprIdx, 64, 64);
//agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
agk::SetSpritePosition(iSprIdx, ixPos, iyPos);
bInit = true;*/
iSpeed = 8;
}
void BrickBall::Update()
{
if (bInit==true)// && BatID > 0)
{
//Move Ball
agk::SetSpriteColor(iSprID, 100, 100, 100, 255);
agk::PrintC("BallX:");
agk::Print(iXPos);
if (bHoriDir == 1) //Right
{
iXPos = iXPos + iSpeed;
if (iXPos > 1024 - iWidth)
{
bHoriDir = 0;
}
}
else
{
iXPos = iXPos - iSpeed;
if (iXPos < 0)
{
bHoriDir = 1;
}
}
if (bVertDir == 1) //down
{
iYPos = iYPos + iSpeed;
if (iYPos > 768 - 64)
{
bVertDir = 0;
}
}
else
{
iYPos = iYPos - iSpeed;
if (iYPos < 0)
{
bVertDir = 1;
}
}
agk::SetSpritePosition(iSprID, iXPos, iYPos);
//END Move Ball
//Bat2Ball Collisions
/*if (agk::GetSpriteCollision(iSprID, BatID))
{
//We have collided.
//As Ball is bigger than the gap below the bat must have hit top or sides
//so just flip the vertcal direction
if (bVertDir == 1)
{
bVertDir = 0;
}
}*/
}
}
void BrickBall::Collided(int OtherSpriteToCheck)
{
if (agk::GetSpriteCollision(iSprID, OtherSpriteToCheck))
{
if (bVertDir == 1)
{
bVertDir = 0;
}
}
}
I don't know the cause of your error, but I got this exact error because I had an iterator to a vector, then I updated the vector, then I tried to dereference the iterator (e.g. access *myIterator). I'm new to C++, but it seems that if you alter a collection after getting an iterator for it, your iterator is no longer valid. You need to repoint your iterator to wherever it was.
I have recently decided to try to learn c++. My major road block so far is object/class declaration I am reasonably experienced in java but the way c++ works confuses me. Can someone please show me a example of using a object (like the one below if possible) inside one file or multiple files? here is my current code (object is not implemented).
//inclusions
#include <GLUT/glut.h>
#include <OpenGL/glu.h>
#include <OpenGL/gl.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//declarations
void keyboard (unsigned char key, int x, int y);
void keyboardUp (unsigned char key, int x, int y);
void mouseLocation(int,int);
int onMouse;
int rightClick;
int a = 0;
int mx;
int my;
float red=1.0, blue=0, green=0;
class Ant
{
private:
int x;
int y;
int speed;
Ant() { } // private default constructor
public:
Ant(int nx, int ny, int nspeed)
{
SetX(nx);
SetY(ny);
SetSpeed(nspeed);
}
void SetX(int nx)
{
x = nx;
}
void SetY(int ny)
{
y = ny;
}
void SetSpeed(int nspeed)
{
speed = nspeed;
}
int GetX() { return x; }
int GetY() { return y; }
int GetSpeed() { return speed; }
};
//mouse listener methods
void mouseLocation(int x,int y) {
mx = x;
my = y;
}
void mouseClicks(int button, int state, int x, int y) {
mx = x;
my = y;
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
onMouse = 1;
}
if(button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
onMouse = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP) {
rightClick = 0;
}
if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
rightClick = 1;
}
}
//keylistner methods
void keyboard (unsigned char key, int x, int y)
{
if (key == 'a')
{
a = 1;
}
}
void keyboardUp (unsigned char key, int x, int y)
{
if(key == 'a')
{
a = 0;
}
}
//drawing methods
void line1()
{
if(a == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(20,20);
glVertex2i(100,400);
glEnd();
}
}
void line2()
{
if(onMouse == 1)
{
glLineWidth(2.5);
glBegin(GL_LINES);
glVertex2i(200,20);
glVertex2i(100,400);
glEnd();
}
}
void rect1()
{
if(mx >= 50 && my >= 50)
{
int x = 100;
int y = 100;
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(x,y,0);
glVertex3f(x+w,y,0);
glVertex3f(x+w,y+h,0);
glVertex3f(x,y+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
void rect2()
{
if(rightClick == 1)
{
int x = 100;
int y = 100;
int w = 100;
int h = 100;
unsigned int rgba = 0xff0000ff; // red, no alpha
glBegin(GL_QUADS);
glColor4f(((rgba>>24)&0xff)/255.0f,
((rgba>>16)&0xff)/255.0f,
((rgba>>8)&0xff)/255.0f,
(rgba&0xff)/255.0f);
glVertex3f(mx,my,0);
glVertex3f(mx+w,my,0);
glVertex3f(mx+w,my+h,0);
glVertex3f(mx,my+h,0);
glEnd();
glColor4f(1, 1, 1, 1);
}
}
//render drawing methods
void renderScence(void){
glClear (GL_COLOR_BUFFER_BIT);
glColor3f(red, green, blue);
line1();
line2();
rect1();
rect2();
glFlush();
}
//graphics init method
void init(void)
{
glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB);
glutInitWindowSize (500,500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Testing");
glClearColor (0, 0, 0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
}
//main/graphics calls
int main(int argc,char** argv)
{
glutInit(&argc, argv);
init();
glutDisplayFunc(renderScence);
glutIdleFunc(renderScence);
glutMouseFunc(mouseClicks);
glutPassiveMotionFunc(mouseLocation);
glutKeyboardUpFunc (keyboardUp);
glutKeyboardFunc (keyboard);
glutMainLoop();
return 0;
}
Your class definition is correct (although a bit Javaish). You can create and use an object of type Ant like this:
Ant a(3, 7, 82);
a.SetSpeed(42);
int speed = a.GetSpeed();
this is my first post on SO, please forgive me if I don't do it right.
I am trying to draw some a simple hexagon grid using C++ SFML. The hex grid is created in it'sown class and called in main.
Hex class Header
class Terrain : public sf::Drawable, public sf::Transformable
{
public:
explicit Terrain(sf::Texture texture, int x, int y);
sf::Texture texture;
sf::CircleShape hexMethod(float x, float y, float Radius);
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
void cameraAngle();
void setTexture(sf::Texture);
void setX(int xint);
void setY(int yint);
void update(sf::Time deltaTime);
sf::Time T_currentTime;
private:
sf::Texture m_terrain;
int xcoord, ycoord;
sf::Vertex m_verticeList[6];
bool isOdd(int integer)
{
if (integer % 2 == 0)
return true;
else
return false;
}
//virtual ~Terrain()
//{
//}
};
Hex class cpp
Terrain::Terrain(sf::Texture texture, int x, int y) :
m_terrain(texture), xcoord(x), ycoord(y)
{
}
void Terrain::setTexture(sf::Texture newText)
{
m_terrain = newText;
}
void Terrain::setX(int xint)
{
xcoord = xint;
}
void Terrain::setY(int yint)
{
ycoord = yint;
}
sf::CircleShape Terrain::hexMethod(float x, float y, float Radius){
float Width = Radius * 2, Height = Width *sqrt(3) / 2;
sf::CircleShape shape(Radius, 6);
float origo = 200;
float yrsize;
float normalDistanceX = origo + Width * 3 / 4 * x;
float normalSeparationY = origo + Height*y;
float isEven = Height / 2;
shape.setTexture(&texture, false);
shape.setOutlineThickness(2);
shape.setOrigin(Radius, Radius);
shape.setRotation(30);
if (Terrain::isOdd(x))
yrsize = normalSeparationY;
else
yrsize = normalSeparationY + isEven;
shape.setPosition(normalDistanceX, yrsize);
m_verticeList[0] = shape.getPoint(0);
m_verticeList[1] = shape.getPoint(1);
m_verticeList[2] = shape.getPoint(2);
m_verticeList[3] = shape.getPoint(3);
m_verticeList[4] = shape.getPoint(4);
m_verticeList[5] = shape.getPoint(5);
return shape;
}
void Terrain::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 3; j++)
{
states.transform *= getTransform();
states.texture = &m_terrain;
target.draw(m_verticeList, 4, sf::Points, states);
}
}
}
How I call it in main:
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 800), "Puppet Masters!");
if (!tTexture.loadFromFile("Green.jpg"))
return EXIT_FAILURE;
Terrain newterrain(tTexture, 3,3);
newterrain.hexMethod(3, 3, 70);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::P)
{
}
window.clear();
window.draw(newterrain);
window.display();
}
return 0;
}
I get no errors when running the code, however I also get no result, just a blank black screen. My intention is to have the hexes drawn from calling the class and defining it's variables. The Hexfunction I used in main at first to get a hex grid working, I don't think know how to translate that into a class properly.