簡體   English   中英

Javascript游戲中基於圖塊的碰撞檢測

[英]tile-based collision detection in Javascript game

http://www.jsfiddle.net/raenset/a0Lauk14/17

var scene;
var tileset;

var ROWS = 20;
var COLS = 40;
var SCREEN_ROWS = 15;
var SCREEN_COLS = 20;

var offRow = 0;
var offCol = 0;

var GRASS = 0;
var DIRT = 1;
var WATER = 2;
var NUMSTATES = 3;

var character;

function Character(){
    tCharacter = new Sprite(scene, "http://www.retroinvaders.net/media/platform/character.png", 20, 20);
    tCharacter.setSpeed(0);
    tCharacter.setPosition(10, 50);
          return tCharacter;

} // end character def


function Tile(){
    tTile = new Sprite(scene, "http://www.retroinvaders.net/media/tile/grass.png", 32, 32);
    tTile.setSpeed(0);
    tTile.state = GRASS;
    tTile.images = new Array("http://www.retroinvaders.net/media/tile/grass.png", "http://www.retroinvaders.net/media/tile/dirt.png", "http://www.retroinvaders.net/media/tile/water.png");
    tTile.row = 0;
    tTile.col = 0;

    tTile.setState = function(state){
        this.state = state;
        this.setImage(this.images[this.state]);
    } // end setState

    tTile.getRow = function(){
        return this.row;
    } // end getRow

    tTile.getCol = function(){
        return this.col;
    } // end getCol;

    tTile.getState = function(){
        return this.state;
    } // end getState

    return tTile;
} // end Tile constructor

function setupTiles(){
    tileset = new Array(SCREEN_ROWS);
    for (row = 0; row < SCREEN_ROWS; row++){
        tRow = new Array(SCREEN_COLS);
        for (col = 0; col < SCREEN_COLS; col++){
            tRow[col] = new Tile();
            xPos = 16 + (32 * col);
            yPos = 16 + (32 * row);
            tRow[col].setPosition(xPos, yPos);
            tRow[col].row = row;
            tRow[col].col = col;
        } // end col for loop
        tileset[row] = tRow;
    } // end row for loop;
} // end setupTiles

function showMap(){
    //displays a piece of the map sized
    //SCREEN_ROWS x SCREEN_COLS
    //offset by offRow, offCol

    for (row = 0; row < SCREEN_ROWS; row++){
        for (col = 0; col < SCREEN_COLS; col++){
            currentVal = map[row + offRow][col + offCol];
            tileset[row][col].setState(currentVal);
            tileset[row][col].update();
        } // end col for
    } // end row for
} // end showMap

function loadMap(){
    // loads a map from an array
    map = new Array(
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(2,2,2,2,2,2,0,0,0,0,1,0,0,0,0,0,2,2,2,2,2,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
      new Array(0,2,2,2,2,2,2,0,0,0,1,0,0,0,2,2,2,2,2,0,0,0,0,0,2,2,0,0,1,1,1,1,1,0,0,0,0,0,0,0),
      new Array(0,0,0,0,0,0,2,2,2,2,1,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,1,1,1,0,0,0,0),
      new Array(0,0,0,0,0,0,0,2,2,2,1,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,1,0,0,0),
      new Array(0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,1,0,0,0),
      new Array(0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,1,1,1),
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2),
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2),
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2),
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2),
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2),
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,2,2,2,2,2,2,2,2,2,2),
      new Array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2)
    );
}



function checkKeys(){
    if (keysDown[K_LEFT]){
        character.changeXby(-5);
        if (offCol > 0){
            offCol--;
        }
    }

    if (keysDown[K_RIGHT]){
        character.changeXby(5);
        if (offCol < (COLS - SCREEN_COLS)){
            offCol++
        }
    }

    if (keysDown[K_UP]){
            character.changeYby(-5);
        character.setImage("http://www.retroinvaders.net/media/platform/characterUp.png");




        if (offRow > 0){
            offRow--;
        }
      }


    if (keysDown[K_DOWN]){
       character.changeYby(5);
        character.setImage("http://www.retroinvaders.net/media/platform/characterUp.png");


        if (offRow < (ROWS - SCREEN_ROWS)){
            offRow++;
            console.log(offRow);
        }
    }

  }


function init(){
    scene = new Scene();
    scene.setSize(640, 480);

    character = new Character();

    loadMap();
    setupTiles();
    showMap(0,0);
    scene.start();
} // end init

function update(){
    scene.clear();
    checkKeys();
    //checkCollisions();
    showMap();
    character.update();
} // endupdate

window.onload =初始化;

請從上面從jsfiddle看代碼。 我想在角色和基於圖塊的地圖的GRASS狀態之間實現某種碰撞檢測,例如,使角色無法進入“草叢”圖塊,而留在“街道”上。 直到今天我嘗試的一切都失敗了,有人提出了類似的建議:if(tileset [characterCurrenTileX] [characterCurrenTileY.state === GRASS){character.hide(); }(隱藏是我正在使用的庫的一種方法...僅出於碰撞測試目的而嘗試...)–

試試這個功能:

function typeOfWalkedTile(){
    return tileset[Math.floor(character.y/32)][Math.floor(character.x/32)].getState();
}

然后在每種情況下,在checkKeys()添加

if(typeOfWalkedTile()==2){
//do stuff  
}

showMap()其添加到移動角色后調用的showMap()的末尾。

更新的小提琴

附言:將您的tileet yx設為基礎有點違反直覺

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM