Esempio n. 1
0
frame::frame(variant node)
   : id_(node["id"].as_string()),
     image_(node["image"].as_string()),
     variant_id_(id_),
     enter_event_id_(get_object_event_id("enter_" + id_ + "_anim")),
	 end_event_id_(get_object_event_id("end_" + id_ + "_anim")),
	 leave_event_id_(get_object_event_id("leave_" + id_ + "_anim")),
	 process_event_id_(get_object_event_id("process_" + id_)),
     texture_(node.has_key("fbo") ? node["fbo"].convert_to<texture_object>()->texture() : graphics::texture::get(image_, node["image_formula"].as_string_default())),
	 solid_(solid_info::create(node)),
     collide_rect_(node.has_key("collide") ? rect(node["collide"]) :
	               rect(node["collide_x"].as_int(),
                        node["collide_y"].as_int(),
                        node["collide_w"].as_int(),
                        node["collide_h"].as_int())),
	 hit_rect_(node.has_key("hit") ? rect(node["hit"]) :
	               rect(node["hit_x"].as_int(),
				        node["hit_y"].as_int(),
				        node["hit_w"].as_int(),
				        node["hit_h"].as_int())),
	 platform_rect_(node.has_key("platform") ? rect(node["platform"]) :
	                rect(node["platform_x"].as_int(),
	                     node["platform_y"].as_int(),
	                     node["platform_w"].as_int(), 1)),
	 img_rect_(node.has_key("rect") ? rect(node["rect"]) :
	           rect(node["x"].as_int(),
	                node["y"].as_int(),
	                node["w"].as_int(),
	                node["h"].as_int())),
	 feet_x_(node["feet_x"].as_int()),
	 feet_y_(node["feet_y"].as_int()),
	 accel_x_(node["accel_x"].as_int(INT_MIN)),
	 accel_y_(node["accel_y"].as_int(INT_MIN)),
	 velocity_x_(node["velocity_x"].as_int(INT_MIN)),
	 velocity_y_(node["velocity_y"].as_int(INT_MIN)),
	 nframes_(node["frames"].as_int(1)),
	 nframes_per_row_(node["frames_per_row"].as_int(-1)),
	 frame_time_(node["duration"].as_int(-1)),
	 reverse_frame_(node["reverse"].as_bool()),
	 play_backwards_(node["play_backwards"].as_bool()),
	 scale_(node["scale"].as_int(2)),
	 pad_(node["pad"].as_int()),
	 rotate_(node["rotate"].as_int()),
	 blur_(node["blur"].as_int()),
	 rotate_on_slope_(node["rotate_on_slope"].as_bool()),
	 damage_(node["damage"].as_int()),
	 sounds_(util::split(node["sound"].as_string_default())),
	 no_remove_alpha_borders_(node["no_remove_alpha_borders"].as_bool(false)),
	 collision_areas_inside_frame_(true),
	 current_palette_(-1)
{
	std::vector<std::string> hit_frames = util::split(node["hit_frames"].as_string_default());
	foreach(const std::string& f, hit_frames) {
		hit_frames_.push_back(boost::lexical_cast<int>(f));
	}
Esempio n. 2
0
frame::frame(wml::const_node_ptr node)
   : id_(node->attr("id")),
     image_(node->attr("image")),
     variant_id_(id_),
     enter_event_id_(get_object_event_id("enter_" + id_ + "_anim")),
	 end_event_id_(get_object_event_id("end_" + id_ + "_anim")),
	 leave_event_id_(get_object_event_id("leave_" + id_ + "_anim")),
	 process_event_id_(get_object_event_id("process_" + id_)),
     texture_(graphics::texture::get(image_, node->attr("image_formula"))),
	 solid_(solid_info::create(node)),
     collide_rect_(node->has_attr("collide") ? rect(node->attr("collide")) :
	               rect(wml::get_int(node, "collide_x"),
                        wml::get_int(node, "collide_y"),
                        wml::get_int(node, "collide_w"),
                        wml::get_int(node, "collide_h"))),
	 hit_rect_(node->has_attr("hit") ? rect(node->attr("hit")) :
	               rect(wml::get_int(node, "hit_x"),
				        wml::get_int(node, "hit_y"),
				        wml::get_int(node, "hit_w"),
				        wml::get_int(node, "hit_h"))),
	 platform_rect_(node->has_attr("platform") ? rect(node->attr("platform")) :
	                rect(wml::get_int(node, "platform_x"),
	                     wml::get_int(node, "platform_y"),
	                     wml::get_int(node, "platform_w"), 1)),
	 img_rect_(node->has_attr("rect") ? rect(node->attr("rect")) :
	           rect(wml::get_int(node, "x"),
	                wml::get_int(node, "y"),
	                wml::get_int(node, "w"),
	                wml::get_int(node, "h"))),
	 feet_x_(wml::get_int(node, "feet_x")),
	 feet_y_(wml::get_int(node, "feet_y")),
	 accel_x_(wml::get_int(node, "accel_x", INT_MIN)),
	 accel_y_(wml::get_int(node, "accel_y", INT_MIN)),
	 velocity_x_(wml::get_int(node, "velocity_x", INT_MIN)),
	 velocity_y_(wml::get_int(node, "velocity_y", INT_MIN)),
	 nframes_(wml::get_int(node, "frames", 1)),
	 nframes_per_row_(wml::get_int(node, "frames_per_row", -1)),
	 frame_time_(wml::get_int(node, "duration", -1)),
	 reverse_frame_(wml::get_bool(node, "reverse")),
	 play_backwards_(wml::get_bool(node, "play_backwards")),
	 scale_(wml::get_int(node, "scale", 2)),
	 pad_(wml::get_int(node, "pad")),
	 rotate_(wml::get_int(node, "rotate")),
	 blur_(wml::get_int(node, "blur")),
	 rotate_on_slope_(wml::get_bool(node, "rotate_on_slope")),
	 damage_(wml::get_int(node, "damage")),
	 sounds_(util::split(node->attr("sound"))),
	 no_remove_alpha_borders_(wml::get_bool(node, "no_remove_alpha_borders", false)),
	 current_palette_(-1)
{
	std::vector<std::string> hit_frames = util::split((*node)["hit_frames"]);
	foreach(const std::string& f, hit_frames) {
		hit_frames_.push_back(boost::lexical_cast<int>(f));
	}
Esempio n. 3
0
void level_runner::video_resize_event(const SDL_Event &event)
{
    const SDL_ResizeEvent* resize = reinterpret_cast<const SDL_ResizeEvent*>(&event);
    int width = resize->w;
    int height = resize->h;

	static const int WindowResizeEventID = get_object_event_id("window_resize");
	game_logic::map_formula_callable_ptr callable(new game_logic::map_formula_callable);
	callable->add("width", variant(width));
	callable->add("height", variant(height));
	lvl_->player()->get_entity().handle_event(WindowResizeEventID, callable.get());
}
Esempio n. 4
0
bool level_runner::handle_mouse_events(const SDL_Event &event)
{
	static const int MouseDownEventID = get_object_event_id("mouse_down");
	static const int MouseUpEventID = get_object_event_id("mouse_up");
	static const int MouseMoveEventID = get_object_event_id("mouse_move");
	static const int MouseDownEventAllID = get_object_event_id("mouse_down*");
	static const int MouseUpEventAllID = get_object_event_id("mouse_up*");
	static const int MouseMoveEventAllID = get_object_event_id("mouse_move*");


	static const int MouseEnterID = get_object_event_id("mouse_enter");
	static const int MouseLeaveID = get_object_event_id("mouse_leave");

	static const int MouseClickID = get_object_event_id("click");
	//static const int MouseDblClickID = get_object_event_id("dblclick");
	static const int MouseDragID = get_object_event_id("drag");
	static const int MouseDragStartID = get_object_event_id("drag_start");
	static const int MouseDragEndID = get_object_event_id("drag_end");

	if(paused) {
		// skip mouse event handling when paused.
		// XXX: when we become unpaused we need to reset the state of drag operations
		// and partial clicks.
		return false;
	}

	switch(event.type)
	{
#if defined(__ANDROID__)
		case SDL_JOYBUTTONDOWN:
		case SDL_JOYBUTTONUP:
		case SDL_JOYBALLMOTION:
			int x, mx = event.type == SDL_JOYBALLMOTION ? event.jball.xrel : event.jbutton.x;
			int y, my = event.type == SDL_JOYBALLMOTION ? event.jball.yrel : event.jbutton.y;
			int i = event.type == SDL_JOYBALLMOTION ? event.jball.ball : event.jbutton.button;
			int event_button_button = event.jbutton.button;
			int event_type = event.type == SDL_JOYBALLMOTION 
				? SDL_MOUSEMOTION
				: event.type == SDL_JOYBUTTONDOWN ? SDL_MOUSEBUTTONDOWN : SDL_MOUSEBUTTONUP;
#else
		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
		case SDL_MOUSEMOTION:
		    int x, mx = event.type == SDL_MOUSEMOTION ? event.motion.x : event.button.x;
			int y, my = event.type == SDL_MOUSEMOTION ? event.motion.y : event.button.y;
			int i = event.type == SDL_MOUSEMOTION ? event.motion.which : event.button.which;
			int event_type = event.type;
			int event_button_button = event.button.button;
#endif
			const int basic_evt = event_type == SDL_MOUSEBUTTONDOWN 
				? MouseDownEventID 
				: event_type == SDL_MOUSEMOTION
					? MouseMoveEventID : MouseUpEventID;
			const int catch_all_event = event_type == SDL_MOUSEBUTTONDOWN 
				? MouseDownEventAllID 
				: event_type == SDL_MOUSEMOTION
					? MouseMoveEventAllID : MouseUpEventAllID;
			Uint8 button_state = SDL_GetMouseState(0,0);
			if(!lvl_->gui_event(event)) {
				x = (mx*graphics::screen_width())/preferences::virtual_screen_width() + last_draw_position().x/100;
				y = (my*graphics::screen_height())/preferences::virtual_screen_height() + last_draw_position().y/100;
				game_logic::map_formula_callable_ptr callable(new game_logic::map_formula_callable);
				callable->add("mouse_x", variant(x));
				callable->add("mouse_y", variant(y));
				callable->add("mouse_index", variant(i));
				if(event_type != SDL_MOUSEMOTION) {
					callable->add("mouse_button", variant(event_button_button));
				} else {
					callable->add("mouse_button", variant(button_state));
				}
				std::vector<variant> items;
				// Grab characters around point, z-order sort them, so that when
				// we process them we go from highest to lowest, allowing a higher
				// object to swallow an event before the lower ones get it.
				std::vector<entity_ptr> cs = lvl_->get_characters_at_point(x, y, last_draw_position().x/100, last_draw_position().y/100);
				std::sort(cs.begin(), cs.end(), zorder_compare);
				std::vector<entity_ptr>::iterator it;
				bool handled = false;
				bool click_handled = false;
				std::set<entity_ptr> mouse_in;
				for(it = cs.begin(); it != cs.end(); ++it) {
					rect clip_area;
					// n.b. clip_area is in level coordinates, not relative to the object.
					if((*it)->get_clip_area(&clip_area)) {
						point p(x,y);
						if((*it)->use_absolute_screen_coordinates()) {
							p = point(mx,my);
						}
						if(point_in_rect(p, clip_area) == false) {
							continue;
						}
					}

					if(event_type == SDL_MOUSEBUTTONDOWN) {
						(*it)->set_mouse_buttons((*it)->get_mouse_buttons() | SDL_BUTTON(event_button_button));
					} else if(event_type == SDL_MOUSEMOTION) {
						// handling for mouse_enter
						if((*it)->is_mouse_over_entity() == false) {
							(*it)->handle_event(MouseEnterID, callable.get());
							(*it)->set_mouse_over_entity();
						}
						mouse_in.insert(*it);
					}

					handled |= (*it)->handle_event(basic_evt, callable.get());
					// XXX: fix this for dragging(with multiple mice)
					if(event_type == SDL_MOUSEBUTTONUP && !click_handled && (*it)->is_being_dragged() == false) {
						(*it)->handle_event(MouseClickID, callable.get());
						if((*it)->mouse_event_swallowed()) {
							click_handled = true;
						}
					}
					items.push_back(variant((*it).get()));
				}
				// Handling for "catch all" mouse events.
				callable->add("handled", variant(handled));
				variant obj_ary(&items);
				callable->add("objects_under_mouse", obj_ary);
				std::vector<entity_ptr> level_chars(level::current().get_chars());
				foreach(entity_ptr object, level_chars) {
					if(object) {
						object->handle_event(catch_all_event, callable.get());

						// drag handling
						if(event_type == SDL_MOUSEBUTTONUP) {
							object->set_mouse_buttons(object->get_mouse_buttons() & ~SDL_BUTTON(event_button_button));
							if(object->get_mouse_buttons() == 0 && object->is_being_dragged()) {
								object->handle_event(MouseDragEndID, callable.get());
								object->set_being_dragged(false);
							}
						} else if(event_type == SDL_MOUSEMOTION) {
							// drag check.
							if(object->is_being_dragged()) {
								if(object->get_mouse_buttons() & button_state) {
									object->handle_event(MouseDragID, callable.get());
								} else {
									object->handle_event(MouseDragEndID, callable.get());
									object->set_being_dragged(false);
								}
							} else if(object->get_mouse_buttons() & button_state) {
								// start drag.
								object->handle_event(MouseDragStartID, callable.get());
								object->set_being_dragged();
							}
						}
					}
				}

				if(event_type == SDL_MOUSEMOTION) {
					// handling for mouse_leave
					level_chars = level::current().get_chars();
					foreach(const entity_ptr& e, level_chars) {
						if(e) {
							// n.b. clip_area is in level coordinates, not relative to the object.
							rect clip_area;
							bool has_clip_area = e->get_clip_area(&clip_area);
							point p(x,y);
							if(e->use_absolute_screen_coordinates()) {
								p = point(mx,my);
							}

							if(mouse_in.find(e) == mouse_in.end() 
								&& ((has_clip_area == false && e->is_mouse_over_entity())
								|| (e->is_mouse_over_entity() && has_clip_area && point_in_rect(p, clip_area) == false))) {
								e->handle_event(MouseLeaveID, callable.get());
								e->set_mouse_over_entity(false);
							}
						}
					}
				}
			}