1

我正在制作一款泡泡射击游戏,我正在尝试让我正在发射的泡泡堆叠起来,然后在列中的正确位置。我放在板上的气泡如下所示:

000000000000000
 000000000000000
000000000000000
 000000000000000

有 4 行,有 15 个气泡。这是我到目前为止写的代码:

主要的

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: Error #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);

[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 通常是由未定义的变量引起的,这可能来自修改变量“bubble”的其他代码。例如,placeContainer 将容器中的气泡分配给变量“bubble”。

函数 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);

我也会仔细检查你的其他计算。Puzzle Bobble 游戏通常将奇数行设置为半径水平偏移,而不是半径 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 Canvas

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

于 2012-07-15T22:57:50.457 回答