(action
(name "default")
(images "lightcone.png")
+ (hitbox 430 93 0 0)
)
)
(action
(name "default")
(images "spotlight_base.png")
+ (hitbox 32 32 0 0)
)
)
(action
(name "default")
(images "spotlight_center.png")
+ (hitbox 32 32 0 0)
)
)
(action
(name "default")
(images "spotlight_lights.png")
+ (hitbox 32 32 0 0)
)
)
(reset-points
)
(objects
- (light )
- (mriceblock (x 666) (y 68) (stay-on-platform #f))
- (mriceblock (x 892) (y 70) (stay-on-platform #f))
- (mriceblock (x 1146) (y 69) (stay-on-platform #f))
- (mriceblock (x 1363) (y 58) (stay-on-platform #f))
- (mriceblock (x 1180) (y 15) (stay-on-platform #f))
- (mriceblock (x 939) (y 22) (stay-on-platform #f))
- (mriceblock (x 703) (y 25) (stay-on-platform #f))
- (stalactite (x 322) (y 288) (stay-on-platform #f))
+ (spotlight )
)
)
base = sprite_manager->create("images/objects/spotlight/spotlight_base.sprite");
lights = sprite_manager->create("images/objects/spotlight/spotlight_lights.sprite");
lightcone = sprite_manager->create("images/objects/spotlight/lightcone.sprite");
+
+ angle = 0.0f;
}
Spotlight::~Spotlight()
}
void
-Spotlight::update(float )
+Spotlight::update(float delta)
{
- // FIXME: add rotation code
+ angle += delta * 50.0f;
}
void
Spotlight::draw(DrawingContext& context)
{
- context.push_target();
+ context.push_target();
context.set_target(DrawingContext::LIGHTMAP);
Vector pos(100, 300);
+
+ lightcone->set_angle(angle);
lightcone->draw(context, pos, 0);
- // rotate this one 180 degree
+
+ lightcone->set_angle(angle + 180.0f);
lightcone->draw(context, pos, 0);
context.set_target(DrawingContext::NORMAL);
+
+ lights->set_angle(angle);
+ lights->draw(context, pos, 0);
+
+ base->set_angle(angle);
base->draw(context, pos, 0);
+
center->draw(context, pos, 0);
context.pop_target();
void draw(DrawingContext& context);
private:
+ float angle;
Sprite* center;
Sprite* base;
Sprite* lights;
#include <cassert>
#include <stdexcept>
+
+#include "video/surface.hpp"
#include "sprite.hpp"
#include "video/drawing_context.hpp"
#include "log.hpp"
#include "timer.hpp"
Sprite::Sprite(SpriteData& newdata)
- : data(newdata), frame(0), animation_loops(-1)
+ : data(newdata), frame(0), animation_loops(-1), angle(0.0f)
{
action = data.get_action("normal");
if(!action)
log_warning << "frame out of range: " << (int)frame << "/" << get_frames() << " at " << get_name() << "/" << get_action() << std::endl;
else
context.draw_surface(action->surfaces[(int)frame],
- pos - Vector(action->x_offset, action->y_offset),
- layer + action->z_order);
+ pos - Vector(action->x_offset, action->y_offset),
+ angle,
+ layer + action->z_order);
}
void
action->fps = new_fps;
}
+void
+Sprite::set_angle(float a)
+{
+ angle = a;
+}
+
+float
+Sprite::get_angle() const
+{
+ return angle;
+}
+/* EOF */
#include <assert.h>
#include <SDL.h>
-#include "video/surface.hpp"
#include "math/vector.hpp"
#include "math/rect.hpp"
#include "sprite_data.hpp"
+class Surface;
class DrawingContext;
class Sprite
/** return current action's hitbox, relative to 0,0 */
Rect get_current_hitbox() const;
+ /** Set the angle of the sprite rotation in degree */
+ void set_angle(float angle);
+
+ /** Get the angle of the sprite rotation in degree */
+ float get_angle() const;
+
/** Get current frame */
int get_frame() const
{ return (int)frame; }
SpriteData& data;
float frame;
- int animation_loops;
+ int animation_loops;
float last_ticks;
-
+ float angle;
+
SpriteData::Action* action;
};
}
void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position,
+DrawingContext::draw_surface(const Surface* surface, const Vector& position, float angle,
int layer)
{
assert(surface != 0);
request.layer = layer;
request.drawing_effect = transform.drawing_effect;
request.alpha = transform.alpha;
+ request.angle = angle;
request.request_data = const_cast<Surface*> (surface);
requests->push_back(request);
}
void
+DrawingContext::draw_surface(const Surface* surface, const Vector& position,
+ int layer)
+{
+ draw_surface(surface, position, 0.0f, layer);
+}
+
+void
DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
const Vector& size, const Vector& dest, int layer)
{
glLoadIdentity();
// FIXME: Add ambient light support here
- glClearColor(0, 0, 0, 1);
+ glClearColor(0.5, 0.5, 0.5, 1);
glClear(GL_COLOR_BUFFER_BIT);
handle_drawing_requests(lightmap_requests);
lightmap_requests.clear();
case SURFACE:
{
const Surface* surface = (const Surface*) i->request_data;
- surface->draw(i->pos.x, i->pos.y, i->alpha, i->drawing_effect);
+ if (i->angle == 0.0f)
+ surface->draw(i->pos.x, i->pos.y, i->alpha, i->drawing_effect);
+ else
+ surface->draw(i->pos.x, i->pos.y, i->alpha, i->angle, i->drawing_effect);
break;
}
case SURFACE_PART:
public:
DrawingContext();
~DrawingContext();
-
+
+ /// Adds a drawing request for a surface into the request list.
+ void draw_surface(const Surface* surface, const Vector& position,
+ int layer);
/// Adds a drawing request for a surface into the request list.
- void draw_surface(const Surface* surface, const Vector& position,
+ void draw_surface(const Surface* surface, const Vector& position, float angle,
int layer);
/// Adds a drawing request for part of a surface.
void draw_surface_part(const Surface* surface, const Vector& source,
DrawingEffect drawing_effect;
float alpha;
Blend blend;
+ float angle;
void* request_data;
+
+ DrawingRequest()
+ : angle(0.0f)
+ {}
bool operator<(const DrawingRequest& other) const
{
glEnd();
}
+static inline void intern_draw2(float left, float top, float right, float bottom,
+ float uv_left, float uv_top,
+ float uv_right, float uv_bottom,
+ float angle,
+ DrawingEffect effect)
+{
+ if(effect & HORIZONTAL_FLIP)
+ std::swap(uv_left, uv_right);
+ if(effect & VERTICAL_FLIP) {
+ std::swap(uv_top, uv_bottom);
+ }
+
+ float center_x = (left + right) / 2;
+ float center_y = (top + bottom) / 2;
+
+ float sa = sinf(angle/180.0f*M_PI);
+ float ca = cosf(angle/180.0f*M_PI);
+
+ left -= center_x;
+ right -= center_x;
+
+ top -= center_y;
+ bottom -= center_y;
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(uv_left, uv_top);
+ glVertex2f(left*ca - top*sa + center_x,
+ left*sa + top*ca + center_y);
+
+ glTexCoord2f(uv_right, uv_top);
+ glVertex2f(right*ca - top*sa + center_x,
+ right*sa + top*ca + center_y);
+
+ glTexCoord2f(uv_right, uv_bottom);
+ glVertex2f(right*ca - bottom*sa + center_x,
+ right*sa + bottom*ca + center_y);
+
+ glTexCoord2f(uv_left, uv_bottom);
+ glVertex2f(left*ca - bottom*sa + center_x,
+ left*sa + bottom*ca + center_y);
+ glEnd();
+}
+
+void
+Surface::draw(float x, float y, float alpha, float angle, DrawingEffect effect) const
+{
+ glColor4f(1.0f, 1.0f, 1.0f, alpha);
+ glBindTexture(GL_TEXTURE_2D, texture->get_handle());
+
+ intern_draw2(x, y,
+ x + width, y + height,
+ uv_left, uv_top, uv_right, uv_bottom,
+ angle,
+ effect);
+}
+
void
Surface::draw(float x, float y, float alpha, DrawingEffect effect) const
{
float uv_right;
float uv_bottom;
+ void draw(float x, float y, float alpha, float angle, DrawingEffect effect) const;
void draw(float x, float y, float alpha, DrawingEffect effect) const;
void draw_part(float src_x, float src_y, float dst_x, float dst_y,
float width, float height,