From 7e3d22eda4aef5950ab194d36e5500e79c42402e Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 20 May 2004 15:58:10 +0000 Subject: [PATCH] converted player to new object system SVN-Revision: 1281 --- src/Makefile.am | 5 +- src/gameloop.cpp | 3 +- src/gameobjs.cpp | 200 -------------------------------------------------- src/gameobjs.h | 48 ------------ src/moving_object.cpp | 10 +++ src/moving_object.h | 39 ++++++++++ src/player.cpp | 29 +++++++- src/player.h | 19 +++-- src/world.cpp | 101 ++++++++++++------------- src/world.h | 4 +- 10 files changed, 148 insertions(+), 310 deletions(-) create mode 100644 src/moving_object.cpp create mode 100644 src/moving_object.h diff --git a/src/Makefile.am b/src/Makefile.am index 6583cce08..1b6289350 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,9 +81,12 @@ game_object.cpp \ game_object.h \ display_manager.h \ display_manager.cpp \ +drawable.h \ background.h \ background.cpp \ tilemap.h \ -tilemap.cpp +tilemap.cpp \ +moving_object.h \ +moving_object.cpp # EOF # diff --git a/src/gameloop.cpp b/src/gameloop.cpp index 698e02bde..b5f331519 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -65,6 +65,7 @@ GameSession::GameSession(const std::string& subset_, int levelnb_, int mode) global_frame_counter = 0; game_pause = false; + fps_fps = 0; fps_timer.init(true); frame_timer.init(true); @@ -669,7 +670,7 @@ GameSession::drawstatus() { char str[60]; - sprintf(str, "%d", player_status.score); + snprintf(str, 60, "%d", player_status.score); white_text->draw("SCORE", 0, 0, 1); gold_text->draw(str, 96, 0, 1); diff --git a/src/gameobjs.cpp b/src/gameobjs.cpp index f2d589b43..ffcadcbd6 100644 --- a/src/gameobjs.cpp +++ b/src/gameobjs.cpp @@ -273,203 +273,3 @@ Trampoline::collision(void *p_c_object, int c_object, CollisionType type) } -/* Object Manager */ -//--------------------------------------------------------------------------- - -ObjectManager::ObjectManager() -{ - std::string filename = datadir + "/images/tilesets/supertux.stbg"; - load_badguys(filename); -} - -ObjectManager::~ObjectManager() -{ - for(std::vector::iterator i = badguys.begin(); i != badguys.end(); ++i) { - delete *i; - } -} - -void ObjectManager::load_badguys(std::string filename) -{ - (void) filename; -/* - lisp_object_t* root_obj = lisp_read_from_file(filename); - - if (!root_obj) - st_abort("Couldn't load file", filename); - - if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-badguys") == 0) - { - lisp_object_t* cur = lisp_cdr(root_obj); - - while(!lisp_nil_p(cur)) - { - lisp_object_t* element = lisp_car(cur); - - if (strcmp(lisp_symbol(lisp_car(element)), "badguy") == 0) - { - - - Tile* tile = new Tile; - tile->id = -1; - tile->solid = false; - tile->brick = false; - tile->ice = false; - tile->water = false; - tile->fullbox = false; - tile->distro = false; - tile->goal = false; - tile->data = 0; - tile->next_tile = 0; - tile->anim_speed = 25; - - LispReader reader(lisp_cdr(element)); - assert(reader.read_int("id", &tile->id)); - reader.read_bool("solid", &tile->solid); - reader.read_bool("brick", &tile->brick); - reader.read_bool("ice", &tile->ice); - reader.read_bool("water", &tile->water); - reader.read_bool("fullbox", &tile->fullbox); - reader.read_bool("distro", &tile->distro); - reader.read_bool("goal", &tile->goal); - reader.read_int("data", &tile->data); - reader.read_int("anim-speed", &tile->anim_speed); - reader.read_int("next-tile", &tile->next_tile); - reader.read_string_vector("images", &tile->filenames); - reader.read_string_vector("editor-images", &tile->editor_filenames); - - for(std::vector::iterator it = tile-> - filenames.begin(); - it != tile->filenames.end(); - ++it) - { - Surface* cur_image; - tile->images.push_back(cur_image); - tile->images[tile->images.size()-1] = new Surface( - datadir + "/images/tilesets/" + (*it), - USE_ALPHA); - } - for(std::vector::iterator it = tile->editor_filenames.begin(); - it != tile->editor_filenames.end(); - ++it) - { - Surface* cur_image; - tile->editor_images.push_back(cur_image); - tile->editor_images[tile->editor_images.size()-1] = new Surface( - datadir + "/images/tilesets/" + (*it), - USE_ALPHA); - } - - if (tile->id + tileset_id >= int(tiles.size()) - ) - tiles.resize(tile->id + tileset_id+1); - - tiles[tile->id + tileset_id] = tile; - } - else if (strcmp(lisp_symbol(lisp_car(element)), "tileset") == 0) - { - LispReader reader(lisp_cdr(element)); - std::string filename; - reader.read_string("file", &filename); - filename = datadir + "/images/tilesets/" + filename; - load_tileset(filename); - } - else if (strcmp(lisp_symbol(lisp_car(element)), "tilegroup") == 0) - { - TileGroup new_; - LispReader reader(lisp_cdr(element)); - reader.read_string("name", &new_.name); - reader.read_int_vector("tiles", &new_.tiles); - if(!tilegroups_) - tilegroups_ = new std::set; - tilegroups_->insert(new_).first; - } - else if (strcmp(lisp_symbol(lisp_car(element)), "properties") == 0) - { - LispReader reader(lisp_cdr(element)); - reader.read_int("id", &tileset_id); - tileset_id *= 1000; - } - else - { - puts("Unhandled symbol"); - } - - cur = lisp_cdr(cur); - } - } - else - { - assert(0); - } - - lisp_free(root_obj); -*/ -} - -void ObjectManager::draw_bg() -{ -/* - for (unsigned int i = 0; i < bouncy_bricks.size(); ++i) - bouncy_bricks[i]->draw(); - - for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) - (*i)->draw(); - - for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) - (*i)->draw(); -*/ -} - -void ObjectManager::draw_fg() -{ -/* - for (unsigned int i = 0; i < bullets.size(); ++i) - bullets[i].draw(); - - for (unsigned int i = 0; i < floating_scores.size(); ++i) - floating_scores[i]->draw(); - - for (unsigned int i = 0; i < upgrades.size(); ++i) - upgrades[i].draw(); - - for (unsigned int i = 0; i < bouncy_distros.size(); ++i) - bouncy_distros[i]->draw(); - - for (unsigned int i = 0; i < broken_bricks.size(); ++i) - broken_bricks[i]->draw(); -*/ -} - -void ObjectManager::actions() -{ -/* - for (unsigned int i = 0; i < bouncy_distros.size(); i++) - bouncy_distros[i]->action(frame_ratio); - - for (unsigned int i = 0; i < broken_bricks.size(); i++) - broken_bricks[i]->action(frame_ratio); - - // Handle all kinds of game objects - for (unsigned int i = 0; i < bouncy_bricks.size(); i++) - bouncy_bricks[i]->action(frame_ratio); - - for (unsigned int i = 0; i < floating_scores.size(); i++) - floating_scores[i]->action(frame_ratio); - - for (unsigned int i = 0; i < bullets.size(); ++i) - bullets[i].action(frame_ratio); - - for (unsigned int i = 0; i < upgrades.size(); i++) - upgrades[i].action(frame_ratio); - - for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) - (*i)->action(frame_ratio); - - for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) - (*i)->action(frame_ratio); -*/ -} - -/* EOF */ - diff --git a/src/gameobjs.h b/src/gameobjs.h index cc1a1daf6..e303bbc4a 100644 --- a/src/gameobjs.h +++ b/src/gameobjs.h @@ -161,54 +161,6 @@ class Trampoline : public GameObject void load_object_gfx(); - -class ObjectManager -{ - private: - ObjectManager(); - ~ObjectManager(); - - static ObjectManager* instance_; - - // XXX Objects will have to be split up into two categories: - // - Drawn before tux - // - Drawn after tux - // Eventually Player should be a part of ObjectManager - - std::vector badguys; - std::vector trampolines; - std::vector bouncy_distros; - std::vector broken_bricks; - std::vector bouncy_bricks; - //std::vector upgrades; - //std::vector bullets; - - void load_badguys(std::string filename); - - public: - static ObjectManager* instance() { return instance_ ? instance_ : instance_ = new ObjectManager(); } - static void destroy_instance() { delete instance_; instance_ = 0; } - - void draw_bg(); - void draw_fg(); - void actions(); - -/* Object* get(unsigned int id) { - if(id < badguys.size()) - { - return badguys[id]; - } - else - { - // Never return 0, but return the 0th tile instead so that - // user code doesn't have to check for NULL pointers all over - // the place - return badguys[0]; - } - } -*/ -}; - #endif /* Local Variables: */ diff --git a/src/moving_object.cpp b/src/moving_object.cpp new file mode 100644 index 000000000..3c4d566f8 --- /dev/null +++ b/src/moving_object.cpp @@ -0,0 +1,10 @@ +#include "moving_object.h" + +MovingObject::MovingObject() +{ +} + +MovingObject::~MovingObject() +{ +} + diff --git a/src/moving_object.h b/src/moving_object.h new file mode 100644 index 000000000..d8be47df1 --- /dev/null +++ b/src/moving_object.h @@ -0,0 +1,39 @@ +#ifndef __MOVING_OBJECT_H__ +#define __MOVING_OBJECT_H__ + +#include "type.h" +#include "game_object.h" +#include "vector.h" +//#include "rectangle.h" + +/** + * Base class for all dynamic/moving game objects. This class contains things + * for handling the bounding boxes and collision feedback. + */ +class MovingObject : public _GameObject +{ +public: + MovingObject(); + virtual ~MovingObject(); + + /** this function is called when the object collided with any other object + */ + virtual void collision(const MovingObject& other_object, + int collision_type) = 0; + + base_type base; + base_type old_base; + +protected: +#if 0 // this will be used in my collision detection rewrite later + /// the current position of the object + Vector pos; + /// the position we want to move until next frame + Vector new_pos; + /// the bounding box relative to the current position + Rectangle bounding_box; +#endif +}; + +#endif + diff --git a/src/player.cpp b/src/player.cpp index 625805b20..0ab9d26a3 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -64,6 +64,16 @@ void player_input_init(player_input_type* pplayer_input) pplayer_input->old_up = UP; } +Player::Player(DisplayManager& display_manager) +{ + display_manager.add_drawable(this, LAYER_OBJECTS); + init(); +} + +Player::~Player() +{ +} + void Player::init() { @@ -162,7 +172,7 @@ Player::level_begin() } void -Player::action(double frame_ratio) +Player::action(float elapsed_time) { bool jumped_in_solid = false; @@ -176,7 +186,7 @@ Player::action(double frame_ratio) if(dying == DYING_NOT) handle_input(); - physic.apply(frame_ratio, base.x, base.y); + physic.apply(elapsed_time, base.x, base.y); if(dying == DYING_NOT) { @@ -203,7 +213,7 @@ Player::action(double frame_ratio) if(!duck && on_ground() && old_base.x == base.x && old_base.y == base.y && collision_object_map(base)) { - base.x += frame_ratio * WALK_SPEED * (dir ? 1: -1); + base.x += elapsed_time * WALK_SPEED * (dir ? 1: -1); previous_base = old_base = base; } @@ -566,8 +576,11 @@ Player::grabdistros() } void -Player::draw() +Player::draw(ViewPort& viewport, int ) { + float scroll_x = viewport.get_translation().x; + float scroll_y = viewport.get_translation().y; + if (!safe_timer.started() || (global_frame_counter % 2) == 0) { if (dying == DYING_SQUISHED) @@ -660,6 +673,14 @@ Player::draw() } void +Player::collision(const MovingObject& other, int collision_type) +{ + (void) other; + (void) collision_type; + // will be implemented later +} + +void Player::collision(void* p_c_object, int c_object) { BadGuy* pbad_c = NULL; diff --git a/src/player.h b/src/player.h index da36ef8c2..d80daf246 100644 --- a/src/player.h +++ b/src/player.h @@ -27,6 +27,8 @@ #include "texture.h" #include "collision.h" #include "sound.h" +#include "moving_object.h" +#include "drawable.h" #include "physic.h" /* Times: */ @@ -105,7 +107,7 @@ extern PlayerSprite largetux; extern PlayerSprite firetux; extern PlayerSprite icetux; -class Player : public GameObject +class Player : public MovingObject, public Drawable { public: enum HurtMode { KILL, SHRINK }; @@ -136,13 +138,22 @@ public: Physic physic; public: + Player(DisplayManager& display_manager); + virtual ~Player(); + void init(); int key_event(SDLKey key, int state); void level_begin(); - void action(double frame_ratio); void handle_input(); void grabdistros(); - void draw(); + + virtual void action(float elapsed_time); + virtual void draw(ViewPort& viewport, int layer); + virtual void collision(const MovingObject& other_object, + int collision_type); + virtual std::string type() const + { return "Player"; } + void collision(void* p_c_object, int c_object); void kill(HurtMode mode); void is_dying(); @@ -153,8 +164,6 @@ public: bool under_solid(); void grow(); - std::string type() { return "Player";}; - private: void handle_horizontal_input(); void handle_vertical_input(); diff --git a/src/world.cpp b/src/world.cpp index 16f70af6f..257b71bc7 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -49,7 +49,9 @@ World::World(const std::string& filename) current_ = this; level = new Level(filename); - tux.init(); + + tux = new Player(displaymanager); + gameobjects.push_back(tux); set_defaults(); @@ -82,7 +84,7 @@ World::World(const std::string& subset, int level_nr) current_ = this; level = new Level(subset, level_nr); - tux.init(); + tux->init(); set_defaults(); @@ -109,6 +111,7 @@ World::World(const std::string& subset, int level_nr) void World::apply_bonuses() { +#if 0 // Apply bonuses from former levels switch (player_status.bonus) { @@ -116,16 +119,17 @@ World::apply_bonuses() break; case PlayerStatus::FLOWER_BONUS: - tux.got_power = tux.FIRE_POWER; // FIXME: add ice power to here + tux->got_power = tux.FIRE_POWER; // FIXME: add ice power to here // fall through case PlayerStatus::GROWUP_BONUS: // FIXME: Move this to Player class - tux.size = BIG; - tux.base.height = 64; - tux.base.y -= 32; + tux->size = BIG; + tux->base.height = 64; + tux->base.y -= 32; break; } +#endif } World::~World() @@ -214,8 +218,6 @@ World::draw() for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) (*i)->draw(); - tux.draw(); - for (unsigned int i = 0; i < bullets.size(); ++i) bullets[i].draw(); @@ -226,8 +228,7 @@ World::draw() void World::action(double frame_ratio) { - tux.action(frame_ratio); - tux.check_bounds(level->back_scrolling, (bool)level->hor_autoscroll_speed); + tux->check_bounds(level->back_scrolling, (bool)level->hor_autoscroll_speed); scrolling(frame_ratio); for (unsigned int i = 0; i < bullets.size(); ++i) @@ -242,10 +243,11 @@ World::action(double frame_ratio) for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) (*i)->action(frame_ratio); - /* update objects */ - for(std::vector<_GameObject*>::iterator i = gameobjects.begin(); - i != gameobjects.end(); ++i) - (*i)->action(frame_ratio); + /* update objects (don't use iterators here, because the list might change + * during the iteration) + */ + for(size_t i = 0; i < gameobjects.size(); ++i) + gameobjects[i]->action(frame_ratio); /* Handle all possible collisions. */ collision_handler(); @@ -291,9 +293,9 @@ void World::scrolling(double frame_ratio) { /* Y-axis scrolling */ - float tux_pos_y = tux.base.y + (tux.base.height/2); + float tux_pos_y = tux->base.y + (tux->base.height/2); - if(level->height > VISIBLE_TILES_Y-1 && !tux.dying) + if(level->height > VISIBLE_TILES_Y-1 && !tux->dying) { if (scroll_y < tux_pos_y - (screen->h - Y_SPACE)) scroll_y = tux_pos_y - (screen->h - Y_SPACE); @@ -318,20 +320,20 @@ void World::scrolling(double frame_ratio) /* Horizontal backscrolling */ - float tux_pos_x = tux.base.x + (tux.base.width/2); + float tux_pos_x = tux->base.x + (tux->base.width/2); - if(tux.old_dir != tux.dir && level->back_scrolling) + if(tux->old_dir != tux->dir && level->back_scrolling) scrolling_timer.start(CHANGE_DIR_SCROLL_SPEED); bool right = false; bool left = false; - if (tux.physic.get_velocity_x() > 0) + if (tux->physic.get_velocity_x() > 0) right = true; - else if (tux.physic.get_velocity_x() < 0) + else if (tux->physic.get_velocity_x() < 0) left = true; else { - if (tux.dir == RIGHT) + if (tux->dir == RIGHT) right = true; else left = true; @@ -347,7 +349,8 @@ void World::scrolling(double frame_ratio) else final_scroll_x = tux_pos_x - X_SPACE; - if((tux.physic.get_velocity_x() > 0 && tux.dir == RIGHT) || (tux.physic.get_velocity_x() < 0 && tux.dir == LEFT)) + if((tux->physic.get_velocity_x() > 0 && tux->dir == RIGHT) + || (tux->physic.get_velocity_x() < 0 && tux->dir == LEFT)) { constant1 = 1.0; constant2 = .4; @@ -362,8 +365,8 @@ void World::scrolling(double frame_ratio) if(left) number *= -1.; scroll_x += number - + constant1 * tux.physic.get_velocity_x() * frame_ratio - + constant2 * tux.physic.get_acceleration_x() * frame_ratio * frame_ratio; + + constant1 * tux->physic.get_velocity_x() * frame_ratio + + constant2 * tux->physic.get_acceleration_x() * frame_ratio * frame_ratio; if ((right && final_scroll_x - scroll_x < 0) || (left && final_scroll_x - scroll_x > 0)) scroll_x = final_scroll_x; @@ -431,7 +434,7 @@ World::collision_handler() } } - if(tux.dying != DYING_NOT) return; + if(tux->dying != DYING_NOT) return; // CO_BADGUY & CO_PLAYER check for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i) @@ -439,21 +442,21 @@ World::collision_handler() if((*i)->dying != DYING_NOT) continue; - if(rectcollision_offset((*i)->base, tux.base, 0, 0)) + if(rectcollision_offset((*i)->base, tux->base, 0, 0)) { // We have detected a collision and now call the collision // functions of the collided objects. - if (tux.previous_base.y < tux.base.y && - tux.previous_base.y + tux.previous_base.height + if (tux->previous_base.y < tux->base.y && + tux->previous_base.y + tux->previous_base.height < (*i)->base.y + (*i)->base.height/2 - && !tux.invincible_timer.started()) + && !tux->invincible_timer.started()) { - (*i)->collision(&tux, CO_PLAYER, COLLISION_SQUISH); + (*i)->collision(tux, CO_PLAYER, COLLISION_SQUISH); } else { - tux.collision(*i, CO_BADGUY); - (*i)->collision(&tux, CO_PLAYER, COLLISION_NORMAL); + tux->collision(*i, CO_BADGUY); + (*i)->collision(tux, CO_PLAYER, COLLISION_NORMAL); } } } @@ -461,29 +464,29 @@ World::collision_handler() // CO_UPGRADE & CO_PLAYER check for(unsigned int i = 0; i < upgrades.size(); ++i) { - if(rectcollision(upgrades[i].base, tux.base)) + if(rectcollision(upgrades[i].base, tux->base)) { // We have detected a collision and now call the collision // functions of the collided objects. - upgrades[i].collision(&tux, CO_PLAYER, COLLISION_NORMAL); + upgrades[i].collision(tux, CO_PLAYER, COLLISION_NORMAL); } } // CO_TRAMPOLINE & (CO_PLAYER or CO_BADGUY) for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) { - if (rectcollision((*i)->base, tux.base)) + if (rectcollision((*i)->base, tux->base)) { - if (tux.previous_base.y < tux.base.y && - tux.previous_base.y + tux.previous_base.height + if (tux->previous_base.y < tux->base.y && + tux->previous_base.y + tux->previous_base.height < (*i)->base.y + (*i)->base.height/2) { - (*i)->collision(&tux, CO_PLAYER, COLLISION_SQUISH); + (*i)->collision(tux, CO_PLAYER, COLLISION_SQUISH); } - else if (tux.previous_base.y <= tux.base.y) + else if (tux->previous_base.y <= tux->base.y) { - tux.collision(*i, CO_TRAMPOLINE); - (*i)->collision(&tux, CO_PLAYER, COLLISION_NORMAL); + tux->collision(*i, CO_TRAMPOLINE); + (*i)->collision(tux, CO_PLAYER, COLLISION_NORMAL); } } } @@ -557,21 +560,21 @@ World::add_upgrade(float x, float y, Direction dir, UpgradeKind kind) void World::add_bullet(float x, float y, float xm, Direction dir) { - if(tux.got_power == tux.FIRE_POWER) + if(tux->got_power == Player::FIRE_POWER) { if(bullets.size() > MAX_FIRE_BULLETS-1) return; } - else if(tux.got_power == tux.ICE_POWER) + else if(tux->got_power == Player::ICE_POWER) { if(bullets.size() > MAX_ICE_BULLETS-1) return; } Bullet new_bullet; - if(tux.got_power == tux.FIRE_POWER) + if(tux->got_power == Player::FIRE_POWER) new_bullet.init(x,y,xm,dir, FIRE_BULLET); - else if(tux.got_power == tux.ICE_POWER) + else if(tux->got_power == Player::ICE_POWER) new_bullet.init(x,y,xm,dir, ICE_BULLET); bullets.push_back(new_bullet); @@ -688,7 +691,7 @@ World::tryemptybox(float x, float y, Direction col_side) break; case 2: // Add a fire flower upgrade! - if (tux.size == SMALL) /* Tux is small, add mints! */ + if (tux->size == SMALL) /* Tux is small, add mints! */ add_upgrade(posx, posy, col_side, UPGRADE_GROWUP); else /* Tux is big, add a fireflower: */ add_upgrade(posx, posy, col_side, UPGRADE_FIREFLOWER); @@ -696,7 +699,7 @@ World::tryemptybox(float x, float y, Direction col_side) break; case 5: // Add an ice flower upgrade! - if (tux.size == SMALL) /* Tux is small, add mints! */ + if (tux->size == SMALL) /* Tux is small, add mints! */ add_upgrade(posx, posy, col_side, UPGRADE_GROWUP); else /* Tux is big, add an iceflower: */ add_upgrade(posx, posy, col_side, UPGRADE_ICEFLOWER); @@ -749,7 +752,7 @@ World::trybumpbadguy(float x, float y) if ((*i)->base.x >= x - 32 && (*i)->base.x <= x + 32 && (*i)->base.y >= y - 16 && (*i)->base.y <= y + 16) { - (*i)->collision(&tux, CO_PLAYER, COLLISION_BUMP); + (*i)->collision(tux, CO_PLAYER, COLLISION_BUMP); } } @@ -760,7 +763,7 @@ World::trybumpbadguy(float x, float y) upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 && upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16) { - upgrades[i].collision(&tux, CO_PLAYER, COLLISION_BUMP); + upgrades[i].collision(tux, CO_PLAYER, COLLISION_BUMP); } } } diff --git a/src/world.h b/src/world.h index 05f54d23d..0f822442b 100644 --- a/src/world.h +++ b/src/world.h @@ -44,7 +44,7 @@ private: typedef std::list Trampolines; Trampolines trampolines; Level* level; - Player tux; + Player* tux; Timer scrolling_timer; @@ -72,7 +72,7 @@ public: ~World(); Level* get_level() { return level; } - Player* get_tux() { return &tux; } + Player* get_tux() { return tux; } void set_defaults(); -- 2.11.0