[phina.js] 마리오 같은 블록 파괴 처리

글쓰기에 전념하고 있다
https://zenn.dev/alkn203/books/phina-tips-rewrite

개시하다


어렸을 때 슈퍼마리오 형제를 처음 놀았을 때 네모난 덩어리가 망가진 것은 참신했고 불필요한 부분을 모두 망가뜨렸다.이번에는 피나야.나는 js로 그것을 재현해 보았다.

블록의 움직임을 관찰하다


나는 마리오 덩어리의 손상 방법을 스스로 관찰해 보았는데, 대략 다음과 같은 몇 가지를 포착할 수 있을 것이다.
  • 를 4개 조각
  • 으로 나눈다.
  • 조각의 도형 경사
  • 위의 조각과 아래의 조각이 서로 다른 각도로 비행
  • 사이다를 네 조각으로 나누다


    이 표현식에 대해 우리는 네 개의 새로운 사이다를 만들기로 결정했는데 그 중 일부는 원시 사이다를 그렸다.
    _marioLike: function(sprite) {
      // 縦横の分割数
      var divX = 2;
      var divY = 2;
    
      var image = sprite.image.domElement;
      // 分割サイズ
      var sizeX = sprite.width / divX;
      var sizeY = sprite.height / divY;
      // グリッド
      var grid = phina.util.Grid(sprite.width, divX);
      var srcRect = sprite.srcRect;
      // 分割スプライト作成
      (divX * divY).times(function(i) {
        // インデックス位置設定
        var xIndex = i % divX;
        var yIndex = (i / divX).floor();
        // 新規canvas作成
        var canvas = phina.graphics.Canvas().setSize(sizeX, sizeY);
        var x = srcRect.x + xIndex * sizeX;
        var y = srcRect.y + yIndex * sizeY;
        // canvasに描画
        canvas.context.drawImage(image, x, y, sizeX, sizeY, 0, 0, sizeX, sizeY);
        // 破片作成
        var piece = phina.display.Sprite(canvas).addChildTo(this);
        // 位置指定
        var px = grid.span(xIndex) + sprite.x - piece.width / 2;
        var py = grid.span(yIndex) + sprite.y - piece.height / 2;
    
        piece.setPosition(px, py);
        piece.rotation = 45;
      }, this);
    }
    

    조각의 도형을 비스듬히 하다


    단순히 조각의 로테이션을 45로 설정했을 뿐이다.

    위의 조각과 아래의 조각은 서로 다른 각도로 비행한다


    이 부근은 시행착오를 통해서만 조정할 수 있다.
    // 破片を散らす
    [[-120, 35], [-60, 35], [-150, 20], [-30, 20]].each(function(elem, i) {
      var piece = this.children[i];
      piece.physical.gravity.y = 4.6;
      piece.physical.velocity = phina.geom.Vector2().fromDegree(elem[0], elem[1]);
    }, this);
    

    확장 파일화


    통용성을 높이기 위해.effect.나는 브레이크라는 반을 골라 보았다.
    https://github.com/alkn203/phina-extensions/blob/master/effect/break.js

    샘플 코드


    코드 보기
    phina.globalize();
    // アセット
    var ASSETS = {
      // 画像
      image: {
        'tiles': 'https://cdn.jsdelivr.net/gh/alkn203/assets_etc/tiles.png',
      },
    };
    // 定数
    var GRID_SIZE = 64; // グリッドのサイズ
    // メインシーン
    phina.define('MainScene', {
      superClass: 'DisplayScene',
      // コンストラクタ
      init: function() {
        // 親クラス初期化
        this.superInit();
        // 背景色
        this.backgroundColor = 'skyblue';
    
        var sprite = Sprite('tiles', GRID_SIZE, GRID_SIZE).addChildTo(this);
        sprite.setPosition(this.gridX.center(), this.gridY.center());
        sprite.setFrameIndex(4);
    
        var self = this;
        this.onpointstart = function() {
          phina.effect.Break(sprite).addChildTo(self);
        };
      },
    });
    // メイン
    phina.main(function() {
      var app = GameApp({
        startLabel: 'main',
        // アセット読み込み
        assets: ASSETS,
      });
    
      app.run();
    });
    

    runstant 프로젝트


    https://runstant.com/alkn203/projects/d2add699

    좋은 웹페이지 즐겨찾기