From: Ingo Ruhnke Date: Wed, 18 Nov 2009 01:45:39 +0000 (+0000) Subject: Split object/block.?pp X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=ce4e3bd4239ed1f122b0b39e247be8ee6850338d;p=supertux.git Split object/block.?pp SVN-Revision: 6020 --- diff --git a/src/object/block.cpp b/src/object/block.cpp index dd57c25c1..420a4b1ad 100644 --- a/src/object/block.cpp +++ b/src/object/block.cpp @@ -155,282 +155,4 @@ Block::start_break(GameObject* hitter) breaking = true; } -//--------------------------------------------------------------------------- - -BonusBlock::BonusBlock(const Vector& pos, int data) : - Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), - contents(), - object(0) -{ - bbox.set_pos(pos); - sprite->set_action("normal"); - switch(data) { - case 1: contents = CONTENT_COIN; break; - case 2: contents = CONTENT_FIREGROW; break; - case 3: contents = CONTENT_STAR; break; - case 4: contents = CONTENT_1UP; break; - case 5: contents = CONTENT_ICEGROW; break; - default: - log_warning << "Invalid box contents" << std::endl; - contents = CONTENT_COIN; - break; - } -} - -BonusBlock::BonusBlock(const Reader& lisp) : - Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), - contents(), - object(0) -{ - Vector pos; - - contents = CONTENT_COIN; - lisp::ListIterator iter(&lisp); - while(iter.next()) { - const std::string& token = iter.item(); - if(token == "x") { - iter.value()->get(pos.x); - } else if(token == "y") { - iter.value()->get(pos.y); - } else if(token == "contents") { - std::string contentstring; - iter.value()->get(contentstring); - if(contentstring == "coin") { - contents = CONTENT_COIN; - } else if(contentstring == "firegrow") { - contents = CONTENT_FIREGROW; - } else if(contentstring == "icegrow") { - contents = CONTENT_ICEGROW; - } else if(contentstring == "star") { - contents = CONTENT_STAR; - } else if(contentstring == "1up") { - contents = CONTENT_1UP; - } else if(contentstring == "custom") { - contents = CONTENT_CUSTOM; - } else { - log_warning << "Invalid box contents '" << contentstring << "'" << std::endl; - } - } else { - if(contents == CONTENT_CUSTOM) { - GameObject* game_object = create_object(token, *(iter.lisp())); - object = dynamic_cast (game_object); - if(object == 0) - throw std::runtime_error( - "Only MovingObjects are allowed inside BonusBlocks"); - } else { - log_warning << "Invalid element '" << token << "' in bonusblock" << std::endl; - } - } - } - - if(contents == CONTENT_CUSTOM && object == 0) - throw std::runtime_error("Need to specify content object for custom block"); - - bbox.set_pos(pos); -} - -BonusBlock::~BonusBlock() -{ - delete object; -} - -void -BonusBlock::hit(Player& ) -{ - try_open(); -} - -HitResponse -BonusBlock::collision(GameObject& other, const CollisionHit& hit){ - - Player* player = dynamic_cast (&other); - if (player) { - if (player->does_buttjump) try_open(); - } - - BadGuy* badguy = dynamic_cast (&other); - if(badguy) { - // hit contains no information for collisions with blocks. - // Badguy's bottom has to be below the top of the block - // SHIFT_DELTA is required to slide over one tile gaps. - if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){ - try_open(); - } - } - Portable* portable = dynamic_cast (&other); - if(portable) { - MovingObject* moving = dynamic_cast (&other); - if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) { - try_open(); - } - } - return Block::collision(other, hit); -} - -void -BonusBlock::try_open() -{ - if(sprite->get_action() == "empty") { - sound_manager->play("sounds/brick.wav"); - return; - } - - Sector* sector = Sector::current(); - assert(sector); - assert(sector->player); - Player& player = *(sector->player); - Direction direction = (player.get_bbox().get_middle().x > get_bbox().get_middle().x) ? LEFT : RIGHT; - - switch(contents) { - case CONTENT_COIN: - Sector::current()->add_object(new BouncyCoin(get_pos(), true)); - player.get_status()->add_coins(1); - Sector::current()->get_level()->stats.coins++; - break; - - case CONTENT_FIREGROW: - if(player.get_status()->bonus == NO_BONUS) { - SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction)); - sector->add_object(riser); - } else { - SpecialRiser* riser = new SpecialRiser( - get_pos(), new Flower(FIRE_BONUS)); - sector->add_object(riser); - } - sound_manager->play("sounds/upgrade.wav"); - break; - - case CONTENT_ICEGROW: - if(player.get_status()->bonus == NO_BONUS) { - SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction)); - sector->add_object(riser); - } else { - SpecialRiser* riser = new SpecialRiser( - get_pos(), new Flower(ICE_BONUS)); - sector->add_object(riser); - } - sound_manager->play("sounds/upgrade.wav"); - break; - - case CONTENT_STAR: - sector->add_object(new Star(get_pos() + Vector(0, -32), direction)); - break; - - case CONTENT_1UP: - sector->add_object(new OneUp(get_pos(), direction)); - break; - - case CONTENT_CUSTOM: - SpecialRiser* riser = new SpecialRiser(get_pos(), object); - object = 0; - sector->add_object(riser); - sound_manager->play("sounds/upgrade.wav"); - break; - } - - start_bounce(&player); - sprite->set_action("empty"); -} - -void -Block::break_me() -{ - Sector* sector = Sector::current(); - sector->add_object( - new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos(), Vector(-100, -400))); - sector->add_object( - new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos() + Vector(0, 16), - Vector(-150, -300))); - sector->add_object( - new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos() + Vector(16, 0), - Vector(100, -400))); - sector->add_object( - new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos() + Vector(16, 16), - Vector(150, -300))); - remove_me(); -} - -IMPLEMENT_FACTORY(BonusBlock, "bonusblock"); - -//--------------------------------------------------------------------------- - -Brick::Brick(const Vector& pos, int data) - : Block(sprite_manager->create("images/objects/bonus_block/brick.sprite")), breakable(false), - coin_counter(0) -{ - bbox.set_pos(pos); - if(data == 1) - coin_counter = 5; - else - breakable = true; -} - -void -Brick::hit(Player& player) -{ - if(sprite->get_action() == "empty") - return; - - try_break(&player); -} - -HitResponse -Brick::collision(GameObject& other, const CollisionHit& hit){ - - Player* player = dynamic_cast (&other); - if (player) { - if (player->does_buttjump) try_break(); - } - - BadGuy* badguy = dynamic_cast (&other); - if(badguy) { - // hit contains no information for collisions with blocks. - // Badguy's bottom has to be below the top of the brick - // SHIFT_DELTA is required to slide over one tile gaps. - if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){ - try_break(); - } - } - Portable* portable = dynamic_cast (&other); - if(portable) { - MovingObject* moving = dynamic_cast (&other); - if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) { - try_break(); - } - } - return Block::collision(other, hit); -} - -void -Brick::try_break(Player* player) -{ - if(sprite->get_action() == "empty") - return; - - sound_manager->play("sounds/brick.wav"); - Sector* sector = Sector::current(); - Player& player_one = *(sector->player); - if(coin_counter > 0) { - sector->add_object(new BouncyCoin(get_pos(),true)); - coin_counter--; - player_one.get_status()->add_coins(1); - if(coin_counter == 0) - sprite->set_action("empty"); - start_bounce(player); - } else if(breakable) { - if(player){ - if(player->is_big()){ - start_break(player); - return; - } else { - start_bounce(player); - return; - } - } - break_me(); - } -} - -//IMPLEMENT_FACTORY(Brick, "brick"); - /* EOF */ diff --git a/src/object/block.hpp b/src/object/block.hpp index d31ba4d8c..fecbd0f14 100644 --- a/src/object/block.hpp +++ b/src/object/block.hpp @@ -55,53 +55,6 @@ private: Block& operator=(const Block&); }; -class BonusBlock : public Block -{ -public: - BonusBlock(const Vector& pos, int data); - BonusBlock(const Reader& lisp); - virtual ~BonusBlock(); - HitResponse collision(GameObject& other, const CollisionHit& hit); - - void try_open(); - - enum Contents { - CONTENT_COIN, - CONTENT_FIREGROW, - CONTENT_ICEGROW, - CONTENT_STAR, - CONTENT_1UP, - CONTENT_CUSTOM - }; - -protected: - virtual void hit(Player& player); - -public: - Contents contents; - MovingObject* object; - -private: - BonusBlock(const BonusBlock&); - BonusBlock& operator=(const BonusBlock&); -}; - -class Brick : public Block -{ -public: - Brick(const Vector& pos, int data); - - void try_break(Player* player = false); - HitResponse collision(GameObject& other, const CollisionHit& hit); - -protected: - virtual void hit(Player& player); - -private: - bool breakable; - int coin_counter; -}; - #endif /* EOF */ diff --git a/src/object/bonus_block.cpp b/src/object/bonus_block.cpp new file mode 100644 index 000000000..26638075b --- /dev/null +++ b/src/object/bonus_block.cpp @@ -0,0 +1,233 @@ +// SuperTux +// Copyright (C) 2009 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "object/bonus_block.hpp" + +#include "audio/sound_manager.hpp" +#include "badguy/badguy.hpp" +#include "lisp/list_iterator.hpp" +#include "object/broken_brick.hpp" +#include "object/coin.hpp" +#include "object/flower.hpp" +#include "object/bouncy_coin.hpp" +#include "object/growup.hpp" +#include "object/oneup.hpp" +#include "object/player.hpp" +#include "object/portable.hpp" +#include "object/specialriser.hpp" +#include "object/star.hpp" +#include "sprite/sprite_manager.hpp" +#include "supertux/constants.hpp" +#include "supertux/level.hpp" +#include "supertux/object_factory.hpp" +#include "supertux/sector.hpp" + +BonusBlock::BonusBlock(const Vector& pos, int data) : + Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), + contents(), + object(0) +{ + bbox.set_pos(pos); + sprite->set_action("normal"); + switch(data) { + case 1: contents = CONTENT_COIN; break; + case 2: contents = CONTENT_FIREGROW; break; + case 3: contents = CONTENT_STAR; break; + case 4: contents = CONTENT_1UP; break; + case 5: contents = CONTENT_ICEGROW; break; + default: + log_warning << "Invalid box contents" << std::endl; + contents = CONTENT_COIN; + break; + } +} + +BonusBlock::BonusBlock(const Reader& lisp) : + Block(sprite_manager->create("images/objects/bonus_block/bonusblock.sprite")), + contents(), + object(0) +{ + Vector pos; + + contents = CONTENT_COIN; + lisp::ListIterator iter(&lisp); + while(iter.next()) { + const std::string& token = iter.item(); + if(token == "x") { + iter.value()->get(pos.x); + } else if(token == "y") { + iter.value()->get(pos.y); + } else if(token == "contents") { + std::string contentstring; + iter.value()->get(contentstring); + if(contentstring == "coin") { + contents = CONTENT_COIN; + } else if(contentstring == "firegrow") { + contents = CONTENT_FIREGROW; + } else if(contentstring == "icegrow") { + contents = CONTENT_ICEGROW; + } else if(contentstring == "star") { + contents = CONTENT_STAR; + } else if(contentstring == "1up") { + contents = CONTENT_1UP; + } else if(contentstring == "custom") { + contents = CONTENT_CUSTOM; + } else { + log_warning << "Invalid box contents '" << contentstring << "'" << std::endl; + } + } else { + if(contents == CONTENT_CUSTOM) { + GameObject* game_object = create_object(token, *(iter.lisp())); + object = dynamic_cast (game_object); + if(object == 0) + throw std::runtime_error( + "Only MovingObjects are allowed inside BonusBlocks"); + } else { + log_warning << "Invalid element '" << token << "' in bonusblock" << std::endl; + } + } + } + + if(contents == CONTENT_CUSTOM && object == 0) + throw std::runtime_error("Need to specify content object for custom block"); + + bbox.set_pos(pos); +} + +BonusBlock::~BonusBlock() +{ + delete object; +} + +void +BonusBlock::hit(Player& ) +{ + try_open(); +} + +HitResponse +BonusBlock::collision(GameObject& other, const CollisionHit& hit){ + + Player* player = dynamic_cast (&other); + if (player) { + if (player->does_buttjump) try_open(); + } + + BadGuy* badguy = dynamic_cast (&other); + if(badguy) { + // hit contains no information for collisions with blocks. + // Badguy's bottom has to be below the top of the block + // SHIFT_DELTA is required to slide over one tile gaps. + if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){ + try_open(); + } + } + Portable* portable = dynamic_cast (&other); + if(portable) { + MovingObject* moving = dynamic_cast (&other); + if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) { + try_open(); + } + } + return Block::collision(other, hit); +} + +void +BonusBlock::try_open() +{ + if(sprite->get_action() == "empty") { + sound_manager->play("sounds/brick.wav"); + return; + } + + Sector* sector = Sector::current(); + assert(sector); + assert(sector->player); + Player& player = *(sector->player); + Direction direction = (player.get_bbox().get_middle().x > get_bbox().get_middle().x) ? LEFT : RIGHT; + + switch(contents) { + case CONTENT_COIN: + Sector::current()->add_object(new BouncyCoin(get_pos(), true)); + player.get_status()->add_coins(1); + Sector::current()->get_level()->stats.coins++; + break; + + case CONTENT_FIREGROW: + if(player.get_status()->bonus == NO_BONUS) { + SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction)); + sector->add_object(riser); + } else { + SpecialRiser* riser = new SpecialRiser( + get_pos(), new Flower(FIRE_BONUS)); + sector->add_object(riser); + } + sound_manager->play("sounds/upgrade.wav"); + break; + + case CONTENT_ICEGROW: + if(player.get_status()->bonus == NO_BONUS) { + SpecialRiser* riser = new SpecialRiser(get_pos(), new GrowUp(direction)); + sector->add_object(riser); + } else { + SpecialRiser* riser = new SpecialRiser( + get_pos(), new Flower(ICE_BONUS)); + sector->add_object(riser); + } + sound_manager->play("sounds/upgrade.wav"); + break; + + case CONTENT_STAR: + sector->add_object(new Star(get_pos() + Vector(0, -32), direction)); + break; + + case CONTENT_1UP: + sector->add_object(new OneUp(get_pos(), direction)); + break; + + case CONTENT_CUSTOM: + SpecialRiser* riser = new SpecialRiser(get_pos(), object); + object = 0; + sector->add_object(riser); + sound_manager->play("sounds/upgrade.wav"); + break; + } + + start_bounce(&player); + sprite->set_action("empty"); +} + +void +Block::break_me() +{ + Sector* sector = Sector::current(); + sector->add_object( + new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos(), Vector(-100, -400))); + sector->add_object( + new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos() + Vector(0, 16), + Vector(-150, -300))); + sector->add_object( + new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos() + Vector(16, 0), + Vector(100, -400))); + sector->add_object( + new BrokenBrick(std::auto_ptr(new Sprite(*sprite)), get_pos() + Vector(16, 16), + Vector(150, -300))); + remove_me(); +} + +IMPLEMENT_FACTORY(BonusBlock, "bonusblock"); + +/* EOF */ diff --git a/src/object/bonus_block.hpp b/src/object/bonus_block.hpp new file mode 100644 index 000000000..98eb74780 --- /dev/null +++ b/src/object/bonus_block.hpp @@ -0,0 +1,55 @@ +// SuperTux +// Copyright (C) 2009 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_OBJECT_BONUS_BLOCK_HPP +#define HEADER_SUPERTUX_OBJECT_BONUS_BLOCK_HPP + +#include "object/block.hpp" + +class BonusBlock : public Block +{ +public: + BonusBlock(const Vector& pos, int data); + BonusBlock(const Reader& lisp); + virtual ~BonusBlock(); + HitResponse collision(GameObject& other, const CollisionHit& hit); + + void try_open(); + + enum Contents { + CONTENT_COIN, + CONTENT_FIREGROW, + CONTENT_ICEGROW, + CONTENT_STAR, + CONTENT_1UP, + CONTENT_CUSTOM + }; + +protected: + virtual void hit(Player& player); + +public: + Contents contents; + MovingObject* object; + +private: + BonusBlock(const BonusBlock&); + BonusBlock& operator=(const BonusBlock&); +}; + +#endif + +/* EOF */ diff --git a/src/object/brick.cpp b/src/object/brick.cpp new file mode 100644 index 000000000..d05475242 --- /dev/null +++ b/src/object/brick.cpp @@ -0,0 +1,117 @@ +// SuperTux +// Copyright (C) 2009 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "object/brick.hpp" + +#include "audio/sound_manager.hpp" +#include "badguy/badguy.hpp" +#include "lisp/list_iterator.hpp" +#include "object/broken_brick.hpp" +#include "object/coin.hpp" +#include "object/flower.hpp" +#include "object/bouncy_coin.hpp" +#include "object/growup.hpp" +#include "object/oneup.hpp" +#include "object/player.hpp" +#include "object/portable.hpp" +#include "object/specialriser.hpp" +#include "object/star.hpp" +#include "sprite/sprite_manager.hpp" +#include "supertux/constants.hpp" +#include "supertux/level.hpp" +#include "supertux/object_factory.hpp" +#include "supertux/sector.hpp" + +Brick::Brick(const Vector& pos, int data) + : Block(sprite_manager->create("images/objects/bonus_block/brick.sprite")), breakable(false), + coin_counter(0) +{ + bbox.set_pos(pos); + if(data == 1) + coin_counter = 5; + else + breakable = true; +} + +void +Brick::hit(Player& player) +{ + if(sprite->get_action() == "empty") + return; + + try_break(&player); +} + +HitResponse +Brick::collision(GameObject& other, const CollisionHit& hit){ + + Player* player = dynamic_cast (&other); + if (player) { + if (player->does_buttjump) try_break(); + } + + BadGuy* badguy = dynamic_cast (&other); + if(badguy) { + // hit contains no information for collisions with blocks. + // Badguy's bottom has to be below the top of the brick + // SHIFT_DELTA is required to slide over one tile gaps. + if( badguy->can_break() && ( badguy->get_bbox().get_bottom() > get_bbox().get_top() + SHIFT_DELTA ) ){ + try_break(); + } + } + Portable* portable = dynamic_cast (&other); + if(portable) { + MovingObject* moving = dynamic_cast (&other); + if(moving->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) { + try_break(); + } + } + return Block::collision(other, hit); +} + +void +Brick::try_break(Player* player) +{ + if(sprite->get_action() == "empty") + return; + + sound_manager->play("sounds/brick.wav"); + Sector* sector = Sector::current(); + Player& player_one = *(sector->player); + if(coin_counter > 0) { + sector->add_object(new BouncyCoin(get_pos(),true)); + coin_counter--; + player_one.get_status()->add_coins(1); + if(coin_counter == 0) + sprite->set_action("empty"); + start_bounce(player); + } else if(breakable) { + if(player){ + if(player->is_big()){ + start_break(player); + return; + } else { + start_bounce(player); + return; + } + } + break_me(); + } +} + +//IMPLEMENT_FACTORY(Brick, "brick"); + +/* EOF */ diff --git a/src/object/brick.hpp b/src/object/brick.hpp new file mode 100644 index 000000000..b837aa9af --- /dev/null +++ b/src/object/brick.hpp @@ -0,0 +1,40 @@ +// SuperTux +// Copyright (C) 2009 Ingo Ruhnke +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#ifndef HEADER_SUPERTUX_OBJECT_BRICK_HPP +#define HEADER_SUPERTUX_OBJECT_BRICK_HPP + +#include "object/block.hpp" + +class Brick : public Block +{ +public: + Brick(const Vector& pos, int data); + + void try_break(Player* player = false); + HitResponse collision(GameObject& other, const CollisionHit& hit); + +protected: + virtual void hit(Player& player); + +private: + bool breakable; + int coin_counter; +}; + +#endif + +/* EOF */ diff --git a/src/supertux/level.cpp b/src/supertux/level.cpp index a398d7fbf..3b69137c2 100644 --- a/src/supertux/level.cpp +++ b/src/supertux/level.cpp @@ -18,7 +18,7 @@ #include "lisp/list_iterator.hpp" #include "lisp/parser.hpp" -#include "object/block.hpp" +#include "object/bonus_block.hpp" #include "object/coin.hpp" #include "supertux/sector.hpp" #include "supertux/tile_manager.hpp" diff --git a/src/supertux/sector.cpp b/src/supertux/sector.cpp index 0ca660195..73dc1e7ce 100644 --- a/src/supertux/sector.cpp +++ b/src/supertux/sector.cpp @@ -24,6 +24,8 @@ #include "lisp/list_iterator.hpp" #include "math/aatriangle.hpp" #include "object/background.hpp" +#include "object/bonus_block.hpp" +#include "object/brick.hpp" #include "object/bullet.hpp" #include "object/camera.hpp" #include "object/coin.hpp"