Utilizing a (long) list of coordinates in a function.

Started by newwaveburritos, Mon 04/09/2023 22:18:44

Previous topic - Next topic

newwaveburritos



So, I'm using the @eri0o Mode 7 module and it's working great with one little exception which isn't really related to the module itself but a problem more broadly so I thought I would start a new thread.

The code to add an object to the "ground" sprite is as such:

Code: ags
Mode7Object* Mode7World.AddObject(int x, int z, float factor, int graphic)

I want to randomly populate the ground with trees and rocks.  So far so good, he does this himself in the demo.  The problem is that I don't want rocks and trees to be drawn into the road and I don't know a good way to do this.  The sprite I am using is roughly 3000x800 which makes it feel huge.  I assume going over the sprite with GetPixel is out since that's like 2.5 million pixels to iterate through.  And also there are two colors to disallow not just one (the black of the highway and the yellow painted lines).  I have a Python script that takes a mask of the highway portion of the ground sprite and returns a CSV with the appropriate coordinates but that's still like 600,000 coordinates and I don't think making an array of Points of 600,000 is a really good answer and I'm not even sure how that would be done anyway.  It doesn't need to be pixel perfect, however.  That is there isn't a real need to tell it not to draw a tree on 0,345 0,346, 0,347 0,348 et al. since a block of fifty pixels to allow or disallow is probably sufficient.  You could also anticipate the disallowed shape somewhat by using a pattern (like maybe a sine wave or something) although I'm going to be using a few different maps just to give variation to the highway.  I'm only kind of trying to recreate Desert Bus here!

The short version is that I somehow need to supply that function with "correct" coordinates so that it can draw the objects but not in particular places.  Anyway, thanks for reading!

newwaveburritos

It occurred to me just now that I might be approaching this backwards.  It might make more sense to figure out where not to draw the trees and rocks first and then make the map match that rather than make the trees and rocks match the map since it's all relatively arbitrary. 

Khris

You don't have to go over every single pixel. All you need to do is check the color of the map after you generated random coordinates.
Assuming you're going to place 100 objects and assuming the track covers 20% of the ground, you will make roughly 120 GetPixel calls (since about one in five times you need to choose a new location).

Code: ags
  int x, z;
  for (int i = 0; i < 100; i++) {
    bool found = false;
    while (!found) {
      x = Random(2999);
      z = Random(799);
      int c = ds.GetPixel(x, z);
      found = c != 12345 && c != 7890; // actual yellow and black go here
    }
    track.AddObject(x, z, factor, graphic);
  }

(Even if you had to do it backwards, you said it yourself: use blocks of 50x50. As in: resize the map to 1/50 of its original size before running GetPixel over it. But again: you do not have to do that at all.)

newwaveburritos

Thanks @Khris your willingness to always help out and write ten lines of code that solves a relatively complicated problem always floors me.  This isn't actually working lol but I think it actually is working and only appears not working because there is something up with the coordinates.  At first I thought it was because the highway was black like Color Number 0 and I remember GetPixel is a little weird about the first colors which I always use stylistically but when I changed it to a weird green it still happened. 

Eventually I had the idea to make a coordinates tracker debugger and when I drive to the edge of the map it's actually got my coordinates at like -1500 so I think there is something going on there and I just need to figure out how the coordinates relate to the map.  I think I'm gonna drive around in the woods a lot!

Khris

You're welcome :)

Maybe the plane has the origin at its center? I.e. you'd need x = Random(2999) - 1500; and same for z.

newwaveburritos

That's definitely part of it.  I fooled around with various figures quite a bit last night and didn't quite get it.  Steps that I took: shrunk the map to make it a little bit easier to take in.  Changed the colors from EGA yellow and black to random colors just to rule out the GetPixel 8 bit color shenanigans.  It's definitely now populating the map with the correct boundaries but doing something else that's curious.  If that code weren't working I would assume that when I increase the for loop iterations it would just completely populate the map with trees but that's not what it's doing.  It's not populating part of the map but I can't figure out what kind of rules it's using.



Code: ags
function khrisTrees(){
  
  
    DynamicSprite* highway = DynamicSprite.CreateFromExistingSprite(9);
    DrawingSurface* ds = highway.GetDrawingSurface();
    int x, z;
    
    for (int i = 0; i < 800; i++) {
      bool found = false;
      while (!found) {
        x = Random(600)-300;
        z = Random(600)-300;
        int c = ds.GetPixel(x, z);
        found = c != 6812 && c != 7127; // actual yellow and black go here
      }
    m7.AddObject(x, z, 0.4, 7);
    }
}

SMF spam blocked by CleanTalk