{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "51b48688",
   "metadata": {},
   "source": [
    "# 20-21 · Kolizje i hitboxy\n",
    "\n",
    "Praktyka do sekcji [„Kolizje i hitboxy”"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a300364",
   "metadata": {},
   "source": [
    "## Cel\n",
    "\n",
    "Zaimplementować i sprawdzić sprawdzanie przecięcia dwóch prostokątów."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ed5937e5",
   "metadata": {},
   "source": [
    "## Sprawa robocza"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "e803748c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-09-03T10:12:17.654021Z",
     "iopub.status.busy": "2026-09-03T10:12:17.653873Z",
     "iopub.status.idle": "2026-09-03T10:12:17.686561Z",
     "shell.execute_reply": "2026-09-03T10:12:17.685942Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Столкновение с близким врагом: True\n",
      "Столкновение с далёким врагом: False\n"
     ]
    }
   ],
   "source": [
    "def pryamougolniki_peresekayutsya(a, b):\n",
    "    ax1, ay1, aw, ah = a\n",
    "    bx1, by1, bw, bh = b\n",
    "    ax2, ay2 = ax1 + aw, ay1 + ah\n",
    "    bx2, by2 = bx1 + bw, by1 + bh\n",
    "    return ax1 < bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1\n",
    "\n",
    "igrok = (100, 100, 40, 40)\n",
    "vrag_blizko = (120, 120, 40, 40)\n",
    "vrag_daleko = (400, 400, 40, 40)\n",
    "\n",
    "print(\"Столкновение с близким врагом:\", pryamougolniki_peresekayutsya(igrok, vrag_blizko))\n",
    "print(\"Столкновение с далёким врагом:\", pryamougolniki_peresekayutsya(igrok, vrag_daleko))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7aad4631",
   "metadata": {},
   "source": [
    "## Sprawdzenie wyniku"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "5a3b85db",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-09-03T10:12:17.687856Z",
     "iopub.status.busy": "2026-09-03T10:12:17.687685Z",
     "iopub.status.idle": "2026-09-03T10:12:17.691869Z",
     "shell.execute_reply": "2026-09-03T10:12:17.691228Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Верно: пересечение находится правильно, включая пограничный случай соприкосновения краями.\n"
     ]
    }
   ],
   "source": [
    "assert pryamougolniki_peresekayutsya(igrok, vrag_blizko) is True\n",
    "assert pryamougolniki_peresekayutsya(igrok, vrag_daleko) is False\n",
    "# kontakt z krawędzią NIE jest uznawany za przecięcie\n",
    "assert pryamougolniki_peresekayutsya((0, 0, 40, 40), (40, 0, 40, 40)) is False\n",
    "print(\"Верно: пересечение находится правильно, включая пограничный случай соприкосновения краями.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9cbf53b2",
   "metadata": {},
   "source": [
    "## Zadanie niezależne od zadania ★★\n",
    "\n",
    "Zmniejsz hitbox gracza o 10 pikseli z każdej strony (czyli o 20 w sumie w szerokości i wysokości — tak jak `rect.inflate(-20, -20)` z sekcji 20.21) i zobacz, co to faktycznie dotyczy.\n",
    "\n",
    "Test na dwóch przeciwnikach: `vrag_blizko`, który wspina się głęboko w gracza i na „krawędziowym” `vrag_kraem = (135, 135, 40, 40)`, który dotyka tylko narożnika obrazka. Upewnij się, że zmniejszenie hitboxa zmienia odpowiedź właśnie dla krańcowego wroga, a prawdziwa, głęboka kolizja pozostaje kolizją."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b557e3f8",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-09-03T10:12:17.693065Z",
     "iopub.status.busy": "2026-09-03T10:12:17.692925Z",
     "iopub.status.idle": "2026-09-03T10:12:17.697025Z",
     "shell.execute_reply": "2026-09-03T10:12:17.696327Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Глубокое перекрытие: до True -> после True\n",
      "Касание углом:       до True -> после False\n",
      "Верно: уменьшение хитбокса убирает попадания по краю, не трогая настоящие столкновения.\n"
     ]
    }
   ],
   "source": [
    "def szhat(rect, na):\n",
    "    x, y, w, h = rect\n",
    "    return (x + na, y + na, w - 2 * na, h - 2 * na)\n",
    "\n",
    "igrok_szhatyj = szhat(igrok, 10)\n",
    "assert igrok_szhatyj == (110, 110, 20, 20)\n",
    "\n",
    "vrag_kraem = (135, 135, 40, 40)   # задевает только угол картинки игрока\n",
    "\n",
    "blizko_do = pryamougolniki_peresekayutsya(igrok, vrag_blizko)\n",
    "blizko_posle = pryamougolniki_peresekayutsya(igrok_szhatyj, vrag_blizko)\n",
    "kraem_do = pryamougolniki_peresekayutsya(igrok, vrag_kraem)\n",
    "kraem_posle = pryamougolniki_peresekayutsya(igrok_szhatyj, vrag_kraem)\n",
    "\n",
    "print(\"Глубокое перекрытие: до\", blizko_do, \"-> после\", blizko_posle)\n",
    "print(\"Касание углом:       до\", kraem_do, \"-> после\", kraem_posle)\n",
    "\n",
    "# Prawdziwa kolizja pozostaje kolizją...\n",
    "assert blizko_do is True\n",
    "assert blizko_posle is True\n",
    "# ... I „nieuczciwy”\n",
    "assert kraem_do is True\n",
    "assert kraem_posle is False\n",
    "print(\"Верно: уменьшение хитбокса убирает попадания по краю, не трогая настоящие столкновения.\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Cartesian Python 3.14",
   "language": "python",
   "name": "cartesian-python314"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.14.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
