Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Platformówka treningówka problem kolizje.
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
KotWButach
Witam
Mam problem mam nadzieję że ktoś z was mógłby mi pomóc. Otóż mam prostą platformówkę ale mam problem z kolizjami wykrywa kolizje dla X ale dla Y już nie sad.gif. Więc wchodzi przez ściany.

Załączam kod.

  1. <body onkeydown="keyDown(event)" onkeyup="keyUp(event)" ></body>
  2. <canvas id="graphics" width="800" height="600" style="position: absolute; top: 0; left: 0; background: red;"></canvas>
  3.  
  4. // VARIBLES
  5. var gameCanvas = document.getElementById("graphics");
  6. var grafx = gameCanvas.getContext("2d"); //or gameCanvas
  7. var player = new object("mario_right.png", 300, 100, 50, 100);
  8.  
  9. var block = [];
  10.  
  11. function build(x, y, xStart, yStart) {
  12. for (var z = 0; z < y; z++) {
  13. xStart2 = xStart
  14. for (var i = 0; i < x; i++) {
  15.  
  16. xStart += 50;
  17. block[block.length] = new object("block.jpg", xStart, yStart, 50, 50);
  18.  
  19. }
  20. xStart = xStart2;
  21. yStart += 50;
  22. }
  23.  
  24. }
  25. build(5, 8, 350, 300);
  26. build(5, 5, 0, 400);
  27.  
  28. var isLeft = false;
  29. var isRight = false;
  30. var prevKey = false;
  31. var isSpace = false;
  32.  
  33. player.gravity = 20;
  34. player.weight = 0.1;
  35.  
  36.  
  37. //EVENTS
  38. function keyDown(e) {
  39.  
  40. if (String.fromCharCode(e.keyCode) === "%")
  41. isLeft = true; // player.x -= 5;
  42. if (String.fromCharCode(e.keyCode) === "'")
  43. isRight = true; // player.x += 5;
  44. if (String.fromCharCode(e.keyCode) === " ")
  45. isSpace = true; // player.x += 5;
  46.  
  47. }
  48. function keyUp(e) {
  49.  
  50. if (String.fromCharCode(e.keyCode) === "%")
  51. isLeft = false; // player.x -= 5;
  52. if (String.fromCharCode(e.keyCode) === "'")
  53. isRight = false; // player.x += 5;
  54. if (String.fromCharCode(e.keyCode) === " ")
  55. isSpace = false; // player.x += 5;
  56.  
  57. }
  58.  
  59. // Main Loop
  60. mainLoop();
  61. function mainLoop() {
  62.  
  63.  
  64.  
  65. // PRE VARRIABLE ADJUSTMENTS
  66. //for(var i=0 ; i<=maxBlock ; i++)
  67. // block[i].x += -player.Velocity_x;
  68. for (var i = 0; i < block.length; i++) {
  69. block[i].x += -player.Velocity_x;
  70. //player.x += player.Velocity_x;
  71. }
  72. player.y += player.Velocity_y;
  73.  
  74. // LOGIC
  75. if (isLeft)
  76. player.Velocity_x = -5;
  77. if (isRight)
  78. player.Velocity_x = 5;
  79. if (!isLeft && !isRight)
  80. player.Velocity_x = 0;
  81.  
  82. if (player.Velocity_y < player.gravity)
  83. player.Velocity_y += player.weight;
  84.  
  85. for (var i = 0; i < block.length; i++) {
  86. if (player.isColliding(block[i]) && player.y + player.height < block[i].y + player.Velocity_y) {
  87. player.y = block[i].y - player.height;
  88. player.Velocity_y = 0;
  89. }
  90. }
  91.  
  92.  
  93. if (isSpace && player.Velocity_y === 0) {
  94. player.Velocity_y = -5;
  95.  
  96. }
  97.  
  98. if (player.y > 700) {
  99. alert('Game Over');
  100. player.y = 100;
  101. player.x = 100;
  102. }
  103.  
  104. // IMAGE CHANGE
  105. if ((isRight && !isLeft) || (!isRight && isLeft)) { // by postac nie znikala
  106. if (isLeft && prevKey === false) {
  107. player.Sprite.src = "mario_left.png";
  108. prevKey = true;
  109. }
  110.  
  111. if (isRight && prevKey === true) {
  112. player.Sprite.src = "mario_right.png";
  113. prevKey = false;
  114. }
  115. }
  116.  
  117.  
  118. // POST VARRIABLE ADJUSTMENTS
  119.  
  120.  
  121. // RENDERING
  122. // czyszczenie obrazu
  123. grafx.clearRect(0, 0, gameCanvas.width, gameCanvas.height);
  124.  
  125. // rysowanie postaci
  126. grafx.drawImage(player.Sprite, player.x, player.y);
  127.  
  128. // rysowanie blokow
  129. for (var i = 0; i < block.length; i++) {
  130. grafx.drawImage(block[i].Sprite, block[i].x, block[i].y);
  131. }
  132. setTimeout(mainLoop, 1000 / 60);
  133. }
  134.  
  135. function object(img, x, y, width, height) {
  136. this.Sprite = new Image();
  137. this.Sprite.src = img;
  138. this.x = x;
  139. this.y = y;
  140. this.width = width;
  141. this.height = height;
  142. this.Previous_x;
  143. this.Previous_y;
  144. this.Velocity_x = 0;
  145. this.Velocity_y = 0;
  146. this.gravity = 0;
  147. this.weight = 0;
  148.  
  149. // wytworzenie kolizji z obiektami. <---------------------- KOLIZJE
  150. this.isColliding = function(obj) {
  151. if (this.x > obj.x + obj.width)
  152. return false;
  153. if (this.x + this.width < obj.x)
  154. return false;
  155. if (this.y > obj.y + obj.height)
  156. return false;
  157. if (this.y + this.height < obj.y)
  158. return false;
  159. return true;
  160. };
  161.  
  162.  
  163. }
  164. </script>
  165. </html>
SmokAnalog
Na moje oko Twoja funkcja do detekcji kolizji wygląda w porządku. Czy problem nie tkwi w rozmiarze kroku? Może postać w jednym kroku "przeskakuje" przez ścianę? Idealnie byłoby, gdyby jeden krok w logice wynosił maksymalnie 1 piksel.
KotWButach
Niestety nie sad.gif zmieniłem na 1 ale dalej nie wykrywa kolizji.

może coś tutaj?

  1. for (var i = 0; i < block.length; i++) {
  2. if (player.isColliding(block[i]) && player.y + player.height < block[i].y + player.Velocity_y) {
  3. player.y = block[i].y - player.height;
  4. player.Velocity_y = 0;
  5. }
  6. }
SmokAnalog
Ja bym w ogóle usunął ten fragment i zrobił inaczej. Zamiast "cofać" gracza w przypadku kolizji z blokiem, lepiej sprawdzać kolizję przed wykonaniem kroku. Zamiast sprawdzać kolizję z blokiem, lepiej też uogólnić logikę i sprawdzać czy nie koliduje z jakimkolwiek obiektem, przez który nie można przejść. Obiekty te możesz definiować na dwa sposoby:
  • trzymać je w tablicy
  • nadawać im określoną właściwość, np. object.obstacle = true
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.