From: LMH Date: Thu, 11 Jul 2013 21:12:25 +0000 (-1000) Subject: New BonusBlock content: 'coinrain'. Causes ten coins to rain down from the top of... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=4ed4ca8;p=supertux.git New BonusBlock content: 'coinrain'. Causes ten coins to rain down from the top of the sector. These coins are counted in level stats. --- diff --git a/data/images/engine/editor/heavy_coin.png b/data/images/engine/editor/heavy_coin.png new file mode 100644 index 000000000..0d762e647 Binary files /dev/null and b/data/images/engine/editor/heavy_coin.png differ diff --git a/data/images/engine/editor/path_coin.png b/data/images/engine/editor/path_coin.png new file mode 100644 index 000000000..5ff2bc5f1 Binary files /dev/null and b/data/images/engine/editor/path_coin.png differ diff --git a/data/images/objects/bonus_block/bonus-rain.png b/data/images/objects/bonus_block/bonus-rain.png new file mode 100644 index 000000000..7c8383c2c Binary files /dev/null and b/data/images/objects/bonus_block/bonus-rain.png differ diff --git a/data/images/tiles.strf b/data/images/tiles.strf index c74c5e57d..6f3015144 100644 --- a/data/images/tiles.strf +++ b/data/images/tiles.strf @@ -15,6 +15,29 @@ ;; src/tile.cpp, unisolid is 3 not 2 (supertux-tiles (tile + (id 2947) + (images + "objects/bonus_block/full-0.png" + "objects/bonus_block/full-1.png" + "objects/bonus_block/full-2.png" + "objects/bonus_block/full-3.png" + "objects/bonus_block/full-4.png" + "objects/bonus_block/full-3.png" + "objects/bonus_block/full-2.png" + "objects/bonus_block/full-1.png" + "objects/bonus_block/full-0.png" + "objects/bonus_block/full-0.png" + "objects/bonus_block/full-0.png" + ) + (solid #t) + (fullbox #t) + (next-tile 84) + (editor-images "objects/bonus_block/bonus-rain.png") + (data 10) + (fps 15) + ) + + (tile (id 2946) (images "objects/bonus_block/full-0.png" @@ -615,7 +638,7 @@ ) (tilegroup (name "Block") - (tiles 27 28 29 47 48 50 49 211 77 51 52 212 78 62 61 213 44 83 84 102 140 103 104 105 112 128 2943 2944 2945 2946 1311 2153) + (tiles 27 28 29 47 48 50 49 211 77 51 52 212 78 62 61 213 44 83 2947 84 102 140 103 104 105 112 128 2943 2944 2945 2946 1311 2153) ) (tilegroup (name "Background") @@ -3915,5 +3938,5 @@ (image "tiles/snow/slope-upper.png" ) ) -;; next-id: 2947 +;; next-id: 2948 ) diff --git a/data/levels/test/bonusblock.stl b/data/levels/test/bonusblock.stl index a3b7b00fd..746425071 100755 --- a/data/levels/test/bonusblock.stl +++ b/data/levels/test/bonusblock.stl @@ -30,7 +30,7 @@ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 384 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 416 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 448 -0 0 0 0 2946 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 480 +0 0 0 0 2946 0 0 0 2947 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 480 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 512 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 544 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ; 576 @@ -45,15 +45,15 @@ 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ; 864 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ; 896 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ; 928 - )) - - (bonusblock - (x 256 ) - (y 640 ) - (contents "coin" ) - (count 3 ) - ) - + )) + + (bonusblock + (x 256 ) + (y 640 ) + (contents "coin" ) + (count 3 ) + ) + (bonusblock (x 384 ) (y 640 ) diff --git a/src/object/bonus_block.cpp b/src/object/bonus_block.cpp index 6c136c355..fa94cb19c 100644 --- a/src/object/bonus_block.cpp +++ b/src/object/bonus_block.cpp @@ -22,6 +22,7 @@ #include "object/broken_brick.hpp" #include "object/flower.hpp" #include "object/bouncy_coin.hpp" +#include "object/coin_rain.hpp" #include "object/growup.hpp" #include "object/oneup.hpp" #include "object/player.hpp" @@ -59,6 +60,7 @@ BonusBlock::BonusBlock(const Vector& pos, int data) : case 7: contents = CONTENT_TRAMPOLINE; break; case 8: contents = CONTENT_PORTTRAMPOLINE; break; case 9: contents = CONTENT_ROCK; break; + case 10: contents = CONTENT_RAIN; break; default: log_warning << "Invalid box contents" << std::endl; contents = CONTENT_COIN; @@ -116,6 +118,8 @@ BonusBlock::BonusBlock(const Reader& lisp) : contents = CONTENT_PORTTRAMPOLINE; } else if(contentstring == "rock") { contents = CONTENT_ROCK; + } else if(contentstring == "rain") { + contents = CONTENT_RAIN; } else { log_warning << "Invalid box contents '" << contentstring << "'" << std::endl; } @@ -291,6 +295,13 @@ BonusBlock::try_open(Player *player) sound_manager->play("sounds/upgrade.wav"); break; } + + case CONTENT_RAIN: + { + hit_counter = 1; // multiple hits of coin rain is not allowed + Sector::current()->add_object(new CoinRain(get_pos(), true)); + sound_manager->play("sounds/upgrade.wav"); + } } if(script != "") { // scripts always run if defined diff --git a/src/object/bonus_block.hpp b/src/object/bonus_block.hpp index 303835866..127965e6c 100644 --- a/src/object/bonus_block.hpp +++ b/src/object/bonus_block.hpp @@ -41,7 +41,8 @@ public: CONTENT_LIGHT, CONTENT_TRAMPOLINE, CONTENT_PORTTRAMPOLINE, - CONTENT_ROCK + CONTENT_ROCK, + CONTENT_RAIN }; protected: diff --git a/src/object/coin.cpp b/src/object/coin.cpp index 19896f97f..b381473f3 100644 --- a/src/object/coin.cpp +++ b/src/object/coin.cpp @@ -26,11 +26,12 @@ #include "supertux/sector.hpp" Coin::Coin(const Vector& pos) - : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE), + : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_MOVING), path(), walker(), offset(), - from_tilemap(false) + from_tilemap(false), + physic() { sound_manager->preload("sounds/coin.wav"); } @@ -40,7 +41,8 @@ Coin::Coin(const Vector& pos, TileMap* tilemap) path(boost::shared_ptr(tilemap->get_path())), walker(boost::shared_ptr(tilemap->get_walker())), offset(), - from_tilemap(true) + from_tilemap(true), + physic() { if(walker.get()) { Vector v = path->get_base(); @@ -51,11 +53,12 @@ Coin::Coin(const Vector& pos, TileMap* tilemap) } Coin::Coin(const Reader& reader) - : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE), + : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_MOVING), path(), walker(), offset(), - from_tilemap(false) + from_tilemap(false), + physic() { const lisp::Lisp* pathLisp = reader.get_lisp("path"); if (pathLisp) { @@ -169,4 +172,48 @@ Coin::collision(GameObject& other, const CollisionHit& ) return ABORT_MOVE; } +/* The following defines a coin subject to gravity */ +HeavyCoin::HeavyCoin(const Vector& pos) + : Coin(pos), + physic() +{ + physic.enable_gravity(true); + sound_manager->preload("sounds/coin.wav"); +} + +HeavyCoin::HeavyCoin(const Vector& pos, const Vector& init_velocity) + : Coin(pos), + physic() +{ + physic.enable_gravity(true); + sound_manager->preload("sounds/coin.wav"); + physic.set_velocity(init_velocity); +} + +HeavyCoin::HeavyCoin(const Reader& reader) + : Coin(reader), + physic() +{ + physic.enable_gravity(true); + sound_manager->preload("sounds/coin.wav"); +} + +void +HeavyCoin::update(float elapsed_time) +{ + // enable physics + movement = physic.get_movement(elapsed_time); +} + +void +HeavyCoin::collision_solid(const CollisionHit& hit) +{ + if(hit.bottom) { + physic.set_velocity_y(0); + } + if(hit.right || hit.left) { + physic.set_velocity_x(-physic.get_velocity_x()); + } +} + /* EOF */ diff --git a/src/object/coin.hpp b/src/object/coin.hpp index f0cd6c8fb..91f3bcd50 100644 --- a/src/object/coin.hpp +++ b/src/object/coin.hpp @@ -18,6 +18,7 @@ #define HEADER_SUPERTUX_OBJECT_COIN_HPP #include "object/moving_sprite.hpp" +#include "supertux/physic.hpp" class Path; class PathWalker; @@ -40,6 +41,21 @@ private: boost::shared_ptr walker; Vector offset; bool from_tilemap; + Physic physic; +}; + +class HeavyCoin : public Coin +{ +public: + HeavyCoin(const Vector& pos); + HeavyCoin(const Vector& pos, const Vector& init_velocity); + HeavyCoin(const Reader& reader); + + virtual void update(float elapsed_time); + virtual void collision_solid(const CollisionHit& hit); + +private: + Physic physic; }; #endif diff --git a/src/object/coin_rain.cpp b/src/object/coin_rain.cpp new file mode 100644 index 000000000..42b1317e5 --- /dev/null +++ b/src/object/coin_rain.cpp @@ -0,0 +1,82 @@ +// SuperTux +// Copyright (C) 2013 LMH +// +// 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/coin_rain.hpp" + +#include "math/random_generator.hpp" +#include "object/coin.hpp" +#include "sprite/sprite.hpp" +#include "sprite/sprite_manager.hpp" +#include "supertux/sector.hpp" + +static const float DROP_TIME = .1f; // time duration between "drops" of coin rain + +CoinRain::CoinRain(const Vector& pos, bool emerge) : + sprite(), + position(pos), + emerge_distance(0), + timer(), + counter(0), + drop(0) +{ + sprite = sprite_manager->create("images/objects/coin/coin.sprite"); + + if(emerge) { + emerge_distance = sprite->get_height(); + } +} + +void +CoinRain::update(float elapsed_time) +{ + // first a single (untouchable) coin flies up above the sector + if(position.y > -32){ + float dist = -500 * elapsed_time; + position.y += dist; + emerge_distance += dist; + } // then the first collectable coin drops from one of ten random positions + else if (counter==0){ + drop = gameRandom.rand(10); + Sector::current()->add_object(new HeavyCoin(Vector (position.x+32*((drop<5)?-drop-1:drop-4),-32))); + counter++; + timer.start(DROP_TIME); + } // finally the remainder of the coins drop in a determined but appears to be a random order + else if(timer.check()){ + if(counter<10){ + drop += 7; + if(drop >= 10) drop -=10; + Sector::current()->add_object(new HeavyCoin(Vector (position.x+32*((drop<5)?-drop-1:drop-4),-32))); + counter++; + timer.start(DROP_TIME); + }else{ + remove_me(); + } + } +} + +void +CoinRain::draw(DrawingContext& context) +{ + int layer; + if(emerge_distance > 0) { + layer = LAYER_OBJECTS - 5; + } else { + layer = LAYER_OBJECTS + 5; + } + sprite->draw(context, position, layer); +} + +/* EOF */ diff --git a/src/object/coin_rain.hpp b/src/object/coin_rain.hpp new file mode 100644 index 000000000..37360c93f --- /dev/null +++ b/src/object/coin_rain.hpp @@ -0,0 +1,48 @@ +// SuperTux +// Copyright (C) 2013 LMH +// +// 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_COIN_RAIN_HPP +#define HEADER_SUPERTUX_OBJECT_COIN_RAIN_HPP + +#include + +#include "math/vector.hpp" +#include "sprite/sprite_ptr.hpp" +#include "supertux/game_object.hpp" +#include "supertux/timer.hpp" +#include "video/color.hpp" + +class Sprite; + +class CoinRain : public GameObject +{ +public: + CoinRain(const Vector& pos, bool emerge=false); + virtual void update(float elapsed_time); + virtual void draw(DrawingContext& context); + +private: + SpritePtr sprite; + Vector position; + float emerge_distance; + Timer timer; + int counter; + int drop; +}; + +#endif + +/* EOF */ diff --git a/src/supertux/level.cpp b/src/supertux/level.cpp index 3b70d653f..e63b4a664 100644 --- a/src/supertux/level.cpp +++ b/src/supertux/level.cpp @@ -203,6 +203,9 @@ Level::get_total_coins() { total_coins += block->hit_counter; continue; + } else if (block->contents == BonusBlock::CONTENT_RAIN) { + total_coins += 10; + continue; } #if 0 // FIXME: do we want this? q.v. src/object/oneup.cpp diff --git a/src/supertux/object_factory.cpp b/src/supertux/object_factory.cpp index 71c177c93..fc01e111d 100644 --- a/src/supertux/object_factory.cpp +++ b/src/supertux/object_factory.cpp @@ -86,6 +86,7 @@ #include "object/candle.hpp" #include "object/cloud_particle_system.hpp" #include "object/coin.hpp" +#include "object/coin_rain.hpp" #include "object/comet_particle_system.hpp" #include "object/decal.hpp" #include "object/display_effect.hpp" @@ -231,6 +232,7 @@ ObjectFactory::init_factories() add_factory("explosion"); add_factory("firefly"); add_factory("gradient"); + add_factory("heavycoin"); add_factory("hurting_platform"); add_factory("icecrusher"); add_factory("infoblock");