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

Re: [pygame] how to bind surface rects without subsurface (need help with bug)



Thanks Patrick, your feedback is greatly appreciated. I'm surprised you took the time to _really_ get to know my code.

I know it's a big mess right now. I cleaned it up a lot the last few weeks, and I even had functionality to find the player offscreen and pre-scroll before the map loads, but I took that and a few other buggy pieces out as I am trying to iron out as much as I can at this point before moving forward. I didn't really know what I was doing when I started tis project, and just sort of ran with it ever since. By the way, I have worked on this project everyday since 01.08. Over a year, and I can't believe how much I learned. With that said, after reading your explanations and suggestions, I have a much better idea of how my game works, and how it could work so much better with half of that unneeded code.

About your solution; the reason I have 3 layers, is so that they will draw in the order bg, player, fg. If you think about it, the foreground shouldnt have anything in front of it...except maybe another foreground with translucent scrolling clouds or something similar. Your solution did fix the problem, and it was what I asked for, but the player can walk through the huge tree trunks...nothing obscures him. I know you offered a solution of using a single pointer instead of 2 surfaces, which would even be more efficient, but I'd like to clean the code up as is right now, so another guy can dive in and help easier.

Thanks for the criticism,
Mike

Sure.  I love looking at other peoples code for problems.  (Honestly,
it's a lot more fun than trying to find problems in code I wrote)

This was hard, because while your code is not bad per say, there is a
lot of indirection, and much overengineering going on.  There are too
many strong connections between classes (like the player having to
know about the background and the foreground), and this coupling makes
it very inflexible.

In this case, the problem is simply a matter of ordering.  The
background is updated, then the player, then the foreground.  When you
start scrolling the screen (from the player update), the background
has already run it's update for that frame, while the foreground gets
to run its update with the move command.  So it is a frame ahead of
the background.

In scene.py, if you change the order that objects are updated:

               self.render.add(self.map.background)
               self.render.add(self.map.foreground)
               self.render.add(self.player)

Then the player will set up the scrolling for the next frame, which
fixes the problem.  A better way to do cameras, instead of having it
happening in the player movement function, is to have a separate
camera update that scrolls the right direction at a maximum speed
until whatever it is focused on is within some region of the screen.
That way if you start the player offscreen, the camera will still be
able to find him.  Also, for cutscenes, you can have the camera focus
on a different character than the player fairly easily.

Another thing that bugged me: It seems weird that you have limited
yourself to only two layers in the code, when any number of layers
would actually be easier.  A map.move() function, which moves all of
its layers by a set amount, means one less line all of the places you
have to write "background.move... foreground.move", and would also
solve the above problem (because the movement happens instantly
instead of waiting for some update).  And in the map, instead of
having background, and foreground, you could simply have layers[].  In
the future, when you want to add a paralax treeshadow layer to display
on top of the player and npc's, you will be hitting yourself at all of
the places you will have to add the new layer.

Good luck with the game, the sprites/tiles look really nice, and the
code isn't all bad :)