The only one that has some appeal is PGU, but I couldn't easily see a
way to integrate it with OpenGL-2D imaging for the acceleration--which
I think we're really going to need, especially with your desire to do
particles and effects.
Here's all the stuff I found:
* pyTyle - http://www.pygame.org/project/871/
* PGU - http://www.pygame.org/project-PGU+-+Phil%27s+pyGame+Utilities-108-.html
* Isotope - http://www.pygame.org/project-Isotope-167-.html
* PygLibs - http://www.pygame.org/project/283/
* Isomyr - http://www.pygame.org/project-Isomyr-1316-.html
* pyEmpire (game) - http://www.pygame.org/project-pyEmpires-1193-.html
* lwpgt - http://www.pygame.org/project-light+weight+python+game+tools-1301-.html
So I did some study. Math, can ya believe it? I suck at math. :) But I
learned some basics, and put together a program to demonstrate tricks
that I think could be useful for our goals.
Uploaded here. http://groups.google.com/group/gumms-rpg-cloud/web/simple_isometric_demo.py?hl=en
I designed this so I could think and code in 2D, and have the 2D space
translated to an isometric space in screen coordinates. It uses
primitive geometry to show a spacial grid and a few moving dots for
visual orientation. With some work it might be grown to accommodate
isometric pixel art. It is graphics system-agnostic, so we could use
SDL or OpenGL to render the images. And there are some pretty good
OpenGL-2D libraries out there.
Unfortunately, using the dynamic rotation and tilt aspect of the demo
in a real game would require real 3D imaging so it is out of the
question. Realistically we would probably pick a static angle (45
degrees) and a static tilt (0.6) and then fashion all our pixel art to
fit that geometry.
Give it a look and let me know what you think.
Gumm
simple_isometric_demo_2.py: http://groups.google.com/group/gumms-rpg-cloud/web/simple_isometric_demo_2.py
This demo adds:
* Reverse translation for screen points (isometric view) to 2D (game
geometry) for things like translating mouse coordinates, screen edges,
etc.
* Intuitive panning via mouse clicks.
* Functions for performing trig calculations: angle given two points;
point given an origin, radius, and angle.
Gumm
What remains:
* Integrate with CMV.
* What tiles look like.
* How tiles are loaded.
* Which tiles get drawn to the screen. Maybe all, and allow SDL to
clip those out of bounds? If I recall, Gummworld didn't sacrifice FPS
by doing this.
* Rendering library: Pygame + OpenGL? The good libs behave much like
Pygame + SDL as far as loading and drawing images.
* Things like collision detection to enforce avatar honoring map
bounds and obstacles.
* Going crazy: story, GUI, anim, combat and GFX, SFX.
Gumm
Good work :)
Jon.
I moved the view class into a module and made 25x25 tiles. Up until
20x20 I was getting 60 fps. When I upped it to 25 I took a performance
hit, only 40 fps. That suggests we would have to do some kind of
zoning, e.g. only process tiles in the vicinity of the avatar. I did
the same thing for Gummworld and it boosted performance even on
humongous tile sets.
I left demo1 and demo2 files up just in case you wanted to see the
progression to demo3. Sometimes it helps to see the baby steps.
Experimentally, I tried pymike's pygl2d in demo4. Performance was a
lot worse and I don't know why. Also, the circle primitive was off: it
did not draw in the correct position on the screen. I'll take a look
at the others and see if any are usable "out of the box".
Gumm
My immediate comment would be that I can see 2 obvious optimisations:
1. You are currently transforming the tiles from 2d to isometric
coords on each draw, I think they only need to be calculated when the
view angle changes. The new coords could be stored in the Tile2d
objects and updated only if the angle changes.
2. You are currently flipping the entire screen even though only a
tiny amount of it has updated. I understand that this is only a simple
demo so getting the dirty rects for everything would be overkill but
this would speed up the fps.
I've had a try at adding images to the tiles, it needs to be cleaned
up but it works (sort of). See attached file for result.
I also trying running the isometric_view.py with psyco. This gave me
an increase from 46-47 fps to 60-61 fps. I think this speed increase
is due to the isometric transformations which psyco would speed up
alot. I'm not suggesting using psyco, just an interesting experiment.
Cheers.
Managed to get this working and it looks good. Are you using 2.6 for
this? I couldn't find a download for Rabbyt for 2.5.
I've made some images for a test player (just a 3d arrow) using a
script I found for Blender that produces isometric images from 3d
models. I've knocked together a quick player class to load and use
these images. I think the result has potential. Let me know what you
think.
Cheers.
p.s. If we go much further with this demo we should think about an
on-line repository for it, the zip file is getting bigger and we don't
want to lose any change history.
I think we are going to have to stick with Rabbyt or similar OpenGL
library. The frame rate of the SDL version (isometric_demo_3_2.py) at
larger screen sizes is pretty bad. I get about 35 fps on a dual-core
computer at 800x600. The OpenGL version gets 55-60 fps on my crappy
laptop's integrated ATI graphics adapter. Even at 1280x800 I'm getting
near 60 fps.
Gumm
On Apr 10, 9:40 am, Jonathan Hollocombe <jholloco...@googlemail.com>
wrote:
> Hi,
>
> Managed to get this working and it looks good. Are you using 2.6 for
> this? I couldn't find a download for Rabbyt for 2.5.
Yes, I haven't seen any red flags for 2.6 so that is what I've been
using.
> I've made some images for a test player (just a 3d arrow) using a
> script I found for Blender that produces isometric images from 3d
> models. I've knocked together a quick player class to load and use
> these images. I think the result has potential. Let me know what you
> think.
Oo, an advancement. I'll check it out. :)
> p.s. If we go much further with this demo we should think about an
> on-line repository for it, the zip file is getting bigger and we don't
> want to lose any change history.
I was thinking the same thing. It seems like we're almost out of proof-
of-concept mode. We should choose a source baseline and a code tree
soon.
Gumm
Drop the attached isometric_demo_5.py in your project directory and run it to see your art in action.
However, there is one thing to notice... you've changed my hard coded
image names to loading the files as they are returned by os.listdir.
This approach may not work if there is more than 100 files as it will
probably load file1, file100, file2, file3, etc.
I can't imagine we'd have > 100 images per sprite but it's worth noting.
Interesting to note your use of rabbyt.Sprite.texture. I had a quick
look for a rabbyt texture loader but I didn't see one, didn't think of
using the Sprite class to do it.
Cheers.
Much tidier :)
However, there is one thing to notice... you've changed my hard coded
image names to loading the files as they are returned by os.listdir.
This approach may not work if there is more than 100 files as it will
probably load file1, file100, file2, file3, etc.
I can't imagine we'd have > 100 images per sprite but it's worth noting.
Interesting to note your use of rabbyt.Sprite.texture. I had a quick
look for a rabbyt texture loader but I didn't see one, didn't think of
using the Sprite class to do it.
As a side note I've tried this code in Linux and it doesn't work:
os.listdir does not return a sorted list in Linux so you have to use
sorted(os.listdir). Interesting to know.
I've gone through and re-factored the code to use the MVC pattern.
It's not optimum and there's definitely room for improvement but it
shows how it can be done. I've added another view (a simple debug
console output if you run the game with command line option: -d) to
show how easily it can be extended. I haven't really extracted the
"model" out of the code so it's more just "views" and "controllers" at
the moment, this is because the IsometricView class currently contains
both "model" and "view" elements so would need to be reworked to
separate them out.
Let me know what you think. (I haven't included any of the images in
the zip, they are unchanged).
Cheers.
os.listdir does not return a sorted list in Linux so you have to use
sorted(os.listdir). Interesting to know.
I've gone through and re-factored the code to use the MVC pattern.
It's not optimum and there's definitely room for improvement but it
shows how it can be done. I've added another view (a simple debug
console output if you run the game with command line option: -d) to
show how easily it can be extended.
I haven't really extracted the
"model" out of the code so it's more just "views" and "controllers" at
the moment, this is because the IsometricView class currently contains
both "model" and "view" elements so would need to be reworked to
separate them out.
Let me know what you think. (I haven't included any of the images in
the zip, they are unchanged).
I think the idea is that you don't need to know the
originator-subscriber relationships at all! If it has been implemented
properly the subscriber to an event should not care where the event
originated from, simply that it is interested in it. For example a
view should just sit there and pick up "model_changed" events,
updating themselves whenever this is seen. In theory, the view should
be coded in such a way that it doesn't matter why or who sent these
events.
I agree the string-based messages are brittle but don't agree you need
to replace them with a class hierarchy based approach. Another way to
do this is to use constants, e.g. events.MODEL_CHANGED, which could be
an int, string or whatever. This is the way it is done in pygame.
> I took a first whack at separating them. I admit I'm having difficulty
> deciding what belongs to model versus view. I think my struggle is that I'm
> trying to do everything in the classes, and finding that they need to know
> about each other--which makes them interdependent when we need them to be
> independent.
>
> I suspect we'll need to make the model and view more pure, and move
> manipulative code to new "glue" functions and classes to integrate the parts
> of MVC. See the attached for my first step in that direction:
> mouse_2d_to_model() and mouse_iso_to_model(). Let me know if you agree with
> this approach. Note that I'm pursuing this evolution just to work out the
> separation, with the intent that the parts can be easily plugged into MVC or
> whatever.
I've been having a go at creating a model / view separation. The way
i'm going is to have a 3D model (so i can implement jumping, etc.) and
a 2D isometric view. I think i've been getting stuck on similar areas
to you (mapping of mouse position from screen -> isometric view ->
model and vice-versa). Your functions look useful, i might try using
them in what i have so far.
> While I found tracing the string-based events hard, and I expect they are
> highly prone typographical error, I like how your implementation mimics the
> Pygame event class with event.type. It makes the cases in recieve() very
> programmer-friendly.
Duck typing, *quack quack*. That's why i love Python :)
Cheers, Jon.
Had a quick glance through and noticed your comment about the fact
that the model needs to interact with the view in the update_avatar
function.
In this function the view is only referenced in the code: avatar.angle
= angle + gv.angle. I'm not sure exactly what this is doing but it
strikes me that the model shouldn't need to know about what angle the
avatar is at in the view? I think it must be possible for the avatar
to only be aware of its angle in the model coords and for the view to
transform this angle to Iso/Topdown coords for rendering.
I'm working on code which is duplicating a lot of what you have done,
but in a slightly different way so i think it's worth comparing the
two solutions. I'm producing this a lot slower than you though, so it
may be some time before i can post anything :)
Cheers, jon.
In this function the view is only referenced in the code: avatar.angle
= angle + gv.angle. I'm not sure exactly what this is doing but it
strikes me that the model shouldn't need to know about what angle the
avatar is at in the view? I think it must be possible for the avatar
to only be aware of its angle in the model coords and for the view to
transform this angle to Iso/Topdown coords for rendering.
I'm working on code which is duplicating a lot of what you have done,
but in a slightly different way so i think it's worth comparing the
two solutions. I'm producing this a lot slower than you though, so it
may be some time before i can post anything :)
My plan was to bring the floor tiles back into the demo for the next
stage. I agree that panning could be problematic for some games, I'll
set the default to no panning at the same time.
As for the jumping: do you think the character should return to the
target after over-jumping or that the target should be set to wherever
it lands? I can think of reasons for both tactics.
I also have plans for the physics (though these would take my
SimpleModel towards a much more complicated one):
> Acceleration + deceleration towards the target, with possible speed increase if holding a "run" button.
> Obstacles, 3D objects that can stop movement, possibly with some bounce off. Some will be short enough to jump over.
Anything else you can think of?
With 32x32 tiles i'm seeing 30 fps but with the mask it goes to 60.
I'm assuming 60 fps is the highest i'm going to see? It seems to be
capped at 60 on my machine which i assume is to do with my screen
refresh rate (60 Hz) and display.flip() pausing the loop until the
next refresh.
was working on. I got to the point where i had mapped the screen into
my 3D model and could restrict the transforms to only those within
this area. Unfortunately the test for whether the object was inside
the area was as expensive as my 3D transform so it didn't help, even
though the maths was pretty simple.
I think at some point we may need
to write some C extension modules to handle the most used functions in
order to get the kinds of speeds we'd like to see. I know how to do
this in Linux, but have no experience of it on Windows.
Can't say I can help much with the wall rendering problems, looking at
doing something similar was quite a long way down my list of things to
do so I don't have much experience to share. I have done some 3D stuff
a long time ago (Direct3D but should be similar) and would be
interested in exploring the possibility of using 3D rendering.
I think at some point it would be good to define some strict
boundaries between the sections (Model/View) and fix some APIs to make
it easier to swap around the models and views to find what works best.