【问题标题】:Flash - Adding objects to a scene randomly, at certain set pointsFlash - 在某些设定点随机将对象添加到场景中
【发布时间】:2014-11-12 20:55:44
【问题描述】:

我正在使用 ActionScript 3.0 创建一个简单的 Flash 游戏,但在将障碍物生成到场景中时遇到了问题。我的目标是在 x 轴上有大约 10 个点(保持在同一个 y 轴上),当在我的场景中生成障碍物时,它会随机选择 2-4 个这些点并在它们上面生成它们。

我遇到了随机生成的障碍,但无法从列表中弄清楚如何让它们在随机设定点生成。如果有人可以提供帮助,我将不胜感激。谢谢

编辑:

我目前的代码:

var a:Array = new Array();
for (var count=0; count< 5; count++) {
        a[count] = new asteroidOne();
        a[count].x = 100 * count + (Math.floor(Math.random() * 200));
        a[count].y = 100;
        addChild(a[count]);
}

// Asteroid obstacle spawning 2.0

player.addEventListener(Event.ENTER_FRAME, obstacleMove);
function obstacleMove(evt:Event):void {
        for (var i=0; i< 5; i++) {
                a[i].y += 5;
                if (a[i].y == 480) {
                        a[i].y = 0;    
                }
                if (player.hitTestObject(a[i])) {
                        trace("HIT");
                }
        }
}

【问题讨论】:

  • 你能把你的代码显示在你有问题的地方吗?
  • 我编写的代码并不是真正的问题,因为我不知道具体如何去做。我已经编辑了我的第一篇文章,以包含我到目前为止的代码。
  • 我不明白你想要完成什么?您有一个循环创建 5 个小行星并将它们填充到一个数组中,并将它们的 x 设置为随机值。然后每帧将它们向下移动 5 个像素。你还想做什么?您是否试图使起始 astroid x 不是完全随机的,而是从可接受的 x 起点列表中获取一个值?
  • 如果是这样,只需创建一个包含所有可接受起点的数组/向量,将其随机化,然后在您的 astroid 创建循环的每次迭代中弹出该数组。如果仍然需要,我将在明天发布一个示例。
  • 那我该怎么做呢?我对此还有些陌生,所以我不太确定如何从中随机挑选它。请举个例子非常有帮助!谢谢! @LDMS

标签: actionscript-3 flash


【解决方案1】:

假设您的生成点在一个数组中,您可以执行以下操作:

var spawnPoints:Array = [100,200,250,300,450,500,600,800]; //your list of spawn x locations
spawnPoints.sort(randomizeArray); //lets randomize the spwanPoints

function randomizeArray(a:*, b:*):int {
    return ( Math.random() < .5 ) ? 1 : -1;
}

var a:Vector.<asteroidOne> = new Vector.<asteroidOne>(); //the array for your astroids - changed to vector for possible performance and code hint improvement (basically the same as Array but every object has to be of the specified type)

for (var count:int=0; count < 5; count++) {
        a.push(new asteroidOne());
        a[count].x = spawnPoints.pop(); //pop removes the last element from the array and returns it
        a[count].y = 100;
        addChild(a[count]);
}

编辑

为了解决您的问题,这里有一个不错的例子:

import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;

var spawnTimer:Timer = new Timer(10000); //timer will tick every 10 seconds
spawnTimer.addEventListener(TimerEvent.TIMER, spawn, false, 0, true); //let's run the spawn function every timer tick
spawnTimer.start();

var spawnPoints:Array = [100,200,250,300,450,500,600,800]; //your list of spawn x locations
var spawnAmount:int = 5; //how many asteroids to have on the screen at once (you could increase this over time to make it more difficult)
var asteroids:Vector.<asteroidOne> = new Vector.<asteroidOne>(); //the array for your asteroids - changed to vector for possible performance and code hint improvement (basically the same as Array but every object has to be of the specified type)

spawn(); //lets call it right away (otherwise it will won't be called until the first timer tick in 10 seconds)

//calling this will spawn as many new asteroids as are needed to reach the given amount
function spawn(e:Event = null):void {
    if(asteroids.length >= spawnAmount) return; //let's not bother running any of the code below if no new asteroids are needed
    spawnPoints.sort(randomizeArray); //lets randomize the spwanPoints
    var spawnIndex:int = 0;

    var a:asteroidOne; //var to hold the asteroid every loop
    while (asteroids.length < spawnAmount) {
        a = new asteroidOne();
        a.x = spawnPoints[spawnIndex];
        spawnIndex++; //incriment the spawn index
        if (spawnIndex >= spawnPoints.length) spawnIndex = 0; //if the index is out of range of the amount of items in the array, go back to the start

        a.y = 100;
        asteroids.push(a); //add it to the array/vector
        addChild(a); //add it to the display 
    }
}

player.addEventListener(Event.ENTER_FRAME, obstacleMove);
function obstacleMove(evt:Event):void {

    //this is the same as a backwards for loop - for(var i:int=asteroids.length-1;i >= 0; i--)
    var i:int = asteroids.length;
    while(i--){  //since we are potentially removing items from the array/vector, we need to iterate backwards - otherwise when you remove an item, the indices will have shifted and you'll eventually get an out of range error
        asteroids[i].y += 5;
        if (asteroids[i].y > stage.stageHeight || asteroids[i].x > stage.stageWidth || asteroids[i].x < -asteroids[i].width || asteroids[i].y < -asteroids[i].height) {
            //object is out of the bounds of the stage, let's remove it

            removeChild(asteroids[i]); //remove it from the display
            asteroids.splice(i, 1); //remove it from the array/vector

            continue; //move on to the next iteration in the for loop
        }

        if (player.hitTestObject(asteroids[i])) {
            trace("HIT");
        }
    }
}

function randomizeArray(a:*, b:*):int {
    return ( Math.random() < .5 ) ? 1 : -1;
}

【讨论】:

  • 哇,看起来很复杂。稍后我会试一试,看看它是如何与我的代码一起工作的。非常感谢,如果我遇到任何问题,我会告诉你!
  • 太棒了,它有效!非常感谢@LDMS 现在我只需要让它每隔几秒钟产生一次新的并在它们离开屏幕时将它们删除,这应该很容易。我是否可以假设我可以将它放入一个循环中,以便在条件为真时每隔“x”秒运行一次?
  • 您绝对不想使用 for 循环来随着时间的推移运行代码 - 为此使用计时器。我将在答案中添加几个示例以帮助您继续前进。
  • 对不起,网站还是有点新。我已经接受了答案,现在正在查看您的新示例。非常感谢:)
  • 对,我已经将该示例添加到我的代码中,但它似乎没有将小行星添加到场景中?我已经检查以确保所有内容都被正确引用,但它似乎不起作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
  • 2021-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多