Topic: Dung - The Dungeon Generator (Read 812 times)

  • Avatar of goldenratio
  • now das fresh
  • PipPipPipPipPipPipPipPipPipPip
  • Group: Member
  • Joined: Jun 27, 2002
  • Posts: 4550
Yeah that's legitimate. I should fix that. That's probably next, dividing up the screen into a "map" area and a "hud" or whatever. Or at least leave a margin or something and make the text show up in there.

Also fyi if you press space it will make a new map.
yes coulombs are "germaine", did you learn that word at talk like a dick school?
  • Avatar of Biggles
  • I know your secrets
  • PipPipPipPipPip
  • Group: Premium Member
  • Joined: May 5, 2005
  • Posts: 688
Thanks for posting the source version. It's nice to see a game posted here that I can run on Linux. It's always really disappointing when someone someone posts something I want to try and it's windows-only. Your code is also really legible, especially compared to some other pygame projects I've read in the past.

I also have a suggestion to improve the fluidity of the movement code: the "requires perfect alignment when going through gaps" seems to have been solved in a couple of different ways (that I have noticed) in commercial 2D games. One way is by using tile based movement, but tile based movement sucks unless you're making a puzzler or RPG and sometimes it even sucks then. The way I like better for pixel-based movement is that the game detects if a player has just missed a gap and sort of pulls them sideways at about one pixel per frame until the hitbox is aligned so that they can go through. It tends to trigger when about half your hitbox or so is over the gap, which sort of looks natural. You can find it in a lot of the 2D Zeldas, and it's easy to imagine that they would feel much clunkier without this minor detail. For example, near the start of that video where the player rolls into the corner slightly, if the game did not autocorrect his movement he would have just stopped awkwardly because the game doesn't allow direction change / influence during a roll.

I was actually going to suggest code to implement this in 'World.py' (particularly as a proof of concept to myself that this really does improve the way movement feels) but to tell the truth I'm stuck as to how gap detection would best be done. On the one hand, you could write a function that just iterates all walls and checks if there's an adjacent wall to the one you're colliding with in the direction you're moving in,  and then returns whether it's above, below, left or right of you, or whether there isn't one. This seems kind of wasteful, though. It requires an extra O(n) on the number of walls every time you collide, and the code hardly sounds elegant. On the other, you could have each wall store the walls above, below, left and right of it as a kind of 'linked grid', but this seems like unnecessary bulk added to the walls class.

So yeah, sorry for providing you with a big long description of the suggestion for such a minor detail and then not helping at all on the implementation. I thought it might be useful to post anyway because I think a lot of people don't know about this whole auto-cornering thing and if my theory about how it works is correct then it might help more than one game be less clunky.
  • Avatar of goldenratio
  • now das fresh
  • PipPipPipPipPipPipPipPipPipPip
  • Group: Member
  • Joined: Jun 27, 2002
  • Posts: 4550
Well by decreasing the collision rectangle for the player when checking for walls, it should let you "start entering" the gap, and the type of collision detection I do actually does nudge the player back outside the wall, but I think my code doesn't do the "move" correctly. Perhaps decreasing the size of that rectangle even more (I do it like 2-3 pixels right?) and double-checking the "move back" stuff would make it work.
yes coulombs are "germaine", did you learn that word at talk like a dick school?
  • Avatar of Biggles
  • I know your secrets
  • PipPipPipPipPip
  • Group: Premium Member
  • Joined: May 5, 2005
  • Posts: 688
The "move back" stuff seemed to be working fine when I played the game, but that's not going to draw them into the gap, is it? Also wouldn't using a much much smaller rect in colliding with walls just result in a weird looking overlap? Maybe I'm understanding you wrong.
  • Avatar of goldenratio
  • now das fresh
  • PipPipPipPipPipPipPipPipPipPip
  • Group: Member
  • Joined: Jun 27, 2002
  • Posts: 4550
yeah you're probably right. I have no idea how to implement any of the stuff you said though so I'll just be thinking about it. If you have any ideas let me know.

The only way I can imagine it working, is to check if less than a certain % or number of pixels is touching the wall, and if the direction you are moving has an open space you CAN move it, then move you there. It's seems fairly simple, but I can't think of a good algorithm that wouldn't be hugely wasteful. I mean I guess at MOST i'd need to check 8 tiles (the tiles directly around the player), and really only 3 (the 3 in the direction you are moving), so maybe i'll try some of this. It would need to be smooth, is the only thing, so I'd have to actually animate diagonally and stuff, I think. Hmm...

Also the next thing I was thinking of implementing was enemies, with some A* pathfinding.
Last Edit: August 13, 2009, 05:49:39 am by Gabriel
yes coulombs are "germaine", did you learn that word at talk like a dick school?
  • Avatar of the bloddy ghost
  • ::pulls another Hideo Kojima::
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Mar 25, 2003
  • Posts: 1050
do you know of any good websites that describe A* pathfinding in detail?
has a girl in his bed. pot in his pipe and family guy on the tube. i like life
  • Avatar of goldenratio
  • now das fresh
  • PipPipPipPipPipPipPipPipPipPip
  • Group: Member
  • Joined: Jun 27, 2002
  • Posts: 4550
http://www.policyalmanac.org/games/aStarTutorial.htm

This one explains it very well. Here's part two (havent read this yet, just found it now): http://www.policyalmanac.org/games/twoTiered.htm

Also if you're making games with python, have you read Beginning Game Development with Python and Pygame? PM if you want a copy, its really really good, has awesome examples with all sorts of stuff. It doesn't seem to go over gravity and stuff like that, which sucks, but it gives very good intros on Vectors and state machines and things. It's a really good book, IMO.
Last Edit: August 13, 2009, 06:07:58 am by Gabriel
yes coulombs are "germaine", did you learn that word at talk like a dick school?
  • None of them knew they were robots.
  • PipPipPipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Nov 5, 2006
  • Posts: 3242
I once coded A* from the wikipedia article on it because it was more abstract, I always saw those A* tutorials where they show those tiled maps and I never understood how to implement them on anything other than tiles
Play Raimond Ex (if you haven't already)


I'll not TAKE ANYTHING you write like this seriously because it looks dumb
  • Avatar of Dale Gobbler
  • Meh.
  • PipPipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Dec 24, 2003
  • Posts: 2079
I probably wouldn't use it, but it looks like a well constructed, functional pile of crap. :fogetnaughty:
m
ohap
  • Avatar of goldenratio
  • now das fresh
  • PipPipPipPipPipPipPipPipPipPip
  • Group: Member
  • Joined: Jun 27, 2002
  • Posts: 4550
Mince, to use an A*-like algorithm without tiles, you would use "nodes" instead. The nodes could be like waypoints you place on a map, or calculated like tiles, but the nodes themselves (which are just points) are like the "tiles" you see in the tutorials.
yes coulombs are "germaine", did you learn that word at talk like a dick school?
  • None of them knew they were robots.
  • PipPipPipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Nov 5, 2006
  • Posts: 3242
Mince, to use an A*-like algorithm without tiles, you would use "nodes" instead. The nodes could be like waypoints you place on a map, or calculated like tiles, but the nodes themselves (which are just points) are like the "tiles" you see in the tutorials.

I know, I already did that I just didn't understand from reading the tile based a* tutorials that the tiles were in fact the "nodes" due to poor attention span

Play Raimond Ex (if you haven't already)


I'll not TAKE ANYTHING you write like this seriously because it looks dumb
  • Avatar of goldenratio
  • now das fresh
  • PipPipPipPipPipPipPipPipPipPip
  • Group: Member
  • Joined: Jun 27, 2002
  • Posts: 4550
jeez louise, thanks a lot aztec.
yes coulombs are "germaine", did you learn that word at talk like a dick school?
  • Avatar of the bloddy ghost
  • ::pulls another Hideo Kojima::
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Mar 25, 2003
  • Posts: 1050
if you want, I can post my A* code here that I just got functioning. it probably has a few bugs.
has a girl in his bed. pot in his pipe and family guy on the tube. i like life
  • Avatar of goldenratio
  • now das fresh
  • PipPipPipPipPipPipPipPipPipPip
  • Group: Member
  • Joined: Jun 27, 2002
  • Posts: 4550
hell yes bro
yes coulombs are "germaine", did you learn that word at talk like a dick school?
  • Avatar of the bloddy ghost
  • ::pulls another Hideo Kojima::
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Mar 25, 2003
  • Posts: 1050
def pathfind(startx=0,starty=0,endx=4,endy=0):
notdone = 1
crashguard = 0
#Add the starting square (or node) to the open list.
openlist = [[startx,starty, 0, (abs(startx - endx * 10))+(abs(starty - endy*10))]]
closedlist = []
inlist = 0
while notdone:
lowestf = openlist[0]
entity.DBmsg("Starting Pathchecking loop...")
#Repeat the following:
for f in openlist:
#a) Look for the lowest F cost square on the open list. We refer to this as the current square.
if f[2]+f[3] < lowestf[2]+lowestf[3]:
lowestf = f
#b) Switch it to the closed list.
closedlist.append(lowestf)
entity.DBmsg("Added:" + str(lowestf[0]) +"," + str(lowestf[1]) + " to path list.")
if lowestf[0] == endx and lowestf[1] == endy:
notdone = 0
for f in openlist:
if f == lowestf:
openlist.remove(f)
pass
for x in range (0,3):
for y in range(0,3):
#If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following.
if game.levels[game.gv_currentdungeon].map[lowestf[0]-1+x][lowestf[1]-1+y] == 1:
entity.DBmsg("Can't add that square.")
pass
else:
if x == 0 and y == 0:
listcheck = [lowestf[0]-1+x,lowestf[1]-1+y,14,(abs(lowestf[0]-1+x - endx * 10))+(abs(lowestf[1]-1+y- endy*10))]
else:
listcheck = [lowestf[0]-1+x,lowestf[1]-1+y,10,(abs(lowestf[0]-1+x - endx * 10))+(abs(lowestf[1]-1+y- endy*10))]
for f in openlist:
if inlist == 0:
#If it is on the open list already, check to see if this path to that square is better, using G cost as the measure.
                                                        #A lower G cost means that this is a better path. If so, change the parent of the square to the current square,
                                                        #and recalculate the G and F scores of the square. If you are keeping your open list sorted by F score, you may need to resort the list to account for   
                                                        #the change.
if f[0] == listcheck[0] and f[1] == listcheck[1]:
inlist = 1
if listcheck[2] < f[2]:
openlist.remove(f)
openlist.append(listcheck)
else:
inlist = 0
openlist.append(listcheck)
crashguard += 1
if crashguard == 1000:
return closedlist
return closedlist
it's very buggy. any ideas on how to fix it?
Last Edit: August 14, 2009, 06:29:54 am by Tomato
has a girl in his bed. pot in his pipe and family guy on the tube. i like life