Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: newwaveburritos on Thu 06/10/2022 20:37:38

Title: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Thu 06/10/2022 20:37:38
I'm trying to write some script that renders a first person dungeon crawler screen and while I think this would work I don't really believe it's the simplest way to do it but also I can't think of a better way to do it rather than just brute force.

Code (ags) Select
function renderVisionCone()
{
  if (playerChar.faceDir==eFaceUp){
   
    clearScreen();
    MazeType tile0 = GetCell(playerChar.x-2, playerChar.y-3);
    if (tile0==eMazeWall){
      DynamicSprite.Create(620, 400);
      DrawingSurface *dungeonWalls = Room.GetDrawingSurfaceForBackground();
      dungeonWalls.DrawImage(0, 0, BACK_LEFT);   
      dungeonWalls.Release();
    }
 
    MazeType tile1 = GetCell(playerChar.x-1, playerChar.y-3);
    if (tile1==eMazeWall){
      DynamicSprite.Create(620, 400);
      DrawingSurface *dungeonWalls = Room.GetDrawingSurfaceForBackground();
      dungeonWalls.DrawImage(0, 0, BACK_MIDDLE_LEFT);   
      dungeonWalls.Release();
    }
 
    MazeType tile2 = GetCell(playerChar.x, playerChar.y-3);
    if (tile2==eMazeWall){
      DynamicSprite.Create(620, 400);
      DrawingSurface *dungeonWalls = Room.GetDrawingSurfaceForBackground();
      dungeonWalls.DrawImage(0, 0, BACK_MIDDLE);   
      dungeonWalls.Release();
    }
   
    //MazeType tile3...
    //this times ten plus one more for each cardinal direction == bad times.
   
  }
 
}

EDIT: I realize now I have my coordinates incorrect but I don't think that really affects the concept too much.
EDIT EDIT: I fixed the coordinates.  I was think there were only 10 tiles I needed to render but there are actually 13.
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Thu 06/10/2022 21:20:42
Okay, this is already a lot better but I think if I arrange the sprites in the order that I need to populate them then I can iterate through them or something like that.

Code (ags) Select
function renderVisionCone()  //draws the walls
{
 clearScreen();
 DynamicSprite.Create(620, 400);
 DrawingSurface *dungeonWalls = Room.GetDrawingSurfaceForBackground();
 
     
  if (playerChar.faceDir==eFaceUp){
   
   
    MazeType tile0 = GetCell(playerChar.x-2, playerChar.y-2);
    if (tile0==eMazeWall){
      dungeonWalls.DrawImage(0, 0, 18);   
    }
 
    MazeType tile1 = GetCell(playerChar.x-1, playerChar.y-2);
    if (tile1==eMazeWall){
      dungeonWalls.DrawImage(0, 0, 12);   
    }
 
    MazeType tile2 = GetCell(playerChar.x, playerChar.y-2);
    if (tile2==eMazeWall){
      dungeonWalls.DrawImage(0, 0, 4);   

    }
   
    //MazeType tile3...
    //this times ten plus one more for each cardinal direction == bad times.
   
  }
 
}
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: eri0o on Thu 06/10/2022 21:48:14
Made one first person dungeon crawler open source in gh here, is the specific maze renderer: https://github.com/ericoporto/galleys/blob/main/DungeonCraw/MazeRenderer.asc

The algorithm/original code is not mine, the game/assets were posted on Open Game Art and I picked up from there. Perhaps it could be useful as inspiration.

Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Fri 07/10/2022 02:11:01
Quote from: eri0o on Thu 06/10/2022 21:48:14Made one first person dungeon crawler open source in gh here, is the specific maze renderer: https://github.com/ericoporto/galleys/blob/main/DungeonCraw/MazeRenderer.asc

The algorithm/original code is not mine, the game/assets were posted on Open Game Art and I picked up from there. Perhaps it could be useful as inspiration.



Lol, I had no idea such a thing existed.  I've already gotten the pathfinding figured out.  But it was a really good exercise in coding since I felt out of my depth the whole time.  This will surely be useful in my endeavors, though, so thanks! EDIT: @eri0o Oh, and there was a comment in there that really saved my bacon.  Draw order is important and I wouldn't have realized that for a long time!!
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Fri 07/10/2022 03:37:03
Dang, I tried to post the whole monster function and it's so long that it gets caught in the spam filter.  :-\
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: Khris on Fri 07/10/2022 08:29:30
You can put it on pastebin (https://pastebin.com/) and post the link.

When I did this last, I used an array of coordinate offsets: [-2, -2], [-1, -2], etc. (in AGScript you can use an array of points for this).
Next I would rotate a copy according to the direction; a 90° rotation means swapping x and y and either x's or y's sign.
A 180° rotation is easier: swap both x's and y's sign.

Then I'd iterate over the rotated offset array and add it to the player position to get the grid coordinate.
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Fri 07/10/2022 11:59:40
Here's the link. (https://pastebin.com/TLrxPzVF)

@Khris Some of that should look a little familiar as I was using a lot of what you explained last time you posted about this.
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: Khris on Fri 07/10/2022 12:45:41
Here's the offset rotation method:

Code (ags) Select
int wallSprites[15];

function game_start() {
  /* wall sprites, 3 rows and 5 columns (eFaceUp)
      14 10  9  3 13
       0  8  2  7  0
       0  6  X  5  0
  */
  wallSprites[0] = 14; wallSprites[1] = 10; wallSprites[2] = 9; wallSprites[3] = 3; wallSprites[4] = 13;
  wallSprites[6] = 8; wallSprites[7] = 2; wallSprites[8] = 7; wallSprites[11] = 6; wallSprites[13] = 5;
}

int[] rOffset(int x, int y, Direction dir) {
  int r[] = new int[2];
  if (dir == eDirUp) { r[0] = x; r[1] = y; } 
  if (dir == eDirDown) { r[0] = -x; r[1] = -y; } 
  if (dir == eDirLeft) { r[0] = y; r[1] = -x; } 
  if (dir == eDirRight) { r[0] = -y; r[1] = x; } 
  return r;
}

function renderVisionCone() //draws the walls
{
  clearScreen();
  DrawingSurface * dungeonWalls = Room.GetDrawingSurfaceForBackground();

  // iterate over cone
  for (int y = -2; y <= 0; y++) {
    for (int x = -2; x <= 0; x++) {
      // rotate offset to find correct cell
      int ro[];
      MazeType mt;
      int sprite;
      ro = rOffset(x, y, playerChar.faceDir);
      mt = GetCell(playerChar.x + ro[0], playerChar.y + ro[1]);
      if (mt == eMazeWall) {
        sprite = wallSprites[(y + 2) * 5 + (x + 2)];
        if (sprite > 0) dungeonWalls.DrawImage(0, 0, sprite);
      }
      if (x < 0) {
        ro = rOffset(-x, y, playerChar.faceDir);
        mt = GetCell(playerChar.x + ro[0], playerChar.y + ro[1]);
        if (mt == eMazeWall) {
          sprite = wallSprites[(y + 2) * 5 + (-x + 2)];
          if (sprite > 0) dungeonWalls.DrawImage(0, 0, sprite);
        }
      }
    }
  }
}

(Probably a bunch of typos in there)

edit: fixed renderVisionCone()
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Fri 07/10/2022 17:19:40
Actually, it worked with very little editing.  One problem is that I think the iterating has to be done out of order or you end up with part of a wall in front. The other part where there's a wall where there shouldn't be I can't really explain.

Video (https://gyazo.com/bea2fe0bc0acdfb08f3e4d4c150fa67f)
Full code (https://pastebin.com/b5puAht3)

Thanks for the help, though!

EDIT: I think I see how to fix the first bit by assigning the sprites to the wallSprites array in a different order.
EDIT EDIT: Sprites 3 and 9 were transposed in the assignment which solves the second part.  Fooling with the order they are assigned is giving very curious results, though.  I should also note that the fact that you figured out which sprite is which based on that meandering function is pretty astonishing.
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: Khris on Fri 07/10/2022 17:50:52
My code is supposed to draw from far to near but let me check my code and get back to you.
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Fri 07/10/2022 18:13:27
Quote from: Khris on Fri 07/10/2022 17:50:52My code is supposed to draw from far to near but let me check my code and get back to you.

It does do that but this comment from Eri0o's code helped me with the order:

/**
The visibility cone is shaped like this:
 
.........
..VVVVV..
..VVVVV..
...V@V...
.........
Drawing is done in this order (a=10, b=11, c=12)
.........
..02431..
..57986..
...acb...
.........
*/
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: Khris on Fri 07/10/2022 20:00:51
You're right, I forgot to draw the outer walls first. Fixed the cone code.
Title: Re: Help simplifying an unwieldy graphics function as for dungeon crawler
Post by: newwaveburritos on Sat 08/10/2022 04:47:17
Amazing work as always.  Thanks again!!