2012-12-21 23 views
12

我正在創建一個新的「whack-a-mole」風格的遊戲,孩子們必須根據問題點擊正確的數字。到目前爲止,它確實發展得很好,我有一個計時器,計算正確和錯誤的答案,當遊戲開始時,我有一些名爲「字符」的div在設定的時間隨機出現在容器中。隨機映射div

我遇到的問題是,因爲它是完全隨機的,有時候「字符」會出現重疊。有沒有辦法將它們組織起來,以便它們出現在容器中的設置位置,並在出現時不重疊。

在這裏我有一個的div映射到容器中的代碼..

function randomFromTo(from, to) { 
     return Math.floor(Math.random() * (to - from + 1) + from); 
} 

function scramble() { 
    var children = $('#container').children(); 
    var randomId = randomFromTo(1, children.length); 
    moveRandom('char' + randomId); 
} 

function moveRandom(id) { 
    var cPos = $('#container').offset(); 
    var cHeight = $('#container').height(); 
    var cWidth = $('#container').width(); 
    var pad = parseInt($('#container').css('padding-top').replace('px', '')); 
    var bHeight = $('#' + id).height(); 
    var bWidth = $('#' + id).width(); 
    maxY = cPos.top + cHeight - bHeight - pad; 
    maxX = cPos.left + cWidth - bWidth - pad; 
    minY = cPos.top + pad; 
    minX = cPos.left + pad; 
    newY = randomFromTo(minY, maxY); 
    newX = randomFromTo(minX, maxX); 
    $('#' + id).css({ 
     top: newY, 
     left: newX 
    }).fadeIn(100, function() { 
     setTimeout(function() { 
      $('#' + id).fadeOut(100); 
      window.cont++; 
     }, 1000); 
    }); 

我有一個小提琴如果有幫助.. http://jsfiddle.net/pUwKb/8/

+0

您可以創建對象,您可以存儲位置的數組,即'[{頂:300, left:200},{top:100,left:400}]'並從數組中隨機獲取座標。當位置正在使用時,您還可以添加一個標誌,以便它們不會重疊。我認爲這是最快的方法之一 – Eru

+0

您所要做的只是保留當前正在覆蓋哪些區域的生活清單,並檢查重疊。如果你創建了一個棋盤式的網格,這樣就不會出現局部重疊的情況,這將特別容易。 – theJollySin

+0

這是一個非常酷的遊戲。不過,我想我可能遇到了一個錯誤 - 我得到了2 + 6的問題,並點擊了8個錯誤的答案。另外,一個建議:我會做出一個規則,正確的答案將始終出現在X循環內。如果程序經過10次或20次迭代而沒有顯示出來,坐下並等待正確答案彈出可能有點令人沮喪。 – AmericanUmlaut

回答

2

你必須要實現的基本思想是,當選擇一個隨機座標,理論上你應該知道什麼是不允許的邊界,你的程序應該知道不要選擇那些地方(無論你是找到一個算法還是簡單地忽略這些範圍,或者你的程序不斷檢查以確保選擇的數字不在邊界內是由你決定的,後者更容易暗示但只是因爲你完全依賴偶然纔是一種糟糕的方式)。

比方說,例如座標50,70被選中。如果圖片大小爲50x50,則所允許的範圍不僅會排除圖片的尺寸,而且還會排除圖片各個方向上的50px,因此不會發生重疊。

希望這會有所幫助。如果我有時間,我可能會嘗試編寫一個示例,但我希望這能夠回答問題的概念方面,如果這是您遇到的問題。

哦,順便說一句,這個計劃忘了說真的很棒。它看起來真棒:)

+0

我明白你的意思了。很明顯,如果你有時間去模擬一個非常棒的遊戲,那麼同時我會去玩。感謝這意味着很多@aug –

2

你可以通過至少兩種方式解決這個問題(這兩個彈出我的腦海)。

  1. 如何基於的問題的數量以產生2維網格分割,問題面板的尺寸和陣列保持每個問題的位置座標,然後將每個時間幀上隨機上定位這些面板允許的座標之一。

注意:請閱讀這篇文章的詳細信息:http://eloquentjavascript.net/chapter8.html

  1. 第二種方法遵循相同的原則,但這個時候你把它放在畫布上之前檢查面板重疊現有的面板。
var _grids; 
var GRID_SIZE = 20 //a constant holding the panel size; 
function createGrids() { 
    _grids = new Array(); 
    for (var i = 0; i< stage.stageWidth/GRID_SIZE; i++) { 
     _grids[i] = new Array(); 
     for (var j = 0; j< stage.stageHeight/GRID_SIZE; j++) { 
      _grids[i][j] = new Array(); 
     } 
    } 
} 

然後在一個單獨的函數來創建碰撞檢查。我在Actionscript中爲碰撞檢查創建了一個gist,但您也可以在Javascript中使用相同的原則。我爲了鼓舞人心的目的創造了這個要旨。

+0

添加鏈接到要點? – tucuxi

+0

我從來沒有見過var i:int語法;這是有效的JS? – tucuxi

+0

不,它是無效的:),我剛剛從我的AS3示例中複製 –

5

正如@aug所說,你應該知道你不能在繪畫時間放置東西,只能將它們放在有效位置。要做到這一點,最簡單的方法就是將當前位置保持在方便的位置,以檢查他們是否符合提議的位置。

我建議是這樣

// locations of current divs; elements like {x: 10, y: 40} 
var boxes = []; 

// p point; b box top-left corner; w and h width and height 
function inside(p, w, h, b) { 
    return (p.x >= b.x) && (p.y >= b.y) && (p.x < b.x + w) && (p.y < b.y + h); 
} 

// a and b box top-left corners; w and h width and height; m is margin 
function overlaps(a, b, w, h, m) { 
    var corners = [a, {x:a.x+w, y:a.y}, {x:a.x, y:a.y+h}, {x:a.x+w, y:a.y+h}]; 
    var bWithMargins = {x:b.x-m, y:b.y-m}; 
    for (var i=0; i<corners.length; i++) { 
     if (inside(corners[i], bWithMargins, w+2*m, h+2*m) return true; 
    } 
    return false; 
} 

// when placing a new piece 
var box; 
while (box === undefined) { 
    box = createRandomPosition(); // returns something like {x: 15, y: 92} 
    for (var i=0; i<boxes.length; i++) { 
     if (overlaps(box, boxes[i], boxwidth, boxheight, margin)) { 
     box = undefined; 
     break; 
     } 
    } 
} 
boxes.push(box); 

警告:未經測試的代碼,謹防錯別字。

+0

我是否替換目前我所擁有的? @tucuxi –

0

只要使用它是基於你的板的寬度,然後用高模隨機數...

你得到一個細胞是在那裏你可以把摩爾。

對於位置的X和Y永遠不會改變,因爲你有9個點讓我們說,痣可能彈出。

x x x 
x x x 
x x x 

每個單元將基於%而不是像素尺寸並且將允許重施膠屏幕

1%3 = 1(X) 3%3 = 0(Y)

那麼不可能有重疊。

一旦痣被定位,它可以顯示或隱藏或移動等根據一些擴展的邏輯,如果需要的話。

如果你想保持自己的方式,你只需要一個快速重新定位算法...只要設置X的寬度> = x的字符你想檢查通過設置X = y +重疊項目的高度。您還可以通過緩存最後一個x並確保隨機數不是項目的最後一個+寬度來強制執行繪圖例程中的邏輯。

newY = randomFromTo(minY, maxY); newX = randomFromTo(minX, maxX); if(newX > lastX + characterWidth){ /*needful*/}

仍有可能但是請重疊......

如果你想完全消除它,你將需要跟蹤狀態,如其中x是,然後遍歷該列表找到一個新的位置或位置他們第一,然後所有他們隨機移動沒有相交,這將只能從該點進行控制。

總的來說,我認爲它會更容易只保留X從0開始,然後再遞增,直到你在一個X +字符寬度>大於板的寬度。然後按字符高度增加Y,設置X = 0或字符寬度或其他偏移量。

newX = 0; newX += characterWidth; if(newX + chracterWidth > boardWidth) newX=0; newY+= characterHeight;

導致沒有重疊並沒有什麼重複或跟蹤額外給你現在做什麼,唯一不足的是所顯示的字符爲「棋盤樣式」或旁邊的格局對方(在水平和垂直位置之間可能的隨機間距,例如,你可以隨意調整填充,如果你想太)

這在增加了複雜性擺在首位的整體隨意的事情。

和我更新你的小提琴證明我消除了隨機和停止重疊:)

http://jsfiddle.net/pUwKb/51/