Hey,
I've let my C++ skills dwindle away and decided it's time to get them polished up again - I didn't realise just how rusty they had become!
To kick things off I decided to convert some Tier 1 code to Tier 2. Last week I banged together a quick and easy parallax scrolling demo so I thought that would be a good thing to convert.
Here is the Tier 1 code:
type t_pxLayer
y as integer
speed as float
x as float[]
spr as integer[]
nearest as integer
furthest as integer
endtype
global pxLayer as t_pxLayer[]
global pxDir as integer
global pxRelativeSpeed as float //The difference in speed between layers
//Add layers FRONT to BACK
function pxCreateLayer(spr, w, h)
px as t_pxLayer
px.y = 0
pxDir = cLEFT
px.spr.insert(spr)
px.x.insert(0.0)
pxRelativeSpeed = 0.1
SetSpriteSize(px.spr[0], w, h)
SetSpriteDepth(px.spr[0], 1000+pxLayer.length)
qty = GetScreenBoundsLeft()/GetSpriteWidth(px.spr[0]) + 1
k = 1
while k <= qty
px.spr.insert(CloneSprite(px.spr[0]))
px.x.insert((GetSpriteWidth(px.spr[0])*k)*1.0)
SetSpriteDepth(px.spr[k], 1000+pxLayer.length)
inc k
endwhile
px.furthest = qty
px.nearest = 0
pxLayer.insert(px)
for k = 0 to pxLayer.length
pxLayer[k].speed = ((pxLayer.length+2)-k)*pxRelativeSpeed
next k
endfunction
function pxUpdate()
if pxLayer.length = -1 then exitfunction
for lay = 0 to pxLayer.length
for s = 0 to pxLayer[lay].spr.length
select pxDir
case cLEFT
if pxLayer[lay].x[s] < 0-GetSpriteWidth(pxLayer[lay].spr[s])
pxLayer[lay].x[s] = pxLayer[lay].x[pxLayer[lay].furthest] + GetSpriteWidth(pxLayer[lay].spr[pxLayer[lay].furthest])
pxLayer[lay].furthest = s
inc pxLayer[lay].nearest
if pxLayer[lay].nearest > pxLayer[lay].spr.length
pxLayer[lay].nearest = 0
endif
endif
endcase
case cRIGHT
if GetSpriteX(pxLayer[lay].spr[s]) > GetScreenBoundsRight()
pxLayer[lay].x[s] = pxLayer[lay].x[pxLayer[lay].nearest] - GetSpriteWidth(pxLayer[lay].spr[pxLayer[lay].nearest])
pxLayer[lay].nearest = s
dec pxLayer[lay].furthest
if pxLayer[lay].furthest < 0
pxLayer[lay].furthest = pxLayer[lay].spr.length
endif
endif
endcase
endselect
pxLayer[lay].x[s] = pxLayer[lay].x[s] + pxLayer[lay].speed * pxDir
SetSpritePosition(pxLayer[lay].spr[s], pxLayer[lay].x[s], pxLayer[lay].y)
next s
next lay
endfunction
function pxSetSpeed(s#)
for k = 0 to pxLayer.length
pxLayer[k].speed = s#
next k
endfunction
function pxSetRelativeSpeed(s#)
pxRelativeSpeed = s#
pxSetSpeed(pxLayer[0].speed)
if pxLayer.length < 1 then exitfunction
for k = 1 to pxLayer.length
pxLayer[k].speed = pxLayer[k-1].speed * pxRelativeSpeed
next k
endfunction
function pxSetLayerSpeed(lay, s#)
if lay < 0 or lay>pxLayer.length
message("pxSetLayerSpeed()"+CRLF$+"Called with illegal layer ID"): exitfunction
endif
pxLayer[lay].speed = s#
endfunction
function pxSetLayerY(lay, Y)
if lay < 0 or lay>pxLayer.length
message("pxSetLayerSpeed()"+CRLF$+"Called with illegal layer ID"): exitfunction
endif
pxLayer[lay].y = Y
endfunction
function pxSetDirection(d)
pxDir = d
endfunction
function pxSetDepth(d)
for lay = 0 to pxLayer.length
for s = 0 to pxLayer[lay].spr.length
SetSpriteDepth(pxLayer[lay].spr[s], d-lay)
next s
next lay
endfunction
function pxSetPosition(p)
endfunction
And my attmept at conversion:
.h
#pragma once
#include <vector>
class pxLayer
{
public:
pxLayer();
~pxLayer();
//SETTERS
void SetY(const int val) { y = val; };
void SetNearest(const int val) { nearest = val; };
void SetFurthest(const int val) { furthest = val; };
void SetSpeed(const double val) { speed = val; };
void SetSprite(const int val) { spr.push_back(val); };
void SetX(const double val) { x.push_back(val); };
void SetWidth(const int val) { width = val; };
//GETTERS
int GetFurthest() { return furthest; };
int GetNearest() { return nearest; };
int GetWidth() { return width; };
int GetY() { return y; };
double GetSpeed() { return speed; };
std::vector<int> spr;
std::vector<double> x;
private:
int y;
int width;
int nearest;
int furthest;
double speed;
};
class Parallax
{
public:
Parallax();
~Parallax();
std::vector<pxLayer> layers;
void CreateLayer(int spr, int w, int h);
void Update();
private:
int direction;
double relativeSpeed;
};
.cpp
#include "Parallax.h"
#include "agk.h"
#include "display.h"
pxLayer::pxLayer()
{
}
pxLayer::~pxLayer()
{
}
Parallax::Parallax()
{
direction = -1;
relativeSpeed = 0.1;
}
Parallax::~Parallax()
{
}
void Parallax::CreateLayer(int spr, int w, int h)
{
pxLayer lay;
lay.SetY(0);
lay.SetSprite(spr);
lay.SetX(0.0);
agk::SetSpriteSize(spr, w, h);
agk::SetSpriteDepth(spr, 1000 + layers.size());
lay.SetWidth(agk::GetSpriteWidth(spr));
int qty = ((agk::GetScreenBoundsRight() - agk::GetScreenBoundsLeft()) / lay.GetWidth()) + 1;
int k = 1;
while (k <= qty)
{
lay.SetSprite(agk::CloneSprite(spr));
lay.SetX(agk::GetSpriteWidth(spr)*k*1.0);
agk::SetSpriteDepth(lay.spr[lay.spr.size()-1], 1000 + layers.size());
k++;
}
lay.SetNearest(0);
lay.SetFurthest(lay.spr.size());
layers.push_back(lay);
k = 0;
for (std::vector<pxLayer>::iterator itlay = layers.begin(); itlay != layers.end(); ++itlay)
{
itlay->SetSpeed((layers.size() + 2 - k++)*relativeSpeed);
}
}
void Parallax::Update()
{
if (layers.size() < 0) { return; }
int kspr = 0;
for (std::vector<pxLayer>::iterator itlay = layers.begin(); itlay != layers.end(); ++itlay)
{
for (std::vector<int>::iterator itspr = itlay->spr.begin(); itspr != itlay->spr.end(); ++itspr)
{
switch (direction)
{
case -1:
if (itlay->x[kspr] < 0 - agk::GetSpriteWidth(itlay->spr[kspr]))
{
itlay->x[kspr] = itlay->x[itlay->GetFurthest()] + itlay->GetWidth();
itlay->SetFurthest(kspr);
itlay->SetNearest(kspr+1);
if (itlay->GetNearest() > itlay->spr.size())
{
itlay->SetNearest(0);
}
}
case 1:
break;
}
itlay->x[kspr] += itlay[kspr].GetSpeed() * direction;
agk::SetSpritePosition(*itspr, itlay->x[kspr], itlay->GetY());
kspr++;
}
}
}
The error I am getting is "Vector iterator not dereferencable"
and it highlights this:
for (std::vector<int>::iterator itspr = itlay->spr.begin(); itspr != itlay->spr.end(); ++itspr)
(line 65 in the code snippet)
I'd really appreciate some guidance because I can't see what is wrong with it.
Thanks