Things to think about: * Loading of sprites, animations, etc. * Probably use tarballs of pngs, opened through library magic. * sprite rendering * use standard SDL_gfx rotozoom, per-pixel alpha for everyone, etc. * copy old spriteline? or use rotozoomsurfacexy? * combat system * use gfxprimitives for bounding-triangles, grid lines, etc * adapt/copy hairy camera code * adapt to use zoomSurface? * adapt rules/targeting/AI/etc. * make LUA code? * does this make network play easier? So step one is to make a useful harness for combat. First we need code for loading sprites and animated sprite sequences. Then we need code for motion, rendering, selection, and all the necessary elements therein. We use a lot of the combat.cpp and combat_display.cpp routines to do the magic for ship state. For example: int32 x, y, a; // location int32 vx, vy, va; // movement int32 ds_x, ds_y, ds_s; // display x, y, size (for mouse clicking) int32 wp_x, wp_y, escaped, wp_time, flee; int32 patx, paty; // patrol cships[c].x += cships[c].vx; cships[c].y += cships[c].vy; cships[c].a = (cships[c].a + cships[c].va) & 1023; We'll need to study the camera code pretty intensely, and although it's fast to use 1024 degrees, we'll keep it to 360 just to make it easier to use the SDL_gfx routines. And we use the code for launching fighters and so on. But we'll have better code for things like selection buttons, and the HUD should be more modular, so that we have surfaces with their own clip rects in which to blit buttons and hull readouts and damage readouts and so forth. functions: Tactical: bounding_triangle bounding_corners grid_reference These should accept manual rotation/scaling or have counterparts that do. Graphical: dsprite (if r/s are 0, use standard blit, etc. memoize rotations/scales. If r is the same as before, just zoom, etc) def dsprite(surface, sprite, x=0, y=0, rot=0, scale=0); init_hud new_window load_sprite load_anim General: init_screen splash_screen also need to handle mouse events and other magic. sound should be ogg for longer tracks, wav for shorter ones. All sound hooks are configured through lua interface. PYGAME PYGAME PYGAME wowee! Okay, so we'll use sprite groups heavily, and life will be good. We subclass the sprite type to make new drawable objects, each full of yummy rules. Game modders then subclass these to make new ships, weapons, etc. Sprite types: MovingObjects SpaceShips Beams Animations Explosions Crosshairs/Outlines Group types: MyShips EnemyShips MyWeapons EnemyWeapons AnimatedEffects ^-- all these are included in the InTheShot group, which is used by the camera routines. OrdersCrosshairs <-- waypoints can scroll off the screen, no problem. So, our update() methods will move ships, cycle frames, call AI methods, call tactical methods, fire weapons, etc. Then we do big cross-group sweeps to determine if we should cause damage, start animations, etc. Some ships will have countdowns for more elaborate powers like cloaking and teleport, as well. Wow, we can use Rect.unionall to manage our camera! We then use inflate on the difference divided by some zoom speed factor, and thus our camera zooms back on the action. Ultimately planets will become part of the zoomery, only entering the game when they're within some normal distance of the ships. Our camera will be managed via many rects. Coordinates will be based on an arbitrary absolute coordinate system scaled 1:1 to the sprites. Then we'll use a unionrect on a particular Sprite Group to determine the critical region. We then make an envelope rect the same size as the tactical clipping region (though we move toward it in increments to make the camera zoom smothly), and use that to determine scale and offset. So the actual sprite object rects are the translated coordinates, ready for blitting onto the screen. Maybe we subclass Rect to be a camera translation rect. It has special elements for absolute coordinates, so you plug in a point and get back the translated coordinate and scale. How do we manage scaling/transforming? 1: determine scale factor: min(camera.w / float(screen.w), camera.h / float(screen.h)) - then clamp based on 2: dx/dy calculated from camera.center and screen.center 3: recenter camera Here we use the update() function to pass in dx, dy, and zoom. 4: apply delta to move centers of all relevant sprite rects 5: rotozoom sprites by scaling factor. OKAY: 1: square the camera 2: zoom = camerasize / min(screen.w, screen.h) - oldzoom / framerate + oldzoom 3: resize unionrect, keeping old topleft. 4: each rect: (sprite.center - old_topleft) * zoom + new_topleft 5: move each rect by the screen.center - camera.center ^-- this turned out to be the way I did it, but I made clever use of a rect to pass in the topleft of each rect, and used the update() method to do repositioning on a whole group. Also I resized without recentering, for the win. ---- Hardpoints will be represented as vectors from sprite center, to make rotozooming placement easier. We'll need smaller damage rects, perhaps calculated after the draw() routine. The camera.draw() calls the parent RenderUpdate.draw() and then goes through the everything group and shrinks all objects' rects by a percentage like rect.inflate(-0.1 * rect.width, -0.1 * rect.height). Waypoints will be a simple ObjectInSpace with a constant rotational velocity and a location rect that is either a trampoline over to a target object or a location in space all its own. It's likely to be descended from an animation type. I may make animation part of the base class, too.