Change to new camera updating system so that collisions are now aligned with the camera's position when necessary

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent cda39a6c2b
commit 974b60fd22
  1. BIN
      C++ProjectTemplate
  2. 6
      SeasonI.h
  3. 78
      main.cpp
  4. 1
      object.h
  5. 46
      test/test.cpp

Binary file not shown.

@ -140,7 +140,7 @@ class SeasonI:public PixelGameEngine{
float ReadFloatFromStream(std::ifstream&f);
double ReadDoubleFromStream(std::ifstream&f);
std::string ReadStringFromStream(std::ifstream&f);
void CenterCameraOnPlayer();
void CenterCameraOnPlayer();
int GetPointQuadrantRelativeToLine(vi2d x1y1,vi2d x2y2,vi2d point);
TILE GetSafeTileData(std::vector<std::vector<TILE*>>&data);
char GetTileDegreeSafely(std::vector<std::vector<TILE*>>&data);
@ -149,7 +149,9 @@ class SeasonI:public PixelGameEngine{
void ReleaseTestKey(Key k);
void PressTestKeyAndRun(Key k);
void ResetTestKeys();
void SetupGameDrawing();
void SetupGameDrawing();
void UpdateCollisionGrid();
void UpdateCamera(vd2d newpos);
};
extern SeasonI*GAME;
#endif

@ -40,6 +40,7 @@ std::vector<Object*> OBJECTS;
const vd2d NO_NEIGHBOR = {-999,-999};
SeasonI*GAME;
//THIS VARIABLE SHOULD NOT BE UPDATED DIRECTLY! Use UpdateCamera(pos) to update the camera position!
vd2d cameraPos={0,0};
std::vector<Item*> PARTY_INVENTORY;
@ -1389,7 +1390,7 @@ void SeasonI::updateGame(){
if (movementComponents.mag()>0) {
movementComponents=movementComponents.norm();
PARTY_MEMBER_OBJ[0]->frameIndex+=frameCount%PARTY_MEMBER_OBJ[0]->animationSpd==0;
if (PARTY_MEMBER_OBJ[0]->SmoothMove(movementComponents)) {`
if (PARTY_MEMBER_OBJ[0]->SmoothMove(movementComponents)) {
UpdatePlayerTrail(movementComponents,facingDir);
for (int i=0;i<CURRENT_MAP->triggers.size();i++) {
if (CURRENT_MAP->triggers[i]->IsInside(PARTY_MEMBER_OBJ[0]->GetPosWithOrigin())) {
@ -4245,24 +4246,28 @@ void SeasonI::AdvanceMessageBox() {
}
void SeasonI::cameraUpdate() {
vd2d adjustCamera=cameraPos;
switch (GAME_STATE) {
case GameState::EDITOR:
case GameState::MAP_POSITION_SELECT:{
//CAMERA MOVEMENTS MUST BE LAST!!!
if (UpHeld()) {
cameraPos.y-=CAMERA_MOVESPD;
adjustCamera.y-=CAMERA_MOVESPD;
}
if (RightHeld()) {
cameraPos.x+=CAMERA_MOVESPD;
adjustCamera.x+=CAMERA_MOVESPD;
}
if (LeftHeld()) {
cameraPos.x-=CAMERA_MOVESPD;
adjustCamera.x-=CAMERA_MOVESPD;
}
if (DownHeld()) {
cameraPos.y+=CAMERA_MOVESPD;
adjustCamera.y+=CAMERA_MOVESPD;
}
}break;
}
if (adjustCamera!=cameraPos) {
UpdateCamera(adjustCamera);
}
}
void SeasonI::StartEffect(Effect*eff) {
@ -4608,9 +4613,26 @@ void SeasonI::DrawRollingCounter(const olc::vi2d &pos,int val,int*rollcounter,in
DrawPartialDecal({(float)(pos.x+41),(float)(pos.y-1)},{7,9},SPRITES["rollingcounter.png"],{0,(float)(rollcounter[0]*13+rolloffset[0]+13)},{7,9},Pixel(255,255,255,boxAlpha));
}
void SeasonI::UpdateCollisionGrid() {
for (int x=-1;x<WIDTH/32+2;x++) {
for (int y=-1;y<HEIGHT/32+2;y++) {
int yTileOffset=cameraPos.y/32;
int xTileOffset=cameraPos.x/32;
char tiles=0;
if (x+xTileOffset>=0&&x+xTileOffset<MAP_WIDTH&&y+yTileOffset>=0&&y+yTileOffset<MAP_HEIGHT) {
if(MAP5[y+yTileOffset][x+xTileOffset]->tileX!=15||MAP5[y+yTileOffset][x+xTileOffset]->tileY!=15) {
SetDrawTarget(layer::COLLISION);
DrawPartialSprite({(int)(x*32-fmod(cameraPos.x,32)),(int)(y*32-fmod(cameraPos.y,32))},CURRENT_MAP->tileset->sprite,{(int)(MAP5[y+yTileOffset][x+xTileOffset]->tileX*32),(int)(MAP5[y+yTileOffset][x+xTileOffset]->tileY*32)},{32,32});
tiles|=1<<5;
}
}
}
}
}
void SeasonI::DrawGameWorld() {
for (int y=-1;y<HEIGHT/32+2;y++) {
int yTileOffset = cameraPos.y/32;
int yTileOffset=cameraPos.y/32;
for (auto&obj:OBJECTS) {
if (!obj->drawn&&(!obj->dead||EDITING_LAYER==layer::ENCOUNTER)&&
(GetTileDegreeSafely(MAP2)==0&&
@ -5002,18 +5024,21 @@ void SeasonI::DrawArrow() {
bool SeasonI::MoveCameraTowardsPoint(vd2d targetPos,PriorityDirection dir,double spd,bool secondRun) {
bool reachedPosition=true;
vd2d newCameraPos=cameraPos;
if (dir==HORZ_FIRST||dir==BOTH) {
if (cameraPos.x!=targetPos.x) {
if (cameraPos.x<targetPos.x) {
cameraPos.x+=spd;
if (cameraPos.x>targetPos.x) {
cameraPos.x=targetPos.x;
if (newCameraPos.x!=targetPos.x) {
if (newCameraPos.x<targetPos.x) {
newCameraPos.x+=spd;
if (newCameraPos.x>targetPos.x) {
newCameraPos.x=targetPos.x;
}
UpdateCamera(newCameraPos);
} else {
cameraPos.x-=spd;
if (cameraPos.x<targetPos.x) {
cameraPos.x=targetPos.x;
newCameraPos.x-=spd;
if (newCameraPos.x<targetPos.x) {
newCameraPos.x=targetPos.x;
}
UpdateCamera(newCameraPos);
}
reachedPosition=false;
} else
@ -5022,17 +5047,19 @@ bool SeasonI::MoveCameraTowardsPoint(vd2d targetPos,PriorityDirection dir,double
}
}
if (dir==VERT_FIRST||dir==BOTH) {
if (cameraPos.y!=targetPos.y) {
if (cameraPos.y<targetPos.y) {
cameraPos.y+=spd;
if (cameraPos.y>targetPos.y) {
cameraPos.y=targetPos.y;
if (newCameraPos.y!=targetPos.y) {
if (newCameraPos.y<targetPos.y) {
newCameraPos.y+=spd;
if (newCameraPos.y>targetPos.y) {
newCameraPos.y=targetPos.y;
}
UpdateCamera(newCameraPos);
} else {
cameraPos.y-=spd;
if (cameraPos.y<targetPos.y) {
cameraPos.y=targetPos.y;
newCameraPos.y-=spd;
if (newCameraPos.y<targetPos.y) {
newCameraPos.y=targetPos.y;
}
UpdateCamera(newCameraPos);
}
reachedPosition=false;
} else
@ -5571,9 +5598,14 @@ void SeasonI::LoadGameSaveData(int saveSlot) {
CHAPTER_NUMBER=ReadIntFromStream(file);
}
void SeasonI::UpdateCamera(vd2d newpos) {
cameraPos=newpos;
UpdateCollisionGrid();
}
void SeasonI::CenterCameraOnPlayer(){
const vi2d cameraOffset={WIDTH/2,HEIGHT/2};
cameraPos=PARTY_MEMBER_OBJ[0]->GetPos()+PARTY_MEMBER_OBJ[0]->originPoint/2-cameraOffset;
UpdateCamera(PARTY_MEMBER_OBJ[0]->GetPos()+PARTY_MEMBER_OBJ[0]->originPoint/2-cameraOffset);
}
int SeasonI::GetPointQuadrantRelativeToLine(vi2d x1y1,vi2d x2y2,vi2d point){

@ -61,6 +61,7 @@ class Object{
bool Collision(vd2d pos) {
GAME->SetDrawTarget(layer::COLLISION);
Pixel collisionData = GAME->GetDrawTarget()->GetPixel((int)pos.x-cameraPos.x,(int)pos.y-cameraPos.y);
Pixel collisionData2 = GAME->GetDrawTarget()->GetPixel((int)pos.x-cameraPos.x-1,(int)pos.y-cameraPos.y);
if (collisionData!=MAGENTA) {
return true;
} else {

@ -646,21 +646,41 @@ bool SeasonI::OnUserCreate(){
PressTestKeyAndRun(DOWN);
Test("Player has moved down-left",
PARTY_MEMBER_OBJ[0]->GetPos().x<prevPlayerPos.x&&PARTY_MEMBER_OBJ[0]->GetPos().y>prevPlayerPos.y);
ReleaseTestKey(LEFT);
prevPlayerPos = PARTY_MEMBER_OBJ[0]->GetPos();
OnUserUpdate(1/60.f);
Test("Player has moved down",
PARTY_MEMBER_OBJ[0]->GetPos().x==prevPlayerPos.x&&PARTY_MEMBER_OBJ[0]->GetPos().y>prevPlayerPos.y);
ReleaseTestKey(DOWN);
prevPlayerPos = PARTY_MEMBER_OBJ[0]->GetPos();
PressTestKeyAndRun(UP);
Test("Player has moved up",
PARTY_MEMBER_OBJ[0]->GetPos().x==prevPlayerPos.x&&PARTY_MEMBER_OBJ[0]->GetPos().y<prevPlayerPos.y);
ResetTestKeys();
PARTY_MEMBER_OBJ[0]->SetPos({29-PARTY_MEMBER_OBJ[0]->originPoint.x,16-PARTY_MEMBER_OBJ[0]->originPoint.y});
Test("Player is now centered at 29,16",
PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().x==29&&PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().y==16);
PARTY_MEMBER_OBJ[0]->SetPos({32-PARTY_MEMBER_OBJ[0]->originPoint.x,16-PARTY_MEMBER_OBJ[0]->originPoint.y});
Test("Player is now centered at 32,16",
PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().x==32&&PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().y==16);
CenterCameraOnPlayer();
PressTestKeyAndRun(LEFT);
std::cout<<PARTY_MEMBER_OBJ[0]->GetPosWithOrigin()<<std::endl;
PressTestKeyAndRun(LEFT);
std::cout<<PARTY_MEMBER_OBJ[0]->GetPosWithOrigin()<<std::endl;
PressTestKeyAndRun(LEFT);
std::cout<<PARTY_MEMBER_OBJ[0]->GetPosWithOrigin()<<std::endl;
PressTestKeyAndRun(LEFT);
std::cout<<PARTY_MEMBER_OBJ[0]->GetPosWithOrigin()<<std::endl;
Test("Collision should occur so pressing left does nothing",
PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().x==29&&PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().y==16);
for (int i=0;i<10;i++) {
PressTestKeyAndRun(LEFT);
ReleaseTestKey(LEFT);
}
Test("Player does not move due to tile collision",
PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().x==32&&PARTY_MEMBER_OBJ[0]->GetPosWithOrigin().y==16);
SetupGameDrawing();
SetDrawTarget(layer::COLLISION);
bool isAllMagenta=true;
for (int x=0;x<WIDTH;x++) {
for (int y=0;y<HEIGHT;y++) {
if (GetDrawTarget()->GetData()[y*WIDTH+x]!=MAGENTA) {
isAllMagenta=false;
goto endOfScreenCheck;
}
}
}
endOfScreenCheck:
Test("Entire screen should be wiped to magenta before drawing anything",
isAllMagenta);
return true;
}

Loading…
Cancel
Save