Rectangle Type

Rectangle

A Rectangle represents a rectangular region on the screen defined by x, y coordinates and dimensions.

Properties

PropertyTypeDescription
xnumberX coordinate of the top-left corner
ynumberY coordinate of the top-left corner
widthnumberWidth of the rectangle in pixels
heightnumberHeight of the rectangle in pixels

Methods

contains_point

rectangle:contains_point(x: number, y: number) -> boolean

Checks if a point is inside this rectangle.

Parameters:

  • x (number): The x coordinate to check
  • y (number): The y coordinate to check

Returns:

  • boolean: True if the point is within the rectangle boundaries

Example:

local rect = Rectangle.new(100, 100, 200, 150)

if rect:contains_point(150, 125) then
    logger:info("Point is inside rectangle!")
end

-- Check mouse position
local mouse_x, mouse_y = mouse.position()
if rect:contains_point(mouse_x, mouse_y) then
    logger:info("Mouse is over rectangle!")
end

center

rectangle:center() -> (number, number)

Returns the center point of the rectangle.

Returns:

  • number: X coordinate of the center
  • number: Y coordinate of the center

Example:

local rect = Rectangle.new(100, 100, 200, 150)
local cx, cy = rect:center()
-- cx = 200, cy = 175

logger:info("Center: " .. cx .. ", " .. cy)

-- Move mouse to center
mouse.move_to(cx, cy)

area

rectangle:area() -> number

Calculates the area of the rectangle (width × height).

Returns:

  • number: The area in square pixels

Example:

local rect = Rectangle.new(100, 100, 200, 150)
local size = rect:area()
-- size = 30000 (200 × 150)

logger:info("Rectangle area: " .. size .. " pixels")

Common Patterns

Screen Region Checking

local game_viewport = Rectangle.new(0, 0, 765, 503)

local function is_in_viewport(x, y)
    return game_viewport:contains_point(x, y)
end

if is_in_viewport(400, 250) then
    logger:info("Point is visible in game viewport")
end

Click Region Validation

local function safe_click_area(rect)
    -- Ensure rectangle is within safe clicking bounds
    if rect.width < 5 or rect.height < 5 then
        logger:warn("Rectangle too small to click safely")
        return false
    end
    
    local cx, cy = rect:center()
    mouse.move_to(cx, cy)
    mouse:click()
    return true
end

local button_area = Rectangle.new(100, 100, 80, 30)
safe_click_area(button_area)

UI Element Detection

local function find_ui_element_at(x, y, ui_elements)
    for name, rect in pairs(ui_elements) do
        if rect:contains_point(x, y) then
            return name
        end
    end
    return nil
end

local ui_layout = {
    inventory = Rectangle.new(550, 210, 190, 262),
    minimap = Rectangle.new(570, 10, 180, 180),
    chatbox = Rectangle.new(0, 345, 519, 158)
}

local mouse_x, mouse_y = mouse.position()
local hovered = find_ui_element_at(mouse_x, mouse_y, ui_layout)

if hovered then
    logger:info("Mouse over: " .. hovered)
end

Random Point in Rectangle

local function random_point_in_rect(rect)
    local x = rect.x + math.random(0, rect.width - 1)
    local y = rect.y + math.random(0, rect.height - 1)
    return x, y
end

local click_area = Rectangle.new(100, 100, 50, 50)
local rx, ry = random_point_in_rect(click_area)

mouse.move_to(rx, ry)
mouse:click()

Bounds Checking for Components

local function get_clickable_center(component)
    local x = component:x()
    local y = component:y()
    local w = component:width()
    local h = component:height()
    
    local bounds = Rectangle.new(x, y, w, h)
    
    -- Shrink by 20% to avoid edges
    local margin = 0.2
    local safe_rect = Rectangle.new(
        x + w * margin,
        y + h * margin,
        w * (1 - 2 * margin),
        h * (1 - 2 * margin)
    )
    
    return safe_rect:center()
end

local component = components:get(149, 0)
if component then
    local cx, cy = get_clickable_center(component)
    mouse.move_to(cx, cy)
end

Collision Detection

local function rectangles_overlap(rect1, rect2)
    -- Check if rectangles overlap
    return rect1.x < rect2.x + rect2.width and
           rect1.x + rect1.width > rect2.x and
           rect1.y < rect2.y + rect2.height and
           rect1.y + rect1.height > rect2.y
end

local area1 = Rectangle.new(100, 100, 50, 50)
local area2 = Rectangle.new(130, 130, 50, 50)

if rectangles_overlap(area1, area2) then
    logger:info("Rectangles overlap!")
end

Size Validation

local function is_valid_click_target(rect)
    local min_size = 10
    local max_size = 500
    
    if rect.width < min_size or rect.height < min_size then
        return false, "Too small to click accurately"
    end
    
    if rect.width > max_size or rect.height > max_size then
        return false, "Unusually large click area"
    end
    
    local area = rect:area()
    if area < 100 then
        return false, "Area too small"
    end
    
    return true, "Valid click target"
end

local button = Rectangle.new(100, 100, 80, 25)
local valid, reason = is_valid_click_target(button)

if valid then
    logger:info("Click target validated")
else
    logger:warn("Invalid click target: " .. reason)
end

Creating Rectangles

From Position and Size

local rect = Rectangle.new(100, 100, 200, 150)
-- Creates rectangle at (100, 100) with size 200x150

From Component Bounds

local function rect_from_component(component)
    return Rectangle.new(
        component:x(),
        component:y(),
        component:width(),
        component:height()
    )
end

local comp = components:get(149, 0)
if comp then
    local bounds = rect_from_component(comp)
    logger:info("Component area: " .. bounds:area())
end

From Table

local rect_table = {
    x = 100,
    y = 100,
    width = 200,
    height = 150
}

-- Rectangle can be created from table format
local rect = Rectangle.new(
    rect_table.x,
    rect_table.y,
    rect_table.width,
    rect_table.height
)

See Also

  • Point - 2D screen coordinates
  • Area - Tile-based game world regions
  • Component - UI components with bounds