2019-03-18 00:33:13 (edited by amerikranian 2019-03-18 00:44:00)

So if anybody played Manamon or Paladin of the sky, they'd be familiar with this concept. For anybody who hasn't, here's a brief rundown.
When moving around, you'd hear tones in relationship to your character. Those tones represent walls, and made it hell of a lot easier for you to find your way through the mazes. I'm not gonna attempt building something like that, no. However, I was always wondering how did that happen. How did the computer know whenever I was near a wall?
As I learned python, that question became much less mysterious, and so here's my take on it, at least on paper.
First of all, I'm assuming that my map is a dictionary. I have tried using lists within a small 2d thingy I've built, they broke, horribly. All I'm gonna say on that topic. I will also assume that we want to hear walls when they're 4 steps away from us.
Second, I would create a list with 4 values. The first 2 are for the left and right, and the second 2 are for forward and backward scans.
in my third step I would create a function that takes in player's x and y as it's parameters. When that's done, I would create two loops within that function, one for the x, and 1 for the y values. Those loops will scan the terrain (read, the dictionary), and retrieve the values from it. If any contain wall tiles, the fun will begin.
If it's in my x-range loop, I'd see if the x is less than or greater than the player's x coordinate. If it is, I would update the first 2 values within my list. If it's my y loop, I'd update the second 2 values.
The fourth and the final step would be me checking if any values equal 4, or the total number of iterations of the loops. Remember, the conditions would be something like for i in range(x-4,x+5). If the counters equal 4, it means there are no walls. If they aren't equal, well, that's when the sounds will come in. I should also mention that I would reset the list every time the function gets called.
So how far am I from the mark? Do I need to go back to the python school and relearn a thing or two? Is my solution more complicated than it needs to be? I'm curious as to what yall think. Even if my solution would work, is there a better method that vgstorm probably uses?

2019-03-18 01:30:34

It will always depend on how the whole map structure is designed and programmed. I most of the time will use a 2D array (or nested lists as in python) to represent a map, each entry will be a tile you can step on. That of course is only cool as long as the maps don't become too large, because thousands and thousands of living objects within a 2D array will take up a good amount of space which doesn't actually need to be there, it always depends on your need. Now imagine me wanting to know if there is a wall left of me, thus checking the x-axis to the left from the player's current position, and how far left it is from me. Imagine python code like this:

player_x = 5
player_y = 2
# imagine there is a wall 2 tiles away from me to the left, so at x = 3
distance = 0
i = player_x # we don't need to check all tiles further right, because we're checking for the left wall
for i in range(player_x, -1, -1):
  # we need to assume you know any way of type checking, like checking if objects are of the same kind, or adding a Type property to it or whatever, so just imagine this check getting applied in the if below
  if map[i][player_y] is Wall:
    distance = player_x - i
    break

In this case, distance would tell you the tiles to reach the wall. If it's zero, no wall could be found left from you. If you're now designing a radar, you'd like to implement a limit, as the radar will probably only check like 10 tiles from your current position, so you don't need to look further left than 10 tiles. Thats pretty easily done by adjusting the for loop:

radar_range = 10

# max will return the larger value. it ensures that you won't try to access negative indices within your map
for i in range(player_x, max(player_x - radar_range, 0), -1):
  # all the stuff from above
  pass

I hope that clarifies things. Over all, that kind of feature is not actually very hard to implement.
Best Regards.
Hijacker

2019-03-18 14:25:15

Without more information about your code it will be harder to give very detailed info, but I can think of two ways of representing a map:
1. Have a 2d array, for each coordinate have a value indicating what tile it is / any other properties
2. Have a list of objects such as walls, and write a function given values x and y which determines which object is on that square.
First method is simpler and works well for small maps, second method is somewhat more complicated but especially if you have large objects it'll work better with larger maps.
Now I don't remember how vgstorm games did this exactly but didn't they just scan directly to the left, directly in front, directly behind and directly to the right? if so you'll have to write a function given a min x, min y, max x, max y range which returns the coordinates of a wall if it is present and -1 otherweise with the assumption that your min coordinates are 0,0.
With the first map implementation this will require a loop, with the second the function shouldn't be that different from the single value function. In fact, you don't need a single value function, just pass the same values to the min and max variables.

Roel
golfing in the kitchen

2019-03-18 14:45:28

hello
What you are looking for, is something called raycasting
Basically, you have 4 ray scans. 1 to y in front, 1 to y behind, 1 to left, 1 to right
check for walls and play wall sounds accordingly, whenever the character moves.
Imagine it like a shadow following your character in this case 4 shadows.

The new unfinished version of danger on the wheel does it and it works quite nicely.

hth

ReferenceError: Signature is not defined.

2019-03-19 00:19:44

@4,  how is that different from what post 3 described with creating a function that scans to the left, the right, ahead, or behind you?  Can you please elaborate?
Of course, I over complicate it again. Looks like I will never learn that complex is better than complicated. Sigh

2019-03-19 04:37:49

The difference is that you don't scan per say, instead of moving only your character, you move 5 characters: your character and four pointers, one for each direction, at a certain distance. Because when you move left, you don't need to rescan tiles you already scanned the move before. However, you need to rescan the axis perpendicular to your movement. At least, that's what I understood from post 4.

However, I have another solution if you are not memory-bound and would prefer have better performance. Since the map is static, you can preprocess all that data and add it to the map data. This way, at runtime you just have to check the new tile your character is standing on and that's it. I don't know the feature you want, but say you want the distance of the closest wall from a tile in all directions, then add 4 fields to every tile: distWallLeft, distWallTop, distWallRight, distWallBottom. Then when you character moves on a tile, lookup those properties and if the value is under a treshold, play a sound or something.

If you stored your map differently, like a list of game objects, you still can burn that data in the map representation if you think about it, but it's always gonna be more memory, it's a tradeoff.

Reading is one form of escape. Running for your life is another. ― Lemony Snicket

2019-03-19 13:44:02

@6:
Ah, I see what you're getting at. Yes, such a system would also work. I'd only use raytracing for larger distances, though. It seems overly complex in this case. But if you ever want to extend your game it might be worth the effort.

Roel
golfing in the kitchen