Phaser로 만든 zNumbers 게임의 HTML5 버전

Karl Bartel의 영리한 퍼즐 게임 zNumbers에 대해 잘 모를 것이라고 확신합니다. 그것은 원래 샤프 자우 루스 (Sharp Zaurus)를 위해 출판 되었지만 아니오, 그것이 무엇인지 묻지 마십시오.

숫자가 있는 모든 타일은 가로, 세로 또는 대각선으로 이동할 수 있습니다. 블록의 번호는 블록을 이동해야하는 거리를 나타냅니다. 시작과 끝 사이의 다른 블록은 이동을 막지 않지만 대상 필드는 자유롭게 있어야 합니다. 블록을 선택하면 가능한 모든 대상이 강조 표시됩니다.

설명하는 것보다 연주하기 쉬운 방법 이니 여기 첫 번째 단계입니다.

번호를 탭 / 터치 한 다음 대상을 누르거나 터치합니다. 모든 번호를 한 번 이동할 수 있습니까? 이 게임은 몇 년 전 라이트 포스 게임에서도 출간되었습니다.

모바일 장치가있는 경우 이 링크에서 직접 재생할 수 있습니다.

원래 게임은 10 레벨을 특징으로하며 모든 레벨의 업데이트를 게시 할 것입니다. 하지만 무엇보다도 무작위로 생성 된 레벨을 만들고 싶습니다.


여기에 완전히 주석 처리 된 소스 코드입니다.
var game; 
// 레벨. 사실, 단지 하나.
var levels = [
    [
        [0, 0, 0, 0, 0, 0],
        [3, 2, 3, 2, 2, 2],
        [0, 0, 2, 3, 2, 2],
        [2, 0, 2, 2, 0, 0],
        [0, 2, 3, 0, 2, 2],
        [2, 3, 0, 2, 0, 4]
    ]
];
// 이 개체는 모든 사용자 지정 가능한 게임 옵션을 포함합니다.
// 게임을 변경하면 게임 플레이에 영향을 미칩니다.
var gameOptions = { 
    // 게임 폭 (픽셀 단위)
gameWidth: 700,
    // 게임 높이 (픽셀 단위)
gameHeight: 700,
    // 타일 크기 (픽셀 단위)
    tileSize: 100,
    // 필드 크기, 객체
fieldSize: { 
        // 필드의 행 단위
        rows: 6,
        // 필드의 열 (단위)
        cols: 6
    }, 
    // 타일 색상
    colors: [0x999999, 0xffcb97, 0xffaeae, 0xa8ffa8, 0x9fcfff],
    // 배열을 여러 방향으로 사용하면 처음 4 개 (위쪽, 아래쪽, 왼쪽, 오른쪽) 만 사용하면 // 게임을 더 세게 만들 수 있습니다.
    directions: [
        new Phaser.Point(0, 1),
        new Phaser.Point(0, -1),
        new Phaser.Point(1, 0),
        new Phaser.Point(-1, 0),
        new Phaser.Point(1, 1),
        new Phaser.Point(-1, -1),
        new Phaser.Point(1, -1),
        new Phaser.Point(-1, 1)
    ]
}
// 페이지가 로드되면 실행되는 함수
window.onload = function() { 
    // 새로운 Phaser 게임 만들기
game = new Phaser.Game(gameOptions.gameWidth, gameOptions.gameHeight); 
    // "TheGame" 상태 추가
    game.state.add("TheGame", TheGame);
    // "TheGame" 상태 실행
    game.state.start("TheGame");
}
/* ****************** TheGame state ****************** */
var TheGame = function(){};
TheGame.prototype = {
    // 게임이 미리로드 될 때 실행되는 기능
    preload: function(){ 
        // 배경색을 어두운 회색으로 설정
        game.stage.backgroundColor = 0xf5f5f5;
        // 게임에서 유일하게 그래픽 애셋을 로드하고 즉석에서 색을 칠할 흰색 타일을로드합니다.
        game.load.image("tiles", "assets/sprites/tile.png");
    },
    // 게임이 완전히 로드되면 바로 실행되는 기능
   create: function(){
        // 비율을 유지하면서 전체 화면을 덮도록 게임을 확장합니다.
        game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
        // 게임의 수평 중심 배치
game.scale.pageAlignHorizontally = true; 
        // 게임을 수직으로 배치
game.scale.pageAlignVertically = true;
        // 이 함수는 레벨을 생성합니다.
   this.createLevel();
   },
createLevel: function(){ 
        // 현재 레벨
        this.level = 0; 
        // 타일은 tilesArray라는 배열에 저장되므로 초기 구성을 잃지 않고 // 타일 레이아웃을 업데이트 할 수 있습니다.
        this.tilesArray = [];
        // 이 그룹에는 모든 타일이 포함됩니다.
this.tileGroup = game.add.group();
        // 우리는 그룹을 수평으로 중심에두고 같은 마진을 바닥에서 유지합니다.
        this.tileGroup.x = (game.width - gameOptions.tileSize * gameOptions.fieldSize.cols) / 2;
        this.tileGroup.y = (game.height - gameOptions.tileSize * gameOptions.fieldSize.rows) / 2; 
        // "gameOptions.fieldSize.rows"x "gameOptions.fieldSize.cols" 열에서 // 만든 눈금을 만드는 두 개의 루프
   for(var i = 0; i < gameOptions.fieldSize.rows; i++){
            this.tilesArray[i] = [];
for(var j = 0; j < gameOptions.fieldSize.cols; j++){ 
                // 이 함수는 "i"행과 "j"행에 타일을 추가합니다.
this.addTile(i, j);
}
}
        // 사용자 입력 대기 중
        game.input.onDown.add(this.pickTile, this);
},
    // "행" 행과 "열" 열에 타일을 추가하는 기능
addTile: function(row, col){
        // 타일 크기에 따라 x 및 y 타일 위치 결정
var tileXPos = col * gameOptions.tileSize + gameOptions.tileSize / 2;
var tileYPos = row * gameOptions.tileSize + gameOptions.tileSize / 2;
        // 타일이 이미지로 추가됩니다.
        var theTile = game.add.sprite(tileXPos, tileYPos, "tiles");
        // 타일 등록 포인트를 중앙에 설정
        theTile.anchor.set(0.5); 
        // 타일 크기에 따라 타일 너비와 높이 조정
        theTile.width = gameOptions.tileSize;
        theTile.height = gameOptions.tileSize;
        // 타일에 임의의 값을 할당하는 시간.이 값은 임의의 색상이기도합니다.
        var tileValue = levels[this.level][row][col];
        // 타일 착색
        theTile.tint = gameOptions.colors[tileValue];
        // 타일 번호 추가
        var tileText = game.add.text(0, 0, tileValue.toString(), {
            font: (gameOptions.tileSize / 2).toString() + "px Arial",
            fontWeight: "bold"
        });
        // 타일 번호 등록 포인트를 센터에 설정
        tileText.anchor.set(0.5); 
        tileText.alpha = (tileValue > 0) ? 0.5 : 0 
        // 이제 타일 번호는 타일 자체의 자식입니다.
        theTile.addChild(tileText); 
        // "tilesArray"배열에 이미지 추가, 객체 만들기
        this.tilesArray[row][col] = {
            // 타일 이미지
            tileSprite: theTile,
            // 타일의 값
            value: tileValue,
            // 타일의 텍스트
            text: tileText
        };
        // "tileGroup"그룹에 추가
this.tileGroup.add(theTile);
},
    // 이 기능은 각 사용자 입력 (클릭 또는 터치)시 실행됩니다.
    pickTile: function(e){
        // 모든 타일 트윈을 재설정하는 메소드
        this.resetTileTweens();
        // tileGroup 내의 입력의 x와 y 위치를 결정한다.
        var posX = e.x - this.tileGroup.x;
        var posY = e.y - this.tileGroup.y; 
        // 좌표를 실제 행과 열로 변환
        var pickedRow = Math.floor(posY / gameOptions.tileSize);
        var pickedCol = Math.floor(posX / gameOptions.tileSize);
        // 행과 열이 실제 게임 필드 안에 있는지 확인하기
        if (pickedRow >= 0 && pickedCol >= 0 && pickedRow < gameOptions.fieldSize.rows && pickedCol < gameOptions.fieldSize.cols){
            // 우리가 고른 타일이에요.
            var pickedTile = this.tilesArray[pickedRow][pickedCol];
            // 타일 값 가져 오기
            var pickedValue = pickedTile.value;
            // 합법적 인 타일 인 경우 ...
            if(pickedValue > 0){ 
                // 선별 된 타일 좌표 저장
                this.saveTile = new Phaser.Point(pickedRow, pickedCol);
                // 여기에 가능한 경우 방문 타일을 배치합니다.
                this.possibleLanding = [];
                this.possibleLanding.length = 0;
                // 타일을 트위닝
                this.setTileTweens(pickedTile.tileSprite); 
                // 모든 방향으로 반복
                for(var i = 0; i < gameOptions.directions.length; i++){ 
                    // 새 좌표 결정
                    var newRow = pickedRow + pickedValue * gameOptions.directions[i].x;
                    var newCol = pickedCol + pickedValue * gameOptions.directions[i].y; 
                    // 우리는 적합한 타일에 있는가?
                    if(newRow < gameOptions.fieldSize.rows && newRow >= 0 && newCol < gameOptions.fieldSize.cols && newCol >=0 && this.tilesArray[newRow][newCol].value == 0){
                        // 우리는 타일을 트위닝
                        this.setTileTweens(this.tilesArray[newRow][newCol].tileSprite);
                        // 이 타일은 착륙 타일 일 가능성이 있습니다.
                        this.possibleLanding.push(new Phaser.Point(newRow, newCol));
                    }
                }
            }
            // 그것은 적합한 타일이 아닙니다. 어쩌면 표현 가능성이 있니?
            else{
                // 선택된 타일이 표시할수 있는지 확인하십시오.
                if(this.pointInArray(new Phaser.Point(pickedRow, pickedCol))){
                    // 이 타일을 더 이상 선택할 수 없습니다.
                    this.tilesArray[pickedRow][pickedCol].value = -1;
                    // 타일 텍스트 표시
                    this.tilesArray[pickedRow][pickedCol].text.alpha = 0.5; 
                    // 대상 타일 텍스트를 소스 타일 값으로 설정
                    this.tilesArray[pickedRow][pickedCol].text.text = this.tilesArray[this.saveTile.x][this.saveTile.y].value.toString();
                    // 빈 소스 타일
                    this.tilesArray[this.saveTile.x][this.saveTile.y].value = 0;
                    // 소스 타일 색 변경
                    this.tilesArray[this.saveTile.x][this.saveTile.y].tileSprite.tint = gameOptions.colors[0]; 
                    // 타일 텍스트 숨기기
                    this.tilesArray[this.saveTile.x][this.saveTile.y].text.alpha = 0;
                }
                // 빈 possibleLanding 배열
                this.possibleLanding = [];
                this.possibleLanding.length = 0;
            }
        }
    },
    // 타일 트윈을 정의합니다.
    setTileTweens: function(tile){
        // 연속 루프와 요요 효과로 폭과 높이를 200 밀리 초씩 변경하는 펄스 트윈 정의
        this.pulseTween = game.add.tween(tile).to({
            width: gameOptions.tileSize * 0.8,
            height: gameOptions.tileSize * 0.8
        }, 200, Phaser.Easing.Cubic.InOut, true, 0, -1, true);
    },
    // 이 함수는 모든 타일 트윈을 재설정합니다.
    resetTileTweens: function(){ 
        // 실행중인 모든 트윈 가져 오기
        var activeTweens = game.tweens.getAll();
        // 실행중인 모든 트윈을 반복
        for(var i = 0; i < activeTweens.length; i++){
            // 타일 너비와 높이를 다시 원래 크기로 설정
            activeTweens[i].target.width = gameOptions.tileSize;
            activeTweens[i].target.height = gameOptions.tileSize;
        }
        // 모든 트윈을 제거하십시오.
        game.tweens.removeAll();
    },
    // possibleLanding 지점이 배열에 있는지 검사합니다.
    pointInArray: function(p){ 
        // possibleLanding을 통해 루핑
        for(var i = 0; i < this.possibleLanding.length; i++){
            // 우리는 i-th 항목지점을 찾습니다.
            if(this.possibleLanding[i].x == p.x && this.possibleLanding[i].y == p.y){
                // 예, 우리는 그것을 발견했습니다.
                return true;
            }
        }
        // p가 possibleLanding 안에 있지 않습니다.
        return false;
    }
}

댓글 없음:

댓글 쓰기