예제 #1
0
void world::update(Uint32 time) 
{
	detect_collisions();
	p1->update(time);
	p2->update(time);
	m_ball->update(time);
}
예제 #2
0
파일: csnow.c 프로젝트: Saruta/ToyOS
void update_flakes(screen_t * screen, flake_t * flakes) {
	for (int i = 0; flakes[i].display; ++i) {
		if (flakes[i].gravity) {
			flakes[i].x += flakes[i].speed;
			if (flakes[i].x < 0) {
				flakes[i].x = screen->width - 1;
			} else if (flakes[i].x >= screen->width) {
				flakes[i].x = 0;
			}
			if (!detect_collisions(screen, flakes, i)) {
				flakes[i].y += flakes[i].gravity;
			}
		}
	}
}
예제 #3
0
파일: Game.cpp 프로젝트: hdt80/SSS
    void Game::update(float delta) {
        _player->tick(delta);
        _asteroidField->tick(delta);
        detect_collisions();

        sss_event e;
        while(sss_poll_event(&e))
            EventHandler::handle_event(e);

        _camera.setPosition(_player->getPosition());
        _camera.setRotation(_player->getRotation());

        _shader->setUniformMat4("perspective", _camera.getModelView());

        for(size_t i = 0; i < _children.size(); i++) {
            if(_children[i]->isPendingKill()) {
                delete _children[i];
                _children[i] = nullptr;
            } else {
                _children[i]->tick();
            }
        }

        for(size_t i = 0; i < _missiles.size(); i++) {
            if(_missiles[i]->isPendingKill()) {
                delete _missiles[i];
                _missiles[i] = nullptr;
            } else {
                _missiles[i]->tick();
            }
        }

        /* both these iterators go through and free the memory of 
         * missiles, asteroids, and enemies no longer in use 
         */
        auto iter(std::remove_if(_children.begin(), _children.end(), [](Actor* a) -> bool { return a == nullptr; }));
        _children.erase(iter, _children.end());
        _children.shrink_to_fit();

        auto iter2(std::remove_if(_missiles.begin(), _missiles.end(), [](Missile* m) -> bool {return m == nullptr; }));
        _missiles.erase(iter2, _missiles.end());
        _missiles.shrink_to_fit();
    
        /* Do Mark Stuff */
        if(Input::isKeyPressed(GLFW_KEY_T))
            Connection::getInstance().write("EVN#8;0;");
    }
예제 #4
0
void Physics::step( real_t dt )
{
    // step the world forward by dt. Need to detect collisions, apply
    // forces, and integrate positions and orientations.
    //
    // Note: put RK4 here, not in any of the physics bodies
    //
    // Must use the functions that you implemented
    //
    // Note, when you change the position/orientation of a physics object,
    // change the position/orientation of the graphical object that represents
    // it
      
    detect_collisions();
    save_initial_states();
    //save initial state after changing it in collisions
    RK4(dt);
    update_graphics();

}
예제 #5
0
static void evolve_shared_collision_detection(struct sys s, DOUBLE dt, void (*dkd_func)(int, struct sys, DOUBLE, DOUBLE, DOUBLE)) {
    FLOAT dtsys;
    int next_level, current_level = 0;
    DOUBLE etime, stime;
    DOUBLE *dt_levels = (DOUBLE*) malloc (MAXLEVEL * sizeof(DOUBLE));
    int *step_at_level = (int*) calloc (MAXLEVEL, sizeof(int));
    int is_collision_detection_enabled;
    
    if (dt == 0.0L) {
        ENDRUN("timestep too small: dt=%Le\n", (long double) dt);
    }
    is_stopping_condition_enabled(COLLISION_DETECTION, &is_collision_detection_enabled);
    set_dt_levels(dt_levels, dt);
    do {
        timestep(current_level, s, s, SIGN(dt));
        dtsys = global_timestep(s);
        while (dtsys < fabs(dt_levels[current_level])) {
            current_level++;
            if (current_level >= MAXLEVEL) {
                stime = time_from_steps(step_at_level, dt_levels);
                ENDRUN("timestep too small: stime=%Le dt=%Le clevel=%u\n", 
                    (long double) stime, (long double) dt_levels[current_level], current_level);
            }
        }
        diag->deepsteps++;
        diag->simtime+=dt_levels[current_level];
        stime = time_from_steps(step_at_level, dt_levels);
        next_level = update_steps_and_get_next_level(step_at_level, current_level);
        etime = time_from_steps(step_at_level, dt_levels);
        dkd_func(current_level, s, stime, etime, dt_levels[current_level]);
        if (is_collision_detection_enabled) {
            detect_collisions(s);
            if (set_conditions & enabled_conditions) break;
        }
        current_level = next_level;
    } while (current_level > 0);
    free(dt_levels);
    free(step_at_level);
}
예제 #6
0
void act(gamedata &g, int jx, int jy, bool jb){

  // Reset hidden/afterburner status
  g.p().hide = false;
  g.p().boost = false;
  g.p().gunthreat = 0;

  switch(g.p().state){
    case 0: // OK planes

      switch(g.p().land){
        case 0: // Stationary on runway
          // Check for mission 0 and mission 1 wins
          if (((g.mission == 0) || (g.mission == 1)) && (!g.p().drak) &&
              (g.p().score >= g.targetscore)){
            g.winner = g.p().side;
          }
          // Start Engine
          if (jy == -1){
            g.p().s = 0.3*GAME_SPEED*GAME_SPEED;
            g.p().land = 1;
            if ((g.p().control) > 0){
              g.sound.volume(g.p().control-1, 0.0);
              g.sound.loop(g.p().control-1, g.p().enginesample);
            }
          }
          break;

        case 1: // Taking off plane
          if (jy == -1){
            g.p().s = dlimit(g.p().s + 0.3*GAME_SPEED*GAME_SPEED, 0.0,
                            6.0*GAME_SPEED);
          }
          // Take off plane
          if ((jx == -1) && (g.p().s > 2.0*GAME_SPEED) &&
              (g.base[g.p().side].planed == 13)){
            g.p().d++;
            g.p().rotate = g.p().maxrotate;
            g.p().land = 2;
          }
          if ((jx == 1) && (g.p().s > 2.0*GAME_SPEED) &&
              (g.base[g.p().side].planed == 5)){
            g.p().d--;
            g.p().rotate = g.p().maxrotate;
            g.p().land = 2;
          }
          // Off end of runway
          if (abs(int(g.p().x - g.base[g.p().side].planex)) >
               g.base[g.p().side].runwaylength){
            g.p().land = 2;
          }
          break;

        case 2: // flying
          // Navigate plane
          if ((g.p().rotate == 0) && (jx !=0)){
            g.p().d = wrap(g.p().d-jx,1,17);
            g.p().rotate = g.p().maxrotate;
          }else{
            if (g.p().rotate > 0){
              g.p().rotate--;
            }
          }
          // Acceleration / Afterburner Controls
          {
            double acceleration = g.accel[g.p().d] * GAME_SPEED * GAME_SPEED;
            if (g.p().burner){
              if (jy == -1){
                acceleration += 0.3*GAME_SPEED*GAME_SPEED;
                g.p().boost = true;
              }
              if ((g.p().s > 6.0*GAME_SPEED) && (jy != -1)){
                acceleration -= 0.3*GAME_SPEED*GAME_SPEED;
              }
              g.p().s = dlimit(g.p().s + acceleration, 0.0, 12.0*GAME_SPEED);
            }else{
              g.p().s = dlimit(g.p().s + acceleration, 0.0, 6.0*GAME_SPEED);
            }
          }
          // Stealth Controls
          if ((jy == -1) && (jx == 0) && (!jb) && (g.p().stealth)){
            g.p().hide = true;
          }
          // Check for shotfire
          if (g.p().shotdelay == 0){
            if ((jb) && (g.p().ammo > 0)){
              fire_shot(g.p(), g.shot, g.sound, g.xmove, g.ymove);              
            }
            // Check for bombdrop
            if ((jy == 1) && (g.p().bombs > 0)){
              drop_bomb(g.p(), g.fall, g.sound, g.bombimage);
            }
          }else{
            g.p().shotdelay--;
          }
          break;

        case 3: // Landing plane
          if ((((g.p().x - g.base[g.p().side].planex) < 2.0) &&
               (g.base[g.p().side].planed == 13)) ||
              (((g.p().x - g.base[g.p().side].planex) > -2.0) &&
               (g.base[g.p().side].planed == 5))){
            g.p().land = 0;
            g.p().x = g.base[g.p().side].planex;
            g.p().y = g.base[g.p().side].planey;
            g.p().d = g.base[g.p().side].planed;
            g.p().xs = 0;
            g.p().ys = 0;
            g.p().s = 0;
            g.p().ammo = g.p().maxammo;
            g.p().bombs = g.p().maxbombs;
            g.p().coms = 0;
            g.p().targetx = 0;
            g.p().targety = 0;
            g.p().cruiseheight = 0;
          }
          break;
      }
      // Set speed for planes
      g.p().xs = g.p().s * g.xmove[g.p().d];
      g.p().ys = g.p().s * g.ymove[g.p().d];
      // Check for stall
      if ((g.p().s < 1.0*GAME_SPEED) && (g.p().land == 2)){
        g.p().state = 1;
        if ((g.p().control) > 0){
          g.sound.stop(g.p().control-1);
          g.sound.play(SOUND_STALL);
        }
      }
      if (g.p().y < 0){
        g.p().y = 0;
        g.p().ys = 0;
        g.p().state = 1;
        if ((g.p().control) > 0){
          g.sound.stop(g.p().control-1);
          g.sound.play(SOUND_STALL);
        }
      }
      break;

    case 1: // Stalling planes
      // Navigate plane
      if ((g.p().rotate == 0) && (jx !=0)){
        g.p().d = wrap(g.p().d-jx,1,17);
        g.p().rotate = g.p().maxrotate;
      }else{
        if (g.p().rotate > 0){
          g.p().rotate--;
        }
      }
      // Check for shotfire
      if (g.p().shotdelay == 0){
        if ((jb) && (g.p().ammo > 0)){
          fire_shot(g.p(), g.shot, g.sound, g.xmove, g.ymove);
        }
        // Check for bombdrop
        if ((jy == 1) && (g.p().bombs > 0)){
          drop_bomb(g.p(), g.fall, g.sound, g.bombimage);
        }
      }else{
        g.p().shotdelay--;
      }
      // Gravity and drag
      g.p().ys += 0.1 * GAME_SPEED * GAME_SPEED;
      if (fabs(g.p().xs) > 0.02 * GAME_SPEED * GAME_SPEED){
        g.p().xs -= g.p().xs / fabs(g.p().xs) * 0.02 * GAME_SPEED * GAME_SPEED;
      }
      // Recover from Stall
      if ((g.p().ys > 3.0 * GAME_SPEED) && (g.p().d == 9)){
        g.p().s = dlimit(g.p().ys, 3.0*GAME_SPEED, 6.0*GAME_SPEED);
        g.p().state = 0;
        g.p().xs = g.p().s * g.xmove[g.p().d];
        g.p().ys = g.p().s * g.ymove[g.p().d];
        g.p().coms = 0;
        if ((g.p().control) > 0){
          double volume = g.p().s / (6.0*GAME_SPEED);
          g.sound.volume(g.p().control-1, volume * 0.5);
          g.sound.loop(g.p().control-1, g.p().enginesample);
        }
      }
      break;

    case 2: // Dead planes
      // Gravity and drag
      g.p().ys += 0.1 * GAME_SPEED * GAME_SPEED;
      if (fabs(g.p().xs) > 0.02 * GAME_SPEED * GAME_SPEED){
        g.p().xs -= g.p().xs/ fabs(g.p().xs) * 0.02 * GAME_SPEED * GAME_SPEED;
      }
      // Smoking plane
      g.p().crash++;
      if (g.p().crash == int(5/GAME_SPEED)){
        g.p().crash = 0;
        smoketype newsmoke;
        newsmoke.x = int(g.p().x);
        newsmoke.y = g.p().y;
        newsmoke.time = 0;
        g.smoke.add(newsmoke);
      }
      break;

    case 3: // Crashed planes
      g.p().crash++;
      if (g.p().crash == int(70/GAME_SPEED)){
        if (!g.p().drak){
          // Respawn plane to runway
          g.p().land = 0;
          g.p().state = 0;
          g.p().rotate = 0;
          g.p().crash = 0;
          g.p().x = g.base[g.p().side].planex;
          g.p().y = g.base[g.p().side].planey;
          g.p().d = g.base[g.p().side].planed;
          g.p().xs = 0;
          g.p().ys = 0;
          g.p().s = 0;
          g.p().ammo = g.p().maxammo;
          g.p().bombs = g.p().maxbombs;
          g.p().coms = 0;
          g.p().targetx = 0;
          g.p().targety = 0;
          g.p().cruiseheight = 0;
        }else{
          // Expunge drak
          g.p().state = 4;
        }
      }
      break;

    case 4: // Expunged drak fighter (NB: shouldn't get here!)
      break;
 

  }
  // Move the planes
  g.p().x += g.p().xs;
  g.p().y += g.p().ys;

  // Control Engine Volume
  if ((g.p().control) > 0){
    if ((g.p().state == 0) && (g.p().land > 0)){
      double volume = g.p().s / (6.0*GAME_SPEED);
      g.sound.volume(g.p().control-1, volume * 0.5);
      if ((g.p().boost) && (g.p().enginesample == SOUND_JET)){
        g.p().enginesample = SOUND_BURNER;
        g.sound.loop(g.p().control-1,SOUND_BURNER);
      }
      if ((!g.p().boost) && (g.p().enginesample == SOUND_BURNER)){
        g.p().enginesample = SOUND_JET;
        g.sound.loop(g.p().control-1,SOUND_JET);
      }
    }else{
      g.sound.stop(g.p().control-1);
    }
  }

  if (g.p().state < 3) detect_collisions(g);

}
gboolean working_area_button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
	// Local variables
	gint				box_height;					// Height of the bounding box
	gint				box_width;					// Width of the bounding box
	GList				*collision_list = NULL;
	guint				count_int;
	gint				finish_x;					// X position at the layer objects finish time
	gint				finish_y;					// Y position at the layer objects finish time
	GList				*layer_pointer;
	GString				*message;					// Used to construct message strings
	guint				num_collisions;
	gint				onscreen_bottom;			// Y coordinate of bounding box bottom
	gint				onscreen_left;				// X coordinate of bounding box left
	gint				onscreen_right;				// X coordinate of bounding box right
	gint				onscreen_top;				// Y coordinate of bounding box top
	gint				pixmap_height;				// Height of the front store
	gint				pixmap_width;				// Width of the front store
	gfloat				scaled_height_ratio;		// Used to calculate a vertical scaling ratio
	gfloat				scaled_width_ratio;			// Used to calculate a horizontal scaling ratio
	gint				selected_row;				// Holds the number of the row that is selected
	gint				start_x;					// X position at the layer objects start time
	gint				start_y;					// Y position at the layer objects start time
	layer 				*this_layer_data;			// Pointer to the data for the selected layer
	slide				*this_slide_data;			// Alias to make things easier
	guint				tmp_int;					// Temporary integer


	// Only do this function if we have a front store available and a project loaded
	if ((NULL == get_front_store()) || (FALSE == get_project_active()))
	{
		return TRUE;
	}

	// Set the delete key focus to be layers
	set_delete_focus(FOCUS_LAYER);

	// Change the focus of the window to be this widget
	gtk_widget_grab_focus(GTK_WIDGET(widget));

	// Initialise some things
	this_slide_data = get_current_slide_data();
	gdk_drawable_get_size(GDK_PIXMAP(get_front_store()), &pixmap_width, &pixmap_height);

	// Check for primary mouse button click
	if (1 != event->button)
	{
		// Not a primary mouse click, so return
		return TRUE;
	}

	// Reset the mouse drag toggle
	set_mouse_dragging(FALSE);

	// Check if this was a double mouse click.  If it was, open an edit dialog
	if (GDK_2BUTTON_PRESS == event->type)
	{
		// Open an edit dialog
		layer_edit();

		return TRUE;
	}

	// Check if this was a triple mouse click.  If it was, ignore it
	if (GDK_3BUTTON_PRESS == event->type)
	{
		return TRUE;
	}

	// If we're presently creating a new highlight layer, store the mouse coordinates
	if (TYPE_HIGHLIGHT == get_new_layer_selected())
	{
		// Save the mouse coordinates
		set_stored_x(event->x);
		set_stored_y(event->y);

		// Reset the invalidation area
		set_invalidation_end_x(event->x);
		set_invalidation_end_y(event->y);
		set_invalidation_start_x(event->x - 1);
		set_invalidation_start_y(event->y - 1);

		return TRUE;
	}

	// If the user has clicked on the start or end points for the selected layer, we
	// don't want to do the collision detection below that changes layers
	if (END_POINTS_INACTIVE == get_end_point_status())
	{
		// * Check if the user is clicking on the layer start or end points *

		// Calculate the height and width scaling values for the main drawing area at its present size
		scaled_height_ratio = (gfloat) get_project_height() / (gfloat) pixmap_height;
		scaled_width_ratio = (gfloat) get_project_width() / (gfloat) pixmap_width;

		// Determine which row is selected in the time line
		selected_row = time_line_get_selected_layer_num(this_slide_data->timeline_widget);
		layer_pointer = g_list_first(this_slide_data->layers);
		this_layer_data = g_list_nth_data(layer_pointer, selected_row);

		// If the layer data isn't accessible, then don't run this function
		if (NULL == this_layer_data)
		{
			return TRUE;
		}

		// Calculate start and end points
		finish_x = (this_layer_data->x_offset_finish / scaled_width_ratio) + END_POINT_HORIZONTAL_OFFSET;
		finish_y = (this_layer_data->y_offset_finish / scaled_height_ratio) + END_POINT_VERTICAL_OFFSET;
		start_x = (this_layer_data->x_offset_start / scaled_width_ratio) + END_POINT_HORIZONTAL_OFFSET;
		start_y = (this_layer_data->y_offset_start / scaled_height_ratio) + END_POINT_VERTICAL_OFFSET;

		// Is the user clicking on an end point?
		if (((event->x >= start_x)							// Start point
			&& (event->x <= start_x + END_POINT_WIDTH)
			&& (event->y >= start_y)
			&& (event->y <= start_y + END_POINT_HEIGHT)) ||
			((event->x >= finish_x)							// End point
			&& (event->x <= finish_x + END_POINT_WIDTH)
			&& (event->y >= finish_y)
			&& (event->y <= finish_y + END_POINT_HEIGHT)))
		{
			// Retrieve the layer size information
			switch (this_layer_data->object_type)
			{
				case TYPE_EMPTY:
					// We can't drag an empty layer, so reset things and return
					set_mouse_dragging(FALSE);
					set_end_point_status(END_POINTS_INACTIVE);
					set_stored_x(-1);
					set_stored_y(-1);
					return TRUE;

				case TYPE_HIGHLIGHT:
					box_width = ((layer_highlight *) this_layer_data->object_data)->width;
					box_height = ((layer_highlight *) this_layer_data->object_data)->height;
					break;

				case TYPE_GDK_PIXBUF:
					// If this is the background layer, then we ignore it
					if (TRUE == this_layer_data->background)
					{
						set_mouse_dragging(FALSE);
						set_end_point_status(END_POINTS_INACTIVE);
						set_stored_x(-1);
						set_stored_y(-1);
						return TRUE;
					}

					// No it's not, so process it
					box_width = ((layer_image *) this_layer_data->object_data)->width;
					box_height = ((layer_image *) this_layer_data->object_data)->height;
					break;

				case TYPE_MOUSE_CURSOR:
					box_width = ((layer_mouse *) this_layer_data->object_data)->width;
					box_height = ((layer_mouse *) this_layer_data->object_data)->height;
					break;

				case TYPE_TEXT:
					box_width = ((layer_text *) this_layer_data->object_data)->rendered_width;
					box_height = ((layer_text *) this_layer_data->object_data)->rendered_height;
					break;

				default:
					message = g_string_new(NULL);
					g_string_printf(message, "%s ED377: %s", _("Error"), _("Unknown layer type."));
					display_warning(message->str);
					g_string_free(message, TRUE);

					return TRUE;  // Unknown layer type, so no idea how to extract the needed data for the next code
			}

			// Work out the bounding box boundaries (scaled)
			if ((event->x >= start_x)							// Left
				&& (event->x <= start_x + END_POINT_WIDTH)		// Right
				&& (event->y >= start_y)						// Top
				&& (event->y <= start_y + END_POINT_HEIGHT))	// Bottom
			{
				// Start point clicked
				onscreen_left = this_layer_data->x_offset_start / scaled_width_ratio;
				onscreen_top = this_layer_data->y_offset_start / scaled_width_ratio;;
				onscreen_right = (this_layer_data->x_offset_start + box_width) / scaled_height_ratio;
				onscreen_bottom = (this_layer_data->y_offset_start + box_height) / scaled_height_ratio;
			} else
			{
				// End point clicked
				onscreen_left = this_layer_data->x_offset_finish / scaled_width_ratio;
				onscreen_top = this_layer_data->y_offset_finish / scaled_width_ratio;;
				onscreen_right = (this_layer_data->x_offset_finish + box_width) / scaled_height_ratio;
				onscreen_bottom = (this_layer_data->y_offset_finish + box_height) / scaled_height_ratio;
			}

			// Ensure the bounding box doesn't go out of bounds
			onscreen_left = CLAMP(onscreen_left, 2, pixmap_width - 2);
			onscreen_top = CLAMP(onscreen_top, 2, pixmap_height - 2);
			onscreen_right = CLAMP(onscreen_right, 2, pixmap_width - 2);
			onscreen_bottom = CLAMP(onscreen_bottom, 2, pixmap_height - 2);

			// Draw a bounding box onscreen
			draw_bounding_box(onscreen_left, onscreen_top, onscreen_right, onscreen_bottom);

			// End point clicked, so we return in order to avoid the collision detection
			return TRUE;
		}
	}

	// * Do collision detection here to determine if the user has clicked on a layer's object *

	this_slide_data = get_current_slide_data();
	calculate_object_boundaries();
	collision_list = detect_collisions(collision_list, event->x, event->y);
	if (NULL == collision_list)
	{
		// If there was no collision, then select the background layer
		time_line_set_selected_layer_num(this_slide_data->timeline_widget, this_slide_data->num_layers - 1);  // *Needs* the -1, don't remove

		// Clear any existing handle box
		gdk_draw_drawable(GDK_DRAWABLE(get_main_drawing_area()->window), GDK_GC(get_main_drawing_area()->style->fg_gc[GTK_WIDGET_STATE(get_main_drawing_area())]),
				GDK_PIXMAP(get_front_store()), 0, 0, 0, 0, -1, -1);

		// Reset the stored mouse coordinates
		set_stored_x(-1);
		set_stored_y(-1);

		// Free the memory allocated during the collision detection
		g_list_free(collision_list);
		collision_list = NULL;

		return TRUE;
	}

	// * To get here there must have been at least one collision *

	// Save the mouse coordinates
	set_stored_x(event->x);
	set_stored_y(event->y);

	// Determine which layer the user has selected in the timeline
	selected_row = time_line_get_selected_layer_num(this_slide_data->timeline_widget);

	// Is the presently selected layer in the collision list?
	collision_list = g_list_first(collision_list);
	num_collisions = g_list_length(collision_list);
	for (count_int = 0; count_int < num_collisions; count_int++)
	{
		collision_list = g_list_first(collision_list);
		collision_list = g_list_nth(collision_list, count_int);
		layer_pointer = g_list_first(this_slide_data->layers);
		tmp_int = g_list_position(layer_pointer, ((boundary_box *) collision_list->data)->layer_ptr);
		if (tmp_int == selected_row)
		{
			// Return if the presently selected row is in the collision list, as we don't want to change our selected layer
			return TRUE;
		}
	}

	// * To get here, the presently selected layer wasn't in the collision list *

	// The presently selected row is not in the collision list, so move the selection row to the first collision
	collision_list = g_list_first(collision_list);
	selected_row = g_list_position(this_slide_data->layers, ((boundary_box *) collision_list->data)->layer_ptr);
	time_line_set_selected_layer_num(this_slide_data->timeline_widget, selected_row);

	// Draw a handle box around the new selected object
	draw_handle_box();

	// Free the memory allocated during the collision detection
	g_list_free(collision_list);
	collision_list = NULL;

	return TRUE;
}