Friday, December 27, 2013

Tank Battle Field HTML5 Game #4: The Object Model

Today's post is about the structure of Tank Battle Field game. Its object model.
Object model defines how objects are related to each other and determines the interactions with each other.

Tank Battle Field object model has two aspects. The containment model and the hierarchical one.

The containment model
As you can see in the picture below the objects are contained in a logical manner.



At the top there is the "Game" object which constitutes a global container which includes all other objects that are intrinsic to the game. It also constitutes a single entry point.
The "Game" object contains the following important objects:


  1.  "Model" object: defines the game logic and abstracts away logic from graphical representation. In turn it cotains
    1. "Field" object, that represents the terrain or the theater in which the game takes place. The aim of this "Field" is to set the dimensions, background and relief.
    2. "PrimaryTank" is the main tank of the game. The one controlled by the player.
    3. "Buildings" is a object containing a collection of buildings. It has also the role to render them and make necessary calculations related to their positioning on the screen.
    4. "Enemies" is the collection that contains the enemy units. This collection plays a role in coordinating AI enemy units movements.
  2. "Graphics" object contains all what is necessary for rendering the game on the screen. Among others it contains:
    1. "context" object which is a direct reference to the graphical device context provided by HTML5.
    2. "layers" array that contains the layers which will be displayed on the screen using the z-index order.  
    3. "layer_ground" object has the lowest z-index order and thus it is displayed the first. It contains the background, and the field details as well as borders.
    4. "layer_objects" object is the layer that contains static objects such as buildings. It is displayed second, over the "layer_ground".
    5. "layer_units" object is responsible of rendering ground military units including friend and foes.
    6. "layer_projectiles" object will contain transient objects such as shells, missiles, rockets as well as explosions. These objects are added to this layer at creation time then are removed when they expire.
    7. "layer_high" object will contain all flying machines like airplanes.
    8. "layer_widgets" object has the highest z-index order and is drawn last. It is responsible of displaying widgets on the screen such as a mini-map, primary tank status, notification messages or chats etc..
  3. "Settings" object is where the game is configured, in terms of control keys, navigation mode etc. For the moment it contains "Navigation" and "Keys" objects for setting the navigation mode and the control keys.
  4. "Res" objects contains resources needed by the game. Such as images, sounds etc...

The hierarchical model
Although that Javascript is not Object Oriented language, the Tank Battle Field game uses commonly known tricks to simulate class hierarchy and inheritance. The inheritance logic is hand crafted and does not use any library in order to keep it simple and minimal.
The concept of class does not exist in Javascript, everything is object but since hierarchy of classes is simulated in this section, the terms "class" and "object" refer to the same entity.



All objects in the game inherit from one super class which is ModelObjectClass. This gives the ability to get and set data and have an ID.

Objects that have dimensions, locations and rotation settings are of type ModelLocatableObjectClass. Note that the setX()/getX(), setY() /getY() coordinates functions represent the center of the object while the getTop(), getLeft() represent the top left corner of the object. It is also important to note that dimensions terms are not exactly the same as one might expect. Actually the width is the horizontal distance following the x-axis, the length is the vertical distance following the y-axis (which normally used to be called height), and height is the elevation from the ground following the z-axis. It is true that this is a 2D game, however the height (z-axis) will play a role.

Moving objects inherit from ModelMoveableObjectClass and have linear and angular speed, as well as acceleration.

VehicleClass contains commands to move forward, backward and to turn left and rights. It has also an import set of functions that determines how the vehicle will behave and how it is going to be rendered on the screen.

TankClass inherits from the VehicleClass and contains a turret object.
Other objects such as BuildingClass and Shell make use of this hierarchy of classes.

Initialization and data
Objects in the class hierarchy are instantiated using the new keyword, however the initialization does not take place inside the constructor, but by explicitly calling init() method and passing to it an arbitrary data object that each class might be expecting.
The reason for this approach is purely technical. Actually when instantiating an object using new keyword, the whole hierarchy of objects is instantiated and linked together via the __proto__ property.
So after the instantiation and the linking are done then it is possible to initialize using the init() method.

The data object given as parameter in the call to init() method, is used as momento design pattern, in the sens that it is used to save the state of the object so it can be saved or transferred via network in a multiplayer game.

Game loop: updates and rendering
As it is known by now, the game loop is a never ending cycle of tasks that is executed sequentially.
The loop reads the input of the user, calls updateModel() function on every object in the graphic layers. This method updates the internal state of the object, such as location, direction, health, etc...then the loop calls renderGraphics() on each object to draw itself on the screen, and finally updateModelAfterRendering() is called to update the state after the rendering phase. One example of the usefulness of the updateModelAfterRendering() method, is to reset the "fire" flag of the tank which was set by the updateModel() method and drawn by the renderGraphics() method.

Demo
That's it for now, as usual you can check the demo by going to http://tankbattlefield.eu.pn


Tuesday, December 24, 2013

HTML5 Game #3: Tank Battle Field, new approach

Welcome to this new episode of HTML5 Tank Battle Field game. In this article a drastic restructuring of the game has been put in place.

In order to make the game more fit to new features and scenarios, some major concepts have been implemented:

1- World concept. The world concept is a simulation of how the tank battle occur in the real world. This is called the Model in the code.
The importance of the Model is that it abstracts away the real stuff from the graphic technicalities. So in theory, once the Model is ready, porting the game to different devices and/or different screen resolutions is a matter of adapting the graphics only.
It also ensures that the game play can vary by only touching the graphics without the need of rewriting the whole game.
A third important reason why the Model is crucial, is that the game could be transformed into multi-player one. So it will present a same world (Model) for all the players without caring about their graphic settings.

2- The Graphics, is what appears on the screen in front of the user. The graphic elements drawn on the screen will reflect what happens in the Model. However that does not mean that the mapping is one-to-one. Some transformations are required in order to render those elements appropriately.
Ideally the graphics coding structure will evolve separately from the Model, and the two can be linked by the "bridge design pattern". This will add great amount of flexibility.

3- Navigation view mode: As said in the first and second article, the game is about "first person vehicle" (as an analogy to the "first person shooter"). So despite the fact that this is a plain top view 2D game, the graphics are rendered to give the impression that the user is inside the tank. Which means that the tank is always fixed at the center of the screen and the objects move around it as it (the tank) moves.

However to keep things open for future navigation modes, this mode is used as part of the settings. In future releases, the user might be able to switch between navigation modes.

4- The game loop of course. It was not present in the previous article for simplicity purpose. However since the game is evolving, the game loop existence is extremely important. It has the role to keep the game together: It reads user input, updates the Model and renders the graphics and sounds.





The Model
As said the Model represents a simulation of the real world of the game which abstracts it from the graphics technical issues and constitutes a unique reference of what is happening in side the game for all players in a multi-player game.

As for this version of the game, the coordinates system of the Model is similar to the screen one, i.e. the origin (0,0) is at the top left of the screen, and the positive x-axis goes to the right, while the positive y-axis goes down.
The dimensions of the battle field, known as Field in the code, is 5000m x 5000m.
The angular system, is similar to the classic trigonometric one. So positive x-axis goes to the right, positive y-axis goes up and a positive angle is the one that goes from right to left.

There is no particular reason I have chosen this configuration, you can choose the one you want as long as you make the appropriate adaptation in your code.



The Graphics
The Graphics is to represent the objects of the Model on screen, by taking into consideration the screen resolution, the navigation settings, etc.
It is composed among other things of five layers:
The ground layer: To draw the background
The objects layer: Usually used to draw static objects such as buildings
The units layer: to draw the vehicles and big mobile objects
The projectiles layer: to draw the shells, rockets, missiles fired by the units
The flying layer: this is to draw any future flying object such as planes etc..
The widgets layer: this layer is for displaying extra features in the game such as mini-map, text messages etc..
As you can notice the existence of the layers determines the depth or z-index of the graphic elemnts. The rendering starts with the ground layer up to the widgets layer.

It is important to note that every object of the Model must be in one of these layers in order to appear on the screen.



The Navigation Mode
As already stated, the navigation mode in this version is about first person vehicle, or FixedCenter as referred to in the code. So the tank is fixed at the center of the screen, only its turret can turn. When trying to turn the chassis, the objects around the tank turns in the opposite direction to give the user the feeling that tank has turned.

So if the tank turns  towards a building on its left, what the user sees on the screen is that the building is turning to the right to come in front of the tank. When the tank moves forward, or backwards, the building approaches or moves away.

It is important to note that all of this is only graphical, in the Model only the tank moves foward and backwards or turns left or right. But when representing those movements on the screen, the impression is given that the tank is fixed and the buildings are moving.

Technically, when the tank moves towards a building the distance between the tank and the building is measured and on the screen the building is drawn closer to the center.

When the tank turns, the building appears to be turning in the opposite direction, in order to come in front of the tank. However there is a little catch in here. Because our tank is always positioned upwards, in practice  it is making 90° with the x-axis (according to our angular system). So when the tank moves left to position 120°, the building should rotate by 30° (120° - 90°) to the right (around the center of course).





Collision detection
For simplicity reason in this version the collision of the tank with any building is reduced to detecting whether the center point of the tank crosses the boundary of any building. Thus you will easily see half of the tank mounting the building.

Note that collision is detected in the Model and not graphically. So once the Model detects that the tank collided it cancel all movements towards the collision point, and this way the graphics on the screen keeps drawing the tank at the same position, giving the impression that it has stopped moving.



Demo
For the demo please go to the following http://tankbattlefield.eu.pn/tank6/index.html





Saturday, December 14, 2013

HTML5 Game #2 : The Tank Battle


In my previous article I have shown how to use a vehicle as "1st person navigator" in 2D.
After a second thought I found that there are more things to tell regarding HTML5game dev. So I decided to continue the series hoping that at the end of which I can come up with a minimum playable game. It would be a good practice for me and others.
During this series if you have remarks, or suggestions feel free to drop a line in the comments.

First I will redefine the game story.
Starting this article the game will be about a tank, navigating and and shooting  on a map. The enemies are not very specific for the time being, they can be computer animated ones or other user(s) in a multiplayer game. Future articles will help determining them, since it is all about what can be achieved in a reasonable amount of time and efforts.

So in this article I will do the following:
1- add a tank with a moving turret
2- control the tank via keyboard instead of push buttons for better playability. 
3- add some quick objects to the map
4- some technical stuff

As a matter of fact this article is more about polishing than anything else. It doesn't require any head scratching.
However before I start, I would like to point that the code has suffered a bit and needs some refactoring. I hope to be able to do this in the next articles.

1. The tank
In order to simulate a tank I have used a  sprite PNG format with a transparent background. See image
The chassis and the turret are separate since the turret should be able to turn 360°.
Placing the chassis and the turret on the screen is straight forward. First you have to load the image then you have to draw each part alone.




It is worth noting that the tank is positioned upwards which is opposed to the relative axis system initial direction. This means that the turret along with its gun as the trajectory of the shell evolve in the negative values of the y-axis.

As I said earlier the chassis is fixed, but the turret can rotate. The good news is that since we are in a 2D and Top view, all objects are symmetric thus we don't need to draw every shape that the turret takes as it rotates. So delegating the job to the graphic engine is sufficient.

Tank forward, reverse, rotation speed as well as the rotation speed of the turret are controlled by the following variables in the code.
var ctDefaultForward = 5;
var ctDefaultBackward = 3;
var ctDefautltTurning = 2;
var ctDefautltTurretTurning = 2;

Firing is also constrained by the loading time. Meaning that after every shot there is a certain amount of time to wait until the next shell is loaded. This time is controlled by the variable.
var ctDefaultLoadTime = 20;

Explosion of the shell is a sequence of sprites that display one after the other.
Each of these sprites is contained in a  64x64 rectangle, so it suffice to know the number of the sequence in order to deduce the sprite position on the sprite sheet.
The variable explosionSeq keeps track of the explosion sequence. A value of -1 means there is no explosion.

Upon firing the gun recoils and this is reflected by move back of the turret. The variable recoil tells if there has been a recoiling and recoilDist controls the amount.

2. Tank control

Unlike in the previous article, the tank is now controlled via keyboard instead of push buttons. This is will allow a greater maneuverability.
The logic of the keyboard controls lies in the existence of a keyDown array. This array will take as index the key code and as value true in case the key is down and false in case the key is up. This keyDown array is essential when several keys are pressed down.
The variables that set the key controls are listed in here:
var ctKeyMoveUp = 69; /*E*/
var ctKeyMoveDown = 68; /*D*/
var ctKeyTurnLeft = 83; /*S*/
var ctKeyTurnRight = 70; /*F*/
var ctKeyTurretLeft = 37; /*left arrow*/
var ctKeyTurretRight = 39; /*right arrow*/
var ctKeyFire = 16; /*shift*/

In order to avoid the differences between QWERTY and AZERTY keyboards, I have set the control keys to match both layouts, whereas E = Forward, D = Backwards, S = TurnLeft, F = TurnRight, Left Arrow = Turret Left, Right Arrow = Turret Right, Shift = Fire.

3. Buildings

For the time being other objects on the map, particularly buildings are no more than rectangles of different dimensions and colors spread randomly.
As of this article, there are no collisions detection implemented in the source code.


4. Technical stuff

The most important technical issues to mentions are:
1- The game loop that maintain the game running. It is called every 100ms and consists of function readInput() for reading and analyzing the key strokes, the update() function that make some calculations regarding the positioning of objects, the drawAll() function that draws all the objects on the screen and finally the postUpdate() method that perform computations for the after drawing phase (useful in case of shell firing).
2- Another important issue, the rotating turret. The turret rotates within a relative axis system. This is the easiest way to do it, since the graphics api is able to rotate the turret sprite without deteriorating its quality.





5. The demo

Here is a live demo of this new version. Give it a try!




Your browser does not support the HTML5 canvas tag.





Keys: E = Forward, D = Backward, S = Left, F = Right, Left Arrow = Turret Left, Right Arrow = Right Turret, Shift = Fire


Please find below the source code of this version:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas2" width="600" height="480" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<br/>
<span id="loadingInfo"></span><br/>
<span id="info">Keys: E = Forward, D = Backward, S = Left, F = Right, Left Arrow = Turret Left, Right Arrow = Right Turret, Up Arrow = Fire</span><br/>

<script>
var timeIntervalID = -1;
var canvas=document.getElementById("myCanvas2");
var ctx=canvas.getContext("2d");
var info=document.getElementById("info");
var loadingInfo=document.getElementById("loadingInfo");
var imgSprites = new Image();
imgSprites.src="file:///C:/projects/tank/t2_1.png";
var imgExplo = new Image();
imgExplo.src="file:///C:/projects/tank/explo2.png";
var keyDown = [];
var ctDefaultLoadTime = 20;
var ctDefaultForward = 5;
var ctDefaultBackward = 3;
var ctDefautltTurning = 2;
var ctDefautltTurretTurning = 2;
var ctTotalExplosionSeq = 5;
var ctShellMaxRange = 300;

var ctKeyMoveUp = 69; /*E*/
var ctKeyMoveDown = 68; /*D*/
var ctKeyTurnLeft = 83; /*S*/
var ctKeyTurnRight = 70; /*F*/
var ctKeyTurretLeft = 37; /*left arrow*/
var ctKeyTurretRight = 39; /*right arrow*/
var ctKeyFire = 16; /*shift*/

// coordinates of the center of the map
// they are also those of the vehicle since it does not physically move on the map.
var canvasWidth = parseInt(canvas.width);
var canvasHeight = parseInt(canvas.height);
var centerX = canvasWidth/2;
var centerY = canvasHeight/2;

// the rotation angle by which the relative system will rotate
var rotAngle = 0;

// the rotation angle of the turret
var rotTurret = 0;

// movements
var deltaAngle = 0;
var deltaMove = 0;
var deltaTurret = 0;
var explosionSeq = -1;

// tank dimensions
var tankWidth = 40;
var tankHeight = 86;
var tankHalfWidth = 20;
var tankHalfHeight = 43;
var realTankPoints = [];



// this is the PI/2 which is 90 in radians
var PIover2 = Math.PI/2;

// coordinates of the objects in the relative system
var buildings = createBuildings();

var shellY = 0;
var fire = false;
var recoil = false;
var recoilDist = 2;
var loadingTime = 0;

// draw everything at start with no translation nor rotation
//drawAll(0, 0);
imgSprites.addEventListener("load", function(){
drawAll(0,0, 0);
});

window.addEventListener("keydown", function(ev){

if(ev.keyCode == ctKeyMoveUp || ev.keyCode == ctKeyTurnLeft|| ev.keyCode == ctKeyMoveDown|| ev.keyCode == ctKeyTurnRight || ev.keyCode == ctKeyTurretLeft || ev.keyCode == ctKeyTurretRight
|| ev.keyCode == ctKeyFire){
keyDown[ev.keyCode] = true;
}
});

window.addEventListener("keyup", function(ev){
if(ev.keyCode == ctKeyMoveUp || ev.keyCode == ctKeyTurnLeft || ev.keyCode == ctKeyMoveDown || ev.keyCode == ctKeyTurnRight || ev.keyCode == ctKeyTurretLeft || ev.keyCode == ctKeyTurretRight){
keyDown[ev.keyCode] = false;
}
});



function readInput(){
deltaAngle = 0;
deltaMove = 0;
deltaTurret = 0;

if(keyDown[ctKeyMoveUp]){
deltaMove = -ctDefaultForward;
}
if(keyDown[ctKeyMoveDown]){
deltaMove = ctDefaultBackward;
}
if(keyDown[ctKeyTurnLeft]){
deltaAngle = ctDefautltTurning;
}
if(keyDown[ctKeyTurnRight]){
deltaAngle = -ctDefautltTurning;
}
if(keyDown[ctKeyTurretLeft]){
deltaTurret = -ctDefautltTurretTurning;
}
if(keyDown[ctKeyTurretRight]){
deltaTurret = ctDefautltTurretTurning;
}

if(loadingTime > 0){
keyDown[ctKeyFire] = false;
}
if(keyDown[ctKeyFire]){
fire = true;
recoil = true;
keyDown[ctKeyFire] = false;
loadingTime = ctDefaultLoadTime;
}
}
function update(){

rotAngle = (rotAngle + deltaAngle) % 360;
}

function postUpdate(){

// loading time
if(loadingTime > 0){
loadingTime --;
loadingTime = Math.max(0, loadingTime);
loadingInfo.innerHTML= "Reloading: " + loadingTime;
}else{
loadingInfo.innerHTML = "Loaded";
}
}

// the drawAll function draws all the map and its objects
// parameters:

function drawAll(){
// compute the total rotation angle of the vehicle in degrees and radians
var rad = rotAngle*Math.PI/180;

// compute the forward vector coordinates in the relative system
var rotdy = Math.round(deltaMove * Math.sin(PIover2-rad));
var rotdx = Math.round(deltaMove * Math.cos(PIover2 - rad));

// clear the map
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, canvasWidth, canvasHeight);

// save the context in order to start the transformation
ctx.save();

// move the coordinates system to the center (this is the relative system)
ctx.translate(centerX, centerY);

// apply the rotation to the relative system
ctx.rotate(rad);


for(var i = 0; i < buildings.length; i++){
// make the necessary translation in the relative system
buildings[i].x += -rotdx;
buildings[i].y += -rotdy;

// draw the objects on the map in the relative system
ctx.fillStyle = buildings[i].c;
ctx.fillRect(buildings[i].x, buildings[i].y ,buildings[i].w, buildings[i].h);
if(buildings[i].hilit){
ctx.strokeStyle="#000000";
ctx.lineWidth=4;
ctx.strokeRect(buildings[i].x, buildings[i].y ,buildings[i].w, buildings[i].h);
}
}

// restore the previous context (return to the fixed system)
ctx.restore();

// draw the vehicle at the center of the map using the fixed system
ctx.drawImage(imgSprites, 1, 0, tankWidth, tankHeight, centerX - tankHalfWidth, centerY - tankHalfHeight, tankWidth, tankHeight);


// draw turrent
rotTurret = (rotTurret + deltaTurret) % 360;
var radDeltaTurret = rotTurret*Math.PI/180;
ctx.save();
ctx.translate(centerX, centerY);

// apply the rotation to the relative system
ctx.rotate(radDeltaTurret);
ctx.drawImage(imgSprites, 75, 0, 27, 99, - 15, - 80 + (recoil ? recoilDist : 0), 28, 99);

//fire
var fired = fire || false;
if(fired || shellY != 0){
if(shellY == 0){
shellY = -107;
}
recoil = false;
ctx.beginPath();
ctx.fillStyle = '#ff0000';
ctx.strokeStyle = '#ff0000';
ctx.arc(0,shellY,2,0,2*Math.PI);
ctx.fill();
ctx.stroke();

shellY += -50;

if(Math.abs(shellY) > ctShellMaxRange){
fire = false;
explosionSeq = 0;
explosionY = shellY;
shellY = 0;
}
}

// explosion
if(explosionSeq > -1){
var eX = (explosionSeq * 64) % 320;
var eY = 0;//(explosionSeq * 64) % 320;
ctx.drawImage(imgExplo, eX, eY, 64, 64, - 32, explosionY - 32, 64, 64);
explosionSeq++;
if(explosionSeq >= ctTotalExplosionSeq){
explosionSeq = -1;
}
}
ctx.restore();
}

timeIntervalID = setInterval(function(){gameLoop();}, 100);
function gameLoop(){
readInput();
update();
drawAll();
postUpdate();
}

function stopGame(){
clearInterval(timeIntervalID);
timeIntervalID = -1;
}

function createBuildings(){
var temp = [];
for(var i = 0; i < 20; i++){
var tx = getRandomInt(-200, 200);
var ty = getRandomInt(-200, 200);
var tw = getRandomInt(50, 150);
var th = getRandomInt(50, 150);
temp[i] = {
x: tx,
y:ty,
w:tw,
h:th,
c:'#'+Math.floor(Math.random()*16777215).toString(16),
}
}
return temp;
}

function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

</script>

</body>
</html>

Friday, December 6, 2013

HTML5 Game #1: First person vehicle in 2D


I am by no mean a game developer, however recently I have been tinkering with HTML5 2D graphics.I encountered a challenging problem when writing a piece of code for simulating a vehicle navigating through out a map.

The main idea is that the vehicle is fixed at the center of the map and the map objects move and rotate around it as the vehicle moves around.
Actually the concept is quite simple. When a person drives the vehicle he has the impression that objects (trees, houses, etc..) are moving.

Logically speaking the problem is quite easy, however the implementation is rather tricky. The issue stems from the fact that raw 2D engines APIs are not very flexible.PS the concept is the same disregarding the 2D technology you are using (JavaScript, c#, Java...)

So let's now put some hypothesis before we start.We have a fixed vehicle positioned at the center of the map having only one single direction which is upward. The vehicle can move forward, backward, and it can also rotate. But since the vehicle is always fixed in position and direction, it is the objects around it that move and rotate.

To solve this problem we will consider two axis systems.
1- the first one we call "fixed system", and is defined by the origin at the upper left corner with x-axis goes to the left, and the y-axis goes down.
2- the second axis system, which we call "relative system", has its origin at the center of the map and the axis can rotate in any direction

The fixed system is used to draw the fixed vehicle, while the relative system is used to draw the moving objects around the vehicle.
When the vehicle turns what actually happens is that the relative axis system that turns.
As you can see in the image below, the vehicle is still fixed but the circle that was on the left side came into the vehicle vision field.
Now when the vehicle move backward or forward the circle gets closer or farther.

So now what is done practically is that you tell the graphics engine to draw the vehicle at the center of the map (or canvas), then you translate the axis system to the center, rotate them then draw the circle. All of this is done via API calls. No tough calculations are done on your side.

Here is the 1st example:



Your browser does not support the HTML5 canvas tag.


In this example you can press the buttons forward and backward to move and the button left and right to rotate. You might be quite happy with that, but there is a glitch!
Try rotate the vehicle 90degrees then go forward!
Surprise! You notice that the vehicle seems to go horizontally rather than vertically. For sure you don't want your vehicle to go on the left or right when you meant to go forward.

So what happened behind the scenes?
It all lies in the relative axis system that has been rotated. The picture below depicts the concept.
Moving forward as seen in the picture happens in the relative axis system, which has been rotated and as you can see its axis directions have changed. So a simple translation of objects won't  give the correct result because the translation occur in the relative system and not the fixed one.
In other words, if you rotate the relative axis 90 degrees the x-axis becomes vertical and the y-axis becomes horizontal,  so moving along the y-axis (which is the forward direction) does not go vertically but horizontally which gives the impression that the vehicle is going to its side!

To solve this problem we need to understand that moving vertically in the fixed system means that we need to adjust the vertical vector to the relative system. This can be done by taking the rotation that occurred to the system into consideration.
Moving dy pixels in the fixed system means that in the relative system we have moved as follows
rdx = dy * cos(Π/2 - Θ); along the relative x-axis
rdy = dy * sin(Π/2 - Θ); along the relative y-axis
where Θ is the rotation angle of the relative system.
Now having the coordinates in the relative system we can translate any object in the that system via a simple operation:
Xobj += - rdx;
Yobj += - dy;

Lets see how this is concertized in reality


Your browser does not support the HTML5 canvas tag.




Hope this was useful to anyone who is facing a similar problem.
The finish, I have included the code below.


<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas2" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<br/>
<input type="button" id="btnForward2" value="forward" onclick="drawAll(0, -5)"/>
<input type="button" id="btnBack2" value="backward" onclick="drawAll(0, 5)"/>
<br/>
<input type="button" id="btnLeft2" value="left" onclick="drawAll(5, 0)"/>
<input type="button" id="btnRight2" value="right" onclick="drawAll(-5, 0)"/>

<br/>

<script>
var canvas=document.getElementById("myCanvas2");
var ctx=canvas.getContext("2d");

// the rotation angle by which the relative system will rotate
var rotAngle = 0;

// coordinates of the center of the map
// they are also those of the vehicle since it does not physically move on the map.
var centerX = 150;
var centerY = 75;

// this is the PI/2 which is 90 in radians
var PIover2 = Math.PI/2;

// coordinates of the objects in the relative system
var obj1X = 100 - centerX ;
var obj1Y = 5 - centerY ;
var obj2X = 135 - centerX ;
var obj2Y = 60- centerY ;

// draw everything at start with no translation nor rotation
drawAll(0, 0);

// the drawAll function draws all the map and its objects
// parameters:
// deltaAngle = is the angle by which the vehicle has turned compared to the previous time
// deltaForward = is the number of pixels the vehicle has moved forward since the last time
function drawAll(deltaAngle,deltaForward){
// compute the total rotation angle of the vehicle in degrees and radians
rotAngle = (rotAngle + deltaAngle) % 360;
var rad = rotAngle*Math.PI/180;

// compute the forward vector coordinates in the relative system
var rotdy = Math.round(deltaForward * Math.sin(PIover2-rad));
var rotdx = Math.round(deltaForward * Math.cos(PIover2 - rad));

// clear the map
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, 300, 150);


// save the context in order to start the transformation
ctx.save();

// move the coordinates system to the center (this is the relative system)
ctx.translate(centerX, centerY);

// apply the rotation to the relative system
ctx.rotate(rad);

// make the necessary translation in the relative system
obj1X += -rotdx;
obj1Y += -rotdy;
obj2X += -rotdx;
obj2Y += -rotdy;

// draw the objects on the map in the relative system
ctx.fillStyle = '#0000ff';
ctx.fillRect(obj1X, obj1Y ,100,10);
ctx.fillRect(obj2X , obj2Y ,30,30);

// restore the previous context (return to the fixed system)
ctx.restore();

// draw the vehicle at the center of the map using the fixed system
ctx.fillStyle = '#ff0000';
ctx.fillRect(centerX - 5, centerY - 5,10, 10);
ctx.fillRect(centerX - 2, centerY - 10,4, 10);

}

</script>

</body>
</html>