我的第一个JavaScript小游戏--战舰世界

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hzy199772/article/details/87864175

这是一个关于战舰的游戏:游戏中有三个战舰群,呈横向或竖向连续排列,当击毁3艘战舰后,战舰群沉没。

下面给出贴图和代码:

贴图:

battleship.js:

var view = {
    dispalyMessage:function(msg){
        var messageArea = document.getElementById("messageArea");
        messageArea.innerHTML = msg;
    },
    displayHit:function(location){
        var cell = document.getElementById(location);
        cell.setAttribute("class","hit");
    },
    displayMiss:function(location){
        var cell = document.getElementById(location);
        cell.setAttribute("class","miss");
    }
} ;

var model = {
    boardSize:7,
    numShips:3,
    shipsSunk:0,
    shipLength:3,
    ships:[ { locations:["0","0","0"],hits:["","",""]},
            { locations:["0","0","0"],hits:["","",""]},
            { locations:["0","0","0"],hits:["","",""]} ],
    fire:function(guess){
        for (var i = 0; i < this.numShips; i++) {
            var ship = this.ships[i];
            var index = ship.locations.indexOf(guess);
            if(index >= 0){
                ship.hits[index] = "hit";
                view.displayHit(guess);
                view.dispalyMessage("HIT!");
                if(this.isSunk(ship)){
                    view.dispalyMessage("You Sank My Battleship!");
                    this.shipsSunk++;
                }
                return true;
            }
        }
        view.displayMiss(guess);
        view.dispalyMessage("You Missed!");
        return false;
    },
    isSunk:function(ship){
        for(var i = 0;i < this.shipLength;i++){
            if(ship.hits[i] !== "hit"){
                return false;
            }
        }
        return true;
    },
    generateShipLocation:function(){
        var loactions;
        for(var i = 0;i<this.numShips;i++){
            do {
                locations = this.generateShip();
            } while (this.collision(locations));
            this.ships[i].locations = locations;
        }
    },
    generateShip:function(){
        var direction = Math.floor(Math.random()*2);
        var row,col;
        /*水平放置*/
        if(direction ===1){
            row = Math.floor(Math.random()*this.boardSize);
            col = Math.floor(Math.random()*(this.boardSize - this.shipLength));
        }else{
            row = Math.floor(Math.random()*(this.boardSize-this.shipLength));/*竖直放置*/
            col = Math.floor(Math.random()*this.boardSize);
        }
        var newShipLocations = [];
        for(var i = 0;i<this.shipLength;i++){
            if(direction === 1){
                newShipLocations.push(row + "" + (col + i));
            }else{
                newShipLocations.push((row+i)+""+col);
            }
        }
        return newShipLocations;
    },
    collision:function(locations){
        for(var i =0;i<this.numShips;i++){
            var ship = model.ships[i];
            for(var j = 0;j<locations.length;j++){
                if(ship.locations.indexOf(locations[j]) >= 0){
                    return true;
                }
            }
        }
        return false;
    }
};

var controller = {
    guesses:0,
    processGuess:function(guess){
        var location = parseGuess(guess);
        if(location){
            this.guesses++;
            var hit = model.fire(location);
            if(hit && model.shipsSunk === model.numShips){
                view.dispalyMessage("你击沉了我们所有的战舰,经过"+this.guesses+"次猜测");
            }
        }
    }
};

function parseGuess(guess){
    var alphabet = ["A","B","C","D","E","F","G"];

    if(guess === null || guess.length !==2){
        alert("请输出符合规定的输入");
    }else{
        firstChar = guess.charAt(0);
        var row = alphabet.indexOf(firstChar);
        var column = guess.charAt(1);

        if(isNaN(row) || isNaN(column)){
            alert("请输入范围内的数字");
        }else if(row<0 || row>=model.boardSize || column<0 || column>=model.boardSize){
            alert("输入内容不再范围内");
        }else{
            return row + column;
        }
    }
    return null;
}

function init(){
    var fireButton = document.getElementById("fireButton");
    fireButton.onclick = handleFireButton;
    var guessInput = document.getElementById("guessInput");
    guessInput.onkeypress = handleKeyPress;

    model.generateShipLocation();
}

function handleFireButton(){
    var guessInput = document.getElementById("guessInput");
    var guess = guessInput.value;
    controller.processGuess(guess);
    guessInput.value = "";
}

function handleKeyPress(e){
    var fireButton = document.getElementById("fireButton");
    if(e.keyCode === 13){
        fireButton.click();
        return false;
    }
}

window.onload = init;

battleship.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>战舰世界</title>
    <style>
        body{
            background-color: black;
        }

        div#board{
            position:relative;
            width:1024px;
            height:863px;
            margin:auto;
            background: url("board.jpg") no-repeat;/*不平铺*/
        }
        div#messageArea{
            position:absolute;
            top:0px;
            left:0px;
            color: rgb(83, 175, 19); 
        }
        table{
            position:absolute;
            left: 173px;
            top:98px;
            border-spacing: 0px;
        }
        td{
            width: 94px;
            height: 94px;
        }
        form{
            position: absolute;
            bottom: 0px;
            right: 0px;
            padding: 15px;
            background-color: rgb(83, 175, 19);
        }
        form input{
            background-color: rgb(152, 207, 113);
            border-color: rgb(83, 175, 19);
            font-size: 1em;
        }
        .hit{
            background: url("ship.png") no-repeat center center;
        }
        .miss{
            background: url("miss.png") no-repeat center center;
        }
        
    </style>
</head>
<body>
    <div id="board">
        <div id="messageArea"></div>
        <table>
            <tr>
                <td id="00"></td> <td id="01"></td> <td id="02"></td> <td id="03"></td>
                <td id="04"></td> <td id="05"></td> <td id="06"></td>
            </tr>
            <tr>
                <td id="10"></td> <td id="11"></td> <td id="12"></td> <td id="13"></td>
                <td id="14"></td> <td id="15"></td> <td id="16"></td>
            </tr>
            <tr>
                <td id="20"></td> <td id="21"></td> <td id="22"></td> <td id="23"></td>
                <td id="24"></td> <td id="25"></td> <td id="26"></td>
            </tr>
            <tr>
                <td id="30"></td> <td id="31"></td> <td id="32"></td> <td id="33"></td>
                <td id="34"></td> <td id="35"></td> <td id="36"></td>
            </tr>
            <tr>
                <td id="40"></td> <td id="41"></td> <td id="42"></td> <td id="43"></td>
                <td id="44"></td> <td id="45"></td> <td id="46"></td>
            </tr>
            <tr>
                <td id="50"></td> <td id="51"></td> <td id="52"></td> <td id="53"></td>
                <td id="54"></td> <td id="55"></td> <td id="56"></td>
            </tr>
             <tr>
                <td id="60"></td> <td id="61"></td> <td id="62"></td> <td id="63"></td>
                <td id="64"></td> <td id="65"></td> <td id="66"></td>
            </tr>
        </table>
        <form>
            <input type="text" id="guessInput" placeholder="A0">
            <input type="button" id="fireButton" value="Fire!">
        </form>
    </div>
    <script src="battleship.js"></script>
</body>
</html>

下面开始解释具体的js代码:

首先我们采用MVC模型,model、view、controller各司其职,所以分别建立了这三个对象,有其各自的属性和方法

view对象:

我们首先来看看负责视图的view对象:

这个对象没什么好说的,就包含了三个视图的更新任务:

显示未击中战舰的MISS

显示击沉的战舰图标

显示提示信息

model对象:

属性:

方法:

fire:

首先需要一个读入的玩家猜测guess,然后通过for循环将战舰从战舰数组中分别读出来,然后使用indexof方法判断猜测是否在ship的locations数组中,如果存在就将对应hit数组位置进行标记,并通知view更新视图,不存在则更新miss视图;同时还需判断战舰群是否已经被击沉,若击沉,将shipsSunk++。

isSunk:

传入一个ship战舰参数,遍历所有hit标记,全部沉没,战舰群才沉没。

generateShipLocation:

这是一个产生战舰的总方法:调用generateShip和collision方法

generateShip:

首先产生一个方向随机数:0表示竖直,1表示水平

这里要注意放置时,不能超出游戏板,所以对起始位置做了限定。

然后将产生的随机位置放入临时数组中return。

collision:

这是一个判断战舰重合的方法,通过遍历检查该位置是否在已有战舰的locations数组中判断是否碰撞。

controller对象:

这是一个控制器,主要是对模型model进行处理:

processGuess:

主要进行获取用户猜测并通知model进行fire的操作

parseGuess:

进行将用户输入转换为位置坐标的操作。

最后要注意的是:window.onload = init;

表示在网页加载完成后回调init方法。

而init方法则是对获取用户输入和战舰初始化的操作。

猜你喜欢

转载自blog.csdn.net/hzy199772/article/details/87864175
今日推荐