Random Spawner?

I was wondering how I could make a method that spawns coins randomly off screen, and then propels them towards the viewing area randomly.

In a way, I need something similar to Factor Samurai where it picks a random number, then creates it, then propels it up on the screen. The only differences is that instead of multiple possibilities, I only need three, and I need them to spawn on the left and right sides of the screen.

Inside the method, I just need to create one of three objects on the left or right, shoot it onto the screen in a random direction, and add them to the physics.

Thanks for the help!

You can easily spawn Objects outside of the screen.

1
2
3
4
5
6
7
8
9
10
11
12
local function createObject()
        -- 0 will be left, 1 will be right
        local right = math.random(0,1)
 
        local obj = display.newImage("myImage.png")
        if (right) then
                obj.x = display.contentWidth+(obj.width/2)
        else
                obj.x = -(obj.width/2)
        end
        return obj
end

What would it look like with those pieces of code in? And, how often will I call it.

How often you want those objects to spawn. It's up to you!
you could use a timer (timer.performWithDelay).

For the other functions check out

Physic Bodies:
http://developer.anscamobile.com/reference/index/physicsaddbody

setLinearImpulse:
http://developer.anscamobile.com/reference/index/bodyapplylinearimpulse

Once you have a physic body, you can give it an impulse to "shoot" it :)
You should put it in the function above where you can see if it's positioned left or right ( to shoot it towards the center).

imho it's the best to try stuff out, if you still happen to have problems, i'm willing to help you out :)

I made some progress, but I'm struggling with the setLinearImpulse. Also, it always seems to spawn on the right, or at least I can't see them on the left.

Could you take a look?

http://dl.dropbox.com/u/27644193/Makin%27%20Bank.zip

I tried to check your code, but I could only see a white square.
then after switching to android i got something. but I can't see the graphics for some reason - only white..
but okay. the first problem..

Change line 74 to

1
if (isRight == 1) then

Now they spawn on both sides, but they aren't being shot inward.

Also, you aren't seeing anything on iOS because the build.settings are only for Android.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function createProjectiles()
        local projectile = display.newImage("visuals/game_coinsilver.png")
        projectile:setReferencePoint(display.TopLeftReferencePoint);
        local isRight = math.random(0, 1)
        if (isRight == 1) then
                projectile.x = 800
                projectile.y = 216
                physics.addBody(projectile)
                projectile:applyLinearImpulse(-math.random(280, 350), 300)
        else
                projectile.x = -48
                projectile.y = 216
                physics.addBody(projectile)
                projectile:applyLinearImpulse(math.random(280, 350), 300)
        end
        return projectile
end

White square is because the images aren't the correct types - I mention this in the other thread you've got going, IKinx.

I resaved the images to work next time. Anyways, my objects are being shot, but they're behaving badly. :/

I want them to sort of be lobbed into the air and then fall down.

http://dl.dropbox.com/u/27644193/Makin%27%20Bank.zip

It's a trial and error thingy.
Just play arounds with the values.
Try changing the y-value for the impulse to shoot it up high. And you might also change the objectes y-position to be more at the bottom.
It's up to you!

I can tell you what functions etc to use, but you have to tweak it for your needs :)

I have the general direction, but it's shooting out way too fast off of the screen. Is there something wrong with these lines?

1
2
3
4
--Left
projectile:applyLinearImpulse(300, -math.random(300, 600))
--Right
projectile:applyLinearImpulse(-300, -math.random(300, 600))

Your code is right, but you haven't tweaked it.

The first problem is that you have used a top left referencePoint!
Without telling the linearImpulse where it should have it's massCenter, you'll have it where the referencePoint is! That's why it looked jaggy!

The next thing: it's way to strong. I was playing around with values and got a decent result!
Also you might want to change those projectiles to projectile.isSensor = true, otherwise they'll collide with eachother!

Here's the working code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function createProjectiles()
                local chooseProjectile = math.random(0, 0)
                if (chooseProjectile == 0) then
                        projectile = display.newImage("visuals/game_coinsilver.png")
                elseif (chooseProjectile == 1) then
                        projectile = display.newImage("visuals/game_coingold.png")
                elseif (chooseProjectile == 2) then
                        projectile = display.newImage("visuals/game_rock.png")
                end
                --projectile:setReferencePoint(display.TopLeftReferencePoint)
        local chooseLocation = math.random(0, 1)
                if (chooseLocation == 0) then
                        projectile.x = -48
                        projectile.y = 421
                        physics.addBody(projectile)
                        projectile:applyLinearImpulse(.2, -math.random(3,5)/10,projectile.x,projectile.y)
        elseif (chooseLocation == 1) then
            projectile.x = 800
            projectile.y = 421
                        physics.addBody(projectile)
                        projectile:applyLinearImpulse(-.2, -math.random(3,5)/10,projectile.x,projectile.y)
        end
        return projectile
end

And to make your code a bit shorter and more effective:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function createProjectiles()
        local projectileImages = {"coinsilver","coingold","rock"}
        local random = math.random(1,#projectileImages)
        projectile = display.newImage("visuals/game_"..projectileImages[random]..".png")
 
        physics.addBody(projectile)
        projectile.isSensor = true
        projectile.isFixedRotation = true
        
        --> 0 = left; 1 = right
        local chooseLocation = math.random(0, 1)
 
    projectile.y = 421
    projectile.x = (-projectile.width/2)+chooseLocation * (display.contentWidth+projectile.width)
    projectile:applyLinearImpulse(.2-(chooseLocation*.4), -math.random(3,5)/10,projectile.x,projectile.y)
    print("Shooting a " .. projectileImages[random])
    return projectile
end

How can I use that simplified code using these animated sprites? I tried to do it myself but failed. :(

1
2
3
4
5
6
        local projectilesheet = sprite.newSpriteSheet("visuals/game_projectiles.png", 48, 48)   
        local projectileset = sprite.newSpriteSet(projectilesheet, 1, 18)
        sprite.add (projectileset, "coinsilver", 1, 6, 250, 0)
        sprite.add (projectileset, "coingold", 7, 6, 250, 0)
        sprite.add (projectileset, "rock", 13, 6, 250, 0)
        projectile = sprite.newSprite(projectileset)

Hm I don't know. Haven't been using spriteSheets yet, but a modified version of Jonathan Beebes BeebeGame Class!

I guess there's a way to randomly use a sprite. I don't know if you can give it physic properties though.

Maybe someone else can help you :/ Sorry

Does anyone know how to do it using the provided code above?

Although everyone tries to offer as much support as they can in some cases you may be better off going with premium support. Link: http://www.anscamobile.com/corona/support/

It's aimed at people who want code debugged or code written for them.

Peach :)

I did it! Now, I'm trying to get it so that the when the pig collides with the coins, it gets rid of the coins. I'm not sure why this doesn't work. Any ideas?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function createPig()
        local pigsheet = sprite.newSpriteSheet("visuals/game_pig.png", 96, 96)  
        local pigset = sprite.newSpriteSet(pigsheet, 1, 6)
        sprite.add (pigset, "pigmleft", 1, 3, 250, 0)
        sprite.add (pigset, "pigmright", 4, 3, 250, 0)
        pig = sprite.newSprite(pigset)
        pig:setReferencePoint(display.TopLeftReferencePoint);
        pig.x = display.contentWidth / 2 - 48
        pig.y = 349
        function collectProjectile(event)
                if(event.phase == "ended") then
                        if(event.other.type == "coinsilver") then
                                event.other:removeSelf()
                                print("Silver Coin!")
                        elseif(event.other.type == "coingold") then
                                event.other.removeSelf()
                                print("Gold Coin!")
                        elseif(event.other.type == "rock") then
                                event.other.removeSelf()
                                print("Rock!")
                        end
                end
        end
        pig:addEventListener("collision", collectProjectile)
end
function createProjectiles()
        local projectilesheet = sprite.newSpriteSheet("visuals/game_projectiles.png", 48, 48)   
        local projectileset = sprite.newSpriteSet(projectilesheet, 1, 18)
        sprite.add (projectileset, "coinsilver", 1, 6, 250, 0)
        sprite.add (projectileset, "coingold", 7, 6, 250, 0)
        sprite.add (projectileset, "rock", 13, 6, 250, 0)
        projectile = sprite.newSprite(projectileset)
        physics.addBody(projectile)
        projectile.isSensor = true
        projectile.isFixedRotation = true
        local chooseProjectile = math.random(0, 2)
                if (chooseProjectile == 0) then
                        projectile.type = "coinsilver"
                        projectile:prepare("coinsilver")
                        projectile:play("coinsilver")
                elseif (chooseProjectile == 1) then
                        projectile.type = "coingold"
                        projectile:prepare("coingold")
                        projectile:play("coingold")
                elseif (chooseProjectile == 2) then
                        projectile.type = "rock"
                        projectile:prepare("rock")
                        projectile:play("rock")
                end
        local chooseLocation = math.random(0, 1)
                projectile.y = 421
                projectile.x = -24 + chooseLocation * 848
                projectile:applyLinearImpulse(0.2 - (chooseLocation * 0.4), -math.random(3, 4) / 10, projectile.x, projectile.y)
        leftButton:toFront()
        rightButton:toFront()
    return projectile
end

Your collision function isn't quite right. Take a look at the Collision Detection part of Corona For Newbies Part 4 on http://Techority.com - that should help.

Peach :)

I made a lot of progress just now, but my projectiles aren't spawning correctly.

1) You can see them when they're off the screen.
2) The right side spawns inside the screen while the left doesn't. I want both to spawn outside.

1
2
3
4
        local chooseLocation = math.random(0, 1)
                projectile.y = 300
                projectile.x = -24 + chooseLocation * 828
                projectile:applyLinearImpulse(0.2 - (chooseLocation * 0.4), -math.random(0.75, 3.475) / 10, projectile.x, projectile.y)

Anyone?

Spawn them further off the screen, that's all.

Peach :)

So it that the only option to make them not show up when they're off screen?

I fixed the spawning inside the screen part, but both the main character and the projectiles can be seen when they're supposed to be off screen.

When they are really offscreen, you shouldn't be able to see them on the screen.
When they aren't far enough, put them far enough.
If they should start invisible, set them to isVisible = false.

Also why did you change

projectile.x = (-projectile.width/2)+chooseLocation * (display.contentWidth+projectile.width)

? Wasn't this working for you?
It should actually position the projectiles exactly offscreen touching the screen on the outside.

When I mean off screen, I mean greater than 800 and less than 0 on the X axis. Are you guys suggesting I just spawn them outside of the phone's viewing area?

Or, I could just make the game stretch to fit the screen in the config.

And I just filled in the thing Fanta wrote with the values that it equates to, but it turns out I screwed up on that. Now it's fixed.

So, is there any other way to avoid images showing when they're off screen?

Basically, is there a line of code that makes portions of images invisible, because my main character teleports to the other side if it goes so far off the screen, similar to Pac-Man.

Anyone know?

views:1758 update:2011/11/25 8:45:21
corona forums © 2003-2011