javascript - 사용법 - 자바스크립트 속성값 가져오기




JavaScript를 사용하여 2D 플랫폼 생성하기 (2)

저는 EaselJS를 사용하여 HTML5 Canvas 게임을 개발하고 있으며 하나 이상의 이미지, 크기 및 위치를 설정하여 "블록"을 만들 수있는 함수를 작성했습니다.

그리고 "블록"에 의해, 내가 의미하는 것은 :

두 가지 방법을 사용하여이 작업을 수행합니다.

첫 번째 방법 :

이 방법을 사용하면 이미지를 무작위로 사용하여 설정 한 위치 내부의 사용 가능한 공간에 블록이 만들어집니다.

두 번째 방법 :

블록은 내가 왼쪽 위 모서리, 윗면, 오른쪽 위 모서리, 왼쪽, 중앙, 오른쪽, 왼쪽 아래 모서리, 아래쪽 모서리 및 오른쪽 하단 구석에 대해 특정 이미지를 사용하여 설정 한 위치 내에 만들어집니다. 이러한 부분들 각각에 대해 하나 이상의 이미지가 생성됩니다 (따라서 시스템은 무작위 이미지를 사용하여 동일한 이미지를 여러 번 반복하지 않습니다).

좋아. 근데 문제가 뭐니?

이 기능은 77 라인 (충돌 감지 관련 부품으로 계산 된 131 라인)을 사용합니다 ! 나는 이것을하는 더 좋은 방법이 있다는 것을 알고 있습니다. 그것은 현재 복용하고있는 것보다 약 절반 또는 그 이상의 줄을 취할 것입니다, 그러나 나는 그것을하는 법을 모르며, 누군가 나를 보여줄 때, 나는 "올바른 길" 을 사용할 것입니다. 내 남은 인생. 너 나 좀 도와 줄 수있어?

내가 원하는 것 :

더 적은 수의 줄을 사용할 수있는 방법은 9 개 이상의 이미지로 합성 된 블록으로 합성 된 블록을 만들 수있는 단일 "방법"을 사용하는 것입니다 (나는 단지 어떻게해야할지 모릅니다. 이해하기 어렵다는 것을 알고 있습니다. 세 번 째 이미지가 9 번 사용되었다고 상상해보십시오.) // 질문의이 부분은 주제에 관한 것입니다!

이 질문은 주관적이지 않습니다. 왜냐하면 여기서의 목표는 적은 수의 줄을 사용하는 것이므로, 이젤이지를 사용하지 않을 것입니다. 왜냐하면 이젤 이지스와 관련된 질문이 아니기 때문에 JavaScript 지식을 가진 사람은 저에게 대답 할 수 있습니다.

여기 내 엄청나게 큰 JavaScript 함수가있다.

var Graphic = function (src, blockWidth, blockHeight) {
    return {
        createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) {
            for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) {
                for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) {

                    var obj = new createjs.Bitmap(src[Math.floor(Math.random() * src.length)]);

                    obj.width = blockWidth;
                    obj.height = blockHeight;
                    if (typeof alpha !== 'undefined') {
                        obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block.
                    }

                    obj.x = Math.round(x + (blockWidth * blockX));
                    obj.y = Math.round(y + (blockHeight * blockY));

                    stage.addChild(obj);
                }
            }
        }
    }
}
var complexBlock = function (topLeft, topCenter, topRight, middleLeft, middleCenter, middleRight, bottomLeft, bottomCenter, bottomRight, blockWidth, blockHeight) {
    return {
        createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) {
            for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) {
                for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) {
                    if (blockY == 0 && blockX == 0) {
                        var obj = new createjs.Bitmap(topLeft[Math.floor(Math.random() * topLeft.length)]);
                    }
                    if (blockY == 0 && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(topCenter[Math.floor(Math.random() * topCenter.length)]);
                    }
                    if (blockY == 0 && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(topRight[Math.floor(Math.random() * topRight.length)]);
                    }

                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == 0) {
                        var obj = new createjs.Bitmap(middleLeft[Math.floor(Math.random() * middleLeft.length)]);
                    }
                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(middleCenter[Math.floor(Math.random() * middleCenter.length)]);
                    }
                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(middleRight[Math.floor(Math.random() * middleRight.length)]);
                    }

                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == 0) {
                        var obj = new createjs.Bitmap(bottomLeft[Math.floor(Math.random() * bottomLeft.length)]);
                    }
                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(bottomCenter[Math.floor(Math.random() * bottomCenter.length)]);
                    }
                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = new createjs.Bitmap(bottomRight[Math.floor(Math.random() * bottomRight.length)]);
                    }

                    obj.width = blockWidth;
                    obj.height = blockHeight;
                    if (typeof alpha !== 'undefined') {
                        obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block.
                    }

                    obj.x = Math.round(x + (blockWidth * blockX));
                    obj.y = Math.round(y + (blockHeight * blockY));

                    stage.addChild(obj);
                }
            }
        }
    }
}

var bigDirt = complexBlock(["http://i.imgur.com/DLwZMwJ.png"], ["http://i.imgur.com/UJn3Mtb.png"], ["http://i.imgur.com/AC2GFM2.png"], ["http://i.imgur.com/iH6wFj0.png"], ["http://i.imgur.com/wDSNzyc.png", "http://i.imgur.com/NUPhXaa.png"], ["http://i.imgur.com/b9vCjrO.png"], ["http://i.imgur.com/hNumqPG.png"], ["http://i.imgur.com/zXvJECc.png"], ["http://i.imgur.com/Whp7EuL.png"], 40, 40);

bigDirt.createBlockAt(0, 0, 40*3, 40*3);

알았어 ... 여기 코드가 많아 어떻게 테스트 할 수 있니?

여기에 우리가 간다 : JSFiddle


나는 가능한 9 개의 브랜치가 주어진 줄 수를 줄이는 쉬운 방법을 보지 못하지만 코드의 반복을 상당히 줄일 수 있습니다.

function randomImage(arr) {
    return new createjs.Bitmap(arr[Math.floor(Math.random() * arr.length)]);
}

if (blockY == 0 && blockX == 0) {
    var obj = randomImage(topLeft);
} // etc

다시 9 가지 브랜치는 상호 배타적이므로, else if 대신에 else if 사용해야하며 자연스럽게 3 개로 그룹화되어 중첩되어야한다고 제안해야합니다.

실제로, 기능 크기를 많이 줄이는 방법이 있습니다. X와 Y에는 세 가지 옵션 (총 9 가지)이 있습니다. 2 차원 검색 테이블을 기반으로 원하는 이미지 배열을 인코딩 할 수 있습니다.

var blocksHigh = blockGroupHeight / blockHeight;
var blocksWide = blockGroupWidth / blockWidth;
var blockSelector = [
    [topLeft, topCenter, topRight],
    [middleLeft, middleCenter, middleRight],
    [bottomLeft, bottomCenter, bottomRight]
];

for (var blockY = 0; blockY < blocksHigh; blockY++) {
    var blockSY = (blockY == 0) ? 0 : blockY < (blocksHigh - 1) ? 1 : 2;
    for (var blockX = 0; blockX < blocksWide; blockX++) {
        var blockSX = (blockY == 0) ? 0 : blockY < (blocksWide - 1) ? 1 : 2;
        var array = blockSelector[blockSY][blockSX];
        var obj = randomImage(array);

        ...
     }
}

blocksHigh 의 정의에 유의하십시오. blocksHighblocksWide 은 루프 바깥쪽에 있습니다. 값 비싼 반복되는 나누기 연산을 줄입니다.

http://jsfiddle.net/alnitak/Kpj3E/를 참조하십시오.


차가운, 나는 해결책을 발견했다.

먼저 전체 "Graphics"함수를 제거하고 "complexBlock"함수로 바꾼 다음 각 인수 배열에 대해 다음과 같이 동일한 세 개의 이미지를 설정합니다.

var dirt = Graphic(["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 
["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"], 40, 40);

그러나 이것은 9 개의 배열을 채우기 위해 같은 이미지를 9 번 재사용해야하기 때문에 좋은 해결책은 아닙니다. 그런 다음 이것을 Graphics 함수에 추가했습니다.

if (typeof topCenter === "undefined") {
            topCenter = topRight = middleLeft = middleCenter = middleRight = bottomLeft = bottomCenter = bottomRight = topLeft;
}

하나의 배열을 선언하고 그것을 다른 배열에 전파 할 수있게 해줍니다.

@Alnitak이 권장 한대로 코드 반복을 줄이기 위해 무작위 이미지로 새 Bitmap 객체를 반환하는 함수를 만들었습니다. 고맙습니다.

다음은 최종 코드입니다.

function randomImage(arr) {
    return new createjs.Bitmap(arr[Math.floor(Math.random() * arr.length)]);
}

var Graphic = function (blockWidth, blockHeight, topLeft, topCenter, topRight, middleLeft, middleCenter, middleRight, bottomLeft, bottomCenter, bottomRight) {
    if (typeof topCenter === "undefined") {
        topCenter = topRight = middleLeft = middleCenter = middleRight = bottomLeft = bottomCenter = bottomRight = topLeft;
    }
    return {
        createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) {
            for (var blockY = 0; blockY < blockGroupHeight / blockHeight; blockY++) {
                for (var blockX = 0; blockX < blockGroupWidth / blockWidth; blockX++) {
                    if (blockY == 0 && blockX == 0) {
                        var obj = randomImage(topLeft);
                    }
                    if (blockY == 0 && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = randomImage(topCenter);
                    }
                    if (blockY == 0 && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = randomImage(topRight);
                    }

                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == 0) {
                        var obj = randomImage(middleLeft);
                    }
                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = randomImage(middleCenter);
                    }
                    if (blockY != 0 && blockY != (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = randomImage(middleRight);
                    }

                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == 0) {
                        var obj = randomImage(bottomLeft);
                    }
                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX != 0 && blockX != (blockGroupWidth / blockWidth - 1)) {
                        var obj = randomImage(bottomCenter);
                    }
                    if (blockY == (blockGroupHeight / blockHeight - 1) && blockX == (blockGroupWidth / blockWidth - 1)) {
                        var obj = randomImage(bottomRight);
                    }

                    obj.width = blockWidth;
                    obj.height = blockHeight;
                    if (typeof alpha !== 'undefined') {
                        obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block.
                    }

                    obj.x = Math.round(x + (blockWidth * blockX));
                    obj.y = Math.round(y + (blockHeight * blockY));

                    stage.addChild(obj);
                }
            }
        }
    }
}
var dirt = Graphic(40, 40, ["http://i.imgur.com/aTNLOXs.png", "http://i.imgur.com/dzD1e1n.png", "http://i.imgur.com/7DN3hGa.png"]);

var bigDirt = Graphic(40, 40, ["http://i.imgur.com/DLwZMwJ.png"], ["http://i.imgur.com/UJn3Mtb.png"], ["http://i.imgur.com/AC2GFM2.png"], ["http://i.imgur.com/iH6wFj0.png"], ["http://i.imgur.com/wDSNzyc.png", "http://i.imgur.com/NUPhXaa.png"], ["http://i.imgur.com/b9vCjrO.png"], ["http://i.imgur.com/hNumqPG.png"], ["http://i.imgur.com/zXvJECc.png"], ["http://i.imgur.com/Whp7EuL.png"]);

dirt.createBlockAt(40, 40, 40 * 3, 40 * 3);
bigDirt.createBlockAt(40 * 4, 40, 40 * 3, 40 * 3);

JSFiddle

이 질문을 정답으로 받아 들일 수는 없지만 (왜냐하면 나는 OP이므로 2 일 정도 기다려야하므로) 코드 개선을위한 새로운 방법은 완전히 환영합니다. 감사.

편집 : @ Alnitak의 대답은 나의 것보다 낫다, 그럼 내가 올바른 것으로 이것을 표시하지 않을거야.





game-engine