[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] My solid tile detection doesn't work



Yes, playerpos and tilepos are supposed to be the same domain. I
realised that the camera coordinates were not taken into
consideration. When I did take them into consideration, it only
reported the right tile when I moved horizontally. Vertical motion is
still all wonky. I relabelled the player coordinates so I could
walkthrough my algorithm more clearly. I'm still at a loss as to what
I'm doing wrong...

On 7/22/06, Brian Fisher <brian@xxxxxxxxxxxxxxxxxxx> wrote:
I assume that the problem you have is that the player draws over
different tiles than the attached code is saying the player is moving
over?

If that's the case the code you sent could be perfectly correct, or it
could be wrong, it really depends on how the coordinates in these
routines are interpreted by other parts of the system, like when you
blit... what I'm thinking of is that it's impossible to tell from this
code alone whether the player_x and player_y values you pull from
player_pos are supposed to be in the same domain as the computed
"truex" and "truey" for a tile - meaning are they both supposed to be
used in the exact same way & are they supposed to be comparable (i.e.
do you blit tiles at truex,truey and players at playerx,playery?)

My general tip for doing stuff with coordinates is to always think of
different coordinates as being parts of different named coordinate
systems or domains, and always name variables with a suffix that makes
the coordinate system explicit. Like if coordinates can be blit to the
screen, they could be "player_screen_x", if they are supposed to be
map grid locations it might be "player_map_grid_x" if it's supposed to
be a pixel offset in the map it might be "player_map_pixel_x". It may
seem like a lot of typing at first, but it really makes you think
about coordinates more, and in the end you are typing lines that read
like English sentences, so it's easier for you to know if the line is
doing the right thing at a glance, and it's really easy for other
people to look at your code.

So one thing I notice is that your mapping from a "tilepos" to a
"true" position for all your tiles depends on the values of starty and
startx and xoff and yoff, while the mapping from "playerpos" to a
"tilepos" doesn't use startx and starty or xoff and yoff at all - so
if both "true" coordinates and "player" coordinates are in the same
domain (like if you pass them directly to pygame to blit) then your
mappings aren't symmetric when any of startx, starty, xoff and yoff
are non-zero.

And if playerpos and tilepos are not supposed to be the same domain
(i.e. there is some other mapping of playerpos and "truex, truey"
before they get blit), then there may be problems with that other
coordinate mapping code in addition to any problems that might exist
in this code.

On 7/22/06, Adeola Bannis <thecodemaiden@xxxxxxxxx> wrote:
> In my little RPG engine-like thing that no one tested, *wink wink*, I
> tried implementing solid tiles. My algorithm doesn't work, and I don't
> know why.
>
> This is the code I use to place tiles onscreen, only the important
> half of the function:
> ---code---
> for y in range(starty, endy):
>         for x in range(startx, endx):
>                 tilepos = y*(self.mapw) + x; #The position in our array of tiles
>                 showx = x - startx; showy = y - starty  #Adjust the position of map
> by blitting it to the top
>                 truex = (showx*tilesize-xoff); truey = (showy*tilesize-yoff)
>                 #print endy
>                 tilenum = self.tiles[tilepos]
>                 self.put_tile(tilenum,(truex,truey), screen)
> ---code---
>
> and this is the code I used to look for a solid tile:
>
> ---code---
> player_x, player_y = player_pos
>                 p_tilex = player_x//tilesize; p_tiley = player_y//tilesize
>                 n_tilex = n_tiley = 0
>
>                 if direction == 'left':
>                         n_tilex = (player_x - speed)// tilesize
>                 if direction == 'right':
>                         n_tilex = (player_x + speed)//tilesize
>                 if direction == 'up':
>                         n_tiley = (player_y - speed)//tilesize
>                 if direction == 'down':
>                         n_tiley = (player_y + speed)//tilesize
>
>                 if (n_tiley == p_tiley) and (n_tilex == p_tilex):
>                         return False
>
>                 if (p_tilex != n_tilex): # we are moving to a new tile horizontally
>                         n_tilepos = p_tiley*self.mapw + n_tilex # the position in our array of tiles
>
>                 if (p_tiley != n_tiley): #we are moving to a new tile vertically
>                         n_tilepos = n_tiley*self.mapw + p_tilex # the position in our array of tiles
>
>                 tilenum = self.tiles[n_tilepos]; print tilenum
>                 return (tilenum in self.solid)
> ---code---
>
> I didn't want to put all that in... what I basically wanted to point
> out was that I was getting the  tile number the exact same way I did
> when I was drawing the map. Yet I usually get a completely different
> tile to the one the player is walking into. Can anybody help me out
> here?
>
> Adeola
>