1

私はBubbleShooterゲームを作成していて、発射しているバブルをスタックして、列の適切な場所に配置しようとしています。ボードに置いた泡は次のようになります。

000000000000000
 000000000000000
000000000000000
 000000000000000

15個の泡がある4列があります。これは私がこれまでに書いたコードです:

主要

package  {
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.display.SpreadMethod;

public class Main extends Sprite {
    private const ROT_SPEED:uint=2;
    private const R:uint=18;
    private const DEG_TO_RAD:Number=0.0174532925;
    private const BUBBLE_SPEED:uint=10;
    private var bubbleArr:Array=new Array();
    private var loadArr:Array=new Array();
    private var cannon:cannon_mc;
    private var bubble:bubble_mc;
    private var row:uint=0;
    private var col:uint=0;
    private var left:Boolean=false;
    private var right:Boolean=false;
    public var bubCont:Sprite;
    private var loadCont:Sprite;
    private var fire:Boolean=false;
    private var vx,vy:Number;
    public function Main() {
        placeContainer();
        placeCannon();
        loadBubble();
        stage.addEventListener(KeyboardEvent.KEY_DOWN,onKDown);
        stage.addEventListener(KeyboardEvent.KEY_UP,onKUp);
        addEventListener(Event.ENTER_FRAME,onEFrame);
        trace("row= "+row+" , col= "+col);
    }
    private function placeCannon():void {
        cannon=new cannon_mc();
        addChild(cannon);
        cannon.y=385.5;
        cannon.x=320;
    }
    private function onKDown(e:KeyboardEvent):void {
        switch(e.keyCode) {
            case 37 :
                left=true;
                break;
            case 39 :
                right=true;
                break;
            case 38 :
                if (! fire) {
                    fire=true;
                    var radians=(cannon.rotation-90)*DEG_TO_RAD;
                    vx=BUBBLE_SPEED*Math.cos(radians);
                    vy=BUBBLE_SPEED*Math.sin(radians);
                }
                break;
        }
    }
    private function onKUp(e:KeyboardEvent):void {
        switch(e.keyCode) {
            case 37 :
                left=false;
                break;
            case 39 :
                right=false;
                break;
        }
    }
    private function onEFrame(e:Event):void {
        if (left) {
            cannon.rotation-=ROT_SPEED;
        }
        if (right) {
            cannon.rotation+=ROT_SPEED;
        }
        if (fire) {
            bubble.x+=vx;
            bubble.y+=vy;
            if (bubble.x<59) {
                bubble.x=59;
                vx*=-1;
            }
            if (bubble.x>(59+R*R)) {
                bubble.x=59+R*R;
                vx*=-1;
            }
            if (bubble.y<(40)) {
                bubble.y=40;
            } 
        }
    }

    public function placeContainer():void {
        var iRow:Boolean=false;
        bubCont=new Sprite();
        addChild(bubCont);
        for (var i:uint=0; i<4; i++) {
            if (! iRow) {
                for (var j:uint=0; j<15; j++) {
                    bubbleArr[i]=new Array();
                    bubbleArr[i][j]=Math.floor(Math.random()*6);
                    bubble = new bubble_mc(bubbleArr[i][j],i,j);
                    bubCont.addChild(bubble);
                    iRow=true;
                    row++;
                    col++;
                }
            } else {
                for (j=0; j<15; j++) {
                    bubbleArr[i]=new Array();
                    bubbleArr[i][j]=Math.floor(Math.random()*6);
                    bubble = new bubble_mc(bubbleArr[i][j],i,j);
                    bubble.x=77+j*2*R;
                    bubCont.addChild(bubble);
                    iRow=false;
                    row++;
                    col++;
                }
            }
        }
    }
    private function loadBubble():void {
        addChild(bubble);
        bubble.gotoAndStop(Math.floor(Math.random()*6))+1;
        bubble.x=320;
        bubble.y=410;
    }
}

bubble_mcクラス:

package  {
import flash.display.MovieClip;
public class bubble_mc extends MovieClip {
    public function bubble_mc(val:uint,row:uint,col:uint) {
        gotoAndStop(val+1);
        name=row+"_"+col;
        x=59+col*36;
        y=40+row*32;
    }
}

バブルを積み重ねる方法がまったくわかりません。hitTestObject-functionを使用して、衝突をチェックし、バブルを適切な場所に配置する関数を呼び出す独自の関数を作成しようとしました。 、しかしそれは機能せず、理由はわかりません。TypeErrorというエラーが発生します:エラー#1010。これが衝突関数とparkBubble関数です-これはバブルを正しい場所に配置することになっています:

private function parkBubble(bubble:bubble_mc,row:int,col:int):void {
        var iRow:Boolean=false;
        for (var j:uint=0; j<col; j++) {
            trace("first for loop ");
            for (var i:uint=row; i>0; i--) {
                trace("second for loop ");
                if (bubbleArr[i][j]!=null) {
                    trace("first if loop ");
                    if (! iRow) {
                        trace("second if loop ");
                        bubbleArr[i+1]=new Array();
                        bubbleArr[i+1][j]=Math.floor(Math.random()*6);
                        bubble = new bubble_mc(bubbleArr[i+1][j],(i+1),j);
                        bubCont.addChild(bubble);
                        iRow=true;
                        row++;
                        col++;
                    } else {
                        trace("first for loop after else ");
                        bubbleArr[i+1]=new Array();
                        bubbleArr[i+1][j]=Math.floor(Math.random()*6);
                        bubble = new bubble_mc(bubbleArr[i+1][j],(i+1),j);
                        bubble.x=77+j*2*R;
                        bubCont.addChild(bubble);
                        iRow=false;
                        row++;
                        col++;
                    }
                }
            }
        }
        removeChild(bubble);
        fire=false;
        loadBubble();
        trace("slutet av parkBubble ");
    }

private function collide(bub:bubble_mc):Boolean {
        var dist_x:Number=bub.x-bubble.x;
        var dist_y:Number=bub.y-bubble.y;
        return Math.sqrt(dist_x*dist_x+dist_y*dist_y)<=2*R-4;
}
4

1 に答える 1

1

この行にTypeErrorがありましたか?

    var placed_bubble:bubble_mc=new bubble_mc([row][col],row,col);

[行]は配列であり、[列]は配列です。ただし、コンストラクターは符号なし整数を想定しています。

    public function bubble_mc(val:uint,row:uint,col:uint) {

バブルをバブルコンテナにコピーするには、フレーム番号を渡します。

    var placed_bubble:bubble_mc=new bubble_mc(bubble.currentFrame-1, row, col);

これだけが問題ではないかもしれません。TypeErrorは、変数が定義されていないことが原因であることがよくあります。これは、変数「バブル」を変更する他のコードが原因である可能性があります。たとえば、placeContainerは、コンテナ内のバブルを変数「バブル」に割り当てます。

関数parkBubbleは常に「iRow」をfalseに設定しますが、バブルがその上の行と衝突する場合は、iRowをtrueにする必要があります。

    var row:uint=Math.floor(bubble.y/(40+R*Math.sqrt(3)));
    var iRow:Boolean= row % 2 == 1 ? true : false;

少なくともコンパイルが終わったら、戻っていくつかの定数名を使用して数学を単純化および最適化すれば、問題は少なくなります。そうすれば、行を計算するための上記のコードが完全に正しくないことがより簡単にわかります。上マージン(40)を引く必要があります。これは、名前付き定数で明らかです。

    private const Y_PER_ROW:int = int(R * Math.sqrt(3));
    private const TOP:int = 40;
    ...
    var row:uint = int((bubble.y - TOP) / Y_PER_ROW);

他の計算も再確認します。パズルボブルゲームは通常、奇数行を2半径(2 * R)ではなく、半径で水平方向にオフセットするように設定します。したがって、それらは六角形のように一緒にフィットします。

placeContainer関数を簡略化できます。偶数行または奇数行のコードのほとんどは同じであるため、ifブロックから取り出すことができます。そして、あなたが投稿したこのコードでは、placeContainerに「row++」と「col++」が必要な理由がわかりません。これは同等で読みやすいです:

    for (var i:uint=0; i<4; i++) {
            var xOffset:int = (i % 2) * 2 * R;
            for (var j:uint=0; j<15; j++) {
                bubbleArr[i] = new Array();
                bubbleArr[i][j] = int(Math.random()*6);
                bubble = new bubble_mc(bubbleArr[i][j], i, j);
                bubble.x += xOffset;
                bubCont.addChild(bubble);
                row++;
                col++;
            }
    }

次に、衝突検出コードを簡略化および最適化して、バブルが遠くにあるときの計算を回避し、コストのかかる平方根計算を回避できます。

サークル衝突検出HTML5キャンバス

http://cgp.wikidot.com/circle-to-circle-collision-detection

于 2012-07-15T22:57:50.457 に答える