Getting closer to a solution... Still need to figure out the desyncs.
This commit is contained in:
parent
49ac2695e1
commit
b103a9209c
@ -5,6 +5,7 @@
|
||||
namespace olc
|
||||
{
|
||||
enum class InputType{
|
||||
NONE,
|
||||
KEY,
|
||||
MOUSE,
|
||||
MOUSE_MOVE,
|
||||
@ -18,10 +19,14 @@ namespace olc
|
||||
float delay;
|
||||
vi2d mousePos;
|
||||
|
||||
public:
|
||||
Input(int32_t key,bool press,InputType type,float delay);
|
||||
Input(int32_t key,bool press,InputType type,float delay,vi2d mousePos); //MOUSE_MOVE
|
||||
friend std::ostream&operator<<(std::ostream&os,const Input&rhs){os<<"Input(Key="<<rhs.key<<",Press="<<rhs.press<<",Type="<<int(rhs.type)<<",Delay="<<rhs.delay<<",MousePos="<<rhs.mousePos;return os;};
|
||||
|
||||
public:
|
||||
Input(Key k);
|
||||
Input(int mouseButton);
|
||||
Input(InputType type);
|
||||
};
|
||||
|
||||
class Recording{
|
||||
@ -30,14 +35,16 @@ namespace olc
|
||||
std::vector<Input>inputs;
|
||||
float lastKeyTime;
|
||||
vi2d prevMousePos;
|
||||
float waitTime;
|
||||
};
|
||||
|
||||
class ReplayFile{
|
||||
friend class Replay;
|
||||
std::string filename;
|
||||
std::vector<Input>inputs;
|
||||
float accTime;
|
||||
float nextKeyTime;
|
||||
double accTime;
|
||||
double nextKeyTime;
|
||||
size_t currentKeyInd;
|
||||
};
|
||||
|
||||
class Replay : public olc::PGEX
|
||||
@ -46,6 +53,13 @@ namespace olc
|
||||
bool isReplaying=false;
|
||||
Recording currentRecording;
|
||||
ReplayFile currentReplay;
|
||||
std::vector<Input>ignoredInputs;
|
||||
HWButton pKeyboardState[256] = { 0 };
|
||||
HWButton pMouseState[nMouseButtons] = { 0 };
|
||||
vi2d vMousePos = {0,0};
|
||||
int32_t nMouseWheelDelta = 0;
|
||||
|
||||
void ResetStates();
|
||||
|
||||
public:
|
||||
Replay();
|
||||
@ -55,6 +69,14 @@ namespace olc
|
||||
void StartReplay(const std::string filename);
|
||||
void StopReplay();
|
||||
|
||||
bool RecordingIsActive();
|
||||
bool ReplayIsActive();
|
||||
|
||||
HWButton GetKey(Key k);
|
||||
HWButton GetMouse(uint32_t button);
|
||||
const vi2d& GetMousePos();
|
||||
int32_t GetMouseWheel();
|
||||
|
||||
protected:
|
||||
virtual void OnAfterUserCreate() override;
|
||||
virtual bool OnBeforeUserUpdate(float& fElapsedTime) override;
|
||||
@ -75,45 +97,162 @@ namespace olc{
|
||||
|
||||
}
|
||||
|
||||
bool Replay::RecordingIsActive(){
|
||||
return isRecording;
|
||||
}
|
||||
bool Replay::ReplayIsActive(){
|
||||
return isReplaying;
|
||||
}
|
||||
|
||||
HWButton Replay::GetKey(Key k){
|
||||
return ReplayIsActive()?pKeyboardState[k]:pge->GetKey(k);
|
||||
}
|
||||
HWButton Replay::GetMouse(uint32_t button){
|
||||
return ReplayIsActive()?pMouseState[button]:pge->GetMouse(button);
|
||||
}
|
||||
const vi2d& Replay::GetMousePos(){
|
||||
return ReplayIsActive()?vMousePos:pge->GetMousePos();
|
||||
}
|
||||
int32_t Replay::GetMouseWheel(){
|
||||
return ReplayIsActive()?nMouseWheelDelta:pge->GetMouseWheel();
|
||||
}
|
||||
|
||||
bool Replay::OnBeforeUserUpdate(float& fElapsedTime){
|
||||
if (isRecording){
|
||||
if (RecordingIsActive()){
|
||||
bool keyChanged=false;
|
||||
for (int i=0;i<256;i++){
|
||||
if (pge->GetKey(Key(i)).bPressed){
|
||||
bool found=false;
|
||||
for (Input&input:ignoredInputs){
|
||||
if (input.type==InputType::KEY&&input.key==i){
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) continue;
|
||||
if (GetKey(Key(i)).bPressed){
|
||||
currentRecording.inputs.push_back({i,true,InputType::KEY,currentRecording.lastKeyTime});
|
||||
currentRecording.lastKeyTime=0;
|
||||
keyChanged=true;
|
||||
}
|
||||
if (pge->GetKey(Key(i)).bReleased){
|
||||
if (GetKey(Key(i)).bReleased){
|
||||
currentRecording.inputs.push_back({i,false,InputType::KEY,currentRecording.lastKeyTime});
|
||||
currentRecording.lastKeyTime=0;
|
||||
keyChanged=true;
|
||||
}
|
||||
}
|
||||
for (int i=0;i<5;i++){
|
||||
if (pge->GetMouse(i).bPressed){
|
||||
bool found=false;
|
||||
for (Input&input:ignoredInputs){
|
||||
if (input.type==InputType::MOUSE&&input.key==i){
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) continue;
|
||||
if (GetMouse(i).bPressed){
|
||||
currentRecording.inputs.push_back({i,true,InputType::MOUSE,currentRecording.lastKeyTime});
|
||||
currentRecording.lastKeyTime=0;
|
||||
keyChanged=true;
|
||||
}
|
||||
if (pge->GetMouse(i).bReleased){
|
||||
if (GetMouse(i).bReleased){
|
||||
currentRecording.inputs.push_back({i,false,InputType::MOUSE,currentRecording.lastKeyTime});
|
||||
currentRecording.lastKeyTime=0;
|
||||
keyChanged=true;
|
||||
}
|
||||
}
|
||||
if (pge->GetMousePos()!=currentRecording.prevMousePos){
|
||||
currentRecording.prevMousePos=pge->GetMousePos();
|
||||
currentRecording.inputs.push_back({0,false,InputType::MOUSE_MOVE,currentRecording.lastKeyTime,pge->GetMousePos()});
|
||||
if (GetMousePos()!=currentRecording.prevMousePos){
|
||||
bool found=false;
|
||||
for (Input&input:ignoredInputs){
|
||||
if (input.type==InputType::MOUSE_MOVE){
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) goto mouseWheelCheck;
|
||||
//GetWindowSize() = vWindowSize
|
||||
//GetScreenSize() = vScreenSize
|
||||
vi2d vScreenSize=pge->GetScreenSize();
|
||||
vi2d vPixelSize=pge->GetPixelSize();
|
||||
vi2d vWindowSize=pge->GetWindowSize();
|
||||
int32_t ww = vScreenSize.x * vPixelSize.x;
|
||||
int32_t wh = vScreenSize.y * vPixelSize.y;
|
||||
float wasp = (float)ww / (float)wh;
|
||||
vi2d vViewSize={0,0};
|
||||
vViewSize.x=vWindowSize.x;
|
||||
vViewSize.y=(int32_t)((float)vViewSize.x/wasp);
|
||||
if (vViewSize.y>vWindowSize.y){
|
||||
vViewSize.y = vWindowSize.y;
|
||||
vViewSize.x=(int32_t)((float)vViewSize.y*wasp);
|
||||
}
|
||||
vi2d vViewPos=(vWindowSize-vViewSize)/2;
|
||||
vi2d vMousePos=GetMousePos();
|
||||
vMousePos.x+=vViewPos.x;
|
||||
vMousePos.y+=vViewPos.y;
|
||||
//currentRecording.prevMousePos=;
|
||||
currentRecording.inputs.push_back({0,false,InputType::MOUSE_MOVE,currentRecording.lastKeyTime,GetMousePos()});
|
||||
currentRecording.lastKeyTime=0;
|
||||
keyChanged=true;
|
||||
}
|
||||
if (pge->GetMouseWheel()!=0){
|
||||
currentRecording.inputs.push_back({pge->GetMouseWheel(),false,InputType::MOUSE_WHEEL,currentRecording.lastKeyTime});
|
||||
mouseWheelCheck:
|
||||
if (GetMouseWheel()!=0){
|
||||
bool found=false;
|
||||
for (Input&input:ignoredInputs){
|
||||
if (input.type==InputType::MOUSE_WHEEL){
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) goto keyTimeUpdate;
|
||||
currentRecording.inputs.push_back({GetMouseWheel(),false,InputType::MOUSE_WHEEL,currentRecording.lastKeyTime});
|
||||
currentRecording.lastKeyTime=0;
|
||||
keyChanged=true;
|
||||
}
|
||||
keyTimeUpdate:
|
||||
if (!keyChanged){
|
||||
currentRecording.lastKeyTime+=fElapsedTime;
|
||||
} else {
|
||||
currentRecording.lastKeyTime=fElapsedTime;
|
||||
}
|
||||
} else {
|
||||
|
||||
} else
|
||||
if (ReplayIsActive()){
|
||||
if (currentReplay.accTime+fElapsedTime>=currentReplay.nextKeyTime){
|
||||
fElapsedTime=currentReplay.nextKeyTime-currentReplay.accTime;
|
||||
Input¤tInput=currentReplay.inputs[currentReplay.currentKeyInd];
|
||||
switch(currentInput.type){
|
||||
case InputType::KEY:{
|
||||
if (currentInput.press){
|
||||
pKeyboardState[currentInput.key].bPressed=pKeyboardState[currentInput.key].bHeld=true;
|
||||
} else {
|
||||
pKeyboardState[currentInput.key].bReleased=true;
|
||||
pKeyboardState[currentInput.key].bHeld=false;
|
||||
}
|
||||
}break;
|
||||
case InputType::MOUSE:{
|
||||
if (currentInput.press){
|
||||
pMouseState[currentInput.key].bPressed=pMouseState[currentInput.key].bHeld=true;
|
||||
} else {
|
||||
pMouseState[currentInput.key].bReleased=true;
|
||||
pMouseState[currentInput.key].bHeld=false;
|
||||
}
|
||||
}break;
|
||||
case InputType::MOUSE_MOVE:{
|
||||
vMousePos={currentInput.mousePos.x,currentInput.mousePos.y};
|
||||
}break;
|
||||
case InputType::MOUSE_WHEEL:{
|
||||
nMouseWheelDelta=currentInput.key;
|
||||
}break;
|
||||
}
|
||||
currentReplay.currentKeyInd++;
|
||||
if (currentReplay.inputs.size()==currentReplay.currentKeyInd){
|
||||
isReplaying=false;
|
||||
std::cout<<"Replay finished"<<std::endl;
|
||||
} else {
|
||||
currentReplay.nextKeyTime=currentReplay.inputs[currentReplay.currentKeyInd].delay;
|
||||
}
|
||||
currentReplay.accTime=0;
|
||||
} else {
|
||||
currentReplay.accTime+=fElapsedTime;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -129,6 +268,7 @@ namespace olc{
|
||||
currentRecording.lastKeyTime=0;
|
||||
currentRecording.prevMousePos=pge->GetMousePos();
|
||||
isRecording=true;
|
||||
ResetStates();
|
||||
}
|
||||
|
||||
void Replay::StopRecording(){
|
||||
@ -143,6 +283,7 @@ namespace olc{
|
||||
file.close();
|
||||
isRecording=false;
|
||||
std::cout<<"Recording has stopped. Recording saved to "<<currentRecording.filename<<"."<<std::endl;
|
||||
ResetStates();
|
||||
}
|
||||
|
||||
void Replay::StartReplay(const std::string filename){
|
||||
@ -151,11 +292,15 @@ namespace olc{
|
||||
currentReplay.inputs.clear();
|
||||
currentReplay.accTime=0;
|
||||
currentReplay.nextKeyTime=0;
|
||||
currentReplay.currentKeyInd=0;
|
||||
while (file.good()){
|
||||
Input newInput(0,false,InputType::KEY,0);
|
||||
Input newInput(0,false,InputType::NONE,0);
|
||||
int type;
|
||||
file >> newInput.key;
|
||||
file >> newInput.delay;
|
||||
if (currentReplay.nextKeyTime==0){
|
||||
currentReplay.nextKeyTime=newInput.delay;
|
||||
}
|
||||
file >> type;
|
||||
newInput.type = InputType(type);
|
||||
file >> newInput.press;
|
||||
@ -170,14 +315,31 @@ namespace olc{
|
||||
}
|
||||
std::cout<<"Read "<<currentReplay.inputs.size()<<" inputs from "<<filename<<"."<<std::endl;
|
||||
isReplaying=true;
|
||||
ResetStates();
|
||||
}
|
||||
|
||||
void Replay::StopReplay(){
|
||||
isReplaying=false;
|
||||
std::cout<<"Replay has halted."<<std::endl;
|
||||
ResetStates();
|
||||
}
|
||||
|
||||
void Replay::ResetStates(){
|
||||
for (int i=0;i<256;i++){
|
||||
pKeyboardState[i]={false,false,false};
|
||||
}
|
||||
for (int i=0;i<nMouseButtons;i++){
|
||||
pMouseState[i]={false,false,false};
|
||||
}
|
||||
vMousePos={0,0};
|
||||
nMouseWheelDelta=0;
|
||||
}
|
||||
|
||||
Input::Input(int32_t key,bool press,InputType type,float delay):key(key),type(type),delay(delay),press(press){};
|
||||
Input::Input(int32_t key,bool press,InputType type,float delay,vi2d mousePos):key(key),type(type),delay(delay),press(press),mousePos(mousePos){};
|
||||
|
||||
Input::Input(Key k):key(int(k)),type(InputType::KEY){};
|
||||
Input::Input(int mouseButton):key(mouseButton),type(InputType::MOUSE){};
|
||||
Input::Input(InputType type):type(type){};
|
||||
}
|
||||
#endif
|
@ -11,34 +11,115 @@ public:
|
||||
sAppName = "Example";
|
||||
}
|
||||
|
||||
struct GameCube{
|
||||
olc::vf2d pos;
|
||||
olc::vf2d size;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
olc::Replay replaySystem;
|
||||
olc::Replay rp;
|
||||
float upMovement=0;
|
||||
float rightMovement=0;
|
||||
float downMovement=0;
|
||||
float leftMovement=0;
|
||||
|
||||
GameCube player;
|
||||
std::vector<GameCube>cubes;
|
||||
float moveSpd=50;
|
||||
float gameTime=0;
|
||||
|
||||
bool OnUserCreate() override
|
||||
{
|
||||
// Called once at the start, so create things here
|
||||
for (int i=0;i<5;i++){
|
||||
cubes.push_back({});
|
||||
}
|
||||
ResetGame();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResetGame(){
|
||||
player={{0,0},{16,16}};
|
||||
for (int i=0;i<cubes.size();i++){
|
||||
cubes[i]={olc::vf2d{float(i*24+32),float(i*16+12)}, olc::vf2d{8,8}};
|
||||
}
|
||||
}
|
||||
|
||||
void PushBoxes(GameCube&original,float x,float y){
|
||||
for (GameCube&cube:cubes){
|
||||
if (&cube==&original)continue;
|
||||
//https://github.com/OneLoneCoder/olcPixelGameEngine/blob/53fe347f26003f9b75e638b23b71d739527da931/utilities/olcUTIL_Geometry2D.h#L702 // Check if rectangle overlaps rectangle
|
||||
if (cube.pos.x<original.pos.x+original.size.x&&cube.pos.x+cube.size.x>original.pos.x&&
|
||||
cube.pos.y<original.pos.y+original.size.y&&cube.pos.y+cube.size.y>original.pos.y){
|
||||
if (x) cube.pos.x+=x>0?std::max(0.1f,x):std::min(-0.1f,x);
|
||||
if (y) cube.pos.y+=y>0?std::max(0.1f,y):std::min(-0.1f,y);
|
||||
PushBoxes(cube,x,y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OnUserUpdate(float fElapsedTime) override
|
||||
{
|
||||
if (GetKey(olc::F1).bPressed){
|
||||
replaySystem.StartRecording("test.replay");
|
||||
gameTime+=fElapsedTime;
|
||||
|
||||
//Replay controls
|
||||
if (GetKey(olc::F1).bReleased){
|
||||
ResetGame();
|
||||
rp.StartRecording("test.replay");
|
||||
}
|
||||
if (GetKey(olc::F2).bPressed){
|
||||
replaySystem.StopRecording();
|
||||
rp.StopRecording();
|
||||
}
|
||||
if (GetKey(olc::F3).bPressed){
|
||||
replaySystem.StartReplay("test.replay");
|
||||
ResetGame();
|
||||
rp.StartReplay("test.replay");
|
||||
}
|
||||
if (GetKey(olc::F4).bPressed){
|
||||
replaySystem.StopReplay();
|
||||
rp.StopReplay();
|
||||
}
|
||||
|
||||
if (GetKey(olc::F5).bPressed){
|
||||
std::cout<<GetKey(olc::F5).bHeld<<std::endl;
|
||||
}
|
||||
|
||||
//Game Controls
|
||||
float moveAmt = fElapsedTime*moveSpd;
|
||||
if (rp.GetKey(olc::W).bHeld){
|
||||
player.pos.y-=moveAmt;
|
||||
PushBoxes(player,0,-moveAmt);
|
||||
}
|
||||
if (rp.GetKey(olc::A).bHeld){
|
||||
player.pos.x-=moveAmt;
|
||||
PushBoxes(player,-moveAmt,0);
|
||||
}
|
||||
if (rp.GetKey(olc::S).bHeld){
|
||||
player.pos.y+=moveAmt;
|
||||
PushBoxes(player,0,moveAmt);
|
||||
}
|
||||
if (rp.GetKey(olc::D).bHeld){
|
||||
player.pos.x+=moveAmt;
|
||||
PushBoxes(player,moveAmt,0);
|
||||
}
|
||||
|
||||
//Render Game
|
||||
Clear(olc::BLACK);
|
||||
if (rp.RecordingIsActive()){
|
||||
if (std::sinf(8*gameTime)>0){
|
||||
FillCircle({10,ScreenHeight()-10},3,olc::RED);
|
||||
}
|
||||
DrawStringDecal({18,float(ScreenHeight()-13)},"RECORDING",olc::RED);
|
||||
}
|
||||
if (rp.ReplayIsActive()){
|
||||
if (std::sinf(8*gameTime)>0){
|
||||
DrawStringDecal({18,float(ScreenHeight()-13)},"REPLAYING",olc::YELLOW);
|
||||
}
|
||||
}
|
||||
FillCircle(rp.GetMousePos(),5,olc::BLUE);
|
||||
FillRectDecal(player.pos,player.size,olc::YELLOW);
|
||||
for (GameCube&cube:cubes){
|
||||
FillRectDecal(cube.pos,cube.size,olc::DARK_GREEN);
|
||||
}
|
||||
// called once per frame
|
||||
for (int x = 0; x < ScreenWidth(); x++)
|
||||
for (int y = 0; y < ScreenHeight(); y++)
|
||||
Draw(x, y, olc::Pixel(rand() % 255, rand() % 255, rand()% 255));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -47,7 +128,7 @@ public:
|
||||
int main()
|
||||
{
|
||||
Example demo;
|
||||
if (demo.Construct(256, 240, 4, 4))
|
||||
if (demo.Construct(256, 240, 4, 4,false,true))
|
||||
demo.Start();
|
||||
|
||||
return 0;
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user