#define OLC_PGE_APPLICATION #include "olcPixelGameEngine.h" #include "olcUTIL_Camera2D.h" #define OLC_PGEX_TRANSFORMEDVIEW #include "olcPGEX_TransformedView.h" #include "olcUTIL_Animate2D.h" using namespace olc; using namespace olc::utils; const vi2d WINDOW_SIZE={24*8,24*8}; enum AnimationState{ WALK_S,WALK_E,WALK_N,WALK_W, IDLE_S,IDLE_E,IDLE_N,IDLE_W }; struct Player{ vf2d pos; float moveSpd; AnimationState animState=AnimationState::IDLE_S; private: Animate2D::Animationanimation; Animate2D::AnimationState internal_animState; Key lastReleasedMovementKey; public: Player(){}; Player(vf2d pos,float moveSpd): pos(pos),moveSpd(moveSpd){ }; void Update(float fElapsedTime){ animation.UpdateState(internal_animState,fElapsedTime); } void AddAnimation(AnimationState state,Animate2D::FrameSequence frame){ animation.AddState(state,frame); }; void UpdateAnimation(AnimationState animState){ animation.ChangeState(internal_animState,animState); } Animate2D::Frame GetFrame(){ return animation.GetFrame(internal_animState); } void SetLastReleasedMovementKey(Key k){ lastReleasedMovementKey=k; } Key GetLastReleasedMovementKey(){ return lastReleasedMovementKey; } }; class Crawler : public olc::PixelGameEngine { const vi2d WORLD_SIZE={64,64}; Camera2D camera; TileTransformedView view; Player player=Player{{},100}; Renderable GFX_Pl_sheet; public: Crawler() { sAppName = "Crawler Concept"; } public: bool OnUserCreate() override { //Initialize Camera. camera=Camera2D{WINDOW_SIZE}; camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow); camera.SetTarget(player.pos); camera.SetWorldBoundary({0,0},WORLD_SIZE*24); camera.EnableWorldBoundary(false); //Graphics GFX_Pl_sheet.Load("assets/nico-warrior.png"); //Animations Animate2D::FrameSequence pl_walk_s{0.2}; pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{1,0}*24,{24,24}}}); pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); pl_walk_s.AddFrame({&GFX_Pl_sheet,{vi2d{2,0}*24,{24,24}}}); Animate2D::FrameSequence pl_walk_e{0.2}; pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{1,3}*24,{24,24}}}); pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); pl_walk_e.AddFrame({&GFX_Pl_sheet,{vi2d{2,3}*24,{24,24}}}); Animate2D::FrameSequence pl_walk_w{0.2}; pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{1,2}*24,{24,24}}}); pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); pl_walk_w.AddFrame({&GFX_Pl_sheet,{vi2d{2,2}*24,{24,24}}}); Animate2D::FrameSequence pl_walk_n{0.2}; pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{1,1}*24,{24,24}}}); pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); pl_walk_n.AddFrame({&GFX_Pl_sheet,{vi2d{2,1}*24,{24,24}}}); Animate2D::FrameSequence pl_idle_s; pl_idle_s.AddFrame({&GFX_Pl_sheet,{vi2d{0,0}*24,{24,24}}}); Animate2D::FrameSequence pl_idle_e; pl_idle_e.AddFrame({&GFX_Pl_sheet,{vi2d{0,3}*24,{24,24}}}); Animate2D::FrameSequence pl_idle_w; pl_idle_w.AddFrame({&GFX_Pl_sheet,{vi2d{0,2}*24,{24,24}}}); Animate2D::FrameSequence pl_idle_n; pl_idle_n.AddFrame({&GFX_Pl_sheet,{vi2d{0,1}*24,{24,24}}}); player.AddAnimation(WALK_N,pl_walk_n); player.AddAnimation(WALK_E,pl_walk_e); player.AddAnimation(WALK_S,pl_walk_s); player.AddAnimation(WALK_W,pl_walk_w); player.AddAnimation(IDLE_N,pl_idle_n); player.AddAnimation(IDLE_E,pl_idle_e); player.AddAnimation(IDLE_S,pl_idle_s); player.AddAnimation(IDLE_W,pl_idle_w); view=TileTransformedView{GetScreenSize(),{1,1}}; player.UpdateAnimation(IDLE_S); return true; } bool OnUserUpdate(float fElapsedTime) override { HandleUserInput(fElapsedTime); player.Update(fElapsedTime); UpdateCamera(fElapsedTime); RenderWorld(); return true; } void HandleUserInput(float fElapsedTime){ bool setIdleAnimation=true; if(GetKey(RIGHT).bHeld){ player.pos.x+=fElapsedTime*player.moveSpd; player.UpdateAnimation(WALK_E); setIdleAnimation=false; } if(GetKey(LEFT).bHeld){ player.pos.x-=fElapsedTime*player.moveSpd; if(setIdleAnimation){ player.UpdateAnimation(WALK_W); } setIdleAnimation=false; } if(GetKey(UP).bHeld){ player.pos.y-=fElapsedTime*player.moveSpd; if(setIdleAnimation){ player.UpdateAnimation(WALK_N); } setIdleAnimation=false; } if(GetKey(DOWN).bHeld){ player.pos.y+=fElapsedTime*player.moveSpd; if(setIdleAnimation){ player.UpdateAnimation(WALK_S); } setIdleAnimation=false; } if(GetKey(UP).bReleased){ player.SetLastReleasedMovementKey(UP); if(GetKey(RIGHT).bHeld){ player.UpdateAnimation(WALK_E); } else if(GetKey(DOWN).bHeld){ player.UpdateAnimation(WALK_S); } else if(GetKey(LEFT).bHeld){ player.UpdateAnimation(WALK_W); } } if(GetKey(RIGHT).bReleased){ player.SetLastReleasedMovementKey(RIGHT); if(GetKey(UP).bHeld){ player.UpdateAnimation(WALK_N); } else if(GetKey(DOWN).bHeld){ player.UpdateAnimation(WALK_S); } else if(GetKey(LEFT).bHeld){ player.UpdateAnimation(WALK_W); } } if(GetKey(LEFT).bReleased){ player.SetLastReleasedMovementKey(LEFT); if(GetKey(RIGHT).bHeld){ player.UpdateAnimation(WALK_E); } else if(GetKey(DOWN).bHeld){ player.UpdateAnimation(WALK_S); } else if(GetKey(UP).bHeld){ player.UpdateAnimation(WALK_N); } } if(GetKey(DOWN).bReleased){ player.SetLastReleasedMovementKey(DOWN); if(GetKey(RIGHT).bHeld){ player.UpdateAnimation(WALK_E); } else if(GetKey(UP).bHeld){ player.UpdateAnimation(WALK_N); } else if(GetKey(LEFT).bHeld){ player.UpdateAnimation(WALK_W); } } if(setIdleAnimation){ switch(player.GetLastReleasedMovementKey()){ case UP:{ player.UpdateAnimation(IDLE_N); }break; case DOWN:{ player.UpdateAnimation(IDLE_S); }break; case LEFT:{ player.UpdateAnimation(IDLE_W); }break; case RIGHT:{ player.UpdateAnimation(IDLE_E); }break; default:{ player.UpdateAnimation(IDLE_S); } } } } void UpdateCamera(float fElapsedTime){ camera.Update(fElapsedTime); view.SetWorldOffset(vi2d(camera.GetViewPosition())); } void RenderWorld(){ Clear({100,180,100}); for (int x = view.GetTopLeftTile().x/24-1; x <= view.GetBottomRightTile().x/24; x++){ for (int y = view.GetTopLeftTile().y/24-1; y <= view.GetBottomRightTile().y/24; y++){ view.DrawRect(vi2d{x,y}*24,{24,24},VERY_DARK_GREY); } } view.DrawPartialDecal(player.pos-vi2d{12,12},player.GetFrame().GetSourceImage()->Decal(),player.GetFrame().GetSourceRect().pos,player.GetFrame().GetSourceRect().size); } }; int main() { Crawler demo; if (demo.Construct(WINDOW_SIZE.x, WINDOW_SIZE.y, 4, 4)) demo.Start(); return 0; }