Log In  

Hello, I am relatively new to Pico-8 (and programming in general) and am trying to create a "Starfield" Effect, as one would see in games like Galaga. I have created a single pixel that travels, but apart from creating many variables and basically duplicating my code, I can't see how I can multiply the pixels. I know there is an easy way, but I have not discovered it. My code is below.

x = 0
y = 0
xthing = false

function _update()
if xthing == false then
 x = rnd(128)
 y = 0
 xthing = true
 end

if xthing == true then
 y = y+1
 end

if y == 128 then
 xthing = false
 end
end

function _draw()
cls()
pset(x,y,7)
end

Thanks =)

P#53370 2018-06-08 01:47 ( Edited 2018-06-09 14:19)

:: Davbo

So lua has tables of information that you can create and loop through. You can then add and remove things from the tables. So I'm gonna try rewrite your code for tables (though I'm just on my phone so may not be perfect and the capitalisation is all over the place so you'll have to fix that.)

--empty table for stars
Stars={}

--instead of global decelerations, let's make a function that adds an entry to a table with some inputs
function createStar(X,y)
Star={}
Star.x = x
Atar.y = y
Add(stars,star)
End

Function _init()
--makr a bunch of stars using our new function. I'm using the same inputs you were.
For I=0,8 do
 CreateStar(end(128),0)
End
End

function _update()
--update each star

For star in all(stars) do
 Star.y = star.y+1

if star.y == 128 then
 --maybe do something else in here, could set the star y back to 0, or randomise the X again?
 Star.y=0
 end
End
end

function _draw()
cls()
--draw all stars
For star in all(stars) do
pset(star.x,star.y,7)
End
end

I realise I'm introducing a lot of new concepts - read through the manual for _init, tables and looping functions to get what's going on a little more. Sorry for the terrible formatting! Hope this helps.

P#53372 2018-06-08 02:38 ( Edited 2018-06-08 06:38)
:: Kepler

So, I edited it a bit, as there were a couple syntax errors. So, I don't understand what the tables are actually doing, as still only one pixel is moving. Can you explain how I can use the tables to draw multiple stars at once? Also, the X value is not randomizing. I'm using Z which Is probably the reason... My code is below. =)

--empty table for stars
stars={}

--instead of global decelerations, let's make a function that adds an entry to a table with some inputs
function createstar(x,y)
star={}
star.x = x
star.y = y
add(stars,star)
end

function _init()
--makr a bunch of stars using our new function. i'm using the same inputs you were.
for i=0,8 do
 createstar (z,0) --Changed this one, it was being strange....
end
end

function _update()
--update each star

for star in all(stars) do
 star.y = star.y+1

if star.y == 128 then
 --maybe do something else in here, could set the star y back to 0, or randomise the x again?
 star.y=0
 z = rnd(128)
 end
end
end

function _draw()
cls()
--draw all stars
for star in all(stars) do
pset(star.x,star.y,7)
end
end
P#53381 2018-06-08 11:50 ( Edited 2018-06-08 15:54)
:: Davbo

Hey I'm at a computer now so hopefully can explain better.

Okay so there's a few things to cover. Firstly - what is a table.
A table is a group of variables.

Let's look at the first part of the create start function

star={}
star.x = x
star.y = y

So firstly I create an empty table. I then add two values to the table, x and y. Now if you were to do
print(star.x,0,0)
it would print the x value passed in. that x value belongs to the star table.

Okay, so next we have the loop for creating stars.

for i=0,8 do
 createstar (z,0)
end

If you check the manual, what the for is doing is running this piece of code several times. It runs it once when i=0, then again when i=1, then again when i=2 until i=8 then stops running it. Every time we run it we create a new star with a passed in x and y co-ordinate.
This is why your change makes it look like there is only one pixel - you're passing in the same x value called z for every star. So they are all drawing on the exact same position. that's why I had rnd(128) there, so the x position of each star is different. (You'll probably want to randomize the y input in the same way).

Okay, lets now go back to the createstar function. After it makes a new star with an x and a y is goes add(stars,star). stars is a different table that we are adding our star table to.
so we now have
stars --contains several--> star --each of which contain--> x,y

Right?
So in your first post you'd say you didn't know how you'd do it without loads of variables. We are essentually still making loads of variables, but we are automating the creation of them and storing them in an easy to manage way!

So, okay, now we have a table of stars. How do we use them? There's lots of ways to loop through a table but I've gone for
for star in all(stars) do
So what this is doing is going through the stars table and returning a 'star' that represents an element in that table. (we could have called it anything here - could have gone for for butt in all(stars) then a butt would have represented an element in the table).

Now I'm applying the same logic you originally posted on each of the star's x and y cordinates to get them to move in the same way you initially designed, and them drawing them in the same way as well.

So, now that I've completely confused you, here's the code again with more comments to explain it in another way

--instead of global decelerations, let's make a function that adds an entry to a table with some inputs
function createstar(x,y)
 --create a new star table.
    star={}
 --assign the passed in x and y values to it
    star.x = x
    star.y = y
 --save that star to the stars table.
    add(stars,star)
end

--_init() is called when the cart first starts. It's considered tidier to keep all your declerations in here.
function _init()
 --empty table for stars
    stars={}

 --make a bunch of stars using our new function. i'm using the same inputs you were.
 --so this for i=0,8 do boils down to 'run this 9 times'
    for i=0,8 do
  -- please make a star with a random x coord and a y coord of 0.
  -- so running this 9 times is going to make 9 stars all starting at the top of the screen but with random x values
     createstar(rnd(128),0)
    end
end

function _update()
 --update each star
 for star in all(stars) do

  -- your logic!
  star.y = star.y+1

    if star.y == 128 then
    --move back to the top of the screen
    star.y=0
  end
 end
end

function _draw()
 cls()
 --draw all stars
 for star in all(stars) do
  --again this is just what you were doing, but x and y are now stored on the star table
    pset(star.x,star.y,7)
 end
end

You said that with the random it looks weird. What you origonally wrote had one dot moving down the screen. With the rnd(128) you now have several dots moving down the screen. What were you expecting to happen?

P#53383 2018-06-08 12:48 ( Edited 2018-06-08 16:48)
:: Kepler

Thanks for all your help!

Ok, so the random you supplied had a typo, which resulted in it saying end. When I tried to fix the syntax errors, I ended up replacing it with

createstar (z,0)

It was not randomizing. After replacing that with your rnd, it works much better.

Now, is there a way I can slow it to only run so many times? There are way too many stars. How can I thin out the stars? I could use a variable to switch back and forth so it only runs the create star function every other update, but is there a better and simpler way?

Also, it runs and runs until the game runs out of memory, is there a way to cap the number of stars produced? Like delete the star from the table after it reaches the bottom of the screen? (it is saving the star's location in the table, right?)

Thanks!

P#53394 2018-06-08 18:39 ( Edited 2018-06-08 22:40)
:: Kepler

After some more experimentation, adding

del(stars,star)

prevented the memory filling up. Thanks for the help!

P#53396 2018-06-08 20:30 ( Edited 2018-06-09 00:30)
:: Davbo

Oh yeah, oops. Rnd auto corrected to end on my phone, sorry about that!
Glad you found a solution! There are lots of ways you could do it from here on. Maybe give each star a random colour as well, different y values, make them move in different patterns, etc . Maybe try out some sin waves even! Lots of fun stuff to experiment with.
Sounds like you're experimenting with different amounts of stars already - my code was making 9 stars in init and only using them. Remember the for I=0,8? You could reduce the 8 to a smaller number to get that to make less stars.
Glad I could help! 😊

P#53407 2018-06-09 04:00 ( Edited 2018-06-09 08:03)
:: Kepler

Thanks a lot!

P#53412 2018-06-09 10:19 ( Edited 2018-06-09 14:19)

[Please log in to post a comment]

Follow Lexaloffle:        
Generated 2020-06-06 11:20 | 0.015s | 2097k | Q:26