[{"data":1,"prerenderedAt":1111},["ShallowReactive",2],{"blog-canvas-collision-physics":3},{"id":4,"title":5,"body":6,"description":15,"extension":1101,"meta":1102,"navigation":261,"path":1107,"seo":1108,"stem":1109,"__hash__":1110},"blog\u002Fblog\u002Fcanvas-collision-physics.md","HTML5 Canvas: Advanced Physics and Collision (Hitbox)",{"type":7,"value":8,"toc":1099},"minimark",[9,1095],[10,11,12,576],"i18n-text",{},[13,14,16,21,25,37,42,49,56,133,140,144,147,167,419,423,440,573],"template",{"v-slot:en":15},"",[17,18,20],"h1",{"id":19},"html5-canvas-advanced-physics-and-hitbox-collision","HTML5 Canvas: Advanced Physics and Hitbox Collision",[22,23,24],"p",{},"Drawing a player and applying gravity is fantastic, but a game isn't a game until objects interact. When a player's foot hits a ball, the ball needs to fly! When the ball hits the ground, it shouldn't just stick—it needs to bounce and roll to a stop.",[22,26,27,28,32,33,36],{},"This module will teach you ",[29,30,31],"strong",{},"Hitbox Collision Detection"," and ",[29,34,35],{},"Advanced Projectile Physics"," (Bounciness and Friction) in a simple, understandable way.",[38,39,41],"h2",{"id":40},"_1-the-hitbox-aabb-collision-detection","1. The Hitbox: AABB Collision Detection",[22,43,44,45,48],{},"In 2D games, we usually don't calculate collisions pixel-by-pixel—it's too slow. Instead, we draw an invisible rectangular box around our sprite called a ",[29,46,47],{},"Hitbox"," (or Bounding Box).",[22,50,51,52,55],{},"The industry standard algorithm for checking if two rectangles overlap is called ",[29,53,54],{},"AABB"," (Axis-Aligned Bounding Box). The math is surprisingly simple! We check four absolute limits:",[57,58,62],"pre",{"className":59,"code":60,"language":61,"meta":15,"style":15},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F Function returns TRUE if Box1 and Box2 overlap \nfunction checkAABBCollision(box1, box2) {\n  \u002F\u002F We check if it's IMPOSSIBLE for them to collide first.\n  \u002F\u002F Example: Is Box1's right edge further left than Box2's left edge?\n  return (\n    box1.x \u003C box2.x + box2.width &&   \u002F\u002F Box1 Left is past Box2 Right\n    box1.x + box1.width > box2.x &&   \u002F\u002F Box1 Right is past Box2 Left\n    box1.y \u003C box2.y + box2.height &&  \u002F\u002F Box1 Top is past Box2 Bottom\n    box1.y + box1.height > box2.y     \u002F\u002F Box1 Bottom is past Box2 Top\n  );\n}\n","javascript",[63,64,65,73,79,85,91,97,103,109,115,121,127],"code",{"__ignoreMap":15},[66,67,70],"span",{"class":68,"line":69},"line",1,[66,71,72],{},"\u002F\u002F Function returns TRUE if Box1 and Box2 overlap \n",[66,74,76],{"class":68,"line":75},2,[66,77,78],{},"function checkAABBCollision(box1, box2) {\n",[66,80,82],{"class":68,"line":81},3,[66,83,84],{},"  \u002F\u002F We check if it's IMPOSSIBLE for them to collide first.\n",[66,86,88],{"class":68,"line":87},4,[66,89,90],{},"  \u002F\u002F Example: Is Box1's right edge further left than Box2's left edge?\n",[66,92,94],{"class":68,"line":93},5,[66,95,96],{},"  return (\n",[66,98,100],{"class":68,"line":99},6,[66,101,102],{},"    box1.x \u003C box2.x + box2.width &&   \u002F\u002F Box1 Left is past Box2 Right\n",[66,104,106],{"class":68,"line":105},7,[66,107,108],{},"    box1.x + box1.width > box2.x &&   \u002F\u002F Box1 Right is past Box2 Left\n",[66,110,112],{"class":68,"line":111},8,[66,113,114],{},"    box1.y \u003C box2.y + box2.height &&  \u002F\u002F Box1 Top is past Box2 Bottom\n",[66,116,118],{"class":68,"line":117},9,[66,119,120],{},"    box1.y + box1.height > box2.y     \u002F\u002F Box1 Bottom is past Box2 Top\n",[66,122,124],{"class":68,"line":123},10,[66,125,126],{},"  );\n",[66,128,130],{"class":68,"line":129},11,[66,131,132],{},"}\n",[22,134,135,136,139],{},"If ",[29,137,138],{},"ALL"," those conditions are true, the two objects are currently crashing into each other!",[38,141,143],{"id":142},"_2-advanced-game-physics-the-ball","2. Advanced Game Physics: The Ball",[22,145,146],{},"If you are making a sports or platformer game, your ball needs to feel realistic. A true physics ball requires two new concepts:",[148,149,150,161],"ol",{},[151,152,153,156,157,160],"li",{},[29,154,155],{},"Bounce \u002F Restitution",": When it hits the floor, it reverses direction ",[63,158,159],{},"(-dy)",", but it loses some energy so it doesn't bounce forever.",[151,162,163,166],{},[29,164,165],{},"Friction \u002F Drag",": When rolling left or right, the grass slows it down until it completely stops.",[57,168,170],{"className":59,"code":169,"language":61,"meta":15,"style":15},"class Ball {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n    this.width = 50;  \u002F\u002F Standardizing hitbox\n    this.height = 50;\n    \n    \u002F\u002F Physics properties\n    this.dx = 0; \u002F\u002F Horizontal speed\n    this.dy = 0; \u002F\u002F Vertical falling speed\n    this.gravity = 0.5;\n    \n    \u002F\u002F THE SECRET INGREDIENTS\n    this.bounce = -0.7; \u002F\u002F Loses 30% of energy every bounce\n    this.friction = 0.98; \u002F\u002F Multiplies dx to slow it down 2% every frame\n  }\n\n  update(groundLevel) {\n    \u002F\u002F 1. Apply Gravity\n    this.dy += this.gravity;\n    \n    \u002F\u002F 2. Apply Friction to slow rolling\n    this.dx *= this.friction; \n\n    \u002F\u002F Stop completely if the speed is incredibly slow (micro-movements)\n    if (Math.abs(this.dx) \u003C 0.1) this.dx = 0;\n\n    \u002F\u002F 3. Move the Ball\n    this.x += this.dx;\n    this.y += this.dy;\n\n    \u002F\u002F 4. Floor Collision & Bouncing Logic\n    if (this.y + this.height >= groundLevel) {\n      this.y = groundLevel - this.height; \u002F\u002F Prevent sinking\n      \n      \u002F\u002F Only bounce if falling fast enough (prevents infinite micro-jitters)\n      if (this.dy > 1) {\n        this.dy *= this.bounce; \u002F\u002F Reverse direction and lose energy!\n      } else {\n        this.dy = 0; \u002F\u002F Settle on the ground completely\n      }\n    }\n  }\n}\n",[63,171,172,177,182,187,192,197,202,207,212,217,222,227,232,238,244,250,256,263,269,275,281,286,292,298,303,309,315,320,326,332,338,343,349,355,361,367,373,379,385,391,397,403,409,414],{"__ignoreMap":15},[66,173,174],{"class":68,"line":69},[66,175,176],{},"class Ball {\n",[66,178,179],{"class":68,"line":75},[66,180,181],{},"  constructor(x, y) {\n",[66,183,184],{"class":68,"line":81},[66,185,186],{},"    this.x = x;\n",[66,188,189],{"class":68,"line":87},[66,190,191],{},"    this.y = y;\n",[66,193,194],{"class":68,"line":93},[66,195,196],{},"    this.width = 50;  \u002F\u002F Standardizing hitbox\n",[66,198,199],{"class":68,"line":99},[66,200,201],{},"    this.height = 50;\n",[66,203,204],{"class":68,"line":105},[66,205,206],{},"    \n",[66,208,209],{"class":68,"line":111},[66,210,211],{},"    \u002F\u002F Physics properties\n",[66,213,214],{"class":68,"line":117},[66,215,216],{},"    this.dx = 0; \u002F\u002F Horizontal speed\n",[66,218,219],{"class":68,"line":123},[66,220,221],{},"    this.dy = 0; \u002F\u002F Vertical falling speed\n",[66,223,224],{"class":68,"line":129},[66,225,226],{},"    this.gravity = 0.5;\n",[66,228,230],{"class":68,"line":229},12,[66,231,206],{},[66,233,235],{"class":68,"line":234},13,[66,236,237],{},"    \u002F\u002F THE SECRET INGREDIENTS\n",[66,239,241],{"class":68,"line":240},14,[66,242,243],{},"    this.bounce = -0.7; \u002F\u002F Loses 30% of energy every bounce\n",[66,245,247],{"class":68,"line":246},15,[66,248,249],{},"    this.friction = 0.98; \u002F\u002F Multiplies dx to slow it down 2% every frame\n",[66,251,253],{"class":68,"line":252},16,[66,254,255],{},"  }\n",[66,257,259],{"class":68,"line":258},17,[66,260,262],{"emptyLinePlaceholder":261},true,"\n",[66,264,266],{"class":68,"line":265},18,[66,267,268],{},"  update(groundLevel) {\n",[66,270,272],{"class":68,"line":271},19,[66,273,274],{},"    \u002F\u002F 1. Apply Gravity\n",[66,276,278],{"class":68,"line":277},20,[66,279,280],{},"    this.dy += this.gravity;\n",[66,282,284],{"class":68,"line":283},21,[66,285,206],{},[66,287,289],{"class":68,"line":288},22,[66,290,291],{},"    \u002F\u002F 2. Apply Friction to slow rolling\n",[66,293,295],{"class":68,"line":294},23,[66,296,297],{},"    this.dx *= this.friction; \n",[66,299,301],{"class":68,"line":300},24,[66,302,262],{"emptyLinePlaceholder":261},[66,304,306],{"class":68,"line":305},25,[66,307,308],{},"    \u002F\u002F Stop completely if the speed is incredibly slow (micro-movements)\n",[66,310,312],{"class":68,"line":311},26,[66,313,314],{},"    if (Math.abs(this.dx) \u003C 0.1) this.dx = 0;\n",[66,316,318],{"class":68,"line":317},27,[66,319,262],{"emptyLinePlaceholder":261},[66,321,323],{"class":68,"line":322},28,[66,324,325],{},"    \u002F\u002F 3. Move the Ball\n",[66,327,329],{"class":68,"line":328},29,[66,330,331],{},"    this.x += this.dx;\n",[66,333,335],{"class":68,"line":334},30,[66,336,337],{},"    this.y += this.dy;\n",[66,339,341],{"class":68,"line":340},31,[66,342,262],{"emptyLinePlaceholder":261},[66,344,346],{"class":68,"line":345},32,[66,347,348],{},"    \u002F\u002F 4. Floor Collision & Bouncing Logic\n",[66,350,352],{"class":68,"line":351},33,[66,353,354],{},"    if (this.y + this.height >= groundLevel) {\n",[66,356,358],{"class":68,"line":357},34,[66,359,360],{},"      this.y = groundLevel - this.height; \u002F\u002F Prevent sinking\n",[66,362,364],{"class":68,"line":363},35,[66,365,366],{},"      \n",[66,368,370],{"class":68,"line":369},36,[66,371,372],{},"      \u002F\u002F Only bounce if falling fast enough (prevents infinite micro-jitters)\n",[66,374,376],{"class":68,"line":375},37,[66,377,378],{},"      if (this.dy > 1) {\n",[66,380,382],{"class":68,"line":381},38,[66,383,384],{},"        this.dy *= this.bounce; \u002F\u002F Reverse direction and lose energy!\n",[66,386,388],{"class":68,"line":387},39,[66,389,390],{},"      } else {\n",[66,392,394],{"class":68,"line":393},40,[66,395,396],{},"        this.dy = 0; \u002F\u002F Settle on the ground completely\n",[66,398,400],{"class":68,"line":399},41,[66,401,402],{},"      }\n",[66,404,406],{"class":68,"line":405},42,[66,407,408],{},"    }\n",[66,410,412],{"class":68,"line":411},43,[66,413,255],{},[66,415,417],{"class":68,"line":416},44,[66,418,132],{},[38,420,422],{"id":421},"_3-creating-the-impact-transferring-momentum","3. Creating the Impact (Transferring Momentum)",[22,424,425,426,428,429,432,433,32,436,439],{},"How do we put everything together? Inside your Game Loop, you use your ",[63,427,54],{}," math to check if the Player touches the Ball.\nIf they touch, AND the player is currently in the ",[63,430,431],{},"\"Kick\""," animation state, we instantly inject explosive velocity (",[63,434,435],{},"dx",[63,437,438],{},"dy",") into the ball!",[57,441,443],{"className":59,"code":442,"language":61,"meta":15,"style":15},"\u002F\u002F Inside your requestAnimationFrame Loop...\n\n\u002F\u002F 1. Update entities\nplayer.update();\nball.update(canvas.height - 90);\n\n\u002F\u002F 2. Check Hitbox Collision\nif (checkAABBCollision(player, ball)) {\n  \n  \u002F\u002F Did the player hit the kick button just now?\n  if (player.state === \"Kick\") {\n    \n    \u002F\u002F BOOM! Transfer huge momentum to the ball\n    \u002F\u002F Shoot it upwards and forwards!\n    ball.dy = -15; \n    \n    \u002F\u002F Shoot left or right depending on player's side\n    if (player.position === \"left\") {\n      ball.dx = 20; \u002F\u002F Blast to the right\n    } else {\n      ball.dx = -20; \u002F\u002F Blast to the left\n    }\n  } else {\n    \u002F\u002F If just walking into it normally, nudge the ball slightly\n    ball.dx = player.dx * 1.2; \n  }\n}\n",[63,444,445,450,454,459,464,469,473,478,483,488,493,498,502,507,512,517,521,526,531,536,541,546,550,555,560,565,569],{"__ignoreMap":15},[66,446,447],{"class":68,"line":69},[66,448,449],{},"\u002F\u002F Inside your requestAnimationFrame Loop...\n",[66,451,452],{"class":68,"line":75},[66,453,262],{"emptyLinePlaceholder":261},[66,455,456],{"class":68,"line":81},[66,457,458],{},"\u002F\u002F 1. Update entities\n",[66,460,461],{"class":68,"line":87},[66,462,463],{},"player.update();\n",[66,465,466],{"class":68,"line":93},[66,467,468],{},"ball.update(canvas.height - 90);\n",[66,470,471],{"class":68,"line":99},[66,472,262],{"emptyLinePlaceholder":261},[66,474,475],{"class":68,"line":105},[66,476,477],{},"\u002F\u002F 2. Check Hitbox Collision\n",[66,479,480],{"class":68,"line":111},[66,481,482],{},"if (checkAABBCollision(player, ball)) {\n",[66,484,485],{"class":68,"line":117},[66,486,487],{},"  \n",[66,489,490],{"class":68,"line":123},[66,491,492],{},"  \u002F\u002F Did the player hit the kick button just now?\n",[66,494,495],{"class":68,"line":129},[66,496,497],{},"  if (player.state === \"Kick\") {\n",[66,499,500],{"class":68,"line":229},[66,501,206],{},[66,503,504],{"class":68,"line":234},[66,505,506],{},"    \u002F\u002F BOOM! Transfer huge momentum to the ball\n",[66,508,509],{"class":68,"line":240},[66,510,511],{},"    \u002F\u002F Shoot it upwards and forwards!\n",[66,513,514],{"class":68,"line":246},[66,515,516],{},"    ball.dy = -15; \n",[66,518,519],{"class":68,"line":252},[66,520,206],{},[66,522,523],{"class":68,"line":258},[66,524,525],{},"    \u002F\u002F Shoot left or right depending on player's side\n",[66,527,528],{"class":68,"line":265},[66,529,530],{},"    if (player.position === \"left\") {\n",[66,532,533],{"class":68,"line":271},[66,534,535],{},"      ball.dx = 20; \u002F\u002F Blast to the right\n",[66,537,538],{"class":68,"line":277},[66,539,540],{},"    } else {\n",[66,542,543],{"class":68,"line":283},[66,544,545],{},"      ball.dx = -20; \u002F\u002F Blast to the left\n",[66,547,548],{"class":68,"line":288},[66,549,408],{},[66,551,552],{"class":68,"line":294},[66,553,554],{},"  } else {\n",[66,556,557],{"class":68,"line":300},[66,558,559],{},"    \u002F\u002F If just walking into it normally, nudge the ball slightly\n",[66,561,562],{"class":68,"line":305},[66,563,564],{},"    ball.dx = player.dx * 1.2; \n",[66,566,567],{"class":68,"line":311},[66,568,255],{},[66,570,571],{"class":68,"line":317},[66,572,132],{},[22,574,575],{},"With these three steps, your characters no longer pass through objects like ghosts! You have successfully implemented a professional Physics Engine logic within HTML5 Canvas.",[13,577,578,582,590,601,608,618,625,677,684,688,691,723,929,933,943,956,1088],{"v-slot:id":15},[17,579,581],{"id":580},"html5-canvas-fisika-tingkat-lanjut-dan-hitbox-kolisi","HTML5 Canvas: Fisika Tingkat Lanjut dan Hitbox Kolisi",[22,583,584,585,589],{},"Menggambar karakter yang bisa melompat dan jatuh karena gravitasi memang mengagumkan, tapi game takkan hidup sampai ada \"interaksi fisik\". Saat kaki Jagoan menendang bola, bola harus meroket mental! Saat bola jatuh ke aspal lapangan, ia tak boleh langsung berhenti kaku—ia seharusnya memantul (",[586,587,588],"em",{},"bouncing","), lalu pelan-pelan menggelinding mereda karena tergesek rumput lapangan.",[22,591,592,593,596,597,600],{},"Di modul ini, kita akan membongkar tuntas rahasia ",[29,594,595],{},"Hitbox (Deteksi Layar Sentuh Tabrakan)"," dan ",[29,598,599],{},"Fisika Objek Mati"," yang cukup kompleks namun dijelaskan secara sederhana!",[38,602,604,605],{"id":603},"_1-jantung-tabrakan-2d-aabb-collision","1. Jantung Tabrakan 2D: ",[586,606,607],{},"AABB Collision",[22,609,610,611,613,614,617],{},"Pada Game Engine 2D manapun, kita nyaris TIDAK PERNAH menghitung tabrakan gambar pixel-per-pixel karena itu akan menyiksa prosesor (terlalu berat). Sebagai gantinya, bayangkan semua gambar karakter dikurung oleh kotak tak terlihat (Transparan) yang kita sebut ",[29,612,47],{}," \u002F ",[586,615,616],{},"Bounding Box",".",[22,619,620,621,624],{},"Algoritma matematika sejuta umat yang sering dipakai untuk membaca apakah dua Hitbox sedang saling tindih menyentuh disebut ",[29,622,623],{},"AABB (Axis-Aligned Bounding Box)",". Rumusnya sangat sederhana, mengecek 4 batas batas ruang:",[57,626,628],{"className":59,"code":627,"language":61,"meta":15,"style":15},"\u002F\u002F Fungsi rahasia mengembalikan nilai Bekerja(TRUE) jika Kotak 1 & 2 bersentuhan !\nfunction bacaTabrakanAABB(karakter, objekBola) {\n  \u002F\u002F Algoritmanya mengecek apakah TIDAK MUNGKIN mereka bertabrakan terlebih dahulu\n  return (\n    karakter.x \u003C objekBola.x + objekBola.width &&   \u002F\u002F Batas Kiri Pemain nabrak Kanan Bola\n    karakter.x + karakter.width > objekBola.x &&   \u002F\u002F Batas Kanan Pemain nabrak Kiri Bola\n    karakter.y \u003C objekBola.y + objekBola.height &&  \u002F\u002F Batas Atas Pemain nabrak Bawah Bola\n    karakter.y + karakter.height > objekBola.y     \u002F\u002F Batas Bawah Pemain menembus Atas Bola\n  );\n}\n",[63,629,630,635,640,645,649,654,659,664,669,673],{"__ignoreMap":15},[66,631,632],{"class":68,"line":69},[66,633,634],{},"\u002F\u002F Fungsi rahasia mengembalikan nilai Bekerja(TRUE) jika Kotak 1 & 2 bersentuhan !\n",[66,636,637],{"class":68,"line":75},[66,638,639],{},"function bacaTabrakanAABB(karakter, objekBola) {\n",[66,641,642],{"class":68,"line":81},[66,643,644],{},"  \u002F\u002F Algoritmanya mengecek apakah TIDAK MUNGKIN mereka bertabrakan terlebih dahulu\n",[66,646,647],{"class":68,"line":87},[66,648,96],{},[66,650,651],{"class":68,"line":93},[66,652,653],{},"    karakter.x \u003C objekBola.x + objekBola.width &&   \u002F\u002F Batas Kiri Pemain nabrak Kanan Bola\n",[66,655,656],{"class":68,"line":99},[66,657,658],{},"    karakter.x + karakter.width > objekBola.x &&   \u002F\u002F Batas Kanan Pemain nabrak Kiri Bola\n",[66,660,661],{"class":68,"line":105},[66,662,663],{},"    karakter.y \u003C objekBola.y + objekBola.height &&  \u002F\u002F Batas Atas Pemain nabrak Bawah Bola\n",[66,665,666],{"class":68,"line":111},[66,667,668],{},"    karakter.y + karakter.height > objekBola.y     \u002F\u002F Batas Bawah Pemain menembus Atas Bola\n",[66,670,671],{"class":68,"line":117},[66,672,126],{},[66,674,675],{"class":68,"line":123},[66,676,132],{},[22,678,679,680,683],{},"Apabila ",[29,681,682],{},"KEEMPAT"," syarat logika di atas terpenuhi semuanya dalam satu frame, dijamin pasti kedua objek itu sedang bertubrukan hebat (Collision)!",[38,685,687],{"id":686},"_2-fisika-lanjutan-benda-mati-bola","2. Fisika Lanjutan: Benda Mati (Bola)",[22,689,690],{},"Apabila Anda meracik Game Olahraga atau Action, peluru pelontar \u002F bolanya harus terasa berbobot nyata dan mematuhi fisika bumi sejati. Sebuah bola cerdas butuh dua DNA Fisika baru:",[148,692,693,710],{},[151,694,695,702,703,706,707,709],{},[29,696,697,698,701],{},"Daya Pegas Pantul (",[586,699,700],{},"Bounce"," \u002F Restitution)",": Saat menabrak aspal keras, alih-alih setop mendadak nilannya ",[63,704,705],{},"(dy=0)",", ia malah memutar arah berbalik angkasa secara negatif ",[63,708,159],{},". Hanya saja tiap memantul kekuatannya diskon \u002F dipotong energi jatuhnya sehingga kelamaan hilang dan mati.",[151,711,712,719,720,722],{},[29,713,714,715,718],{},"Gaya Gesek (",[586,716,717],{},"Friction"," \u002F Drag)",": Tarikan kasar dari pasir lapangan rumput yang menyiksa laju kecepatan ",[63,721,435],{},". Makin menggelinding pelan memelan, lalu berhentih total.",[57,724,726],{"className":59,"code":725,"language":61,"meta":15,"style":15},"class BolaFisika {\n  constructor(x, y) {\n    this.x = x;\n    this.y = y;\n    this.width = 50;  \u002F\u002F Patokan Lebar Kotak Hitbox Bola\n    this.height = 50; \u002F\u002F Tinggi Kotak Bola\n    \n    \u002F\u002F Status Momentum Otot Gerakan\n    this.dx = 0; \u002F\u002F Tarikan maju-mundur Horizontal\n    this.dy = 0; \u002F\u002F Daya jatuh\u002Fterbang Vertikal\n    this.gravity = 0.5; \u002F\u002F Berat Bola standar ideal\n    \n    \u002F\u002F DUA RESEP RAHASIA FISIKA BUMI:\n    this.bounce = -0.7; \u002F\u002F Tiap nabrak bumi, berbalik angkasa TAPI kehilangan 30% kekencangannya!\n    this.friction = 0.98; \u002F\u002F Tiap frame berlari, kecepatan dx-nya dipangkas aus disikon 2% terhalang rumput!\n  }\n\n  update(groundLevel) {\n    \u002F\u002F 1. Seret bola oleh Gravitasi per frame\n    this.dy += this.gravity;\n    \n    \u002F\u002F 2. Potong tenaga Lari Horizontal dgn Paksaan Daya Gesek Rumput\n    this.dx *= this.friction; \n\n    \u002F\u002F Jika tenaganya sudah teramat sangat pelan (mendekati cacat), matikan total kemudi rodanya!\n    if (Math.abs(this.dx) \u003C 0.1) this.dx = 0;\n\n    \u002F\u002F 3. Aplikasikan penambahan titik kordinat riil bola ini berlayar\n    this.x += this.dx;\n    this.y += this.dy;\n\n    \u002F\u002F 4. LOGIKA PANTULAN (Kolisi menghujam lantai bawah Bumi!)\n    if (this.y + this.height >= groundLevel) {\n      this.y = groundLevel - this.height; \u002F\u002F Tahan di tepi aspal daratan, cegah bolanya nyungsep tembus bumi\n      \n      \u002F\u002F Cuma kasi izin mental jika masih meluncur berkecepatan tinggi!\n      \u002F\u002F (Bila sudah lemah pantulannya dibawah 1 px, berhentikan bolanya istirahat menapas di tanah)\n      if (this.dy > 1) {\n        this.dy *= this.bounce; \u002F\u002F Balikkan arah tenaga dy ke angkasa (- minus) lalu diskon energi 30% pakai bounce! \n      } else {\n        this.dy = 0; \u002F\u002F Biarkan si Bola Istirahat sempurna pulas di rerumputan!\n      }\n    }\n  }\n}\n",[63,727,728,733,737,741,745,750,755,759,764,769,774,779,783,788,793,798,802,806,810,815,819,823,828,832,836,841,845,849,854,858,862,866,871,875,880,884,889,894,898,903,907,912,916,920,924],{"__ignoreMap":15},[66,729,730],{"class":68,"line":69},[66,731,732],{},"class BolaFisika {\n",[66,734,735],{"class":68,"line":75},[66,736,181],{},[66,738,739],{"class":68,"line":81},[66,740,186],{},[66,742,743],{"class":68,"line":87},[66,744,191],{},[66,746,747],{"class":68,"line":93},[66,748,749],{},"    this.width = 50;  \u002F\u002F Patokan Lebar Kotak Hitbox Bola\n",[66,751,752],{"class":68,"line":99},[66,753,754],{},"    this.height = 50; \u002F\u002F Tinggi Kotak Bola\n",[66,756,757],{"class":68,"line":105},[66,758,206],{},[66,760,761],{"class":68,"line":111},[66,762,763],{},"    \u002F\u002F Status Momentum Otot Gerakan\n",[66,765,766],{"class":68,"line":117},[66,767,768],{},"    this.dx = 0; \u002F\u002F Tarikan maju-mundur Horizontal\n",[66,770,771],{"class":68,"line":123},[66,772,773],{},"    this.dy = 0; \u002F\u002F Daya jatuh\u002Fterbang Vertikal\n",[66,775,776],{"class":68,"line":129},[66,777,778],{},"    this.gravity = 0.5; \u002F\u002F Berat Bola standar ideal\n",[66,780,781],{"class":68,"line":229},[66,782,206],{},[66,784,785],{"class":68,"line":234},[66,786,787],{},"    \u002F\u002F DUA RESEP RAHASIA FISIKA BUMI:\n",[66,789,790],{"class":68,"line":240},[66,791,792],{},"    this.bounce = -0.7; \u002F\u002F Tiap nabrak bumi, berbalik angkasa TAPI kehilangan 30% kekencangannya!\n",[66,794,795],{"class":68,"line":246},[66,796,797],{},"    this.friction = 0.98; \u002F\u002F Tiap frame berlari, kecepatan dx-nya dipangkas aus disikon 2% terhalang rumput!\n",[66,799,800],{"class":68,"line":252},[66,801,255],{},[66,803,804],{"class":68,"line":258},[66,805,262],{"emptyLinePlaceholder":261},[66,807,808],{"class":68,"line":265},[66,809,268],{},[66,811,812],{"class":68,"line":271},[66,813,814],{},"    \u002F\u002F 1. Seret bola oleh Gravitasi per frame\n",[66,816,817],{"class":68,"line":277},[66,818,280],{},[66,820,821],{"class":68,"line":283},[66,822,206],{},[66,824,825],{"class":68,"line":288},[66,826,827],{},"    \u002F\u002F 2. Potong tenaga Lari Horizontal dgn Paksaan Daya Gesek Rumput\n",[66,829,830],{"class":68,"line":294},[66,831,297],{},[66,833,834],{"class":68,"line":300},[66,835,262],{"emptyLinePlaceholder":261},[66,837,838],{"class":68,"line":305},[66,839,840],{},"    \u002F\u002F Jika tenaganya sudah teramat sangat pelan (mendekati cacat), matikan total kemudi rodanya!\n",[66,842,843],{"class":68,"line":311},[66,844,314],{},[66,846,847],{"class":68,"line":317},[66,848,262],{"emptyLinePlaceholder":261},[66,850,851],{"class":68,"line":322},[66,852,853],{},"    \u002F\u002F 3. Aplikasikan penambahan titik kordinat riil bola ini berlayar\n",[66,855,856],{"class":68,"line":328},[66,857,331],{},[66,859,860],{"class":68,"line":334},[66,861,337],{},[66,863,864],{"class":68,"line":340},[66,865,262],{"emptyLinePlaceholder":261},[66,867,868],{"class":68,"line":345},[66,869,870],{},"    \u002F\u002F 4. LOGIKA PANTULAN (Kolisi menghujam lantai bawah Bumi!)\n",[66,872,873],{"class":68,"line":351},[66,874,354],{},[66,876,877],{"class":68,"line":357},[66,878,879],{},"      this.y = groundLevel - this.height; \u002F\u002F Tahan di tepi aspal daratan, cegah bolanya nyungsep tembus bumi\n",[66,881,882],{"class":68,"line":363},[66,883,366],{},[66,885,886],{"class":68,"line":369},[66,887,888],{},"      \u002F\u002F Cuma kasi izin mental jika masih meluncur berkecepatan tinggi!\n",[66,890,891],{"class":68,"line":375},[66,892,893],{},"      \u002F\u002F (Bila sudah lemah pantulannya dibawah 1 px, berhentikan bolanya istirahat menapas di tanah)\n",[66,895,896],{"class":68,"line":381},[66,897,378],{},[66,899,900],{"class":68,"line":387},[66,901,902],{},"        this.dy *= this.bounce; \u002F\u002F Balikkan arah tenaga dy ke angkasa (- minus) lalu diskon energi 30% pakai bounce! \n",[66,904,905],{"class":68,"line":393},[66,906,390],{},[66,908,909],{"class":68,"line":399},[66,910,911],{},"        this.dy = 0; \u002F\u002F Biarkan si Bola Istirahat sempurna pulas di rerumputan!\n",[66,913,914],{"class":68,"line":405},[66,915,402],{},[66,917,918],{"class":68,"line":411},[66,919,408],{},[66,921,922],{"class":68,"line":416},[66,923,255],{},[66,925,927],{"class":68,"line":926},45,[66,928,132],{},[38,930,932],{"id":931},"_3-moment-of-impact-transfer-energi-tendangan-lurus","3. Moment of Impact! (Transfer Energi Tendangan Lurus)",[22,934,935,936,939,940,942],{},"Bagaimana merekatkan gabungan Karakter Utama penendang tersebut dengan Logika Kolisi Bola pintar ini? Mudah saja! Di dalam rotasi ",[586,937,938],{},"Game Loop",", kita gunakan Matematika sensor Hitbox ",[63,941,54],{}," diatas guna membaca adegan jika Pemain Anda secara kulit menyentuh Hitbox Bola!",[22,944,945,946,949,950,952,953,955],{},"Dan Bila bersentuhan, DAN Si Pemain rupanya kebetulan sedang menekan Tombol ",[63,947,948],{},"\"KICK \u002F TENDANG\"",", Kita suntikkan paksa aliran energi Daya Ledak tinggi ke Nadi ",[63,951,435],{}," maupun ",[63,954,438],{}," peluru Bola tersebut seolah roket terbang!",[57,957,959],{"className":59,"code":958,"language":61,"meta":15,"style":15},"\u002F\u002F Di rongga terdalam RequestAnimationFrame \u002F Game Loop Anda...\n\n\u002F\u002F 1. Eksekusi Logika Luruh Entitas Dulu!\nplayer.update();\nbola.update(canvas.height - 90); \u002F\u002F 90 adalah patokan tebal lantai\n\n\u002F\u002F 2. Radar Deteksi Tabrakan Fisik Dinyalakan (AABB System)\nif (bacaTabrakanAABB(player, bola)) {\n  \n  \u002F\u002F Oh, ternyata Hitbox bersentuhan, Apakah sang Pemain tepat bertepatan menyalakan status TEBASAN ANIMASI TENDANG(KICK)?\n  if (player.state === \"Kick\") {\n    \n    \u002F\u002F BOOOM!!! Transfer Energi rahang luar biasa kedalam Jasad Si Bola\n    \u002F\u002F Tembak mental ke Angkasa jauh ke atas (- Minus Besar)!\n    bola.dy = -15; \n    \n    \u002F\u002F Tembakan arah bola berdasarkan kubu si Pemain!\n    if (player.position === \"left\") {\n      bola.dx = 20; \u002F\u002F Jika dia dari markas Kiri, Dorong ledakan Kecepatan bola X melancip jauh ke arah Kanan Markas Musuh!\n    } else {\n      bola.dx = -20; \u002F\u002F Jika dia dari Kanan, dorong Tembakan Rudal ke wilayah Kiri Positif!\n    }\n  } else {\n    \u002F\u002F Apabila si pemain sekonyong-konyongnya jalan menabrak biasa gawang Bola secara damai?\n    \u002F\u002F Boleh digradasi sedikit seolah \"Menggiring (Dribble) Bola\"\n    bola.dx = player.dx * 1.2; \u002F\u002F Tambahan daya gesek dikit ke bola dari speed pelan kaki!\n  }\n}\n",[63,960,961,966,970,975,979,984,988,993,998,1002,1007,1011,1015,1020,1025,1030,1034,1039,1043,1048,1052,1057,1061,1065,1070,1075,1080,1084],{"__ignoreMap":15},[66,962,963],{"class":68,"line":69},[66,964,965],{},"\u002F\u002F Di rongga terdalam RequestAnimationFrame \u002F Game Loop Anda...\n",[66,967,968],{"class":68,"line":75},[66,969,262],{"emptyLinePlaceholder":261},[66,971,972],{"class":68,"line":81},[66,973,974],{},"\u002F\u002F 1. Eksekusi Logika Luruh Entitas Dulu!\n",[66,976,977],{"class":68,"line":87},[66,978,463],{},[66,980,981],{"class":68,"line":93},[66,982,983],{},"bola.update(canvas.height - 90); \u002F\u002F 90 adalah patokan tebal lantai\n",[66,985,986],{"class":68,"line":99},[66,987,262],{"emptyLinePlaceholder":261},[66,989,990],{"class":68,"line":105},[66,991,992],{},"\u002F\u002F 2. Radar Deteksi Tabrakan Fisik Dinyalakan (AABB System)\n",[66,994,995],{"class":68,"line":111},[66,996,997],{},"if (bacaTabrakanAABB(player, bola)) {\n",[66,999,1000],{"class":68,"line":117},[66,1001,487],{},[66,1003,1004],{"class":68,"line":123},[66,1005,1006],{},"  \u002F\u002F Oh, ternyata Hitbox bersentuhan, Apakah sang Pemain tepat bertepatan menyalakan status TEBASAN ANIMASI TENDANG(KICK)?\n",[66,1008,1009],{"class":68,"line":129},[66,1010,497],{},[66,1012,1013],{"class":68,"line":229},[66,1014,206],{},[66,1016,1017],{"class":68,"line":234},[66,1018,1019],{},"    \u002F\u002F BOOOM!!! Transfer Energi rahang luar biasa kedalam Jasad Si Bola\n",[66,1021,1022],{"class":68,"line":240},[66,1023,1024],{},"    \u002F\u002F Tembak mental ke Angkasa jauh ke atas (- Minus Besar)!\n",[66,1026,1027],{"class":68,"line":246},[66,1028,1029],{},"    bola.dy = -15; \n",[66,1031,1032],{"class":68,"line":252},[66,1033,206],{},[66,1035,1036],{"class":68,"line":258},[66,1037,1038],{},"    \u002F\u002F Tembakan arah bola berdasarkan kubu si Pemain!\n",[66,1040,1041],{"class":68,"line":265},[66,1042,530],{},[66,1044,1045],{"class":68,"line":271},[66,1046,1047],{},"      bola.dx = 20; \u002F\u002F Jika dia dari markas Kiri, Dorong ledakan Kecepatan bola X melancip jauh ke arah Kanan Markas Musuh!\n",[66,1049,1050],{"class":68,"line":277},[66,1051,540],{},[66,1053,1054],{"class":68,"line":283},[66,1055,1056],{},"      bola.dx = -20; \u002F\u002F Jika dia dari Kanan, dorong Tembakan Rudal ke wilayah Kiri Positif!\n",[66,1058,1059],{"class":68,"line":288},[66,1060,408],{},[66,1062,1063],{"class":68,"line":294},[66,1064,554],{},[66,1066,1067],{"class":68,"line":300},[66,1068,1069],{},"    \u002F\u002F Apabila si pemain sekonyong-konyongnya jalan menabrak biasa gawang Bola secara damai?\n",[66,1071,1072],{"class":68,"line":305},[66,1073,1074],{},"    \u002F\u002F Boleh digradasi sedikit seolah \"Menggiring (Dribble) Bola\"\n",[66,1076,1077],{"class":68,"line":311},[66,1078,1079],{},"    bola.dx = player.dx * 1.2; \u002F\u002F Tambahan daya gesek dikit ke bola dari speed pelan kaki!\n",[66,1081,1082],{"class":68,"line":317},[66,1083,255],{},[66,1085,1086],{"class":68,"line":322},[66,1087,132],{},[22,1089,1090,1091,1094],{},"Melengkapi ketiga sistem tersebut, Tokoh dan Objek properti Game Anda tak lagi hampa saling menembus raba raga sebagai gumpalan bayang hantu! Anda berhasil mengakali penyematan ",[29,1092,1093],{},"Hukum Kolisi Gravitasi Game Engine Fisika (Physics System Simulator)"," kelas wahid langsung di dalam barisan Canvas Web Platform buatan mandiri murni anda tersebut!",[1096,1097,1098],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":15,"searchDepth":75,"depth":75,"links":1100},[],"md",{"title_en":5,"title_id":581,"description_en":1103,"description_id":1104,"date":1105,"readingTime":1106},"Discover the secrets of 2D game collisions, projectile physics, bouncing balls, friction, and responsive hitboxes.","Temukan rahasia di balik tabrakan game 2D, fisika proyektil, bola memantul, gesekan lantai (friction), dan hitbox responsif.","2026-03-25","12 min read","\u002Fblog\u002Fcanvas-collision-physics",{"title":5,"description":15},"blog\u002Fcanvas-collision-physics","JrWbGKGq-KjBvoDwOxbpq7s0f82sWZAwQFX4rYYc-hk",1783751390654]