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

2009-03-11 Thread Michael Fiano
Makes so much more sense now...and that worked great.

Thanks :)

/me does a little happy python dance

On Tue, Mar 10, 2009 at 12:34 PM, Patrick Mullen wrote:

> Yep, changing the layer order is just a quick fix, not a real
> solution.  You can keep the layer order you had before, and add a
> move_layers function to the map.  Give the player a reference to the
> map instead of the two layers, and call move_layers in the spots you
> are setting the background.move and foreground.move.  Map.move_layers
> would look something like this:
>
> def move_layers(self, amount):
>for layer in [self.background, self.foreground]:
>layer.dirty = 1
>layer.rect.move_ip(amount)
>
> Actually, it might be even better to just make move a function instead
> of an attribute on TileLayer.  You will have to change less code (but
> will still have the ugly bg/fg references in player).
>
> class TileLayer(pygame.sprite.DirtySprite):
>def __init__(self, screen, layer, w, numx, h, numy):
>self.screen = screen
>pygame.sprite.DirtySprite.__init__(self)
>if layer == 'fg':
>self.image = pygame.Surface((w*numx,h*numy),
> SRCALPHA, 32).convert_alpha()
>else:
>self.image =
> pygame.Surface((w*numx,h*numy)).convert()
>self.rect = self.image.get_rect()
>
>def move(self):
>self.dirty = 1
>self.rect.move_ip(self.move)
>
> Then in player you would say:
> self.background.move([self.movement, 0])
> self.foreground.move([self.movement, 0])
>
> etc.  Instead of assigning to those values.
>
> The real problem is that you are delaying an action until the update
> functions when it is really (in this case) an in-place action.
>


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

2009-03-10 Thread Patrick Mullen
Yep, changing the layer order is just a quick fix, not a real
solution.  You can keep the layer order you had before, and add a
move_layers function to the map.  Give the player a reference to the
map instead of the two layers, and call move_layers in the spots you
are setting the background.move and foreground.move.  Map.move_layers
would look something like this:

def move_layers(self, amount):
for layer in [self.background, self.foreground]:
layer.dirty = 1
layer.rect.move_ip(amount)

Actually, it might be even better to just make move a function instead
of an attribute on TileLayer.  You will have to change less code (but
will still have the ugly bg/fg references in player).

class TileLayer(pygame.sprite.DirtySprite):
def __init__(self, screen, layer, w, numx, h, numy):
self.screen = screen
pygame.sprite.DirtySprite.__init__(self)
if layer == 'fg':
self.image = pygame.Surface((w*numx,h*numy), SRCALPHA, 
32).convert_alpha()
else:
self.image = pygame.Surface((w*numx,h*numy)).convert()
self.rect = self.image.get_rect()

def move(self):
self.dirty = 1
self.rect.move_ip(self.move)

Then in player you would say:
self.background.move([self.movement, 0])
self.foreground.move([self.movement, 0])

etc.  Instead of assigning to those values.

The real problem is that you are delaying an action until the update
functions when it is really (in this case) an in-place action.


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

2009-03-10 Thread Michael Fiano
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 :)
>


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

2009-03-09 Thread Patrick Mullen
On Mon, Mar 9, 2009 at 10:31 PM, Michael Fiano  wrote:
> I realize my code isn't the best code there is, but it's also my first
> programming project and I've been teaching myself all sorts of things
> as I go. But, could someone please take a look at code and
> tell me why the foreground isn't aligned when scrolling? To reproduce,
> you'll have to move the player toward the right side of the screen
> until it scrolls the map, and while it does pay attention to the huge
> trees and other foreground objects such as the tall grass.

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 :)


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

2009-03-09 Thread Michael Fiano
I have been working on a game for a while, and ran into a problem. I am
drawing layers with a background, player, and foreground layer. The
forground is transparent and redraws treetops and stuff the user should
always be in front of. That works great, however I cannot find any
logic in my code as to why The foreground layer is slightly offset by 3
or 4 pixels when the map is scrolling (the map scrolls when the player
is within range of the screen's edge).

I realize my code isn't the best code there is, but it's also my first
programming project and I've been teaching myself all sorts of things
as I go. But, could someone please take a look at code and
tell me why the foreground isn't aligned when scrolling? To reproduce,
you'll have to move the player toward the right side of the screen
until it scrolls the map, and while it does pay attention to the huge
trees and other foreground objects such as the tall grass.

You can grab the source at
http://bloodcurse.axedcode.net/files/bloodcurse-0.1-week61.tar.gz

Thanks for all the help,
Michael Fiano