Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool collides(unsigned short x1, unsigned short y1, unsigned short x2, unsigned short y2,
- unsigned short left, unsigned short top, unsigned short right, unsigned short bottom,
- float &averageX, float &averageY) {
- //Vertical and horizontal lines handling
- if (x1 == x2) {
- if (x1 >= left && x1 <= right) {
- bool y1in = y1 >= top && y1 <= bottom;
- bool y2in = y2 >= top && y2 <= bottom;
- if (y1in && !y2in) {
- averageX = x1;
- float secondY = y1 < y2 ? (bottom) : (top);
- averageY = (secondY + y1) / 2;
- return true;
- } else if (!y1in && y2in) {
- averageX = x1;
- float secondY = y2 < y1 ? (bottom) : (top);
- averageY = (secondY + y2) / 2;
- return true;
- } else if (y1in && y2in) {
- averageX = x1;
- averageY = (y1 + y2) / 2;
- return true;
- } else {
- if (y1 < y2) {
- if (y1 < top && y2 > bottom) {
- averageX = x1;
- averageY = (bottom + top) / 2;
- return true;
- }
- } else {
- if (y2 < top && y2 > bottom) {
- averageX = x1;
- averageY = (bottom + top) / 2;
- }
- }
- }
- return false;
- }
- return false;
- } else if (y1 == y2) {
- if (y1 >= top && y1 <= bottom) {
- bool x1in = x1 >= left && x1 <= right;
- bool x2in = x2 >= left && x2 <= right;
- if (x1in && !x2in) {
- averageY = y1;
- float secondX = x1 < x2 ? (right) : (left);
- averageX = (secondX + x1) / 2;
- return true;
- } else if (!x1in && x2in) {
- averageY = y1;
- float secondX = x2 < x1 ? (right) : (left);
- averageX = (secondX + x2) / 2;
- return true;
- } else if (x1in && x2in) {
- averageY = y1;
- averageX = (x1 + x2) / 2;
- return true;
- } else {
- if (x1 < x2) {
- if (x1 < left && x2 > right) {
- averageY = y1;
- averageX = (left + right) / 2;
- return true;
- }
- } else {
- if (x2 < left && x1 > right) {
- averageY = y1;
- averageX = (left + right) / 2;
- }
- }
- }
- return false;
- }
- return false;
- }
- //Start of Liang-Barsky
- float p2 = (x2 - x1);
- float p1 = -p2;
- float p4 = (y2 - y1);
- float p3 = -p4;
- float q1 = x1 - left;
- float q2 = right - x1;
- float q3 = y1 - top;
- float q4 = bottom - y1;
- float max = 0.0f;
- float min = 1.0f;
- float r1 = q1 / p1;
- float r2 = q2 / p2;
- if (p1 < 0) {
- if (r1 > max) {
- max = r1;
- }
- if (r2 < min) {
- min = r2;
- }
- } else {
- if (r2 > max) {
- max = r2;
- }
- if (r1 < min) {
- min = r1;
- }
- }
- float r3 = q3 / p3;
- float r4 = q4 / p4;
- if (p3 < 0) {
- if (r3 > max) {
- max = r3;
- }
- if (r4 < min) {
- min = r4;
- }
- } else {
- if (r4 > max) {
- max = r4;
- }
- if (r3 < min) {
- min = r3;
- }
- }
- if (max > min) {
- return false;
- }
- float ax = ((x1 + p2 * max) + (x1 + p2 * min)) / 2;
- float ay = ((y1 + p4 * max) + (y1 + p4 * min)) / 2;
- averageX = ax;
- averageY = ay;
- return true;
- }
- //oldX and oldY is a coordinates before move
- if (oldX != this->x || oldY != this->y) {
- PhysicsLine* lines = world->getLines();
- unsigned int i;
- unsigned int count = world->getLinesCount();
- unsigned short left = this->x - this->halfWidth;
- unsigned short right = this->x + this->halfWidth;
- unsigned short top = this->y - this->halfHeight;
- unsigned short bottom = this->y;
- float averageX, averageY;
- float dx = this->x - oldX;
- float dy = this->y - oldY;
- float* vectorsX = new float[count];
- float* vectorsY = new float[count];
- unsigned int vectorsN = 0;
- //check collisions
- for (i = 0; i < count; i++) {
- PhysicsLine line = lines[i];
- if (collides(
- line.x1, line.y1,
- line.x2, line.y2,
- left, top, right, bottom,
- averageX, averageY //response from collision function
- )) {
- vectorsX[vectorsN] = this->x - averageX;
- vectorsY[vectorsN] = this->y - averageY;
- vectorsN++;
- }
- }
- //apply vectors
- for (i = 0; i < vectorsN; i++) {
- //normalize vector
- float vx = vectorsX[i];
- float vy = vectorsY[i];
- float len = sqrt(vx * vx + vy * vy);
- vx /= len;
- vy /= len;
- dx += vx * this->speed / vectorsN;
- dy += vy * this->speed / vectorsN;
- }
- delete[] vectorsX;
- delete[] vectorsY;
- //move player to result velocity vector
- this->x = (unsigned short) (oldX + dx);
- this->y = (unsigned short) (oldY + dy);
- }
Add Comment
Please, Sign In to add comment