The first time I developed a small game, I used Hilo framework. Due to the limited development time of the project, I have no knowledge of games and CANVAS. The code sucks, but keep track of the potholes you step on! This article is broken read model, not in-depth, write wrong place hope to give directions.
I. CANVAS landscape adaptation processing
The game is a horizontal screen game in wechat. If landscape is forced, prompting the user to control the landscape switch is not friendly.
The solution is to make the game scene into the purple part of the structure in the picture below, and exchange the width and height of the game with the mobile phone screen. If the phone is portrait, rotate the game 90 degrees.
Note: the [landscape] switch is opened for the user to allow landscape and landscape, real landscape.
The code looks like this:
let width = document.documentElement.clientWidth;
let height = document.documentElement.clientHeight;
let box = document.getElementsByTagName('canvas');
let style = ' ';
/ / vertical screen
if (width < height) {
style += `width:${height}px; `;
style += `height:${width}px; `;
style += '-webkit-transform: rotate(90deg); transform: rotate(90deg); ';
// Pay attention to the rotation midpoint processing
style += `-webkit-transform-origin: ${width / 2}px ${width / 2}px; `;
style += `transform-origin: ${width / 2}px ${width / 2}px; `;
}
if (box.length) {
box[0].style.cssText = style;
}
Copy the code
When the user turns the landscape switch on, if the user turns the landscape on, rotate the scene 0° to restore the original look. As follows:
/ / landscape
if (width > height) {
style += `width:${width}px; `; // Note the width and height switch after rotation
style += `height:${height}px; `;
style += '-webkit-transform: rotate(0); transform: rotate(0); ';
style += '-webkit-transform-origin: 0 0; ';
style += 'transform-origin: 0 0; ';
}
if (box.length) {
box[0].style.cssText = style;
}
Copy the code
Landscape screen is not as smooth as expected, our game is in the wechat scene. When the user turns on the landscape switch, the built-in browser header of wechat will also occupy a large part of the area. So our game scene rotation is obviously incomplete.
The solution is to use Hilo’s API resize to get off stage
// Solve the height change caused by wechat landscape browser head
this.stage.resize(height, width, true);
Copy the code
A few final caveats:
1, pay attention to the width and height switching in the rotation process2, pay attention to unit adaptation3, pay attention to the wechat browser header, because this header changes. The whole game needs to be dealt with, so try not to deal with it yourself...Copy the code
Refer to the article
Click event is invalid
As shown below, the two buttons in the game end scene.
Rotate the left side by 90° and it becomes landscape right, but the landscape under portrait (i.e. rotate it by 90°) [Try Again] button click event will not work, but click the red area (no button, roughly drawing is not accurate) this time will be triggered.
And the user landscape (landscape switch turned on, natural landscape) [Try again] button click event will not fail.
The coordinates are (0,0) at the upper left corner of the game scene when drawing, and (0,0) at the lower left corner of the game scene after 90° rotation. Because the lower left corner of the game scene becomes the upper left corner of the visual scene after 90° rotation. The reason why a horizontal click on the red area under portrait works is because Hilo’s click event is bound to the coordinate area where the element was drawn. After rotation, the button click event interval becomes the red area according to the drawn X and Y.
So how to solve this problem, as shown in the figure above, the rotated X and y are shown in blue. You can work out
// Play the button again
const start = this.gameOverScene.getChildById('start');
New x = width of the game canvas - drawn Y - height of the button
const startNewX = this.width - start.y - start.height ;
// Play the button again new y = drawn x
const startNewY = start.x;
// Listen for stage click events
this.stage.on(Hilo.event.POINTER_START, (e) = > {
// Use the height and width of the new x and y and the button itself to determine whether the button is clicked in the button area
if ((e.stageX > startNewX && e.stageX < startNewX + start.height) &&
(e.stageY > startNewY && e.stageY < startNewY + start.width)) {
// Play a logic processing})};Copy the code
The button click issue is resolved, but it’s not that simple.
Add events to the other share button, what? Neither landscape nor portrait click events take effect. At least the “Play Again” button event still works, it just doesn’t work.
For reasons, observe the diagram above. The share button is initialized to the right of the game canvas, outside the phone screen. After testing, it was found that clicking events outside the screen of the phone while drawing did not work. The solution is to “Play again”, which computs coordinate judgments in both landscape and portrait.
3. Compatible music playback
Hilo’s HTMLAudio sound playback module, the official document states [Usage restriction: iOS platform requires user event trigger to play, many Android browsers can only play one audio at a time.] But at present, the browser test is OK, and most mobile phones cannot play normally. The solution is to use DOM audio, but the same iOS platform requires user event trigger to play. So the ultimate solution is to grab all the music before entering the game or at a suitable point, play it first and pause it. The user doesn’t perceive it. It works perfectly. As follows:
// html
<audio id="audio" src="xxx.mp3" preload="auto"></audio>
// dom is retrieved
const dom = document.getElementById('audio');
dom.play();
dom.pause();
Copy the code
4. Some models of game scenes are not fully displayed
There may be certain elements of the game that are often reused and therefore cut out separately. The left side of the picture below
As shown on the right, the initial implementation is as follows. The Y axis of the common element was truncated during initialization. This effect seemed OK, but during the testing phase it was found that some iphones could not display these two elements.
new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [0.100.50.300].y: 0});new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [0.150.50.300].y: 0});Copy the code
Look at Hilo source drawing picture is to use CanvasRenderingContext2D. The drawImage method.
CanvasRenderingContext2D. DrawImage () is a native browser provides draws a picture on the canvas.
It has the following three parameter forms (detailed usage instructions and demonstration visible MDN) :
-
ctx.drawImage(image, dx, dy); ctx.drawImage(image, dx, dy, dWidth, dHeight); ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); Copy the code
parameter | meaning |
---|---|
sx, sy | The offset of the selection region of the source image |
sWidth, sHeight | Width and height of the selection area of the source image |
dx, dy | The offset of the selection area of the target canvas |
dWidth, dHeight | Width and height of the selection area of the target canvas |
Note:
- Under Chrome and Firefox, the final selection area is not drawn beyond the source image.
- In IE and Edge, the portion of the final selection area beyond the source image is filled with the image’s boundary pixels.
- Safari 7.1 additional requirements
sx + sWidth
和sy + sHeight
Does not exceed the width and height of the source imagedrawImage()
Function does not draw any graph. (Not tested on later versions of Safari) - In the old version of Firefox that supports Canvas, there are similar restrictions on Sx, SY, sWidth, sHeight as Internet Explorer and other browsers. In the new version, these restrictions have been removed.
Our element doesn’t show up on some models because it triggered the 3rd pit. Fix the code as follows by drawing the image in its entirety and then using the element’s coordinates to reach the target style.
new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [0.0.50.300].y: -100});new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [0.0.50.300].y: -150});Copy the code
Refer to the article
Five, collision detection, impact coordinates are not accurate
One of the first fun things about Hilo is that collision detection doesn’t need to be written by Hilo itself. HitTestObject checks whether the object specified by the object parameter intersects it. So the impact region can write the impact coordinates.
// Assign collision coordinates to one of the polygons shown below
new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [0.0.50.300].y: -100.boundsArea: [
// Test coordinates, imprecise coordinates, the coordinates of the red dot in the graph, from left to right
{x: 0.y: 0},
{x: 0.y: 100},
{x: 100.y: 100},
{x: 100.y: 200},
{x: 200.y: 200},
{x: 200.y: 100},
{x: 300.y: 100},
{x: 300.y: 0}]});Copy the code
Ideally, the collision detection area should be composed of the following yellow areas.
What is actually happening is the yellow area below, the wall of air. User feedback why not hit the dead. (Read the Hilo collision detection this part of the implementation of the source code, do not understand polygon processing.)
Solution, similar to Sprite diagram use, um… It’s mostly lazy to slice
new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [0.0.100.100].y: 0.boundsArea: [
// Test coordinates, imprecise coordinates, the coordinates of the red dot in the graph, from left to right
{x: 0.y: 0},
{x: 0.y: 100},
{x: 100.y: 100},
{x: 100.y: 0}]});new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [100.0.100.200].y: 0.boundsArea: [
// Test coordinates, imprecise coordinates, the coordinates of the red dot in the graph, from left to right
{x: 0.y: 0},
{x: 0.y: 200},
{x: 100.y: 200},
{x: 100.y: 0}]});new Hilo.Bitmap({
// Draw the picture
image: 'imgurl'.// Test coordinates, imprecise coordinates
rect: [200.0.100.100].y: 0.boundsArea: [
// Test coordinates, imprecise coordinates, the coordinates of the red dot in the graph, from left to right
{x: 0.y: 0},
{x: 0.y: 100},
{x: 100.y: 100},
{x: 100.y: 0}]});Copy the code
In fact, a map is cut into three maps, the cut out area impact coordinates are normal. Too irregular graphics can only be written as rough as possible.
So easy to solve?? Of course NO!!!!!! Review the fourth point, some models of game scene display incomplete. Of the 3 images cropped above, the last one triggered another Safari bug. O (╥﹏╥) O, so still obediently cut figure, or Sprite figure to leave a little safety area!
And later I learned that Sprite is more performanceconsuming for CANVAS, it is not as good as multi-point image