eCollisionResult Enemy::handleBallCollision(Actor *ball) { stabilize(); Ball *tempBall = static_cast<Ball*>(ball); int startX, startY, endX, endY; leftSideLine(startX, startY, endX, endY); if (SDL_IntersectRectAndLine(tempBall->getImageRect(), &startX, &startY, &endX, &endY)) { if (tempBall->PrevColHor != ID) { tempBall->moveLeft(); // store an object a ball currently collides with horizontally tempBall->PrevColHor = ID; } } else { rightSideLine(startX, startY, endX, endY); if (SDL_IntersectRectAndLine(tempBall->getImageRect(), &startX, &startY, &endX, &endY)) { if (tempBall->PrevColHor != ID) { tempBall->moveRight(); tempBall->PrevColHor = ID; } } } // handle top/bottom collision a bit differently topSideLine(startX, startY, endX, endY); if (SDL_IntersectRectAndLine(tempBall->getImageRect(), &startX, &startY, &endX, &endY)) { if (tempBall->PrevColVert != ID) { // calculate new angle (more to the sides of object, greater the angle) float xVel = -tempBall->getAcceleration() * (X - tempBall->getX()) / Width; tempBall->alterXVelocity(xVel); tempBall->reverseYVelocity(); // store an object a ball currently collides with vertically tempBall->PrevColVert = ID; } } else { bottomSideLine(startX, startY, endX, endY); if (SDL_IntersectRectAndLine(tempBall->getImageRect(), &startX, &startY, &endX, &endY)) { if (tempBall->PrevColVert != ID) { float xVel = -tempBall->getAcceleration() * (X - tempBall->getX()) / Width; tempBall->alterXVelocity(xVel); tempBall->reverseYVelocity(); tempBall->PrevColVert = ID; } } } tempBall->PrevBorCol = 0; tempBall->approveBoost(true); return RESULT_NORMAL; }
int SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { BlendLineFunc func; if (!dst) { SDL_SetError("SDL_BlendLine(): Passed NULL destination surface"); return -1; } func = SDL_CalculateBlendLineFunc(dst->format); if (!func) { SDL_SetError("SDL_BlendLine(): Unsupported surface format"); return -1; } /* Perform clipping */ /* FIXME: We don't actually want to clip, as it may change line slope */ if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { return 0; } func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE); return 0; }
bool intersectsBlock(const Vector2& currentVertex, const Vector2& neighborVertex, const std::vector<Block>& blocks) { int x1 = static_cast<int>(currentVertex.mX); int y1 = static_cast<int>(currentVertex.mY); int x2 = static_cast<int>(neighborVertex.mX); int y2 = static_cast<int>(neighborVertex.mY); for (std::vector<Block>::const_iterator it = blocks.begin(); it != blocks.end(); ++it) { int blockWidth = it->getWidth(); int blockHeight = it->getHeight(); int enlargedCornerX = it->getTopLeftX() - blockWidth / 4; int enlargedCornerY = it->getTopLeftY() - blockHeight / 4; int enlargedWidth = blockWidth * 1.5; int enlargedHeight = blockHeight * 1.5; const SDL_Rect r = { enlargedCornerX, enlargedCornerY, enlargedWidth, enlargedHeight }; if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) { return true; } } return false; }
static void DrawRectLineIntersections(SDL_Window * window) { int i, j, window_w, window_h; /* Query the sizes */ SDL_GetWindowSize(window, &window_w, &window_h); SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE); for (i = 0; i < num_rects; i++) for (j = 0; j < num_lines; j++) { int x1, y1, x2, y2; SDL_Rect r; r = rects[i]; x1 = lines[j].x; y1 = lines[j].y; x2 = lines[j].w; y2 = lines[j].h; if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) { SDL_SetRenderDrawColor(0, 255, 55, 255); SDL_RenderDrawLine(x1, y1, x2, y2); } } SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE); }
/* * SDL.intersectRectAndLine(rect, x1, y1, x2, y2) * * Arguments: * rect the rectangle * x1 the starting x * y1 the starting y * x2 the ending x * y2 the ending y * * Returns: * The rectangle * The updated x1, * The updated y1, * The updated x2, * The updated y2 */ static int l_intersectRectAndLine(lua_State *L) { SDL_Rect rect; int x1, y1, x2, y2, rvalue; videoGetRect(L, 1, &rect); x1 = luaL_checkinteger(L, 2); y1 = luaL_checkinteger(L, 3); x2 = luaL_checkinteger(L, 4); y2 = luaL_checkinteger(L, 5); rvalue = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); return commonPush(L, "biiii", rvalue, x1, y1, x2, y2); }
int SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { int i; int x1, y1; int x2, y2; SDL_bool draw_end; BlendLineFunc func; if (!dst) { SDL_SetError("SDL_BlendLines(): Passed NULL destination surface"); return -1; } func = SDL_CalculateBlendLineFunc(dst->format); if (!func) { SDL_SetError("SDL_BlendLines(): Unsupported surface format"); return -1; } for (i = 1; i < count; ++i) { x1 = points[i-1].x; y1 = points[i-1].y; x2 = points[i].x; y2 = points[i].y; /* Perform clipping */ /* FIXME: We don't actually want to clip, as it may change line slope */ if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { continue; } /* Draw the end if it was clipped */ draw_end = (x2 != points[i].x || y2 != points[i].y); func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end); } if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { SDL_BlendPoint(dst, points[count-1].x, points[count-1].y, blendMode, r, g, b, a); } return 0; }
bool Inimigo::TemVisaoDoJogador(){ double dx = jogador->PegaBoundingBox().x - x; double dy = jogador->PegaBoundingBox().y - y; double dd = sqrt(dx*dx+dy*dy); if (visao >= dd){ cMap* tiles = mapa->PegaColisao(); unsigned int qtd = mapa->PegaQtdColisao(); for(unsigned int i = 0; i < qtd; i++){ if(tiles[i].id == 1){ int x1 = (int)x+16; int y1 = (int)y+16; int x2 = jogador->PegaBoundingBox().x+16; int y2 = jogador->PegaBoundingBox().y+16; if(SDL_IntersectRectAndLine(&tiles[i].rect, &x1, &y1, &x2, &y2) == SDL_TRUE){ return false; } } } return true; } return false; }
int SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color) { DrawLineFunc func; if (!dst) { return SDL_SetError("SDL_DrawLine(): Passed NULL destination surface"); } func = SDL_CalculateDrawLineFunc(dst->format); if (!func) { return SDL_SetError("SDL_DrawLine(): Unsupported surface format"); } /* Perform clipping */ /* FIXME: We don't actually want to clip, as it may change line slope */ if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { return 0; } func(dst, x1, y1, x2, y2, color, SDL_TRUE); return 0; }
static void DrawRectLineIntersections(SDL_Renderer * renderer) { int i, j; SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255); for (i = 0; i < num_rects; i++) for (j = 0; j < num_lines; j++) { int x1, y1, x2, y2; SDL_Rect r; r = rects[i]; x1 = lines[j].x; y1 = lines[j].y; x2 = lines[j].w; y2 = lines[j].h; if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) { SDL_RenderDrawLine(renderer, x1, y1, x2, y2); } } }
/** * @brief Tests SDL_IntersectRectAndLine() */ static void rect_testIntersectRectAndLine (void) { SDL_Rect rect = { 0, 0, 32, 32 }; int x1, y1; int x2, y2; SDL_bool clipped; SDL_ATbegin( "IntersectRectAndLine" ); x1 = -10; y1 = 0; x2 = -10; y2 = 31; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( !clipped && x1 == -10 && y1 == 0 && x2 == -10 && y2 == 31, "line outside to the left was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = 40; y1 = 0; x2 = 40; y2 = 31; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( !clipped && x1 == 40 && y1 == 0 && x2 == 40 && y2 == 31, "line outside to the right was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = 0; y1 = -10; x2 = 31; y2 = -10; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( !clipped && x1 == 0 && y1 == -10 && x2 == 31 && y2 == -10, "line outside above was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = 0; y1 = 40; x2 = 31; y2 = 40; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( !clipped && x1 == 0 && y1 == 40 && x2 == 31 && y2 == 40, "line outside below was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = 0; y1 = 0; x2 = 31; y2 = 31; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( clipped && x1 == 0 && y1 == 0 && x2 == 31 && y2 == 31, "line fully inside rect was clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = -10; y1 = 15; x2 = 40; y2 = 15; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( clipped && x1 == 0 && y1 == 15 && x2 == 31 && y2 == 15, "horizontal line rect was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = -32; y1 = -32; x2 = 63; y2 = 63; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( clipped && x1 == 0 && y1 == 0 && x2 == 31 && y2 == 31, "diagonal line to lower right was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = 63; y1 = 63; x2 = -32; y2 = -32; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( clipped && x1 == 31 && y1 == 31 && x2 == 0 && y2 == 0, "diagonal line to upper left was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = 63; y1 = -32; x2 = -32; y2 = 63; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( clipped && x1 == 31 && y1 == 0 && x2 == 0 && y2 == 31, "diagonal line to lower left was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); x1 = -32; y1 = 63; x2 = 63; y2 = -32; clipped = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); SDL_ATvassert( clipped && x1 == 0 && y1 == 31 && x2 == 31 && y2 == 0, "diagonal line to upper right was incorrectly clipped: %d,%d - %d,%d", x1, y1, x2, y2); SDL_ATend(); }
bool overlaps(Line l, SDL_Rect r) { return SDL_IntersectRectAndLine(&r, &l.x1,&l.y1, &l.x2,&l.y2); }
int SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, int blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { SDL_PixelFormat *fmt = dst->format; /* This function doesn't work on surfaces < 8 bpp */ if (dst->format->BitsPerPixel < 8) { SDL_SetError("SDL_BlendLine(): Unsupported surface format"); return (-1); } /* Perform clipping */ if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { return (0); } if ((blendMode == SDL_BLENDMODE_BLEND) || (blendMode == SDL_BLENDMODE_ADD)) { r = DRAW_MUL(r, a); g = DRAW_MUL(g, a); b = DRAW_MUL(b, a); } switch (fmt->BitsPerPixel) { case 15: switch (fmt->Rmask) { case 0x7C00: return SDL_BlendLine_RGB555(dst, x1, y1, x2, y2, blendMode, r, g, b, a); } break; case 16: switch (fmt->Rmask) { case 0xF800: return SDL_BlendLine_RGB565(dst, x1, y1, x2, y2, blendMode, r, g, b, a); } break; case 32: switch (fmt->Rmask) { case 0x00FF0000: if (!fmt->Amask) { return SDL_BlendLine_RGB888(dst, x1, y1, x2, y2, blendMode, r, g, b, a); } else { return SDL_BlendLine_ARGB8888(dst, x1, y1, x2, y2, blendMode, r, g, b, a); } break; } default: break; } if (!fmt->Amask) { return SDL_BlendLine_RGB(dst, x1, y1, x2, y2, blendMode, r, g, b, a); } else { return SDL_BlendLine_RGBA(dst, x1, y1, x2, y2, blendMode, r, g, b, a); } }
static int X11_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, int count) { X11_RenderData *data = (X11_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; SDL_Rect clip, rect; unsigned long foreground; XPoint *xpoints, *xpoint; int i, xcount; int minx, miny; int maxx, maxy; clip.x = 0; clip.y = 0; clip.w = window->w; clip.h = window->h; foreground = renderdrawcolor(renderer, 1); XSetForeground(data->display, data->gc, foreground); xpoint = xpoints = SDL_stack_alloc(XPoint, count); xcount = 0; minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN; for (i = 0; i < count; ++i) { int x = points[i].x; int y = points[i].y; /* If the point is inside the window, add it to the list */ if (x >= 0 && x < window->w && y >= 0 && y < window->h) { if (x < minx) { minx = x; } else if (x > maxx) { maxx = x; } if (y < miny) { miny = y; } else if (y > maxy) { maxy = y; } xpoint->x = (short)x; xpoint->y = (short)y; ++xpoint; ++xcount; continue; } /* We need to clip the line segments joined by this point */ if (xcount > 0) { int x1 = xpoint[-1].x; int y1 = xpoint[-1].y; int x2 = x; int y2 = y; if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) { if (x2 < minx) { minx = x2; } else if (x2 > maxx) { maxx = x2; } if (y2 < miny) { miny = y2; } else if (y2 > maxy) { maxy = y2; } xpoint->x = (short)x2; xpoint->y = (short)y2; ++xpoint; ++xcount; } XDrawLines(data->display, data->drawable, data->gc, xpoints, xcount, CoordModeOrigin); if (xpoints[0].x != x2 || xpoints[0].y != y2) { XDrawPoint(data->display, data->drawable, data->gc, x2, y2); } if (data->makedirty) { SDL_Rect rect; rect.x = minx; rect.y = miny; rect.w = (maxx - minx) + 1; rect.h = (maxy - miny) + 1; SDL_AddDirtyRect(&data->dirty, &rect); } xpoint = xpoints; xcount = 0; minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN; } if (i < (count-1)) { int x1 = x; int y1 = y; int x2 = points[i+1].x; int y2 = points[i+1].y; if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) { if (x1 < minx) { minx = x1; } else if (x1 > maxx) { maxx = x1; } if (y1 < miny) { miny = y1; } else if (y1 > maxy) { maxy = y1; } xpoint->x = (short)x1; xpoint->y = (short)y1; ++xpoint; ++xcount; } } } if (xcount > 1) { int x2 = xpoint[-1].x; int y2 = xpoint[-1].y; XDrawLines(data->display, data->drawable, data->gc, xpoints, xcount, CoordModeOrigin); if (xpoints[0].x != x2 || xpoints[0].y != y2) { XDrawPoint(data->display, data->drawable, data->gc, x2, y2); } if (data->makedirty) { SDL_Rect rect; rect.x = minx; rect.y = miny; rect.w = (maxx - minx) + 1; rect.h = (maxy - miny) + 1; SDL_AddDirtyRect(&data->dirty, &rect); } } SDL_stack_free(xpoints); return 0; }
bool CHitscanWeapon::Attack(int x, int y, float dirX, float dirY) { if (debugPause) { abs(1); } //////////// //This method creates a collection of CDevLasers and puts them into basevector //The objects stay as long as needed and get their pos and rotation updated each time the method is called // bool breaker = false; //rotation amount of textures float degrees = atan2(dirY, dirX); degrees *= (180 / 3.1415); //calculate x and y amount for next piece in beam float a = sqrt(dirX*dirX + dirY*dirY) / (4 - 1); //length of piece of beam -1 (-1 because otherwise we get small gaps at some angles) float speedX = dirX / a; float speedY = dirY / a; //calculate starting position. starting position is somewhere in a circle around the object. Circle size is given by weapon size, which is given by offsetX and offsetY //we then add these coordinates to the objects center coordinates float angle = atan2(dirY, dirX); float radius = sqrt(offsetX*offsetX + offsetY*offsetY); //find the point on the circle float correctedOffsetX = (float)(radius * cos(angle)); float correctedOffsetY = (float)(radius * sin(angle)); //temp holder for next x and y pos, and counter int temp[2] = { 0 }; int i = -1; //bool breaker = false; do { //calculate next pos i++; temp[0] = x+correctedOffsetX + i*(speedX); temp[1] = y+correctedOffsetY + i*(speedY); //check if next pos is outside map, if so break if (temp[0] / 64 > tileVector->at(1).size() - 1 || temp[0] / 64 < 0 || temp[1] / 64 > tileVector->size() - 1 || temp[1] / 64 < 0) { break; } //if i >= laservector.size that means that the beam in this frame is longer than last frames, and we need new objects if (i >= laserVector.size()) { //we push it into basevector for rendering purposes CDevLaser * laserPiece = new CDevLaser(temp[0], temp[1], 2, 4, 4, degrees); laserVector.push_back(laserPiece); // vm->AddBackgroundObject(laserPiece); } else //else we just update the old objects { laserVector[i]->pos[0] = temp[0]; laserVector[i]->pos[1] = temp[1]; laserVector[i]->rotation = degrees; } //check if it collides with any damagables for (int i = 0; i < solidVector->size(); i++) { SDL_Rect obj; obj.x = solidVector->at(i)->GetX(); obj.y = solidVector->at(i)->GetY(); obj.w = solidVector->at(i)->GetWidth(); obj.h = solidVector->at(i)->GetHeight(); SDL_Point intersection; int x1; x1 = laserVector[0]->GetX(); int x2; x2 = laserVector[laserVector.size() - 1]->GetX() + speedX; int y1; y1 = laserVector[0]->GetY() + (laserVector[0]->GetHeight() / 2); int y2; y2 = laserVector[laserVector.size() - 1]->GetY() + (laserVector[0]->GetHeight() / 2) + speedY; if (SDL_IntersectRectAndLine(&obj, &x1, &y1, &x2, &y2)) { for (int a = 0; a < msSinceDmg / msBetweenDmg; a++) { int damage = 2; solidVector->at(i)->TakeDamage(damage); CDamageNumber* dmg = new CDamageNumber(damage, solidVector->at(i)->GetX(), solidVector->at(i)->GetY()); vm->GetSoundPlayer()->PlayDamageSound(damage); vm->AddObject(dmg); msSinceDmg -= msBetweenDmg; a--; } breaker = true; break; } } //rotated rectangle collision detection } while (tileVector->at(temp[1] / 64).at(temp[0] / 64) == nullptr && breaker == false); //loop this as long as no laserobject is on top of a tile //i only grows as large as needed. when a laserobject is on top of a tile, the loop ends and i stops growing //the point where i stopped growing is the point where the beam ended. if laservector is bigger than i then there are too many objects, so we delete. while (i < laserVector.size()) { for (int o = baseVector->size() - 1; o >= 0; o--) { //delete object and its pointers if (baseVector->at(o) == laserVector.at(i)) { vm->DeleteObject(baseVector->at(o)); laserVector.erase(laserVector.begin() + i, laserVector.begin() + i + 1); break; } } } //return false means that the attack command will not be deleted. in this case, the attack command should be deleted by other means, //for example: //1. the user lets go of the attack button (inputhandler deletes it) //2. out of ammo (CAnimate returns true -> commandhandler deletes it) return false; }