1

JavaScriptを使用してHTML5キャンバスベースのゲームを作成しています。ゲームは単純なもので、キャンバスにいくつかの画像といくつかの説明ボックスが表示されます。ユーザーは、各画像を対応する説明ボックスにドラッグアンドドロップする必要があります。

現在、画像と説明ボックスを表示するキャンバスがあります。これらはページが読み込まれるとすぐに表示されますが、画像や説明ボックスなどが表示されてゲームを開始する前にユーザーがクリックする必要がある「スタートボタン」を追加したいと思います。

私のページのコードは現在次のようになっています。

    <!DOCTYPE HTML>
<html>
  <head>
    <style>
  body {
    margin: 0px;
    padding: 0px;
  }
  canvas{
    border: 1px solid #9C9898;
    background:#F5F5F5;
  }
</style>
<div id="container"></div>
<script src="kinetic.js"></script>
<script src="drawdescriptionboxes.js"></script>
<script src="drawLevelOneElements.js"></script>
<script src="startGameDrawGameElementsDrawStartButton.js"></script>
<script>
/*Add the game elements' global variables */
var currentLevel = 1;
var totalLevels = 3;
var currentScore = 0;
var currentScorePositionX = 950;
var currentScorePositionY = 10;

/*Add code to draw images to random locations here */
    //var imageX = Math.floor(Math.random()*950);
    //var imageY = Math.floor(Math.random()*450);

    var stage = new Kinetic.Stage({
      container: "container",
      width: 1000,
      height: 500
    });
    var imagesLayer = new Kinetic.Layer();
    var canvas = imagesLayer.getCanvas();
    var context = canvas.getContext("2d");
    console.log("Foo ");

/*Load the images from the HTML into the JavaScript */
function loadImages(sources, callback){
    var imagesDir = "";
    var images = {};
    var loadedImages = 0;
    var numImages = 0;

    //console.log("length " + sources.length);
    for (var src in sources){
        numImages++;
    }
    //console.log("Num Images " + numImages);

    var index=0;
    console.log("length " + sources.length);
    for (index=0;index < numImages ;index++){
        console.log(index);
        images[index] = new Image();
        images[index].src = sources[index];
        console.log("Adding " + sources[index]);
        callback(images[index]);
        console.log("sources array length = " + sources.length);
    }

    stage.add(imagesLayer); // should only be added once!!
}

/*Function to check whether the item being dragged is near its description box */
function isNearDescriptionBox(itemImage, descriptionBox){
    var ii = itemImage;
    var db = descriptionBox;
    if(ii.attrs.x > db.x - 20 && ii.attrs.x < db.x + 20 && ii.attrs.y > db.y - 20 && ii.attrs.y < db.y +20){
        return true;
    }else{
        return false;
    }
}

/* This function draws the game elements */
function drawGameElements(){
    /* Draw a line for the 'score bar'. */
    context.moveTo(0, 25);
    context.lineTo(1000, 25);
    context.stroke();

    /* Draw current level/ total levels on the left, and current score on the right. */
    context.font = "11pt Calibri"; /* Text font & size */
    context.strokeStyle = "black"; /* Font colour */
    context.strokeText(currentLevel + "/" + totalLevels, 10, 15);
    context.strokeText(currentScore, 750, 15);
}

function initStage(images){
    var stage = new Kinetic.Stage({
        container: "container",
        width: 1000,
        height: 500
    });
    var descriptionLayer = new Kinetic.Layer();
    //var imagesLayer = new Kinetic.Layer();
    var allImages = [];
    var currentScore = 0;

    var descriptionBoxes = {
        assetsDescriptionBox: {
            x: 70,
            y: 400
        },
        liabilitiesDescriptionBox: {
            x: 300,
            y: 400
        },
        incomeDescriptionBox: {
            x: 530,
            y: 400
        },
        expenditureDescriptionBox: {
            x: 760,
            y: 400
        },
    };

    /*Code to detect whether image has been dragged to correct description box */
    for (var key in sources){
        /*Anonymous function to induce scope */
        (function(){
            var privateKey = key;
            var imageSource = sources[key];

            /*Check if image has been dragged to the correct box, and add it to that box's
                array and remove from canvas if it has */
            canvasImage.on("dragend", function(){
                var descriptionBox = descriptionBoxes[privateKey];
                if(!canvasImage.inRightPlace && isNearDescriptionBox(itemImage, descriptionBox)){
                    context.remove(canvasImage);
                    /*Will need to add a line in here to add the image to the box's array */
                }
            })

        })();
    }

}

function drawImage(imageObj) {
    //var layer = new Kinetic.Layer();

    //var imageX = Math.floor(Math.random()*950);
    //var imageY = Math.floor(Math.random()*450);

    /*Got the code from generating random coordinates from:
        http://stackoverflow.com/questions/4959975/random-between-two-numbers-in-javascript*/
    function randomPosition(from, to){
        return Math.floor(Math.random()*(to-from+1)+from);
    }

    var canvasImage = new Kinetic.Image({
      image: imageObj,
      width: 50,
      height: 50,
      // puts the image in teh middle of the canvas
      x: randomPosition(0, 950),  //imageX,    //stage.getWidth() / 2 - 50 / 2,
      y: randomPosition(30, 350),  //imageY,    //stage.getHeight() / 2 - 50 / 2,
      draggable: true
    });

    // add cursor styling
    canvasImage.on('mouseover', function() {
      document.body.style.cursor = 'pointer';
    });
    canvasImage.on('mouseout', function() {
      document.body.style.cursor = 'default';
    });

    imagesLayer.add(canvasImage);
}

/*This code loads the images to the canvas when the browser window loads */
window.onload = function(){
    var sources = [];
        sources[0] = document.getElementById("building").src,
        sources[1] = document.getElementById("chair").src,
        sources[2] = document.getElementById("drink").src,
        sources[3] = document.getElementById("food").src,
        sources[4] = document.getElementById("fridge").src,
        sources[5] = document.getElementById("land").src,
        sources[6] = document.getElementById("money").src,
        sources[7] = document.getElementById("oven").src,
        sources[8] = document.getElementById("table").src,
        sources[9] = document.getElementById("van").src,

        sources[10] = document.getElementById("burger").src,
        sources[11] = document.getElementById("chips").src,
        sources[12] = document.getElementById("drink").src,
        sources[13] = document.getElementById("franchiseFee").src,
        sources[14] = document.getElementById("wages").src,

        sources[15] = document.getElementById("admin").src,
        sources[16] = document.getElementById("cleaners").src,
        sources[17] = document.getElementById("electricity").src,
        sources[18] = document.getElementById("insurance").src,
        sources[19] = document.getElementById("manager").src,
        sources[20] = document.getElementById("rates").src,
        sources[21] = document.getElementById("training").src,
        sources[22] = document.getElementById("water").src,

        sources[23] = document.getElementById("burger").src,
        sources[24] = document.getElementById("chips").src,
        sources[25] = document.getElementById("drink").src,

        sources[26] = document.getElementById("creditors").src,
        sources[27] = document.getElementById("electricity").src,
        sources[28] = document.getElementById("food").src,
        sources[29] = document.getElementById("hirePurchase").src,
        sources[30] = document.getElementById("loan").src,
        sources[31] = document.getElementById("overdraft").src,
        sources[32] = document.getElementById("payeTax").src,
        sources[33] = document.getElementById("tax").src;

    drawStartButton();
    loadImages(sources, drawImage);
    //drawGameElements();
    //drawDescriptionBoxes();

};

また、ページの非表示セクションがあり<body></body>、JSを使用して操作する前に、使用するすべての画像を最初にHTMLにロードしました。

現在、ブラウザでページを表示すると、sources配列のすべての画像が、説明ボックス、スコアバー、スタートボタンとともに、キャンバス上のランダムな場所に表示されます。

しかし、私がしたいのは、ページが最初に読み込まれるとき、スタートボタンだけがキャンバスに表示され、ユーザーがこれをクリックすると、他のすべてが表示されるということです。

drawStartButton()おそらく、これを行うには、関数の最後を除くすべての関数の呼び出しを削除/コメントアウトしてから、スタートボタンに関連付けられwindows.onload = function(){...}たイベントで他の関数の呼び出しを行いたいと思いますか?onmousedown

ただし、何らかの理由で、この関数の最後でへの呼び出しをコメントアウトしてからloadImages(sources, drawImage);、ブラウザでページを再度表示すると、キャンバスがページに表示されなくなります。画像が表示されていなくても、キャンバスはまだそこにあると思っていました。なぜこれが起こらないのか、そしてどうすればそれを正しくすることができるのか、誰かが知っていますか?

loadImages(sources, drawImage);私の関数のコードは次のとおりです。

function loadImages(sources, callback){
    var imagesDir = "";
    var images = {};
    var loadedImages = 0;
    var numImages = 0;

    //console.log("length " + sources.length);
    for (var src in sources){
        numImages++;
    }
    //console.log("Num Images " + numImages);

    var index=0;
    console.log("length " + sources.length);
    for (index=0;index < numImages ;index++){
        console.log(index);
        images[index] = new Image();
        images[index].src = sources[index];
        console.log("Adding " + sources[index]);
        callback(images[index]);
        console.log("sources array length = " + sources.length);
    }

    stage.add(imagesLayer); // should only be added once!!
}

この関数の呼び出しを削除すると、キャンバスがページに表示されなくなる理由がわかりません...何かアイデアはありますか?

4

1 に答える 1

0

関数の最後の行、

stage.add(imagesLayer); // should only be added once!!

レイヤーをステージに追加します。ステージはコンテナー (div など) ですが、レイヤーは実際のキャンバスです。

を呼び出さないとloadImages()、その行が実行されないため、レイヤが DOM に追加されることはありません。

于 2013-02-15T13:24:28.663 に答える