#include "sdlpp.hpp" #include #include #include #define PLAYER_ID 0x00000001 #define STONE_ID 0x00000002 class Player : public SDLPP::RectangleRender { public: Player(double x, double y, double w, double h, std::shared_ptr &r, double _max_gravity = 1.0, uint32_t _max_gravity_time = 1000) : SDLPP::RectangleRender(x,y,w,h,r) { max_gravity = _max_gravity; jump_speed = 1.5*max_gravity; max_gravity_time = _max_gravity_time; cur_gravity_time = max_gravity_time; } void setGravity(bool grav) { gravity_enabled = grav; } void enableGravity() { gravity_enabled = true; } void disableGravity() { gravity_enabled = false; } bool isGravityEnabled() { return gravity_enabled; } bool isJumping() { return jumping; } void setLastStand() { cur_gravity_time = max_gravity_time; jumping = false; } void jump() { jumping = true; } virtual void move(int ticks) { auto dimensions = renderer->getDimensions(); auto time_portion = (static_cast(ticks)/1000); auto addx = static_cast(movementSpeed * movementDirection.first)*time_portion; auto addy = static_cast(movementSpeed * movementDirection.second)*time_portion; x_ += addx; y_ += addy; cur_gravity_time -= ticks; auto grav = gravity_enabled * max_gravity * (max_gravity_time - cur_gravity_time)/max_gravity_time; if( grav > max_gravity) grav = max_gravity; auto jump_ = jumping * jump_speed * cur_gravity_time/max_gravity_time; if(jump_ < 0 || jump_ > jump_speed) jump_ = 0; y_ += grav * time_portion; y_ -= jump_ * time_portion; rect.x = x_ * dimensions.first; rect.y = y_ * dimensions.second; for( auto &x : collisions ) { x->updateCollision(collisionPushX(), collisionPushY(), collisionWidth(), collisionHeight()); } } private: double max_gravity = 1.0; double jump_speed = 2.0; uint32_t max_gravity_time = 1000; uint32_t cur_gravity_time = 1000; bool gravity_enabled = false; bool jumping = false; }; std::shared_ptr player; std::vector> bgtextures; bool quit = false; void addStuff(SDLPP::Scene &scene, std::shared_ptr &r) { std::shared_ptr stone; double posx = 0; while(posx < 1) { stone = std::make_shared(posx,0.5,0.15,0.1,r); stone->addCollision(SDLPP::Rect(0,0,1,1)); stone->setTexture("stone.png"); stone->setId(STONE_ID); scene.addObject(stone); posx += 0.15; } auto x = std::make_shared(0,0,0.2,0.2, r); x->addCollision(SDLPP::Rect(0,0,1,1)); x->setTexture("5.png"); x->setId(PLAYER_ID); scene.addObject(x); player = x; } void quitGame() { std::cout << "Quitting!" << std::endl; quit = true; } void handleKeyDown(SDL_Keycode key, SDLPP::Scene &scene) { switch(key) { case SDLK_UP: scene.setBackground(bgtextures[0]); break; case SDLK_DOWN: scene.setBackground(bgtextures[1]); break; case SDLK_RIGHT: scene.setBackground(bgtextures[2]); break; case SDLK_LEFT: scene.setBackground(bgtextures[3]); break; case SDLK_ESCAPE: quitGame(); break; case SDLK_a: player->addMovement(-1,0); break; case SDLK_d: player->addMovement(1,0); break; case SDLK_w: if(!player->isJumping()) { player->setLastStand(); player->jump(); } break; case SDLK_s: break; default: scene.setBackground(bgtextures[4]); break; } } void handleKeyUp(SDL_Keycode key) { switch(key) { case SDLK_a: player->addMovement(1,0); break; case SDLK_d: player->addMovement(-1,0); break; case SDLK_w: break; case SDLK_s: default: break; } } void pollEvents(SDLPP::Scene &scene) { SDL_Event event; while( SDL_PollEvent( &event ) != 0 ) { switch(event.type) { case SDL_QUIT: quitGame(); break; case SDL_KEYDOWN: if( !event.key.repeat ) handleKeyDown(event.key.keysym.sym, scene); break; case SDL_KEYUP: handleKeyUp(event.key.keysym.sym); break; case SDL_WINDOWEVENT: if(event.window.event == SDL_WINDOWEVENT_RESIZED) scene.updateSizeAndPosition(); default: break; } } } void doInput(std::shared_ptr scene) { FPSmanager gFPS; SDL_initFramerate(&gFPS); SDL_setFramerate(&gFPS, 200); int base = SDL_GetTicks(); int frames = 0; while(!quit) { SDL_framerateDelay(&gFPS); pollEvents(*scene); scene->movement(); bool gravity = true; for( auto &x : scene->getCollisions(*player) ) { if( x->getId() == STONE_ID ) { gravity = false; auto stoneRect = x->getDoubleRect(); auto playerPos = player->getDoubleRect(); auto newPX = playerPos.first.first; auto newPY = playerPos.first.second; newPY = stoneRect.first.second - playerPos.second.second; player->setPos(newPX, newPY); if(player->isGravityEnabled()) player->setLastStand(); } } player->setGravity(gravity); frames++; if(SDL_GetTicks() - base >= 1000) { base = SDL_GetTicks(); printf("FPS: %d\n", frames); frames = 0; } } } int main() { SDLPP::init(); SDLPP::Window w("Oh yeah, boi!"); auto renderer = std::make_shared(w); auto main_scene = std::make_shared(renderer); bgtextures.push_back(std::make_shared(renderer, "1.bmp")); bgtextures.push_back(std::make_shared(renderer, "2.bmp")); bgtextures.push_back(std::make_shared(renderer, "3.png")); bgtextures.push_back(std::make_shared(renderer, "4.png")); bgtextures.push_back(std::make_shared(renderer, "test.bmp")); main_scene->setBackground(bgtextures[0]); addStuff(*main_scene, renderer); player->setMovementSpeed(0.3); player->enableGravity(); FPSmanager gFPS; SDL_initFramerate(&gFPS); SDL_setFramerate(&gFPS, 60); std::thread inputThread(doInput, main_scene); while( !quit ) { SDL_framerateDelay(&gFPS); main_scene->renderScene(); main_scene->presentScene(); } inputThread.join(); }