X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fgameobjs.cpp;h=3201eb285fe817eba0f1a07d3a33d3a1d7af195a;hb=ee6972038331a3c26a2a6a0bdb2baca25475b1d2;hp=61580e204ccd8aa39f21bea600e79cbc3471a19e;hpb=5ab69550afb268f8775d876406a9a5797f224f97;p=supertux.git diff --git a/src/gameobjs.cpp b/src/gameobjs.cpp index 61580e204..3201eb285 100644 --- a/src/gameobjs.cpp +++ b/src/gameobjs.cpp @@ -18,47 +18,64 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include -#include "world.h" +#include + +#include "app/globals.h" #include "tile.h" +#include "tile_manager.h" #include "gameloop.h" #include "gameobjs.h" -#include "sprite_manager.h" +#include "special/sprite_manager.h" #include "resources.h" -#include "level.h" -#include "display_manager.h" +#include "sector.h" +#include "tilemap.h" +#include "video/drawing_context.h" +#include "camera.h" -BouncyDistro::BouncyDistro(DisplayManager& displaymanager, const Vector& pos) +BouncyCoin::BouncyCoin(const Vector& pos) : position(pos) { - ym = -2; - displaymanager.add_drawable(this, LAYER_OBJECTS); + timer.start(.3); + sprite = sprite_manager->create("coin"); + sprite->set_action("still"); +} + +BouncyCoin::~BouncyCoin() +{ + delete sprite; } void -BouncyDistro::action(float elapsed_time) +BouncyCoin::action(float elapsed_time) { - position.y += ym * elapsed_time; + position.y += -200 * elapsed_time; - ym += 0.1 * elapsed_time; // not framerate independent... but who really cares - if(ym >= 0) + if(timer.check()) remove_me(); } void -BouncyDistro::draw(ViewPort& viewport, int ) +BouncyCoin::draw(DrawingContext& context) { - img_distro[0]->draw(viewport.world2screen(position)); + sprite->draw(context, position, LAYER_OBJECTS); } +//--------------------------------------------------------------------------- -BrokenBrick::BrokenBrick(DisplayManager& displaymanager, Tile* ntile, +BrokenBrick::BrokenBrick(Sprite* nsprite, const Vector& pos, const Vector& nmovement) - : tile(ntile), position(pos), movement(nmovement) + : sprite(new Sprite(*nsprite)), position(pos), movement(nmovement) +{ + timer.start(.2); +} + +BrokenBrick::~BrokenBrick() { - displaymanager.add_drawable(this, LAYER_OBJECTS); - timer.start(200); + delete sprite; } void @@ -66,95 +83,95 @@ BrokenBrick::action(float elapsed_time) { position += movement * elapsed_time; - if (!timer.check()) + if (timer.check()) remove_me(); } void -BrokenBrick::draw(ViewPort& viewport, int ) +BrokenBrick::draw(DrawingContext& context) { - SDL_Rect src, dest; - src.x = rand() % 16; - src.y = rand() % 16; - src.w = 16; - src.h = 16; - - dest.x = (int)(position.x - viewport.get_translation().x); - dest.y = (int)(position.y - viewport.get_translation().y); - dest.w = 16; - dest.h = 16; - - if (tile->images.size() > 0) - tile->images[0]->draw_part(src.x,src.y,dest.x,dest.y,dest.w,dest.h); + sprite->draw_part(context, + Vector(rand() % 16, rand() % 16), Vector(16, 16), + position, LAYER_OBJECTS + 1); } -BouncyBrick::BouncyBrick(DisplayManager& displaymanager, const Vector& pos) - : position(pos), offset(0), offset_m(-BOUNCY_BRICK_SPEED) -{ - displaymanager.add_drawable(this, LAYER_OBJECTS); - shape = World::current()->get_level()->gettileid(pos.x, pos.y); -} +//--------------------------------------------------------------------------- -void -BouncyBrick::action(float elapsed_time) +FloatingText::FloatingText(const Vector& pos, const std::string& text_) + : position(pos), text(text_) { - offset += offset_m * elapsed_time; - - /* Go back down? */ - if (offset < -BOUNCY_BRICK_MAX_OFFSET) - offset_m = BOUNCY_BRICK_SPEED; - - /* Stop bouncing? */ - if (offset >= 0) - remove_me(); + timer.start(.1); + position.x -= text.size() * 8; } -void -BouncyBrick::draw(ViewPort& viewport, int) -{ - Tile::draw(viewport.world2screen(position + Vector(0, offset)), shape); -} - -FloatingScore::FloatingScore(DisplayManager& displaymanager, - const Vector& pos, int score) +FloatingText::FloatingText(const Vector& pos, int score) : position(pos) { - displaymanager.add_drawable(this, LAYER_OBJECTS); - timer.start(1000); + timer.start(.1); + + // turn int into a string + char str[10]; snprintf(str, 10, "%d", score); - position.x -= strlen(str) * 8; + text = str; + + position.x -= text.size() * 8; } void -FloatingScore::action(float elapsed_time) +FloatingText::action(float elapsed_time) { - position.y -= 2 * elapsed_time; + position.y -= 1.4 * elapsed_time; - if(!timer.check()) + if(timer.check()) remove_me(); } +#define FADING_TIME .350 + void -FloatingScore::draw(ViewPort& viewport, int ) +FloatingText::draw(DrawingContext& context) { - gold_text->draw(str, viewport.world2screen(position)); + // make an alpha animation when disapearing + int alpha; + if(timer.get_timeleft() < FADING_TIME) + alpha = int(timer.get_timeleft() * 255 / FADING_TIME); + else + alpha = 255; + + context.push_transform(); + context.set_alpha(alpha); + + context.draw_text(gold_text, text, position, LEFT_ALLIGN, LAYER_OBJECTS+1); + + context.pop_transform(); } /* Trampoline */ -#define TRAMPOLINE_FRAMES 4 -Sprite *img_trampoline[TRAMPOLINE_FRAMES]; +#if 0 +Sprite *img_trampoline; + +Trampoline::Trampoline(LispReader& reader) +{ + reader.read_float("x", base.x); + reader.read_float("y", base.y); + base.width = 32; + base.height = 32; + power = 7.5; + reader.read_float("power", power); + + frame = 0; + mode = M_NORMAL; + physic.reset(); +} -Trampoline::Trampoline(DisplayManager& displaymanager, LispReader& reader) +Trampoline::Trampoline(float x, float y) { - displaymanager.add_drawable(this, LAYER_OBJECTS); - - reader.read_float("x", &base.x); - reader.read_float("y", &base.y); + base.x = x; + base.y = y; base.width = 32; base.height = 32; power = 7.5; - reader.read_float("power", &power); frame = 0; mode = M_NORMAL; @@ -174,9 +191,10 @@ Trampoline::write(LispWriter& writer) } void -Trampoline::draw(ViewPort& viewport, int ) +Trampoline::draw(DrawingContext& context) { - img_trampoline[frame]->draw(viewport.world2screen(Vector(base.x, base.y))); + img_trampoline->set_frame(frame); + img_trampoline->draw(context, base, LAYER_OBJECTS); frame = 0; } @@ -206,7 +224,7 @@ Trampoline::action(float frame_ratio) { /* FIXME: The trampoline object shouldn't know about pplayer objects. */ /* If we're holding the iceblock */ - Player& tux = *World::current()->get_tux(); + Player& tux = *Sector::current()->player; Direction dir = tux.dir; if(dir == RIGHT) @@ -227,7 +245,7 @@ Trampoline::action(float frame_ratio) } } - physic.apply(frame_ratio, base.x, base.y); + physic.apply(frame_ratio, base.x, base.y, Sector::current()->gravity); collision_swept_object_map(&old_base, &base); } @@ -264,8 +282,10 @@ Trampoline::collision(void *p_c_object, int c_object, CollisionType type) else frame = 0; - if (squish_amount < 20) + if (squish_amount < 20) { pplayer_c->physic.set_velocity_y(power); + pplayer_c->fall_mode = Player::TRAMPOLINE_JUMP; + } else if (pplayer_c->physic.get_velocity_y() < 0) pplayer_c->physic.set_velocity_y(-squish_amount/32); } @@ -277,21 +297,20 @@ Trampoline::collision(void *p_c_object, int c_object, CollisionType type) } } +#endif /* Flying Platform */ -#define FLYING_PLATFORM_FRAMES 1 -Sprite *img_flying_platform[FLYING_PLATFORM_FRAMES]; +#if 0 +Sprite *img_flying_platform; -FlyingPlatform::FlyingPlatform(DisplayManager& displaymanager, LispReader& reader) +FlyingPlatform::FlyingPlatform(LispReader& reader) { - displaymanager.add_drawable(this, LAYER_OBJECTS); - - reader.read_int_vector("x", &pos_x); - reader.read_int_vector("y", &pos_y); + reader.read_int_vector("x", pos_x); + reader.read_int_vector("y", pos_y); velocity = 2.0; - reader.read_float("velocity", &velocity); + reader.read_float("velocity", velocity); base.x = pos_x[0]; base.y = pos_y[0]; @@ -301,9 +320,22 @@ FlyingPlatform::FlyingPlatform(DisplayManager& displaymanager, LispReader& reade point = 0; move = false; + float x = pos_x[point+1] - pos_x[point]; + float y = pos_y[point+1] - pos_y[point]; + vel_x = x*velocity / sqrt(x*x + y*y); + vel_y = -(velocity - vel_x); + frame = 0; } +FlyingPlatform::FlyingPlatform(int x, int y) +{ +base.x = x; +base.y = y; +point = 0; +move = false; +} + void FlyingPlatform::write(LispWriter& writer) { @@ -317,9 +349,9 @@ FlyingPlatform::write(LispWriter& writer) } void -FlyingPlatform::draw(ViewPort& viewport, int ) +FlyingPlatform::draw(DrawingContext& context) { -img_flying_platform[frame]->draw(viewport.world2screen(Vector(base.x, base.y))); + img_flying_platform->draw(context, base, LAYER_OBJECTS); } void @@ -327,46 +359,46 @@ FlyingPlatform::action(float frame_ratio) { // TODO: Remove if we're too far off the screen - // FIXME: change frame if(!move) return; if((unsigned)point+1 != pos_x.size()) + { if(((pos_x[point+1] > pos_x[point] && base.x >= pos_x[point+1]) || (pos_x[point+1] < pos_x[point] && base.x <= pos_x[point+1]) || - pos_x[point+1] == pos_x[point+1]) && + pos_x[point] == pos_x[point+1]) && ((pos_y[point+1] > pos_y[point] && base.y >= pos_y[point+1]) || (pos_y[point+1] < pos_y[point] && base.y <= pos_y[point+1]) || - pos_y[point+1] == pos_y[point+1])) + pos_y[point] == pos_y[point+1])) { point++; -std::cerr << "next point: " << point << std::endl; + + float x = pos_x[point+1] - pos_x[point]; + float y = pos_y[point+1] - pos_y[point]; + vel_x = x*velocity / sqrt(x*x + y*y); + vel_y = -(velocity - vel_x); } + } else // last point { // point = 0; // reverse vector return; } - -if(pos_x[point] > base.x) +/* +if(pos_x[point+1] > base.x) base.x += velocity * frame_ratio; -else if(pos_x[point] < base.x) +else if(pos_x[point+1] < base.x) base.x -= velocity * frame_ratio; -if(pos_y[point] > base.y) +if(pos_y[point+1] > base.y) base.y += velocity * frame_ratio; -else if(pos_y[point] < base.y) +else if(pos_y[point+1] < base.y) base.y -= velocity * frame_ratio; -/* -float x = pos_x[point+1] - pos_x[point]; -float y = pos_y[point+1] - pos_y[point]; -float vel_x = x*velocity / sqrt(x*x + y*y); -float vel_y = velocity - vel_x; +*/ base.x += vel_x * frame_ratio; base.y += vel_y * frame_ratio; -*/ } void @@ -387,7 +419,7 @@ FlyingPlatform::collision(void *p_c_object, int c_object, CollisionType type) case CO_PLAYER: // pplayer_c = (Player*) p_c_object; move = true; - + break; default: @@ -395,20 +427,119 @@ FlyingPlatform::collision(void *p_c_object, int c_object, CollisionType type) } } +#endif -void load_object_gfx() +Sprite *img_smoke_cloud = 0; + +SmokeCloud::SmokeCloud(const Vector& pos) + : position(pos) { - char sprite_name[16]; + timer.start(.3); +} - for (int i = 0; i < TRAMPOLINE_FRAMES; i++) - { - sprintf(sprite_name, "trampoline-%i", i+1); - img_trampoline[i] = sprite_manager->load(sprite_name); +void +SmokeCloud::action(float elapsed_time) +{ + position.y -= 120 * elapsed_time; + + if(timer.check()) + remove_me(); +} + +void +SmokeCloud::draw(DrawingContext& context) +{ + img_smoke_cloud->draw(context, position, LAYER_OBJECTS+1); +} + +Particles::Particles(const Vector& epicenter, int min_angle, int max_angle, + const Vector& initial_velocity, const Vector& acceleration, int number, + Color color_, int size_, float life_time, int drawing_layer_) + : accel(acceleration), color(color_), size(size_), drawing_layer(drawing_layer_) +{ + if(life_time == 0) { + live_forever = true; + } else { + live_forever = false; + timer.start(life_time); } - for (int i = 0; i < FLYING_PLATFORM_FRAMES; i++) - { - sprintf(sprite_name, "flying_platform-%i", i+1); - img_flying_platform[i] = sprite_manager->load(sprite_name); + // create particles + for(int p = 0; p < number; p++) + { + Particle* particle = new Particle; + particle->pos = epicenter; + + float angle = ((rand() % (max_angle-min_angle))+min_angle) + * (M_PI / 180); // convert to radius + particle->vel.x = /*fabs*/(sin(angle)) * initial_velocity.x; +// if(angle >= M_PI && angle < M_PI*2) +// particle->vel.x *= -1; // work around to fix signal + particle->vel.y = /*fabs*/(cos(angle)) * initial_velocity.y; +// if(angle >= M_PI_2 && angle < 3*M_PI_2) +// particle->vel.y *= -1; + + particles.push_back(particle); + } +} + +Particles::~Particles() +{ + // free particles + for(std::vector::iterator i = particles.begin(); + i < particles.end(); i++) + delete (*i); +} + +void +Particles::action(float elapsed_time) +{ + Vector camera = Sector::current()->camera->get_translation(); + + // update particles + for(std::vector::iterator i = particles.begin(); + i != particles.end(); ) { + (*i)->pos.x += (*i)->vel.x * elapsed_time; + (*i)->pos.y += (*i)->vel.y * elapsed_time; + + (*i)->vel.x += accel.x * elapsed_time; + (*i)->vel.y += accel.y * elapsed_time; + + if((*i)->pos.x < camera.x || (*i)->pos.x > screen->w + camera.x || + (*i)->pos.y < camera.y || (*i)->pos.y > screen->h + camera.y) { + delete (*i); + i = particles.erase(i); + } else { + ++i; + } + } + + if((timer.check() && !live_forever) || particles.size() == 0) + remove_me(); +} + +void +Particles::draw(DrawingContext& context) +{ + // draw particles + for(std::vector::iterator i = particles.begin(); + i != particles.end(); i++) { + context.draw_filled_rect((*i)->pos, Vector(size,size), color,drawing_layer); } } + +void load_object_gfx() +{ +#if 0 + img_trampoline = sprite_manager->load("trampoline"); + img_trampoline->start_animation(0); + img_flying_platform = sprite_manager->load("flying_platform"); +#endif + img_smoke_cloud = sprite_manager->create("stomp"); +} + +void free_object_gfx() +{ + delete img_smoke_cloud; +} +