|
From: Karl K. <kar...@ut...> - 2006-12-01 05:29:21
|
Hello to everyone, I'm Karl, and I picked up Pythoncard a few months ago
with a few specific projects in mind, but only recently started working on
them seriously. Anyway, I have a few questions and a lot of background
info on my project. Sorry about the length :)
Basically, I am going to be making a game engine that is specific to the
traditional tile-and-sprite system (HUD and in-world sprites overlaying a
tiled background) that is used to implement things like isometric or
forced-perspective tactics games and RPGs (but also platformers) - stuff
like you would have on a GBA or on cell phones, except developed on/for
desktop, in Python. :) I may end up using Pygame or something else
(possibly lots of my own C or C++ modules) for the engine itself (actually
there is also a "virtual machine" component as well; I want it to feel
like you're programming for the device via an emulator - except that it
groks Python), but I think PythonCard should be a good choice for some
editor tools, which are my starting point - a "tile editor" (really more
of a map-maker) and a "sprite editor" (for marking sprite coordinates on a
sprite sheet, and possibly moving them around too).
However, I've run into a few technical issues... I'd like to share a
couple of things I learned by experience (combined with lots of
surprisingly painful Googling) as well as asking a bunch of questions :)
- Key bindings were quite troublesome for me. I wanted "global" key
handling, not any kind of messing around with keyboard focus (although I
may revise that later). At first, I had some horrible hack that relied on
grabbing a reference to the global Application instance that was "running"
my Background subclass - and for reasons I don't understand, it would only
grab key-up events, not key-down ones. Nothing else seemed to work; using
.Bind() on the class really sounded like it was supposed to work, but it
had no effect.
Eventually I found a sample in some wxPython tutorials, from which I got
something that worked:
# in on_initialize of the Background subclass
panel = wx.Panel(self, -1)
panel.Bind(wx.EVT_KEY_DOWN, self.on_keyDown)
panel.SetFocus()
The key being creation of a separate Panel object. My questions are, (1)
why is this seemingly necessary? and (2) what is the -1 value passed to
the Panel constructor?
- I want to represent sprite rectangles on the sprite-sheet by "shading"
them via alpha-blending towards a solid colour. The idea being that you
would see (and be warned about) overlapping sprite areas automatically,
because the shading effect would double up.
So far I have only found one hack that will accomplish that, and it's
quite ugly and seems not to work in some cases for reasons I don't
understand (but I probably just have to do some debugging). This is,
create a texture filled with solid colour, and .Blit() from it. This is
nasty because (a) it only works for rects (doesn't give me the effect I
really want, which is that of a translucent Pen or Brush); (b) may
require multiple blits unless you have a large texture set up, and will
thus be driven by somewhat complex code.
I would do it manually in Python, but you can only get a read/write buffer
for an Image, and you need a Bitmap for drawing to the screen, and the
conversion costs are unacceptable (I need the effected region to change in
near-real time in response to key commands or mouse drags). I'd do it
manually in my own C++ module, but I have no idea where to even begin with
that kind of integration (i.e. how do I get at the buffer on the C++
side?). Although I'd probably like to drop to that level eventually
anyway, for the engine, so I should learn how :\
And worse, I haven't even been able to get custom stippling working (not
that it would really have the desired effect anyway, since the stipple
textures always "align" and won't darken each other)! Only the built-in
hatches (when set via .fillMode) seem to work. I tried replacing the Brush
of the BitmapCanvas' underlying _bufImage, and also calling SetStipple()
on it, but these simply have no apparent effect. (Yes, I know you
shouldn't touch "private" members starting with an underscore, but there
doesn't seem to be anything in the public interface that does this, and
you're supposed to be able to do this stuff directly in wxPython, so...)
- Image rescaling seems to have a bug. (I had been using it because I want
to be able to "zoom in" on the spritesheet, without any filtering and with
full precision.) Specifically, if you rescale to an integer multiple of
the old size (the same multiple in both dimensions - I haven't tried other
cases), then in some cases, it will "shift" the texture one pixel each
direction. That is to say, if the multiple is N, then the top-left pixel
gets represented by an (N+1) by (N+1) block in the rescaled image, and the
bottom-right by an (N-1) by (N-1) block.
I assume this is a wxPython problem; where might I report it? Or, have
any of you any good ideas about how to deal with it? (Right now I put in
some code to do it manually; I am planning to change it to do a
.Rescale(), check the resulting image via the data-buffer to detect the
problem, and correct it with some blitting logic when it happens.)
- Any good ideas about how to control the key repeat rate for keyDown
messages?
- Later, I will want to implement a scrolling canvas (I need this also for
the tile editor and engine). For the editors (not the engine ;) ) I want
to attach scroll bars to the canvas area, to indicate what part of the
image is drawn, and to scroll it. I thought about using Sliders, but they
don't look right, and don't indicate the relative size of the displayed
window, the way real scrollbars do. But I haven't found a scrollbar-widget
in PythonCard. Did I miss something? Or is there something I can use from
wxPython? Also, is there some benefit I can gain from making a "group" of
controls here (the canvas, horizontal scrollbar and vertical scrollbar)?
Karl Knechtel {:>
|