3D 網(wǎng)頁版貪吃蛇游戲!下面來具體講一下如何實(shí)現(xiàn)。
該游戲使用 Hightopo 的 SDK 制作,總共 100 多行代碼,沒有 WebG L基礎(chǔ)的同學(xué)們也可很快掌握。
場景初始化
首先,我們對頁面進(jìn)行初始化,包括初始化3D場景,設(shè)置地面網(wǎng)格,以及開啟事件監(jiān)聽等。主要代碼及注釋如下:
w = 40; // 網(wǎng)格間距 m = 20; // 網(wǎng)格行列數(shù) d = w * m / 2; food = null; dm = new ht.DataModel(); g3d = new ht.graph3d.Graph3dView(dm); // 初始化一個(gè)3d場景 // 配置網(wǎng)格 g3d.setGridVisible(true); g3d.setGridColor('#29B098'); g3d.setGridSize(m); g3d.setGridGap(w); // 將3D場景添加到body下面 view = g3d.getView(); view.className = 'main'; document.body.appendChild(view); // 開啟事件監(jiān)聽 window.addEventListener('resize', function (e) { g3d.invalidate(); }, false); g3d.sm().setSelectionMode('none'); view.addEventListener(ht.Default.isTouchable ? 'touchstart' : 'mousedown', function(e){ if(isRunning){ var p = g3d.getHitPosition(e); // 獲取當(dāng)前鼠標(biāo)點(diǎn)擊點(diǎn)在3D場景中的位置 // 根據(jù)點(diǎn)擊點(diǎn)x,z軸坐標(biāo),計(jì)算貪吃蛇前進(jìn)方向 if(Math.abs(p[0]) < d && Math.abs(p[2]) < d){ if(direction === 'up' || direction === 'down'){ direction = p[0] > snake[0].p3()[0] ? 'right' : 'left'; } else if(direction === 'left' || direction === 'right'){ direction = p[2] > snake[0].p3()[2] ? 'down' : 'up'; } } }else if(ht.Default.isDoubleClick(e)){ start(); // 雙擊啟動(dòng)游戲 } }, false); start(); setInterval(function(){ if(isRunning){ isRunning = next(); } }, 200); // 每間隔200ms貪吃蛇往前走一步
創(chuàng)建食物
貪吃蛇每次吃完一個(gè)食物,其身體就會(huì)增長一段。此時(shí)需要?jiǎng)?chuàng)建新的食物并隨機(jī)放到一個(gè)新的位置。創(chuàng)建食物時(shí),其位置不能與上一個(gè)位置重合,也不能與當(dāng)前貪吃蛇身體重復(fù)。
/**
* 創(chuàng)建食物,并擺放到隨機(jī)位置。
* 食物不能放到貪吃蛇身上,也不能放到上一個(gè)食物的位置
*
*/
function createFood(){
var x = getRandom(), y = getRandom();
// 確保新創(chuàng)建的食物不與貪吃蛇重疊,也不與上一個(gè)食物的位置重疊
while(touchFood(x, y) || touchSnake(x, y)){ x = getRandom(); y = getRandom(); }
if(food) dm.remove(food);
food = createNode(x, y);
food.s({'shape3d': 'sphere', 'shape3d.color': 'red'});
}
/**
* x, y是否與snake身體重疊
*
* @param {*} x
* @param {*} y
* @return {*}
*/
function touchSnake(x, y){
for(var i=0; i
創(chuàng)建貪吃蛇及四周圍墻
在第一步初始化時(shí),我們設(shè)置了網(wǎng)格大小及間距。這樣也就確定了整個(gè)網(wǎng)格的長寬以及貪吃蛇每個(gè)塊的大小。在這一步,我們?yōu)榫W(wǎng)格增加邊界,同時(shí)生成貪吃蛇。
/**
* 清空場景。創(chuàng)建貪吃蛇及四周圍墻。
*
*/
function start(){
dm.clear(); snake = []; score = 0; direction = 'up'; isRunning = true;
// 四周圍墻
shape = new ht.Shape();
shape.setPoints(new ht.List([
{x: -d, y: d},
{x: d, y: d},
{x: d, y: -d},
{x: -d, y: -d},
{x: -d, y: d}
]));
shape.setThickness(4);
shape.setTall(w);
shape.setElevation(w/2);
shape.s({'all.color': 'rgba(20, 120, 120, 0.5)', 'all.transparent': true, 'all.reverse.cull': true});
dm.add(shape);
// 創(chuàng)建貪吃蛇的身體
for(var i=0; i
處理貪吃蛇行走邏輯
有了貪吃蛇和食物后,下一步就是處理貪吃蛇行走邏輯。包括:
* 1. 檢測到達(dá)邊界或接觸自己身體,則游戲結(jié)束
* 2. 如果吃到食物,則身體增加一段
* 3. 否則,繼續(xù)往前走
/**
* 根據(jù)direction計(jì)算下一個(gè)位置。同時(shí):
* 1. 檢測到達(dá)邊界或接觸自己身體,則游戲結(jié)束
* 2. 如果吃到食物,則身體增加一段
* 3. 繼續(xù)往前走
*
* @return {*}
*/
function next(){
var node = snake[0], x = node.a('x'), y = node.a('y');
if(direction === 'up') y--;
if(direction === 'down') y++;
if(direction === 'left') x--;
if(direction === 'right') x++;
if(x < 0 || x >= m || y < 0 || y >= m || touchSnake(x, y)){ return false; }
if(touchFood(x, y)){
score++;
snake.splice(0, 0, createNode(x, y));
createFood();
}else{
snake.splice(0, 0, createNode(x, y));
dm.remove(snake.pop());
}
return true;
}
到這里,整個(gè)貪吃蛇游戲就完成了。雙擊場景即可啟動(dòng)游戲。點(diǎn)擊場景可改變貪吃蛇運(yùn)動(dòng)方向。
審核編輯 黃宇
-
3D
+關(guān)注
關(guān)注
9文章
3011瀏覽量
115016 -
JAVA
+關(guān)注
關(guān)注
20文章
3001瀏覽量
116422 -
源碼
+關(guān)注
關(guān)注
8文章
685瀏覽量
31317 -
javascript
+關(guān)注
關(guān)注
0文章
526瀏覽量
56321 -
javascript編程
+關(guān)注
關(guān)注
0文章
2瀏覽量
1978
發(fā)布評論請先 登錄
常見3D打印材料介紹及應(yīng)用場景分析
探索TLE493D-P3XX-MS2GO 3D 2Go套件:開啟3D磁傳感器評估之旅
iDS iToF Nion 3D相機(jī),開啟高性價(jià)比3D視覺新紀(jì)元!
玩轉(zhuǎn) KiCad 3D模型的使用
3D打印能用哪些材質(zhì)?
開源項(xiàng)目!如何制作一個(gè)手機(jī)用的電動(dòng)3D掃描轉(zhuǎn)盤
英倫科技光場裸眼3D顯示產(chǎn)品在博物館裸眼3D顯示方面的應(yīng)用
讓人欲罷不能樹莓派貪吃蛇掌機(jī)!
一種以圖像為中心的3D感知模型BIP3D
如何使用javascript制作一個(gè)網(wǎng)頁端3D貪吃蛇游戲(附源碼)
評論