Moving up is still done using a linear speed because it felt better.
SVN-Revision: 6403
(images "iceblock.png"
)
)
(images "iceblock.png"
)
)
+ (action
+ (name "crushing")
+ (hitbox 11 8 64 64)
+ (images "iceblock.png"
+ )
+ )
+ (action
+ (name "recovering")
+ (hitbox 11 8 64 64)
+ (images "iceblock.png"
+ )
+ )
// IceCrusher - A block to stand on, which can drop down to crush the player
// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
// IceCrusher - A block to stand on, which can drop down to crush the player
// Copyright (C) 2008 Christoph Sommer <christoph.sommer@2008.expires.deltadevelopment.de>
+// Copyright (C) 2010 Florian Forster <supertux at octo.it>
//
// 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
//
// 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
#include "supertux/sector.hpp"
namespace {
#include "supertux/sector.hpp"
namespace {
-const float DROP_SPEED = 500;
-const float RECOVER_SPEED = 200;
+/* Maximum movement speed in pixels per LOGICAL_FPS */
+const float MAX_DROP_SPEED = 10.0;
+const float RECOVER_SPEED = -3.125;
+const float ACTIVATION_DISTANCE = 4.0;
}
IceCrusher::IceCrusher(const Reader& reader) :
MovingSprite(reader, "images/creatures/icecrusher/icecrusher.sprite", LAYER_OBJECTS, COLGROUP_STATIC),
state(IDLE),
start_position(),
}
IceCrusher::IceCrusher(const Reader& reader) :
MovingSprite(reader, "images/creatures/icecrusher/icecrusher.sprite", LAYER_OBJECTS, COLGROUP_STATIC),
state(IDLE),
start_position(),
{
start_position = get_bbox().p1;
set_state(state, true);
{
start_position = get_bbox().p1;
set_state(state, true);
switch(state) {
case IDLE:
set_group(COLGROUP_STATIC);
switch(state) {
case IDLE:
set_group(COLGROUP_STATIC);
+ physic.enable_gravity (false);
sprite->set_action("idle");
break;
case CRUSHING:
set_group(COLGROUP_MOVING_STATIC);
sprite->set_action("idle");
break;
case CRUSHING:
set_group(COLGROUP_MOVING_STATIC);
- speed=Vector(0, DROP_SPEED);
- sprite->set_action("idle");
+ physic.reset ();
+ physic.enable_gravity (true);
+ sprite->set_action("crushing");
break;
case RECOVERING:
set_group(COLGROUP_MOVING_STATIC);
break;
case RECOVERING:
set_group(COLGROUP_MOVING_STATIC);
- speed=Vector(0, -RECOVER_SPEED);
- sprite->set_action("idle");
+ physic.enable_gravity (false);
+ sprite->set_action("recovering");
break;
default:
log_debug << "IceCrusher in invalid state" << std::endl;
break;
default:
log_debug << "IceCrusher in invalid state" << std::endl;
IceCrusher::collision(GameObject& other, const CollisionHit& hit)
{
Player* player = dynamic_cast<Player*>(&other);
IceCrusher::collision(GameObject& other, const CollisionHit& hit)
{
Player* player = dynamic_cast<Player*>(&other);
+
+ /* If the other object is the player, and the collision is at the bottom of
+ * the ice crusher, hurt the player. */
if (player && hit.bottom) {
if(player->is_invincible()) {
if (player && hit.bottom) {
if(player->is_invincible()) {
- if (state == CRUSHING) set_state(RECOVERING);
+ if (state == CRUSHING)
+ set_state(RECOVERING);
return ABORT_MOVE;
}
player->kill(false);
return ABORT_MOVE;
}
player->kill(false);
- if (state == CRUSHING) set_state(RECOVERING);
+ if (state == CRUSHING)
+ set_state(RECOVERING);
return FORCE_MOVE;
}
BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
return FORCE_MOVE;
}
BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
-IceCrusher::collision_solid(const CollisionHit& )
+IceCrusher::collision_solid(const CollisionHit& hit)
{
switch(state) {
case IDLE:
break;
case CRUSHING:
{
switch(state) {
case IDLE:
break;
case CRUSHING:
+ if (hit.bottom) {
+ set_state(RECOVERING);
+ }
break;
case RECOVERING:
break;
break;
case RECOVERING:
break;
{
switch(state) {
case IDLE:
{
switch(state) {
case IDLE:
- if (found_victim()) set_state(CRUSHING);
+ movement = Vector (0, 0);
+ if (found_victim())
+ set_state(CRUSHING);
+ movement = physic.get_movement (elapsed_time);
+ if (movement.y > MAX_DROP_SPEED)
+ movement.y = MAX_DROP_SPEED;
break;
case RECOVERING:
if (get_bbox().p1.y <= start_position.y+1) {
set_pos(start_position);
break;
case RECOVERING:
if (get_bbox().p1.y <= start_position.y+1) {
set_pos(start_position);
+ movement = Vector (0, 0);
+ else {
+ movement = Vector (0, RECOVER_SPEED);
+ }
break;
default:
log_debug << "IceCrusher in invalid state" << std::endl;
break;
}
break;
default:
log_debug << "IceCrusher in invalid state" << std::endl;
break;
}
- movement = speed * elapsed_time;
Player* player = this->get_nearest_player();
if (!player) return false;
Player* player = this->get_nearest_player();
if (!player) return false;
- const Rectf& pr = player->get_bbox();
- const Rectf& br = get_bbox();
- if ((pr.p2.x > br.p1.x) && (pr.p1.x < br.p2.x) && (pr.p1.y >= br.p2.y)) {
+ const Rectf& player_bbox = player->get_bbox();
+ const Rectf& crusher_bbox = get_bbox();
+ if ((player_bbox.p1.y >= crusher_bbox.p2.y) /* player is below crusher */
+ && (player_bbox.p2.x > (crusher_bbox.p1.x - ACTIVATION_DISTANCE))
+ && (player_bbox.p1.x < (crusher_bbox.p2.x + ACTIVATION_DISTANCE)))
#define HEADER_SUPERTUX_OBJECT_ICECRUSHER_HPP
#include "object/moving_sprite.hpp"
#define HEADER_SUPERTUX_OBJECT_ICECRUSHER_HPP
#include "object/moving_sprite.hpp"
+#include "supertux/physic.hpp"
virtual void collision_solid(const CollisionHit& hit);
virtual void update(float elapsed_time);
virtual void collision_solid(const CollisionHit& hit);
virtual void update(float elapsed_time);
const Vector& get_speed() const
{
return speed;
}
const Vector& get_speed() const
{
return speed;
}
protected:
enum IceCrusherState {
protected:
enum IceCrusherState {
};
IceCrusherState state;
Vector start_position;
};
IceCrusherState state;
Vector start_position;
Player* get_nearest_player();
bool found_victim();
Player* get_nearest_player();
bool found_victim();