In order to achieve a small game based on HTML5 scene, I used HT for Web to achieve, just 200 lines of code, I can use “first person” to operate forward and backward, up, down, left and right, and achieve collision detection.

First look at the effect of the implementation: http://hightopo.com/guide/guide/core/3d/ht-3d-guide.html#ref_collision

Or v.youku.com/v_show/id_X… The problem of the frames in the video is my screen recorder, which will not happen when I actually operate it. I suggest using the above link to operate it by myself, either with mouse or touch screen, but I think the most convenient is to operate the keyboard WSAD to control up, down, left and right.

                

My idea is to lay out the scene first with the following code:

[javascript]
view plain
copy
print
?

  1. createHT([100, -20, 100], ‘#E74C3C’);                    
  2. createHT([-100, -20, 100], ‘#1ABC9C’);                      
  3. createHT([100, -20, -100], ‘#3498DB’);                     
  4. createHT([-100, -20, -100], ‘#9B59B6’);     
  5. createCurve([0, -20, 0]);  
  6. createCircle();  

createHT([100, -20, 100], '#E74C3C');                  
createHT([-100, -20, 100], '#1ABC9C');                    
createHT([100, -20, -100], '#3498DB');                   
createHT([-100, -20, -100], '#9B59B6');   
createCurve([0, -20, 0]);
createCircle();Copy the code

CreateHT (createHT); createHT (createHT); createHT (createHT); CreateCurve is the yellow curve that draws the middle of the scene; CreateCircle draws the outermost circle, which is also dotted because it is not an all-encompassing circle.

Ht. Shape is a component that can be used to draw shapes based on their stroke points. SetPoints (pointsArray) can be used to add all points to an array and set to Shape. Then setSegments() is used to set the information of the line segment array, that is, how to connect the two points, which is described in Shape manual. If you are interested, please refer to HT for Web Shape manual. Take one of the functions that delineates a point:

[javascript]
view plain
copy
print
?

  1. function createHT(p3, color){  
  2.     shape = new ht.Shape();                  
  3.     shape.s({  
  4.         ‘shape.background’null.
  5.         ‘shape.border.width’: 10,  
  6.         ‘shape.border.color’: color,  
  7.         ‘all.color’: color  
  8.     });  
  9.     shape.setTall(40);  
  10.     shape.setThickness(5);  
  11.     shape.setPoints([                      
  12.         // draw H  
  13.         {x: 20, y: 0},  
  14.         {x: 20, y: 100},  
  15.         {x: 20, y: 50},  
  16.         {x: 80, y: 50},  
  17.         {x: 80, y: 0},  
  18.         {x: 80, y: 100},  
  19.   
  20.         // draw T  
  21.         {x: 120, y: 0},  
  22.         {x: 180, y: 0},  
  23.         {x: 150, y: 0},  
  24.         {x: 150, y: 100}                      
  25.     ]);                                  
  26.     shape.setSegments([  
  27.         // draw H  
  28.         1, // moveTo  
  29.         2, // lineTo  
  30.         1, // moveTo  
  31.         2, // lineTo  
  32.         1, // moveTo  
  33.         2, // lineTo  
  34.   
  35.         // draw T  
  36.         1, // moveTo  
  37.         2, // lineTo  
  38.         1, // moveTo  
  39.         2 // lineTo  
  40.     ]);                  
  41.     shape.p3(p3);  
  42.     dataModel.add(shape);   
  43.     return shape;  
  44. }  

function createHT(p3, color){
    shape = new ht.Shape();                
    shape.s({
        'shape.background': null,
        'shape.border.width': 10,
        'shape.border.color': color,
        'all.color': color
    });
    shape.setTall(40);
    shape.setThickness(5);
    shape.setPoints([                    
        // draw H
        {x: 20, y: 0},
        {x: 20, y: 100},
        {x: 20, y: 50},
        {x: 80, y: 50},
        {x: 80, y: 0},
        {x: 80, y: 100},

        // draw T
        {x: 120, y: 0},
        {x: 180, y: 0},
        {x: 150, y: 0},
        {x: 150, y: 100}                    
    ]);                                
    shape.setSegments([
        // draw H
        1, // moveTo
        2, // lineTo
        1, // moveTo
        2, // lineTo
        1, // moveTo
        2, // lineTo

        // draw T
        1, // moveTo
        2, // lineTo
        1, // moveTo
        2 // lineTo
    ]);                
    shape.p3(p3);
    dataModel.add(shape); 
    return shape;
}Copy the code

The code looks a bit big because the word “HT” has a lot of points to draw, and you’d be surprised to see how to draw an incomplete circle in 20 lines of code, including styles:

[javascript]
view plain
copy
print
?

  1. shape = new ht.Shape();                  
  2. shape.s({  
  3.     ‘shape.background’null.
  4.     ‘shape.border.width’: 10,  
  5.     ‘shape.border.color’‘#D26911’.
  6.     ‘all.color’‘#D26911’  
  7. });  
  8. shape.setTall(40);  
  9. shape.p3(0, -20, 0);  
  10. shape.setThickness(10);  
  11.                   
  12. var r = 300;  
  13. for(var i=0; i<36; i++){  
  14.     var angle = Math.PI * 2 * i / 36;  
  15.     shape.addPoint({  
  16.         x: r * Math.cos(angle),  
  17.         y: r * Math.sin(angle)  
  18.     });  
  19. }  
  20.                   
  21. dataModel.add(shape);   
  22. return shape;  

shape = new ht.Shape();                
shape.s({
    'shape.background': null,
    'shape.border.width': 10,
    'shape.border.color': '#D26911',
    'all.color': '#D26911'
});
shape.setTall(40);
shape.p3(0, -20, 0);
shape.setThickness(10);
                
var r = 300;
for(var i=0; i<36; i++){
    var angle = Math.PI * 2 * i / 36;
    shape.addPoint({
        x: r * Math.cos(angle),
        y: r * Math.sin(angle)
    });
}
                
dataModel.add(shape); 
return shape;Copy the code

After setting up the scene, the next step is to display the position of “ME” in 3D in 2D. First I need to set “I” to “first person Roaming mode” and just go to g3d.setFirstPersonMode(true). The first person roaming mode essentially controls eye and Center. If the first person roaming mode is not set, the mouse or trackpad drag will rotate around center. See the HT for Web 3D manual for details.

HT 3D is encapsulated with two methods, getEye and getCenter. These two methods are to obtain the location of camera and the location of target center respectively. The former is like a camera on your head, where you go, its center will take pictures, which can easily record your position. The latter is the position where you look out, but this is not the same as us, because people can see in a wide range, but this center is the position of a point in front of you, which is the focus of your eyes.

Now that we know about getEye and getCenter, we can get the current position and line of sight:

[javascript]
view plain
copy
print
?

  1. g2d.addTopPainter(function(g){  
  2.     var eye = g3d.getEye(),  
  3.     center = g3d.getCenter();  
  4.                           
  5.     g.fillStyle = ‘red’;  
  6.     g.strokeStyle = ‘black’;  
  7.     g.lineWidth = 1;  
  8.     g.beginPath();                      
  9.     g.arc(eye[0], eye[2], 12, 0, Math.PI * 2, true); // Draw a circle, and get the position of “me” in 3D in real time  
  10.     g.fill();  
  11.     g.stroke();    
  12.                       
  13.     g.strokeStyle = ‘black’;  
  14.     g.lineWidth = 2;  
  15.     g.beginPath();   
  16.     g.moveTo(eye[0], eye[2]);  
  17.     g.lineTo(center[0], center[2]); // Draw a line to change the line segment between “ME” and “my line position” in real time  
  18.     g.stroke();   
  19. });  

g2d.addTopPainter(function(g){ var eye = g3d.getEye(), center = g3d.getCenter(); g.fillStyle = 'red'; g.strokeStyle = 'black'; g.lineWidth = 1; g.beginPath(); g.arc(eye[0], eye[2], 12, 0, Math.PI * 2, true); // Draw a circle, and also get the position of "I" in 3D in real time. g.stroke(); g.strokeStyle = 'black'; g.lineWidth = 2; g.beginPath(); g.moveTo(eye[0], eye[2]); g.lineTo(center[0], center[2]); G.stroke (); g.stroke(); g.stroke(); });Copy the code

In the code, we find that this method is only drawn once, and the position and movement of the 2d interface “I” will not change if we do not keep redrawing, so we also listen for the change of 3d properties:

[javascript]
view plain
copy
print
?

  1. g3d.mp(function(e){// Update the 2D interface in real time based on the position and line of sight of the “ME” on 3d  
  2.     if(e.property === ‘eye’ || e.property === ‘center’) { // If e changes to get/setEye, get/setCenter, then redraw the 2D interface  
  3.         g2d.redraw();  
  4.     }   
  5. });  

G3d. Mp (function (e) {/ / according to the "I" on the 3 d location and the line of sight to real-time update 2 d interface if (e.p roperty = = = 'eye' | | e.p roperty = = = 'center') {/ / if e attribute changes to get/setEye, Get /setCenter, then redraw the 2D interface g2d.redraw(); }});Copy the code
[javascript]
view plain
copy
print
?

  1.   

Copy the code

In 2D, I can edit an pixel, move its points, change the size of an pixel, and so on. Whenever I change an pixel, my crash test will have to be updated:

[javascript]
view plain
copy
print
?

  1. function updateBoundaries(){  
  2.     boundaries = [];  
  3.     dataModel.each(function(data){//HT curve circle                
  4.         boundaries = boundaries.concat(ht.Default.toBoundaries(data.getPoints(), data.getSegments()));  
  5.         // ht.default. toBoundaries Convert the discontinuous curves into the parameter format required by Graph3dView#setBoundaries(bs)  
  6.     });   
  7.     g3d.setBoundaries(boundaries);//setBoundary() specifies the collision boundary  
  8. }  

function updateBoundaries(){ boundaries = []; dataModel.each(function(data){//HT curve circle boundaries = boundaries.concat(ht.Default.toBoundaries(data.getPoints(),  data.getSegments())); // ht.default. toBoundaries Convert the discontinuous curves to Graph3dView#setBoundaries(bs) {); g3d.setBoundaries(boundaries); //setBoundary() specifies the collision boundary}Copy the code
[javascript]
view plain
copy
print
?

  1.   

Copy the code

So what we’re curious about is, how do we maintain collision detection while dragging and dropping primitives to change size?

One of HT for properties change of surveillance addDataPropertyChangeListener (), can be abbreviated to md (), when we drag the primitives, map the yuan based points will be changed, so we just monitoring points have be changed, How to use this event can you refer to the HT for Web Data Model manual

[javascript]
view plain
copy
print
?

  1. dataModel.md(function(e){// Data attribute change event  
  2.     if(e.property === ‘points’) {// If the data property changes to getPoints/setPoints, then update the boundary  
  3.         updateBoundaries();  
  4.     }  
  5. });  

Datamodel. md(function(e){if(e.perty === 'points'){datamodel. md(function(e){if(e.perty === 'points'){ So updateBoundaries updateBoundaries(); }});Copy the code