// main function int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "usage:\n\t%s [image.png]\n", *argv); return 1; } char *filename_in = argv[1]; struct FTR f = ftr_new_window(512,512); struct viewer_state e[1]; f.userdata = e; e->img = iio_read_image_float_vec(filename_in, &e->iw, &e->ih, &e->pd); center_view(&f); paint_state(&f); ftr_set_handler(&f, "key", event_key); ftr_set_handler(&f, "button", event_button); ftr_set_handler(&f, "motion", event_motion); ftr_set_handler(&f, "resize", event_resize); return ftr_loop_run(&f); }
// key handler static void event_key(struct FTR *f, int k, int m, int x, int y) { if (k == 'q') { ftr_notify_the_desire_to_stop_this_loop(f, 0); return; } struct viewer_state *e = f->userdata; if (k == 'c') center_view(f); if (k == 'J') change_view_offset(e, 0, -1); if (k == 'K') change_view_offset(e, 0, 1); if (k == 'H') change_view_offset(e, 1, 0); if (k == 'L') change_view_offset(e, -1, 0); if (k == 'j') change_view_offset(e, 0, -10); if (k == 'k') change_view_offset(e, 0, 10); if (k == 'h') change_view_offset(e, 10, 0); if (k == 'l') change_view_offset(e, -10, 0); if (k == FTR_KEY_DOWN ) change_view_offset(e, 0, -100); if (k == FTR_KEY_UP ) change_view_offset(e, 0, 100); if (k == FTR_KEY_RIGHT) change_view_offset(e, -100, 0); if (k == FTR_KEY_LEFT) change_view_offset(e, 100, 0); if (k == '+') change_view_scale(e, f->w/2, f->h/2, ZOOM_FACTOR); if (k == '-') change_view_scale(e, f->w/2, f->h/2, 1.0/ZOOM_FACTOR); if (k == 'p') e->tile_plane = !e->tile_plane; if (k == 'w') e->show_horizon = !e->show_horizon; if (k >= '0' && k <= '9') e->interpolation_order = k - '0'; if (k == '.') e->show_grid_points = !e->show_grid_points; if (k == 'z') { e->dragging_point = false; e->dragging_ipoint = false; } paint_state(f); }
static int entry_render(LuaState *L) { Entry *e = ms_lua_checkclass(L, CLASS, 1); const char *prompt = luaL_checkstring(L, 2); g_assert(e->curs_off <= e->bufused); /* FIXME: This assumes 1 byte == 1 char */ guint lmargin = strlen(prompt); ms_term_goto(MS_TERM_LINES - 1, 0); ms_term_write_chars((gchar *)prompt); if (try_render(e, lmargin) == -1) { e->view_off = center_view(e, MS_TERM_COLS - lmargin); if (try_render(e, lmargin) == -1) { /* This should never happen, but just in case. */ if (e->curs_off == 0) { e->view_off = 0; } else { e->view_off = e->curs_off - 1; } try_render(e, lmargin); } } return 0; }
GameScreen::GameScreen(Game* game, std::string filename) { this->game = game; this->score = 100; std::uniform_int_distribution<int> dist(0, 2); level = Level(filename); level.load(); auto positions = level.getEnemyPositions(); for (auto pos : positions) entities.push_back(new Enemy(pos.first, pos.second, 64, 64, dist(gen), this)); Player *player = new Player(0, 0, 50, 64, this); player->setPosition(level.getStart()); player->setTiles(level.getTiles()); entities.push_back(player); view.setSize(640, 480); center_view(player); game->set_view(view); music.openFromFile("sounds/Orbital_Colossus.ogg"); music.setVolume(33); music.play(); // fillRect is used for screen fading. fillRect.setPosition(sf::Vector2f(0, 0)); fillRect.setSize(sf::Vector2f(1500, 1500)); fillRect.setFillColor(sf::Color(0, 0, 0, alpha)); font.loadFromFile("HATTEN.ttf"); scoretext = centered_text("Score: " + std::to_string(score), view.getCenter().x, view.getCenter().y - WINDOW_HEIGHT / 2, font); }
// Transition to the next tilemap. Clear entities and spawn new ones. void GameScreen::transition() { level.transition(); Player *player = nullptr; for (Entity *e : entities) { if (player = dynamic_cast<Player*>(e)) { player->setPosition(level.getStart()); player->setTiles(level.getTiles()); center_view(player); break; } } entities.clear(); entities.push_back(player); std::uniform_int_distribution<int> dist(0, 2); std::vector<std::pair<int, int>> positions = level.getEnemyPositions(); for (auto pos : positions) { entities.push_back(new Enemy(pos.first, pos.second, 64.f, 64.f, dist(gen), this)); } }
GameState* GameScreen::update() { switch (status) { case START: if (fade(true)) status = NORMAL; return nullptr; case END: if (fade(false)) return new WinState(game, alive, score); return nullptr; case QUIT: return new MainMenu(game); } if (music.getStatus() == sf::Music::Stopped) music.play(); delta = clock.restart().asSeconds(); // Decrement score every second. timer += delta; if (timer >= 1) { score--; timer = 0; } sf::Event event; while (game->get_window().pollEvent(event)) if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::P) game->push_state(new PauseState(game, this)); status = END; alive = false; for (Entity *e : entities) { e->update(delta); if (Player *p = dynamic_cast<Player*>(e)) { status = NORMAL; alive = true; center_view(p); // Are we at the end of the current tilemap? Load next one if it exists. Else quit. if (level.getGoal().intersects(p->getBounds())) { if (level.hasNext()) { p->transition(); game->push_state(new TransitionState(game, this)); } else { p->transition(); status = END; } } } } // Remove destroyed entities. // Erase-remove idiom // https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom entities.erase( std::remove_if(std::begin(entities), std::end(entities), [](Entity *entity) { if (entity->isDestroyed()) { delete entity; return true; } return false; }), std::end(entities)); // Add new entities from queue. for (Entity *e : queue) entities.push_back(std::move(e)); queue.clear(); scoretext.setString("Score: " + std::to_string(score)); scoretext.setPosition(sf::Vector2f(view.getCenter().x, view.getCenter().y - WINDOW_HEIGHT / 2)); return nullptr; }