- Sprite Class
In this class 4 parameters are passed: x, y, width and height, x and y will be the position of the sprite that will be drawn on the screen, while width and height will be the size of the sprite.
Attention, there is a difference in the size of the sprite and the size of the image, if the width of the sprite is greater than the width of the image and the "imgDouble" property is true, then it creates a horizontal image sequence, which is the floor case).
To set the image, just create a "new Image (width, height)" and set it in the "img" property, then just set the "src" property of the image.
It is also possible to rotate the image of the sprite, which is the case of the player, with the property "rotate", as the player falls the image is rotated clockwise to a certain angle, and when the "rotate" property is flying set to a value where the bird is pointed upwards, giving the impression that it is rising.
Once these properties are set, to draw, just call the "draw" function, which is another property of the sprite.
- Button Class
Like the sprite, the "Button" class has 4 parameters, and the parameters are the same, x, y, width and height. This class does not have the property to rotate, however, it has other properties for writing text on the button like: text, fontSize. In addition to properties to increase the size of the button image when the mouse over is over the button such as: mouseOver (receives true or false), scaleOriginal (size when the mouse is not over the button), scale (current size of the button).
The image property of the button to be drawn, is the "imgMain" that the image is created with the class, lacking to set the "src" property of the image.
Like the "Sprite" class, the "Button" class has the function of drawing it. Just call the "draw" function inside the object and then the button will be drawn at the position of the x and y property values, with the size of the button's width and height property values, and with the image of the "imgMain" property.
The "Button" class has 2 functions linked to the click event:
- clicked, which will return a true or false value depending on whether the click is over the button (the values of the "mouseClick" array are used, which stores the x and y coordinates from which it was clicked).
- onclick, which will receive the logic of the button, calling when the "clicked" function returns true.
The Background is just an object created from the Sprite class, which receives an image and is then drawn on the canvas, the Background and Clouds objects are in the "background and clouds.js" file.
- Clouds
Within the "updateClouds" function that is called in the "frame" function, clouds are created at a random height, at a random time interval, with a random sprite image, the variables that control the time interval are: addCloudTime ( which will receive the amount of time to add the next cloud), and counterAddCloud (which will receive +1 for each update). When "counterAddCloud" is greater / equal to "addCloudTime", "addCloudTime" will receive a new random value, "counterAddCloud" will receive 0, and will create a new Sprite, with the source and image size of the sprite being a random from the array "cloudsSrc".
This sprite will receive the "update" function, which will decrease the x axis of the sprite and draw it on the canvas. This function will be called for each frame.
To be able to call the update sprite function later, it will be stored in the "clouds" array, which then, inside the "updateClouds" function, a for loop will be passed, which will call the update function of the clouds and remove the clouds left the canvas.
The floor is an object of the Sprite class, which has the width of an image smaller than the sprite and with the property "imgDouble" receiving true. In other words, it is a sprite whose image is repeated sequentially and horizontally.
The drawing function of the "floor" object is part of an update function, because it is necessary to decrease the x axis of the floor and then when the floor has moved a certain distance (width of the sprite image) the x is set to 0, to give the impression that the canvas is in motion and the floor sprite never leaves the canvas.
That's why this sprite is wider than the canvas itself.
The floor refresh function is being called within the "frame" function.
The obstacles have 2 sprites ("up" and "down", which are the ends through which the player can pass), and an array of sprites for each of them (which are what is missing to complete the obstacle columns), I I did it like this, because in the beginning I used the sprite from the green column of the Super Mario Bros game, which at the top has a different sprite, and I didn’t modify it for the developer who buys this item, decide that the sprite on the ends are different from the sprites that complete the column.
Obstacles are created if the "status" variable is equal to the "playing" variable and if there are no obstacles, that is, when the "obstacles" array has no items, or when the x of the last obstacle in the array has a difference in width (the right end) of the 7 tilesets canvas, which is the value of the variable "addObstacleDistance". And then the function "addNewObstacle" is called, which creates the object "obstacle", sets the ends "up" and "down", and completes the missing sprites for the columns (if necessary), creates the function "update" that will update and draw all the sprites of the "obstacle" object, and place it in the "obstacles" array.
The "decision" variable at the end of the "addNewObstacle" function, serves to create a random y in tileset for the "up" sprite of the next obstacle. Then move on to the "obstacleSize" variable and convert the number (in tileset) to pixels.
I made this logic for the next obstacle, so that the first obstacle is created with the top column being the same height as the bottom one.
O espaço entre a sprite "up" e "down", são de 7 tilesets, que é o valor da variavel "obstacleSpace".
The "updateObstacles" function is called by the "frame" function and has the utility of updating all obstacles, removing the obstacle from the array if the obstacle comes out on the left of the canvas. This function also checks if the bird has collided with an obstacle that is being updated, calling the "collision" function of the "player" object and passing the parameters that will check if the bird has collided with the upper obstacle and the lower obstacle.
- rotate, is an integer value and serves to rotate the image when drawing according to the value.
- angle, receives the value "rotate" however converted to degrees, used to measure how far it should stop rotating, when falling or rising.
- gravity, is what constantly increases the y of the "player", causing it to fall.
- gravitySpeed, is what constantly increases "gravity", giving the impression of gravity.
- upFlying, when this variable receives true, "gravitySpeed" will decrease "gravity". And when "upFlying" receives false, "gravitySpeed" will increase "gravity".
- timePressJump, when the player makes a short flight upwards, this variable will receive a "setTimeout", which 200 milliseconds later, if the mouse button is still being held, "upFlying" receives true.
- flightForce, Flight force (short).
- width
- height
- fallingImage, centerImage, flyingImage, deadImage, which are images of the bird to change during animations.
- animationFly, which is the animation for each short flight
It consists of several functions that change the character's sprite and is called "setTimeout" s, that the variable that stores it is the local variable "time". As soon as a function is called, the Timeout is deleted, and the next function is called in another Timeout. It is necessary to delete the Timeout because in the case of another function "animationFly", to be called while the previous one is not over yet, the images of the bird will be changed in both functions, making the animation strange. It is called by the player object's "oneFly" function.
- oneFly
This function is always called when it has the "status" with the same value as the "playing" variable and, when the mouse clicks on the canvas and in a place other than a button.
The function set some variables, creates the "setTimeout" for the "timePressJump" property of the player object, calls the "animationFly" function, sets the gravity for the player to go up, and plays an audio to give the sound of the flight.
This function checks the collision by passing the x, y, width, and height of the object as parameter, it is called by the obstacles when it is going to update them.
The "pixelsAngleY" and "pixelsAngleX" variables are used to modify the collision points according to the player's rotation angle.
It is in this function that the logic of some bird skills (without spoiler). obviously, those that involve the player colliding with the obstacle.
Another function somewhat similar to this one, which I did to see the bird's collision points to be able to make it more precise, when the bird touches the obstacle, which is the "drawRectColision" function inside the player object, it is commented within the update function of the player after the draw function.
As the points of collision form a rectangle, I had to calibrate so that the rectangle could be in an area that depending on the angle of the bird (very up or very down) it would be in the parts where they would collide with obstacle.
Example:
If the bird is tilted upwards (going upwards), there is no way for the rear to collide with any obstacle, so the rectangle of the collision does not fill that part of the bird's body.
- flyingSound, sound effect played when the bird takes a short flight when playing.
- victorySound, music of when the bird falls to the floor and the score passes the record.
- gameOverSound, music of when the bird falls to the floor without the score passes the record.
- deadSound, a sound effect that plays when the bird collides with the obstacle.
- deadFireworkSound, sound effect, when a specific bird uses its skill.
- music, background music, short music that has a playback loop.
- clickSound, sound effect that is played when a button is clicked.
The 2 buttons basically have the same properties and the same functions, however using different variables and images, the images are in the properties "imgEnable", and "imgDisable", and the property "imgMain", is the image that will show one of the two dependent on whether the button is enabled or disabled. The functions are also very similar however using different variables.
- buttonMusic, image of a musical note, used to activate or deactivate the background music when clicked.
- buttonEffectSound, image of a speaker, used to activate or deactivate the sound effects when clicked.
- btnBackNewBird, is a button with an image of an arrow pointing to the left, when clicked, it goes back to the previous screen, but if you have another bird unlocked it will show it just as it showed the previous one.
- btnShowNewBird, is a button with an image of an eye, when clicked on the screen it is redirected to the bird watching screen, to see more details of the unlocked bird.
- imgMain, standard image of the "Button" class, is the one that will be drawn on the canvas. In this case, it is the image of the skill button when it is unlocked.
- imgLocked, image of the skill button when it is blocked.
- skillTime, skill cooldown.
- skillTimeDuration, skill length of time.
- skillTimeOut, current time, it increases when the skill is activated (duration) and decreases when it is disabled (cooldown).
- skillOn, property to define whether the skill is active or not.
- interval, property that will receive the time interval of 1 second to decrease or increase the "skillTimeOut". Receive "undefined" when the interval is cleared.
I used the color of the button to demonstrate how much time is left before the skill can be used and how long the skill lasts for a better look. I had to create a new logic of drawing for this button, since the function of the "Button" class to draw, I was unable to make the button change images so that it seems that time is needed to click the button (a part of the button without color, and another with color).
The logic is to draw a part of the unlocked image with the height divided by time and then multiplied by "skillTimeOut", and drawing a part of the locked image on the missing part to complete the image.
Called by the button update function. And there are 3 actions for the interval to perform under different conditions:
1 - Increase the value of the "skillTimeOut" property, until the duration of the skill ends.
2 - Decrease the value of the "skillTimeOut" property, until the skill cooldown ends.
3 - Resume the cooldown after the skill has expired.
It is called every 1 second, and the duration and cooldown varies from skill to skill. The interval is stored in the object's "interval" property in case the game needs to delete the interval.
The "mouseClick" array is used to store the click data, the event stores the 1st value of the array with the X coordinate of the mouse click and stores the 2nd value of the array with the Y coordinate of the mouse click. With this simple logic it is possible to know if 1 button was clicked.
For the click to happen only 1 time, this variable is reset (receives a new array with null values) at each loop of the "frame" function.
After these variables receive the click value, the "clickPress" function is called to perform all the logic with conditions to know which screen is on and if the button was clicked.
This event simply receives the "clickRelease" function, which basically serves to stop the player from flying without falling.
Recalling, the variables of the "mouseClick" array, receive "null" in the "frame" function.
Like the Mouse Down event, it stores the 1st and 2nd values of an array (in this case, this array is the variable "mousePos") with the X and Y coordinates of the mouse, however, this function is called only with the movement of the mouse, the array is not zeroed at any time, and does not call any function, only gives values. All objects that make use of the event, use the "mousePos" array, in their own functions.
Keyboard Event
To make the keyboard event work on the canvas I had to give some value to the "tabIndex" property of the canvas, it also makes a border appear outside the canvas to show that it is in focus, that border can be removed by adding the code that is commented on the "outline" property that receives "none" in the canvas CSS in "style.css".
The event receives the function "keyboardDown" and if the key pressed is "space" and has the variable "status" receiving the same value of "playing", then the "onclick" function of "btnSkill" is called, activating the skill of the bird.
Clean the canvas;
Updates the "shine" variable (which makes the letters shine);
Updates and draws specific objects depending on the current screen;
And it gives a null value for the first two positions of the variable "mouseClick".