成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

基于HTML5及WebGL開發(fā)的2D3D第一人稱漫游進(jìn)行碰撞檢測

JowayYoung / 658人閱讀

摘要:為了實(shí)現(xiàn)一個(gè)基于的場景小游戲,我采用了來實(shí)現(xiàn),短短行代碼,我就能實(shí)現(xiàn)用第一人稱來操作前進(jìn)后退上下左右,并且實(shí)現(xiàn)了碰撞檢測。首先我得先設(shè)置我是第一人稱漫游模式,直接將即可。

為了實(shí)現(xiàn)一個(gè)基于HTML5的場景小游戲,我采用了HT for Web來實(shí)現(xiàn),短短200行代碼,我就能實(shí)現(xiàn)用“第一人稱”來操作前進(jìn)后退上下左右,并且實(shí)現(xiàn)了碰撞檢測。
先來看下實(shí)現(xiàn)的效果: http://hightopo.com/guide/gui...
或者h(yuǎn)ttp://v.youku.com/v_show/id_...視頻中出現(xiàn)的幀的問題是我屏幕錄制器的問題,真正操作的時(shí)候不會有,建議用上面的鏈接自己操作玩玩,鼠標(biāo)或者觸屏都可以,不過我覺得最方便的還是操作鍵盤wsad控制上下左右。
我的想法是先把場景布局好,代碼如下:

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();

這幾個(gè)都是自定義的函數(shù),createHT為描繪HT形狀的圖,場景中有四個(gè),所以調(diào)用了四次;createCurve是描繪場景中間的黃色的曲線;createCircle是描繪最外層的圓,因?yàn)椴皇侨膱A,所以也是描點(diǎn)畫的。
HT中封裝了一個(gè)組件,ht.Shape(以下簡稱Shape),能夠根據(jù)描點(diǎn)來自由描繪圖形,可以通過shape.setPoints(pointsArray)將所有的點(diǎn)添加進(jìn)數(shù)組中,并且設(shè)置到shape中,然后通過setSegments()設(shè)置線段數(shù)組信息,也就是用什么樣的方式來連接兩點(diǎn),在Shape手冊中有著重描寫,感興趣的可以參考HT for Web Shape 手冊。抽其中的一個(gè)描繪點(diǎn)的函數(shù)來看看:

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;
}

因?yàn)椤癏T”這個(gè)字眼要描繪的點(diǎn)比較多,所以代碼看起來有點(diǎn)大,如果你看到如何描繪一個(gè)不完全的圓用20行代碼來完成,而且包括樣式,還是會驚訝的:

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;

場景設(shè)置完畢,接下來要將在3d中“我”處于的位置在2d中也顯示出來。首先我得先設(shè)置“我”是“第一人稱漫游模式”,直接將g3d.setFirstPersonMode(true)即可。第一人稱漫游模式本質(zhì)是控制eye和center,如果沒有設(shè)置第一人稱漫游模式,那么鼠標(biāo)或者觸控板拖拽會繞著center旋轉(zhuǎn)。詳情參考HT for Web 3D手冊。
因?yàn)镠T 3D中封裝了兩個(gè)方法getEye和getCenter,這兩個(gè)方法分別是獲取camera的位置和目標(biāo)中心點(diǎn)的位置,前者按照想象來說就比方你頭上有個(gè)攝像機(jī),你走到哪里它的中心點(diǎn)就拍攝到哪里,可以很方便的記錄你的位置;后者就相當(dāng)于你看出去的位置,但是這里跟我們?nèi)瞬惶粯樱驗(yàn)槿耸强梢詮V度看到大范圍的,但是這個(gè)center相當(dāng)于你眼球和都不能轉(zhuǎn)動(dòng),是正前方的某一點(diǎn)的位置就是你的視線聚焦位置。
了解了getEye和getCenter后我們就可以獲取當(dāng)前位置和視線位置了:

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); //繪制圓,而且還能實(shí)時(shí)獲取3d中“我”的位置
    g.fill();
    g.stroke();  
                    
    g.strokeStyle = "black";
    g.lineWidth = 2;
    g.beginPath(); 
    g.moveTo(eye[0], eye[2]);
    g.lineTo(center[0], center[2]); //繪制線,能實(shí)時(shí)更改“我”和“我的視線位置” 之間的線段   
    g.stroke(); 
});

但是在代碼中我們發(fā)現(xiàn),這個(gè)方法只被繪制了一次,如果不一直重繪,那么2d界面的“我”的位置和移動(dòng)也是不會變的,所以我們又監(jiān)聽了3d中屬性的變化:

g3d.mp(function(e){//根據(jù)3d上的“我”的位置和視線來實(shí)時(shí)更新2d界面
    if(e.property === "eye" || e.property === "center"){ //如果e屬性變化為get/setEye,get/setCenter,那么重繪2d界面
        g2d.redraw();
    } 
});

在2D中,我可以編輯圖元,移動(dòng)它的點(diǎn),變化某個(gè)圖元的大小,等等功能,只要變化了圖元,那么我的碰撞測試就得更新:

function updateBoundaries(){
    boundaries = [];
    dataModel.each(function(data){//HT curve circle              
        boundaries = boundaries.concat(ht.Default.toBoundaries(data.getPoints(), data.getSegments()));
        // ht.Default.toBoundaries將不連續(xù)曲線轉(zhuǎn)化成Graph3dView#setBoundaries(bs)需要的參數(shù)格式
    }); 
    g3d.setBoundaries(boundaries);//setBoundary()可指定碰撞邊界
}

那么我們好奇的點(diǎn)在于,如何在拖拽圖元改變大小的時(shí)候還能保持碰撞檢測呢?
HT中有一個(gè)對于屬性變化的監(jiān)聽事件addDataPropertyChangeListener(),可簡寫為md(),在我們拖拽圖元的時(shí)候,繪制這個(gè)圖元的基礎(chǔ)points就會被改變,所以我們只要監(jiān)聽points有沒有被改變就行了,如何使用這個(gè)事件可以參考HT for Web 數(shù)據(jù)模型手冊

dataModel.md(function(e){//data屬性變化事件    
    if(e.property === "points"){//如果data屬性變化為getPoints/setPoints,那么更新邊界
        updateBoundaries();
    }
});

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/51394.html

相關(guān)文章

  • 基于WEBGL架構(gòu)3D可視化平臺—家居城3D展示

    摘要:本文將模擬一個(gè)歐派,讓大家足不出戶在家里就能更加直觀立體的挑選家具。創(chuàng)建廣告牌寬度高度深度寬度上的節(jié)數(shù)高度上的節(jié)數(shù)深度上的節(jié)數(shù)中心點(diǎn)家具展銷歐派這里給我們給整個(gè)場景用抽象物體圍起來了,以免第一人稱控件開啟時(shí)會造成無碰撞體系墜落出場景。 本文將模擬一個(gè)歐派,讓大家足不出戶在家里就能更加直觀立體的挑選家具。 第一步,利用CampusBuilder搭建模擬場景。CampusBuilder的模...

    libin19890520 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<