Tag Archive: coding


Taking Five

Tuning up on WeeSmall is going well – thanks to the way the enemy types run off a base class, I was able to implement a test-type enemy, which I can then muck about with the settings on in order to check that everything works. So far I’ve fixed a number of major issues with collision detection, stunning and sliding and so forth…

But I’m taking a breather from WeeSmall for now: the next XNA-UK meet is on Wednesday coming, and I wanted to see if I could hash something together for the Windows Phone – partly just to see if I could, but also to see if I could win a competition that’s running.

So – six days to write a game. This calls for simplicity and self-generation of data. It also calls for lots of placeholder content – graphics, sound, music etc. and use of a completely new control dynamic (touchscreen). But it’s also a chance to try and improve my structuring – the basics on WeeSmall were good but the tuning has revealed I could have done a lot better. And after a couple of hours of brainstorming, I came up with the following:

The player controls a small spaceship – this has a main engine (to thrust forward), thrusters (to rotate) and a tractor beam (to grapple stationary objects). Their task is to crystals that phase into the playing field and drop them into receiver pods – a given number must be retrieved before time runs out.

The complications:

  • The player’s ship can only grapple one crystal at a time and must use their momentum plus releasing the tractor beam to throw the crystals towards the pods.
  • The crystals glow with different colours. The crystal’s colour must match that of the receiver pod the player is trying to put it in. Once a pod has succesfully received a crystal, it will shut down for a short time, then select a new colour.
  • If a cystal impacts anything apart from a correctly coloured pod, it will blow up, taking anything nearby with it (apart from receiver pods)
  • If the player’s ship impacts anything, it will blow up, causing a life to be lost.
  • Enemy drones regularly phase into the playing field. The player can destroy these with a well-thrown crystal.

So this is a 2D game, with the player controlling their ship by dragging on screen to determine direction and thrust for moving, and tapping to activate/deactivate the tractor beam. There are other more advanced additions I have in mind (power ups, bonuses, gravity wells, floating obstructions), but these will do for starters.

So far, we have the basic scene mechanics, pulled straight in from WeeSmall so that’s the gamestate management sorted. The work on LRK has given some good insights for 2D graphical work, but needs a good overhaul, and at the moment I’m trying to port the WeeSmall particle system from 3D to 2D as this will provide all the effects I want.

And the title? Still working on that… but originally the player was going to have a grapple arm instead of a tractor beam, so the working project name is…. “Project: Star Claws” (Tadah!)

The clock is ticking! Let’s see how much we can do…

So really good progress over the last few days – I know I’ve said this before, but at the risk of tempting fate: “All the preparatory work I’ve done is now starting to pay off”. WeeSmall is starting to look like the game I want it to be.

A Particle System has been added, based on three classes: Particle, Emitter (which has a collection or Particles) and ParticleSystem (which has a collection of Emitters). This is based off what I learned while writing Ultra LRK; the Emitters give much more control over when and how many particles are generated, and the ParticleSystem provides a nice interface so I can call it to create a new effect when needed without having to muck about looking for the first available Emitter.

The Enemy base class is in, with simple movement and stubs for AI control, based on behavioural characteristics. There’s a small problem with collisions with Slider-based objects, but it’s enough for testing.

Lift control has been added into the main gameplay loop – this is now based on a level having a minimum number of Sliders and Enemies. If either (or both) fall below these levels, an object is assigned to be brought into play after a given number of updates – since both Sliders and Enemies inherit from MovingObject, it’s just a case of working out which one to assign – and the lift control takes over. Once the number of updates has elapsed, the new object is brought into play as soon as a lift is vacant.

The Slider (and Enemy) array have been dumped and replaced with lists – instead of recycling old sliders and enemies, new ones are created whenever required and either spliced into the list at the first gap or tagged onto the end. This works in conjunction with the classes that inherit from Slider and Enemy, allowing easy creation of different Slider and Enemy types.

The two Slider-inheriting classes are under way – Brick and Bomb. Both have a limited lifespan, which decreases over time or when the object impacts another (slight tweak in the Slider class) – the difference is in how they die. Bombs (not yet implemented) will explode and take out everything nearby. Bricks crumble into bits, which was a simple matter of checking their lifespan and if it falls below one, set the Slider status to OutOfPlay and have the ParticleSystem fire a single burst of various sized particles using the brick model.

Considering that these are supposed to be placeholder graphics, I’m already seriously chuffed with how this looks, especially the “brick crumble” effect. The next step (after solving the collision glitches) will be the Bomb class – alpha/additive blend capabilities have been added to the GameObjectComponents as part of the particle system, which makes for some funky effects and getting correct particle to object collisions working (bounce off, die or ignore).

And also – a shiney new (and hopefully less borky) laptop has just arrived…

I hadn’t really thought about it until I started tweaking things, but I’ve never written a multiplayer game before. However, WeeSmall is well suited for the task – once again, mainly due to the way the structure is set up.

First step is to reconfigure what we currently have to handle multiple players:

  • The number of PlayerCharacters on the field has to be increased
  • Each PlayerCharacter must respond to a different controller
  • No PlayerCharacter should ever go out of shot in multiplayer mode
  • Each PlayerCharacter should be able to alter the playing field in their favour

Without giving too much away, the objective of the one-player game involves altering the playing field to meet verious conditions. The multiplayer version will be a timed round, with whoever has the greatest area of the field set in their favour declared the winner.

So – first of all, increasing the number of PlayerCharacters – easy enough. Just make an array of PlayerCharacters within the GameplayScene, instead of just the one. Job done.

Each PlayerCharacter responds to its own controllers – again, quite straightforward. An additional property on the PlayerCharacter class to state which controller was being read and a new method in the ControlHandler class to return a named controller’s state rather than the generic aggregate controller, and it’s running. Moveover, this opens up the possibility of new controller types. At the moment, we have “Keyboard” and “Gamepad” – maybe we can add “AI” for computer-controlled PlayerCharacters in a multiplayer game, and even “Networked”, so we can have multiplayer over a network, either in single or multiplayer view? Again, for the future – the main reason I’m adding multiplayer at all at this stage is that it makes a good test for the sliding block to other object collisions and physics.

No PlayerCharacter should ever be out of shot – in single player mode, this is not a problem as the camera follows the player. But with multiple PlayerCharacters on screen, we need a fixed camera. Fortunately, the CameraHandler was almost completely independent from the PlayerCharacter – just a few parameters passing from the latter to the former to keep things locked together. So another property in the PlayerCharacter class – “IsCameraLocked”, and when we run round the update look for the PlayerCharacters, we update the camera for the one that this property is true for. Sorted!

Finally, all that was left was a couple more properties to override the PlayerCharacter field manipulation behaviour when in multiplayer mode – again, taking single player mode into account – which just leaves a little bit of zoom functionality to develop for the Camera (to ensure best possible zoom dependent on the PlayingField size), and we’re ready to move on into SlidingBlock to object collisions.

KnoSQwYSOmze

It took a while, but WeeSmall has been rebuilt to use the new structuring – this also prompted a lot of thought about how I handle the terrain and obstructions on it, which has had a knock-on effect of further improving the way various things are handled.

GameObjectComponents have had a new property added – a Texture2D called “OverrideTexture”. If not null, this is called on in the render process, overriding the default texture used by the model. This not only saves on having loads of identical models – eg: different coloured obstructions in “WeeSmall” – but also because only one model is being used, there’s no size/scale conflicts. This goes hand-in-hand with the TextureBank class – a logical follow-up to the ModelBank class, except serving Texture2Ds – I guess the next step is to combine these into a single ResourceBank class. But with these as services, all Models and Texture2Ds can be loaded at startup and just grabbed from the banks are required.

A new generic class with properties specific for “WeeSmall” now sits between the GameObject class and the individual parts of the game – this is purely to increase the reusability of the GameObject/GameObjectComponent classes as the properties and methods in these classes can remain generic, with standard physics parameters handed down from the class above.

Of course, this leads to some quite complicated layering, dependent on what “game part” is involved – the PlayerCharacter inherits from the WeeSmall generic object class, which is quite straightforward. However, Obstructions are a different kettle of fish:

  • GameObject – provides physics and a list of GameObjectComponents
  • WeeSmall generic object class – provides the game-specific base properties
  • Obstruction class – provides a common wrapper for all obstructions and basic properties (movable, height etc)

On top of this, there is currently the BasicBlock class – virtually all obstructions will use this as it provides the primary object that forms the obstruction – other classes will then inherit from this to add their own properties and additional models/texture for decoration and identification. At the moment, the class in progress is the SlidingBlock which – surprise! – can be shoved around by the PlayerCharacter (and a few other things).

This leads to a new angle I hadn’t even considered before: it started off with the concept of “There will be moving enemy characters on the terrain. What happens if one gets hit by a moving SlidingBlock?” Answer: “The block pushes them along.” Question: “What happens if the block has sufficient momentum that it will hit a stationary block and it’s pushing an enemy?” Answer: It squashes (kills) them!” The obvious way to handle this is to have a base class which handles this possibility which all enemies inherit from. But if the PlayerCharacter is updated to have these properties as well (with player control lost while being pushed by a block)… Lightbulb! Multiplayer option!

But that will come in time. First step is to get the SlidingBlock working correctly. Once that’s in, there are only a few big bits of “basic” stuff – like the pushed/squashed-by-block thing – but bits are starting to slot in more easily now.

So it goes to prove – well thought out basics end up making life easier!

(Oh, and the camera now runs on quaternions, too…)

After fighting with my manual maths trying to get the attack working in WeeSmall, I realised that my basic classes had become too complicated.

So last night, armed with new knowledge and ideas from the XNA UK User Group and a lot of planning and thinking, I set out to rewrite everything from the ground up. I worked out what I could keep (a lot, fortunately!), what I wanted to update, and what I could just plain dump, then started off with a simple app to set up a camera, load a model and draw it in the world.

This was rapidly built up into a class similar to the GameObject class I already had, but with a major concept change – the position and rotation values within the class were relative, with additional position and rotation Vector3s being passed into the Draw method. When called, the internal position was rotated by the passed rotation vector using Vector3.Transform and quaternion rotation (eular angles are not as good, apparently). The result of this is added to the passed translation vector, then the normal matrix sequence is applied in the mesh draw loop, starting with all rotations (corrective, to ensure correct orientation along the x-axis, then relative and passed Vector3 – again all using quaternions), then scaling and finally translation with the passed position Vector3 and transformed offset).

This is the GameObjectComponent class, and it neatly takes the load off working out all the relative positions.

The next step was to put three of these on the screen – in this case, the three parts of Project: WeeSmall’s player – and group them together. I was able to salvage a lot of the physics and component list handling from my FieldObject class and I also took the opportunity to sort out a clash between component names and model tags which had caused some ealier problems. This is the GameObject class, and will now form the basis of everything drawable in Project: WeeSmall.

So that just leaves the camera, which at the moment is running on a combination of trigonometric functions and pythagorus calculations, based on the pitch angle forming a right-angled triangle with the horizontal plane so I can get the Y coordinate and the horizontal distance from the lookat point to the position – the latter of which I can apply sine and cosine to to work out X and Z. Very messy. But with that fixed, it should be simple enough to rebuild WeeSmall to use the new classes – then the only way is forward!

It seems like every step I’ve take with Project: WeeSmall recently a bunch of possible refinements have opened up, and this weekend was a big one!

With the player’s basic movement and interaction with the playing field terrain working, the next step is the addition of objects on the playing field and to make the player interact with them: most cannot be moved, most can be jumped over and so forth. It quickly became apparent that the best way to handle this was to focus only on the unmovable objects to begin with as these can be position-linked to the terrain (and also directly affect it as the player cannot interact with anything underneath an unmoveable object).

The Physics Object class got a big upgrade into the FieldObject class – as far as I can see, this will become the base class for every object on the playing field. It wraps in all the original functionality of the PhysicsObject:

  • Position in the world that all individual model positions for the object are relative to
  • Horizontal acceleration values which can be decreased by a friction value over time if required
  • Vertical acceleration values which are subject to gravity, handling jumping, falling and landing on the playing field or falling through a hole it it.
  • When impacting the playing field from a fall, impact deformation and “settling bounces” are handled, based on given values.

So these all allow me to do my “bouncing ball” trick – start the ball from a height and give it positive vertical acceleration if I want it to start with an upward bounce, and let the class do the rest – the vertical velocity reduces due to gravity until it accelerates downward, then when the ball hits the terrain level, it either falls through it (if there’s a hole), or deforms on impact and bounces up again to a lower height, at which point gravity takes over again – rinse, repeat until the vertical acceleration upwards following an impact is less than a minimum value.

But what about the models? A single bouncing ball is all well and good, but my player is going to have a number of models. And also, what about other features that I want multiple models for? Cue evolution and the addition of components:

  • Components are a list of models attached to the object and positioned relative to the main object position
  • The AddComponent method adds a model to the component list with its own size, scale etc. and a reference name (Yay for ModelTag!)
  • Components can therefore be referenced by name, allowing position offsets, rotations etc. to be set.

Of course, the player handler immediately got re-written to accomodate these changes!

Next step – the playing field object, or “Obstruction”: with the new FieldObject class, this was simple. Since obstructions all have the properties of whether or not they can move and whether or not they can be jumped over, it made sense to create an Obstruction class that inherited from the FieldObject class – after all, an obstruction would need position, at least one model and possibly more, and if it was moveable horizonal acceleration would apply, as would vertical if it got moved over a hole in the terrain.

From this came the simplest kind of obstruction – an unmoving block that the player could not pass through, but could be jumped over. Again, a quick class for these – StaticSingleBlock – inheriting from Obstruction. When instantiated, the class loads a specific model and sets its position, as passed into it.

So as a test, I chucked in loops to put a wall of blocks around the outside of my playing field, and threw in a few randomly positioned ones for good measure. A few hiccups and then bam! Blocks. Nice. Unfortunately, they made absolutely no difference as my player character would still waltz right through them – easily fixed though: knowing the player and obstruction locations, player facing direction, whether or not they want to move forward or backward and whether or not they want to move or jump gives everything needed to prevent motions that are obstructed by our blocks.

Looking at my wall, it also rapidly dawned on my that loading the same damn model for every block was very inefficient. Time for another GameService – the ModelBank class:

  • Add method loads a model, tags it with a given name and adds it to the list of available models
  • Get returns a model of a given tag name

A quick upgrade to the StaticSingleBlock class, and we have a nice wall with only the one model – schoolboy stuff really, but good to have available.

As of now, I’m part way through the player’s “attack” control – this goes hand-in-hand with the obstructions as I want attacking certain types of obstruction to have various effects (push them out of the way, destroy them and so on). Again, this is proving challenging – I don’t think I’ve ever written a player control handler this complex before! – but the numbers look good so far and it should just be a case of applying them to the models. But I think that the classes I’ve developed are now strong enough to handle all the basic movement and display I’m going to need.

“Project: WeeSmall” is now officially go!

It took a complete rebuild, but a successful test on the motion controls I want for my player prompted the decision. This was one of the hardest player handlers I’ve ever worked on, because of how the character works – it bounces like a ball when moving, using a rotate-and-thrust type control.

  • There are four actions the player can perform – attack, turn, move and jump. Because the player bounces, move and jump are essentially the same apart from the distance travelled.
  • When an action is in progress, no other action can start until the action is complete.
  • When falling, the player must act like a ball: deform on impact with the floor then bounce to a stop, not just stop dead on the ground – except if another move/jump is started.

This actually turned out to be a lot harder than I first thought. I ended up tying myself in knots with horizontal plane movements then trying to add the gravity, then the deforming, then the bounce-on-impact, before I starting over, this time with gravity. Much better – before too long I had my player character bouncing around his environment, with the camera tracking and rotating to behind it unless overridden.

I also reworked all my gamestate management over the weekend for 3D, and I think it’s a big improvement over the original 2D version from April time – the activate/deactivate/exit handling is much cleaner, with the backbone in place for customisable cross-scene transitions. As before, each state of the game is represented by a greatly re-worked Scene class, with the addition of a SceneHandler to oversee control, transitions etc.  Ultimately, what I’m looking for is for my base XNA game class to set a couple of bits up, say “Go” and not get involved again until told to stop.

The next step was migrating the  camera, playing field and player character into the gamestate classes, along with the control wrapper I built last week. This also allowed me to structure things a lot better – the camera and controller are generic, so they were plugged in at Scene class level, while the playing field and player character were added to the Scene-inheriting gamestate class for playing.

There are still some bits to fill in round the edges before basic player control is complete – “attack” is totally missing, for example – but it’s beginning to look how I want it to – both from a code and a playing point of view.