1 decade ago by Arantor
I've mentioned this before, in passing, but I'm happy to show off what I have thus far in case anyone's interested.
It started out as a Datastorm clone (it's a 1988 Amiga game that's a Defender variant), and for the current testing purposes I have ahem borrowed Datastorm's player-ship, lander and bullets.
The two things I really wanted to get right at this stage were the wraparound scrolling (it's a 1920 wide playing area, looped) and the radar, needless to say things like proper collision detection or enemy logic are minor things right now. Proper playability is nil, and I'm not entirely happy with the way the player moves either, but that'll get fixed in time.
So, without further ado, http://arantor.org/datastorm-render-demo/ - this link will at some point be replaced with a proper link to the game when it gains its own identity and be posted on whatsthatgame.co.uk, but for now, that is what it is. At the same time I'll also change the graphics too, to ones that suit the game overall.
The implementation in places is still raw and naive in places but it works.
Controls are arrows, X to fire, A to autofire reload (more on this later)
As far as implementing things goes, there is a custom entity called a Dsentity, from which everything inherits. The two key differences compared to a normal entity at this point are that it has its own update logic that runs after the normal update logic, and a custom draw routine (which breaks the debugger facilities for hitboxes etc.) - it just felt like a cleaner way that using a plugin and injecting into Impact.Entity.
The playfield is as you might expect a 0-1919 area and entity positions are considered normally, with the exception that if an entity leaves one edge (x <0 || x > 1919), the Dsentity update moves it around to the other edge allowing for velocity etc.
The custom draw then resolves screen position and draws it in the right place - note that I do not ever change screen.x or worry about the normal drawingPos routines, simply because while sometimes I'll be drawing things reasonably normally, sometimes I'm drawing stuff that the engine considers would be 'off screen' so I ignore that and do all my own drawing.
As for the radar, there's a second canvas who starts off receiving the background image, then getImageData is called, and we step through all the entities that have a colour defined (the ground doesn't, and bullets don't) and entities that have a colour, their position is divided by 10 (since the radar is 192x20 compared to the main area of 1920x200) and the relevant pixel is updated in the image data, before we transfer that wholesale (and doing the rescaling to main canvas scale in the process) to the main canvas, so we get the 2x scaling for little code effort, and almost certainly less effort overall than drawing the 2x2 pixels manually, or drawing an image for each enemy on the radar. (And it amounts to two draws per frame, but they're ones that aren't going to be accounted for in the debug panel, but that's cool.)
There's a few other things I've experimented with to see what happens, namely 'autofire', which is an ammo based autofire facility (like Datastorm had), whereby it spits out a bullet each frame, meaning there can be dozens of entities added to the screen. Press A to reload 500 rounds into the autofire (normally you'd collect a powerup but this is for debugging) and then you can just hold X to autofire a bullet per frame while X is held down. The result is to see how well handling dozens of new entities works out both in terms of handling the update and the draw cycle, but so far it doesn't seem to cripple things either way.
Also note that the movement is a bit special (and has legacy code that needs pruning) - essentially the idea is that if you're moving, you're moving under thrust and that your ship is dealing with the inertia for you, so that moving is basically direct control, but if you let go, certain things happen - namely that the ship can continue left/right for a short while (under friction), and that gravity can take effect too. The up/down movement's a bit fast but I'm working on that. Also, the ground is bouncy, but not quite bouncy enough yet ;) It too is an entity for all the same custom drawing requirements.
All in all, I'm pretty happy with it so far, the bigger thing is to decide exactly what directions to go with this now the very core mechanics have been settled (though there is still occasionally a very slight visual blip if you happen to shoot an enemy under specific circumstances while they cross the 0/1920 line, but you generally don't notice it because of their movement, the bullet's movement etc. the collision generally works as expected.
And yes, that sparkly rainbow ground exists solely so that I could validate the movement was silky smooth (it runs from red through all the colours and back to red, so red is the crossover point)
It started out as a Datastorm clone (it's a 1988 Amiga game that's a Defender variant), and for the current testing purposes I have ahem borrowed Datastorm's player-ship, lander and bullets.
The two things I really wanted to get right at this stage were the wraparound scrolling (it's a 1920 wide playing area, looped) and the radar, needless to say things like proper collision detection or enemy logic are minor things right now. Proper playability is nil, and I'm not entirely happy with the way the player moves either, but that'll get fixed in time.
So, without further ado, http://arantor.org/datastorm-render-demo/ - this link will at some point be replaced with a proper link to the game when it gains its own identity and be posted on whatsthatgame.co.uk, but for now, that is what it is. At the same time I'll also change the graphics too, to ones that suit the game overall.
The implementation in places is still raw and naive in places but it works.
Controls are arrows, X to fire, A to autofire reload (more on this later)
As far as implementing things goes, there is a custom entity called a Dsentity, from which everything inherits. The two key differences compared to a normal entity at this point are that it has its own update logic that runs after the normal update logic, and a custom draw routine (which breaks the debugger facilities for hitboxes etc.) - it just felt like a cleaner way that using a plugin and injecting into Impact.Entity.
The playfield is as you might expect a 0-1919 area and entity positions are considered normally, with the exception that if an entity leaves one edge (x <0 || x > 1919), the Dsentity update moves it around to the other edge allowing for velocity etc.
The custom draw then resolves screen position and draws it in the right place - note that I do not ever change screen.x or worry about the normal drawingPos routines, simply because while sometimes I'll be drawing things reasonably normally, sometimes I'm drawing stuff that the engine considers would be 'off screen' so I ignore that and do all my own drawing.
As for the radar, there's a second canvas who starts off receiving the background image, then getImageData is called, and we step through all the entities that have a colour defined (the ground doesn't, and bullets don't) and entities that have a colour, their position is divided by 10 (since the radar is 192x20 compared to the main area of 1920x200) and the relevant pixel is updated in the image data, before we transfer that wholesale (and doing the rescaling to main canvas scale in the process) to the main canvas, so we get the 2x scaling for little code effort, and almost certainly less effort overall than drawing the 2x2 pixels manually, or drawing an image for each enemy on the radar. (And it amounts to two draws per frame, but they're ones that aren't going to be accounted for in the debug panel, but that's cool.)
There's a few other things I've experimented with to see what happens, namely 'autofire', which is an ammo based autofire facility (like Datastorm had), whereby it spits out a bullet each frame, meaning there can be dozens of entities added to the screen. Press A to reload 500 rounds into the autofire (normally you'd collect a powerup but this is for debugging) and then you can just hold X to autofire a bullet per frame while X is held down. The result is to see how well handling dozens of new entities works out both in terms of handling the update and the draw cycle, but so far it doesn't seem to cripple things either way.
Also note that the movement is a bit special (and has legacy code that needs pruning) - essentially the idea is that if you're moving, you're moving under thrust and that your ship is dealing with the inertia for you, so that moving is basically direct control, but if you let go, certain things happen - namely that the ship can continue left/right for a short while (under friction), and that gravity can take effect too. The up/down movement's a bit fast but I'm working on that. Also, the ground is bouncy, but not quite bouncy enough yet ;) It too is an entity for all the same custom drawing requirements.
All in all, I'm pretty happy with it so far, the bigger thing is to decide exactly what directions to go with this now the very core mechanics have been settled (though there is still occasionally a very slight visual blip if you happen to shoot an enemy under specific circumstances while they cross the 0/1920 line, but you generally don't notice it because of their movement, the bullet's movement etc. the collision generally works as expected.
And yes, that sparkly rainbow ground exists solely so that I could validate the movement was silky smooth (it runs from red through all the colours and back to red, so red is the crossover point)