Friday 3 August 2012

Racing Game – Bobo’s end


In my last post I mentioned that having play tested a little I wasn’t really satisfied with how the game played. The levels were too blocky, character movement felt like it was in the wrong direction, and the story/theme was a bit forced and rubbish.
The simplest way to reduce the blockiness of the level would be to simply shink the tile sizes. Creating loads of block objects seemed a bad idea though (taking it to the extreme there could be one per pixel!). Instead I went back to the drawing board to rethink the level concept. Here’s a simple definition of a level:
  • A level row is 10px high and 240px wide
  • The viewable portion of the level is 320px high (32 x rows)
  • An example row could be: 80px wide grass, 80px wide road, 80px wide grass
  • The road sections are the same width in all the levels rows
  • The left grass section can increase/decrease in width by up to 4px per consecutive row
  • The right grass section takes up the remainder of the levelRow width
With these rules defined, I went on to rewrite the level generation code:
 public Level(int screenWidth, int roadWidth, int roadOffset, int levelLength, int rowHeight) {  
  this.screenWidth = screenWidth;  
  this.roadWidth = roadWidth;  
  this.roadOffset = roadOffset;  
  this.levelLength = levelLength;  
  this.rowHeight = rowHeight;  
  this.levelRowRoadOffset = new int[levelLength];  
  offroadAreas = new Array();  
  generateOffsets();  
  generateOffroadAreas();  
  generateFinishLine();  
  car = new Car(new Vector2((screenWidth/2)-(Car.WIDTH/2), 20));  
 }  
 private void generateOffsets() {  
  for (int row=0; row<levelLength; row++) { // for each row in the level  
  levelRowRoadOffset[row] = roadOffset;  
  // generate a random integer (between -4 and +4)  
  int modifier = (randomGenerator.nextInt(9)) - 4;  
  System.out.println("Modifier: "+modifier);  
  // apply modifier offset provided road would remain in bounds  
  if ((roadOffset + modifier >= 1) && (roadOffset + modifier + roadWidth <= screenWidth)) {  
   roadOffset += modifier;  
  }  
  }  
 }  
 private void generateOffroadAreas() {  
  for (int row=0; row<levelLength; row++) { // for each row in the level  
  OffroadArea leftGrass = new OffroadArea(0, row * rowHeight, levelRowRoadOffset[row], rowHeight);  
  offroadAreas.add(leftGrass);  
  OffroadArea rightGrass = new OffroadArea(levelRowRoadOffset[row] + roadWidth, row * rowHeight, screenWidth - (levelRowRoadOffset[row] + roadWidth), rowHeight);  
  offroadAreas.add(rightGrass);  
  }  
 }  
 private void generateFinishLine() {  
  finishLine = new FinishLine(0, levelLength * rowHeight, screenWidth, 40);  
 }  

Bobo became Car, Block became OffroadArea, and there were a few little changes to these classes, nothing really worth mentioning here. The drawing routine in GameScreen changed a little:
 for(OffroadArea offroadArea: level.getOffroadAreas()) {  
  spriteBatch.draw(grassTextureRegion, offroadArea.getBounds().x, offroadArea.getBounds().y, offroadArea.getBounds().width, offroadArea.getBounds().height);  
 }  

If you’d like to see the full extent of the changes made, the complete source can be found here.


What next?

Lots to do…
  • I can think of a couple of of efficiency improvements to do – there’s no sense in checking the whole level for collisions, and the same goes for rendering rows that are offscreen (espcecially those you have passed and won’t possibly see again).
  • I think maybe there should be subclasses of OffroadArea, ice, grass, rocks, finish line, etc, all with different behaviour, but for now I’ll leave things as they are, “it aint broke, why fix it”.
  • The level may need a little tweaking, certainly in later levels the game would need to get tougher. Deceleration when offroad needs tweaking too, it’s too sudden at the moment.
  • There’s a cheat possible where if you leave the screen bounds you race ahead, I’ll need to constrain car to world bounds.
  • The timer needs to be reintroduced, current time should be displayed oncreen, and high scores should be saved to persistent memory.
  • A delay before starting the race would be nice, maybe a traffic light graphic or “3, 2, 1, Go!” message.
  • The finish line could be improved, maybe a nice animation of the car driving offscreen?
  • Sound effects would be nice.
  • Maybe the car should rotate a little when ‘steering’?
  • Maybe some dirt particles should get kicked up when the car is offroad?
  • I’m already thinking about the third dimension. I need to forget about this for now if I ever want to produce a finished game. Maybe this game should be RaceGame2D, and RaceGame3D could be another project for another time!
There’s no doubt loads more to do that I’ve not thought of yet. I think I have plenty to be getting on with though! Don’t really know what I’ll tackle next, so the next update will be a lucky dip! Until then, here’s a bonus video of the basic game as it currently stands :)
          

No comments:

Post a Comment