亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

JowayYoung / 710人閱讀

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

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

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

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)比較多,所以代碼看起來(lái)有點(diǎn)大,如果你看到如何描繪一個(gè)不完全的圓用20行代碼來(lái)完成,而且包括樣式,還是會(huì)驚訝的:

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;

場(chǎng)景設(shè)置完畢,接下來(lái)要將在3d中“我”處于的位置在2d中也顯示出來(lái)。首先我得先設(shè)置“我”是“第一人稱漫游模式”,直接將g3d.setFirstPersonMode(true)即可。第一人稱漫游模式本質(zhì)是控制eye和center,如果沒(méi)有設(shè)置第一人稱漫游模式,那么鼠標(biāo)或者觸控板拖拽會(huì)繞著center旋轉(zhuǎn)。詳情參考HT for Web 3D手冊(cè)。
因?yàn)镠T 3D中封裝了兩個(gè)方法getEye和getCenter,這兩個(gè)方法分別是獲取camera的位置和目標(biāo)中心點(diǎn)的位置,前者按照想象來(lái)說(shuō)就比方你頭上有個(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)也是不會(huì)變的,所以我們又監(jiān)聽(tīng)了3d中屬性的變化:

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

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

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í)候還能保持碰撞檢測(cè)呢?
HT中有一個(gè)對(duì)于屬性變化的監(jiān)聽(tīng)事件addDataPropertyChangeListener(),可簡(jiǎn)寫(xiě)為md(),在我們拖拽圖元的時(shí)候,繪制這個(gè)圖元的基礎(chǔ)points就會(huì)被改變,所以我們只要監(jiān)聽(tīng)points有沒(méi)有被改變就行了,如何使用這個(gè)事件可以參考HT for Web 數(shù)據(jù)模型手冊(cè)

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/51394.html

相關(guān)文章

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

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

    libin19890520 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

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