Dynamisch Sprites, Sprite abhängig von umgebenen Instanzen

    • GM 8

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Dynamisch Sprites, Sprite abhängig von umgebenen Instanzen

      Hallo Community!
      Zur Zeit arbeite ich an einem Strategiespiel (TopDown) bei dem der Spieler sich in einer zufallsgenerierten Map befindet.
      Der Generator ist auch garnicht mein Problem:

      Zuerst wird der Raum mit Wasserinstanzen (128x128 ist die Größe jedes Spielfeldes) ausgefüllt, dann werden zufällig Inselgruppen
      in das Wasser hineingesetzt. Hierbei wird jeweils das Wasserfeld entfernt und durch ein Grasfeld ersetzt.
      Auf den Inseln werden dann wiederum Biome und andere Sachen generiert.
      Das ganze dauert etwa 1-5 Sekunden, der Raum ist 9600x9600 Pixel groß und die Raumgeschwindigkeit beträgt 60 Steps pro Sekunde.

      Nun zum Problem!

      Ich möchte beispielsweise einem Grasfeld am Wasser einen anderen Sprite geben als ein Grasfeld was von anderen Grasfeldern umgeben ist.

      Einige zusätzliche Schwierigkeiten:
      Die Inseln werden nicht gleichzeitig generiert, 1 Grasfeld pro Step, also kann ich nicht einfach eine Abfrage in das Create-event der Grasfelder
      schreiben, da beim Generieren bspw. Noch ein Wasserfeld neben dem Grasfeld ist welches im Weiteren Verlauf entfernt wird, somit hätte
      das Grasfeld später einen Falschen Sprite.

      Ich habe schon mehrere Variationen meiner Abfragetechnik ausprobiert, sie kommt mir allerdings sehr uneffizient vor und führt nicht zum
      gewollten Endergebnis.

      Wenn ich den Code ins Step-event der Grasfelder schreibe, wobei der Code nur ausgeführt wird wenn alle Inseln generiert wurden(durch Variable
      "global.GeneratingIslands=false" erreicht) ändern nur einige ihren Sprite und die FPS sinkt unter 1 (und es liegt sicher nicht daran dass ich einen
      schlechten PC hätte ^^).

      Auch habe ich getestet ein Objekt zu erstellen was nach der Generation über die Map "fliegt" und wenn es auf ein Grasfeld trifft diesem durch
      untenstehenden Code in einer while with Schleife den richtigen Sprite zuordnet, allerdings friert das SPiel in diesem Fall komplett ein sobald
      es auf ein Grasfeld trifft.

      Vielen Dank im Vorraus für Vorschläge, bin wirklich seit Tagen am verzweifeln!

      Hier der Code:

      Quellcode

      1. //water only up
      2. if collision_point (x,y-128,wld_water1,true,true) &!
      3. collision_point (x,y+128,wld_water1,true,true)
      4. &! collision_point (x+128,y,wld_water1,true,true) &! collision_point (x-128,y,wld_water1,true,true)
      5. {
      6. sprite_index=spr_wld_grass_up;
      7. }
      8. //water only down
      9. if collision_point (x,y+128,wld_water1,true,true) &!
      10. collision_point (x,y-128,wld_water1,true,true)
      11. &! collision_point (x+128,y,wld_water1,true,true) &! collision_point (x-128,y,wld_water1,true,true)
      12. {
      13. sprite_index=spr_wld_grass_down;
      14. }
      15. //water up &down
      16. if collision_point (x,y+128,wld_water1,true,true) && collision_point (x,y-128,wld_water1,true,true)
      17. &! collision_point (x+128,y,wld_water1,true,true) &! collision_point (x-128,y,wld_water1,true,true)
      18. {
      19. sprite_index=spr_wld_grass_up_down;
      20. }
      21. //water only left
      22. if collision_point (x-128,y,wld_water1,true,true) &!
      23. collision_point (x,y-128,wld_water1,true,true)
      24. &! collision_point (x+128,y,wld_water1,true,true) &! collision_point (x,y+128,wld_water1,true,true)
      25. {
      26. sprite_index=spr_wld_grass_left;
      27. }
      28. //water only right
      29. if collision_point (x+128,y,wld_water1,true,true) &!
      30. collision_point (x,y-128,wld_water1,true,true)
      31. &! collision_point (x,y+128,wld_water1,true,true) &! collision_point (x-128,y,wld_water1,true,true)
      32. {
      33. sprite_index=spr_wld_grass_right;
      34. }
      35. //water left & right
      36. if collision_point (x+128,y,wld_water1,true,true) && collision_point (x-128,y,wld_water1,true,true)
      37. &! collision_point (x,y+128,wld_water1,true,true) &! collision_point (x,y-128,wld_water1,true,true)
      38. {
      39. sprite_index=spr_wld_grass_left_right;
      40. }
      41. //water up & left
      42. if collision_point (x-128,y,wld_water1,true,true) && collision_point (x,y-128,wld_water1,true,true)
      43. &! collision_point (x,y+128,wld_water1,true,true) &! collision_point (x+128,y,wld_water1,true,true)
      44. {
      45. sprite_index=spr_wld_grass_up_left;
      46. }
      47. //water up & right
      48. if collision_point (x+128,y,wld_water1,true,true) && collision_point (x,y-128,wld_water1,true,true)
      49. &! collision_point (x,y+128,wld_water1,true,true) &! collision_point (x-128,y,wld_water1,true,true)
      50. {
      51. sprite_index=spr_wld_grass_up_right;
      52. }
      53. //water down & left
      54. if collision_point (x-128,y,wld_water1,true,true) && collision_point (x,y+128,wld_water1,true,true)
      55. &! collision_point (x,y-128,wld_water1,true,true) &! collision_point (x+128,y,wld_water1,true,true)
      56. {
      57. sprite_index=spr_wld_grass_down_left;
      58. }
      59. //water down & right
      60. if collision_point (x+128,y,wld_water1,true,true) && collision_point (x,y+128,wld_water1,true,true)
      61. &! collision_point (x,y-128,wld_water1,true,true) &! collision_point (x-128,y,wld_water1,true,true)
      62. {
      63. sprite_index=spr_wld_grass_down_right;
      64. }
      65. //water up & left & right
      66. if collision_point (x-128,y,wld_water1,true,true) && collision_point (x,y-128,wld_water1,true,true)
      67. && collision_point (x+128,y,wld_water1,true,true) &! collision_point (x,y+128,wld_water1,true,true)
      68. {
      69. sprite_index=spr_wld_grass_up_left_right;
      70. }
      71. //water down & left & right
      72. if collision_point (x-128,y,wld_water1,true,true) && collision_point (x,y+128,wld_water1,true,true)
      73. && collision_point (x+128,y,wld_water1,true,true) &! collision_point (x,y-128,wld_water1,true,true)
      74. {
      75. sprite_index=spr_wld_grass_down_left_right;
      76. }
      77. //water left & up & down
      78. if collision_point (x-128,y,wld_water1,true,true) && collision_point (x,y-128,wld_water1,true,true)
      79. && collision_point (x,y+128,wld_water1,true,true) &! collision_point (x+128,y,wld_water1,true,true)
      80. {
      81. sprite_index=spr_wld_grass_left_up_down;
      82. }
      83. //water right & up & down
      84. if collision_point (x+128,y,wld_water1,true,true) && collision_point (x,y-128,wld_water1,true,true)
      85. && collision_point (x,y+128,wld_water1,true,true) &! collision_point (x-128,y,wld_water1,true,true)
      86. {
      87. sprite_index=spr_wld_grass_right_up_down;
      88. }
      89. //water left & up & down & right
      90. if collision_point (x-128,y,wld_water1,true,true) && collision_point (x,y-128,wld_water1,true,true)
      91. && collision_point (x,y+128,wld_water1,true,true) && collision_point (x+128,y,wld_water1,true,true)
      92. {
      93. sprite_index=spr_wld_grass_up_down_right_left;
      94. }
      Alles anzeigen
      132 little bugs in the code. 132 little bugs. Fix a few, set the compiler to stew, 172 little bugs in the code... :vogel:
    • Erstmal würde ich collision_point in einer Variable zwischen speichern damit verhinderst du einige redundante Aufrufe:

      GML-Quellcode

      1. var up, down, left, right;
      2. up = collision_point(x, y - 128, wld_water1, true, true) >= 0; // ">= 0" weil "[...] sie melden einen negativen Wert, wenn keine Kollision vorliegt."
      3. down = collision_point(x, y + 128, wld_water1, true, true) >= 0;
      4. left = collision_point(x - 128, y,wld_water1, true, true) >= 0;
      5. right = collision_point(x + 128, y,wld_water1, true, true) >= 0;
      6. //water only up
      7. if up &! down &! right &! left
      8. sprite_index = spr_wld_grass_up;
      9. //water only down
      10. if down &! up&! right &! left
      11. sprite_index = spr_wld_grass_down;
      12. //water up &down
      13. if down && up&! right &! left
      14. sprite_index = spr_wld_grass_up_down;
      15. //water only left
      16. if left &!up &! right &! down
      17. sprite_index = spr_wld_grass_left;
      18. //water only right
      19. if right &!up&! down &! left
      20. sprite_index = spr_wld_grass_right;
      21. //water left & right
      22. if right && left&! down &! up
      23. sprite_index = spr_wld_grass_left_right;
      24. //water up & left
      25. if left && up&! down &! right
      26. sprite_index = spr_wld_grass_up_left;
      27. //water up & right
      28. if right && up&! down &! left
      29. sprite_index = spr_wld_grass_up_right;
      30. //water down & left
      31. if left && down &! up &! right
      32. sprite_index = spr_wld_grass_down_left;
      33. //water down & right
      34. if right && down&! up &! left
      35. sprite_index = spr_wld_grass_down_right;
      36. //water up & left & right
      37. if left && up && right &! down
      38. sprite_index = spr_wld_grass_up_left_right;
      39. //water down & left & right
      40. if left && down && right &! up
      41. sprite_index = spr_wld_grass_down_left_right;
      42. //water left & up & down
      43. if left && up && down &! right
      44. sprite_index = spr_wld_grass_left_up_down;
      45. //water right & up & down
      46. if right && up && down &! left
      47. sprite_index = spr_wld_grass_right_up_down;
      48. //water left & up & down & right
      49. if left && up && down && right
      50. sprite_index = spr_wld_grass_up_down_right_left;
      Alles anzeigen


      Du kannst die Werte auch mit Bitoperatoren zu einem Wert zusammenfügen und dann die Sprites in einem (globalen) Array speichern (ist möglicherweise schneller):

      GML-Quellcode

      1. // Sprite setzen:
      2. sprite_index = global.sprites[(right << 3) | (left << 2) | (down << 1) | up];
      3. // Look-up Table:
      4. global.sprites[(0 << 3) | (0 << 2) | (0 << 1) | 0] = spr_wld_grass; //kein Wasser
      5. global.sprites[(0 << 3) | (0 << 2) | (0 << 1) | 1] = spr_wld_grass_up;
      6. // [...]
      7. global.sprites[(1 << 3) | (1 << 2) | (1 << 1) | 1] = spr_wld_grass_up_down_right_left;



      Damit das ganze nur einmal ausgeführt wird kannst du mit with alle Instanzen von deinem Grass-Objekt durchgehen und dann die Sprite ändern (in einem Skript z.B.).
      wupto.net/ Nicht meine Seite!
      We love Koalas.

      GM-D-Spam-o-Meter: 32%

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von henrik1235 ()

    • Danke für die Superschnelle Antwort, werde dann jetzt mal rumprobieren :thumbsup:


      ok, habe jetzt mal ein Objekt namens "spriter" erstellt, es in den Raum gepackt und folgendes in das Step event geschrieben:

      Quellcode

      1. if global.GeneratingIslands=false
      2. {
      3. var up, down, left, right;
      4. up = collision_point(x, y - 128, wld_water1, true, true) >= 0;
      5. down = collision_point(x, y + 128, wld_water1, true, true) >= 0;
      6. left = collision_point(x - 128, y,wld_water1, true, true) >= 0;
      7. right = collision_point(x + 128, y,wld_water1, true, true) >= 0;
      8. while(instance_exists(wld_grass_preset))
      9. {
      10. with wld_grass_preset
      11. {
      12. //water only up
      13. if up &! down &! right &! left
      14. sprite_index = spr_wld_grass_up;
      15. //water only down
      16. if down &! up&! right &! left
      17. sprite_index = spr_wld_grass_down;
      18. //water up &down
      19. if down && up&! right &! left
      20. sprite_index = spr_wld_grass_up_down;
      21. //water only left
      22. if left &!up &! right &! down
      23. sprite_index = spr_wld_grass_left;
      24. //water only right
      25. if right &!up&! down &! left
      26. sprite_index = spr_wld_grass_right;
      27. //water left & right
      28. if right && left&! down &! up
      29. sprite_index = spr_wld_grass_left_right;
      30. //water up & left
      31. if left && up&! down &! right
      32. sprite_index = spr_wld_grass_up_left;
      33. //water up & right
      34. if right && up&! down &! left
      35. sprite_index = spr_wld_grass_up_right;
      36. //water down & left
      37. if left && down &! up &! right
      38. sprite_index = spr_wld_grass_down_left;
      39. //water down & right
      40. if right && down&! up &! left
      41. sprite_index = spr_wld_grass_down_right;
      42. //water up & left & right
      43. if left && up && right &! down
      44. sprite_index = spr_wld_grass_up_left_right;
      45. //water down & left & right
      46. if left && down && right &! up
      47. sprite_index = spr_wld_grass_down_left_right;
      48. //water left & up & down
      49. if left && up && down &! right
      50. sprite_index = spr_wld_grass_left_up_down;
      51. //water right & up & down
      52. if right && up && down &! left
      53. sprite_index = spr_wld_grass_right_up_down;
      54. //water left & up & down & right
      55. if left && up && down && right
      56. sprite_index = spr_wld_grass_up_down_right_left;
      57. }
      58. }
      59. instance_destroy();
      60. }
      Alles anzeigen


      Allerdings tut sich jetzt nichts mehr, das Spiel friert ein.
      Sorry falls ich die while Schleife falsch geschrieben habe, habs noch nie so recht benutzt^^
      132 little bugs in the code. 132 little bugs. Fix a few, set the compiler to stew, 172 little bugs in the code... :vogel:

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Rhazul ()

    • Solange wld_gras present existiert wird irgendwas ausgeführt...
      Vieleicht sollte das instance_destory eine zeile höher.
      Und wozu überhaupt while? with durchläuft doch schon alle instancen.
      Kopiere dies in deine Signatur, um es in deiner Signatur zu haben.
      Achtung: Dieser Beitrag läuft ende des Monats ab, bitte lese ihn noch vor dem Monatswechsel...
      Nach langer zeit wieder im Forum aktiv :D
    • Am einfachsten ist es du kopierst meinen Code komplett in ein Skript (kannst du "scr_FindGrassTile" oder so nennen) und das rufst du dann für jede Instance auf:

      GML-Quellcode

      1. //der Code sollte nur einmal aufgerufen werden wenn die Generation fertig ist (vielleicht dahin wo du global.GeneratingIslands setzt)
      2. with(wld_grass_preset) {
      3. scr_FindGrassTile();
      4. }


      Wichtig ist das du den Code nur einmal ausführst nicht jeden Step, weil wir ja nur einmal raus finden müssen wo Wasser ist und wo nicht.

      Zu deinem Code:

      Du musst die up, down... Werte innerhalb einer wld_grass_preset Instance rausfinden, weil sonst zeigt ja "x" und "y" nicht auf die Instance die wir ändern wollen zeigt, sondern auf eine Instance von dem Objekt "spriter". Die While-Schleife brauchst du überhaupt nicht und sorgt nur dafür das dein Spiel in einer Endlosschleife einfriert.
      wupto.net/ Nicht meine Seite!
      We love Koalas.

      GM-D-Spam-o-Meter: 32%
    • Danke an euch alle! Ihr habt mir den richtigen Denkanstoß gegeben! :thumbsup:

      Das mit den Variablen innerhalb der With Schleife war das entscheidene, war ein sehr dummer Fehler von mir.
      Habe das While entfernt und siehe da, es läuft wie geschmiert!

      Danke sehr und seit gespannt wann es demnächst bei Steam Greenlight "MagicMaster" zu kaufen gibt! xD
      132 little bugs in the code. 132 little bugs. Fix a few, set the compiler to stew, 172 little bugs in the code... :vogel: