Exemple #1
0
bool Rotation::post_compose(Origin origin) {
	PointSet tps,tps2; tps.owner=this; tps2.owner=this;
	Point tp,tp2,tp3;
	std::vector<PointSet> tpsv;
	origin.angle = normalise_angle(PI+origin.angle+angles[0]);
    // Now the extra rotation magic...  
    for( auto iter=composed_points.begin(); iter!=composed_points.end();++iter) {
        tps = *iter;
        tps2=*iter;
        tps2.points.clear();
        for(auto magnumpi=tps.points.begin();magnumpi!=tps.points.end();++magnumpi) {
			if((tps.render_flags&RENDER_SURFACE)>0) {
	            tp=*magnumpi;
				if( magnumpi - tps.points.begin() < 1 ) {
				    tp2=*magnumpi;
					tp.x=origin.position.x-tp.x;
					tp.y=origin.position.y-tp.y;
	            	tp2.x=tp.x*cos(origin.angle)-tp.y*sin(origin.angle);
	            	tp2.y=tp.x*sin(origin.angle)+tp.y*cos(origin.angle);
					tp2.x+=origin.position.x;
					tp2.y+=origin.position.y;
					tp=tp2; 
				} else {
				}
	            tps2.points.push_back(tp);
				// This is a special case for surfaces as they are rotated and scaled differently
			} else {
	            tp=*magnumpi;
				tp.x=origin.position.x-tp.x;
				tp.y=origin.position.y-tp.y;
	            tp2.x=tp.x*cos(origin.angle)-tp.y*sin(origin.angle);
	            tp2.y=tp.x*sin(origin.angle)+tp.y*cos(origin.angle);
				tp2.x+=origin.position.x;
				tp2.y+=origin.position.y;
	            tps2.points.push_back(tp2);
			}			
        }
		if((tps2.render_flags&RENDER_SURFACE)>0) {
			Element* argh=static_cast<Element*>(tps2.owner);
			if( argh->inherit_angle ) {
				tps2.surface_angle += (normalise_angle(origin.angle-PI-angles[0]) * (180/PI));
			}
			//cout << "Composed surface: " << tps2.points[0].x << ", " << tps2.points[0].y << ", " << tps2.points[1].x << ", " << tps2.points[1].y << ", @" << tps2.surface_angle << "(origin says " << origin.angle << ")" << endl;
		}
        tpsv.push_back(tps2);
    }
    composed_points=tpsv;
	return false;
	// Composition is good to go!
}
Exemple #2
0
bool Container::pre_compose(Origin origin) {
	composed_points.clear();
    if(!inherit_position) { origin.position.x=0.0; origin.position.y=0.0; }
    if(!inherit_scale) { origin.scale.x=1.0; origin.scale.y=1.0; }
    if(!inherit_angle) { origin.angle=0.0; }
	if(calc_rel_pos) {
	    origin.position.x+=geometry[0];
	    origin.position.y+=geometry[1];
	} else {
	    origin.position.x=geometry[0];
	    origin.position.y=geometry[1];
	}
	if(calc_rel_scale) {
	    origin.scale.x *= scale[0];
	    origin.scale.y *= scale[1];
	} else {
		origin.scale.x=scale[0];
		origin.scale.y=scale[1];
	}
	if(calc_rel_rot) {
	    origin.angle += angles[0]; // Not interested in passing on rotation as we'll do this after...
	} else {
		origin.angle = normalise_angle(angles[0]);
	}
//    Element* el;
    for(auto iter=contents.begin(); iter!=contents.end();++iter) {
        // Now we compose each child element...
        auto el2=*iter;
        el2->compose(origin);
        composed_points.insert(composed_points.end(),el2->composed_points.cbegin(),el2->composed_points.cend());
        el2->composed_points.clear();
    }
	return false;
}
Exemple #3
0
/* Check if the ball will collide with something if it is moved to the
 * specified coordinates. If so, the direction is changed and 1 is returned
 * to indicate that the caller should recalculate the new coordinates and
 * try again. If there was no collision it returns 0. If something exceptional
 * happens (eg. the last brick is destroyed or the last ball is lost) it
 * returns 2 to indicate that the caller should give up trying to move the
 * ball. */
int check_ball_collision(nbstate *state, coords *c)
{
	int i, bc;
	grid *g = state->grid;

	/* Check for a collision with the top of the game area: */
	if(c->y < state->ball.s->h + (2 * BALLS_BORDER) + state->scores.h) {
		/* Bounce the ball back down and ask the caller to try again: */
		state->ball.d = normalise_angle(M_PI - state->ball.d);
		return 1;
	}

	/* Check for a collision with the bottom of the game area: */
	if(c->y > state->canvasheight - state->ball.s->h) {
		/* If the solidfloor cheat is active, bounce the ball back up
		 * and ask the caller to try again: */
		if(state->flags.sf) {
			state->ball.d = normalise_angle(M_PI - state->ball.d);
			return 1;
		} else {
			/* Otherwise destroy the ball, move the new ball to
			 * the parked position (park_ball() is called by
			 * lost_ball()) and ask the caller to give up trying
			 * to move the ball: */
			lost_ball(state);
			move_ball(state);
			return 2;
		}
	}

	/* Check for a collision with the left hand side of the game area: */
	if(c->x < 0) {
		/* Bounce the ball back and ask the caller to try again: */
		state->ball.d = normalise_angle((2 * M_PI) - state->ball.d);
		return 1;
	}

	/* Check for a collision with the right hand side of the game area: */
	if(c->x > state->canvaswidth - state->ball.s->w) {
		/* Bounce the ball back and ask the caller to try again: */
		state->ball.d = normalise_angle((2 * M_PI) - state->ball.d);
		return 1;
	}

	/* Check for a collision with the bat: */
	if(c->y > state->canvasheight - state->batheight - state->ball.s->h &&
			c->x > state->batx -
			(state->batwidths[state->bat] / 2) - state->ball.s->w &&
			c->x < state->batx +
			(state->batwidths[state->bat] / 2)) {

		/* If the collision happened with the side of the bat instead
		 * of the top, we don't care so just tell the caller there
		 * was no collision: */
		if(state->ball.y > state->canvasheight - state->batheight -
				state->ball.s->h)
			return 0;

		/* If the StickyBat power-up is active, park the ball: */
		if(state->powertimes.stickybat) {
			park_ball(state);
			move_ball(state);
			return 2;
		} else {
			/* Otherwise bounce it back up and ask the caller to
			 * try again: */
			state->ball.d = normalise_angle(((c->x +
						(state->ball.s->w / 2)
						- state->batx) /
						state->batwidths[state->bat] /
						2) * M_PI);
			return 1;
		}
	}

	/* Check for collisions with the bricks: */
	bc = 0; /* No collisions have happened yet. */
	/* For each brick in the grid: */
	for(i = 0; i < state->width * state->height; i++) {
		/* If there is a brick in this grid position and the ball
		 * intersects it:  */
		if(g->b && c->y + state->ball.s->h > g->y && c->y < g->y +
				state->brickheight && c->x + state->ball.s->w
				> g->x && c->x < g->x + state->brickwidth) {

			/* Perform the brick collision actions, and if
			 * something exceptional happens (ie. we destroy the
			 * last brick), return straight away asking the caller
			 * to give up trying to move the ball: */
			if(brick_collision(state, g)) return 2;

			/* Unless the NoBounce cheat is active, bounce the
			 * ball off the brick. Only do this on the first brick
			 * collision we find. */
			if(!state->flags.nb && !bc) {
				bc = 1;
				/* Bounce off the left face: */
				if(state->ball.x + state->ball.s->w < g->x) {
					state->ball.d = normalise_angle((2 *
							M_PI) - state->ball.d);
				/* Bounce off the right face: */
				} else if(state->ball.x >= g->x +
						state->brickwidth) {
					state->ball.d = normalise_angle((2 *
							M_PI) - state->ball.d);
				/* Bounce off the upper face: */
				} else if(state->ball.y + state->ball.s->h
								< g->y) {
					state->ball.d = normalise_angle(M_PI -
								state->ball.d);
				/* Bounce off the lower face: */
				} else if(state->ball.y >= g->y +
							state->brickheight) {
					state->ball.d = normalise_angle(M_PI -
								state->ball.d);
				} else {
					/* This shouldn't happen, but I don't
					 * trust the above algorithm 100%. */
					debug_printf ("Internal error: "
						"couldn't figure out brick "
						"collision face\n");
				}
			}
		}
		g++; /* Increment to the next grid position. */
	}

	/* If a brick collision occured, ask the caller to try again: */
	if(bc) return 1;
	return 0; /* Otherwise tell the caller that no collision occured. */
}