Omnimaga
Calculator Community => Other Calc-Related Projects and Ideas => TI Z80 => Topic started by: JWinslow23 on January 25, 2014, 08:22:52 pm
-
This is a demo of snow falling that I made. Basically, press any key to exit.
There is no melting yet. I'm still working on it.
If you want more information, ask me.
(http://img.ourl.ca/SnowDemo.gif)
-
How do you detect snowflake collision?
-
I have all of the coordinates in Y.X format (i.e. Y=7 and X=12 would be 7.12), and each time I need to know if a snowflake is in a spot, I check sum(L1=Y+.01X). If it's 1, a snowflake is in that spot.
-
Hmm, you could use a matrix (it uses indices the same as pixel coords or homescreen coordinates, so "Y" then "X").
This way, the program doesn't start to slow down as more snow flakes are added. Basically, just create an 8*16 matrix (it will be huge, being the size of a 128 element list). Then you can just check if a snow flake is already in a spot as if you were reading homescreen coordinates:
[A](Y,X
This might speed things up a bit (not sure).
-
This looked kinda simple, but I liked how it had collision detection for snowflakes.
-
Hmm, you could use a matrix (it uses indices the same as pixel coords or homescreen coordinates, so "Y" then "X").
This way, the program doesn't start to slow down as more snow flakes are added. Basically, just create an 8*16 matrix (it will be huge, being the size of a 128 element list). Then you can just check if a snow flake is already in a spot as if you were reading homescreen coordinates:
[A](Y,X
This might speed things up a bit (not sure).
You're right! Now, it will only take 128 iterations of a For( loop (plus a little bit extra time) to move and display the snowflakes, not to mention to extra size of a matrix! :P
Besides, I think it's pretty fast already.
-
Haha, touché :P
Also, what rules are you using? Like, do you move down 1/2 the time, and move left/right 1/4 of the time?
-
What I do, in pseudocode:
:If a snowflake can move down,
:Then
::Erase the snowflake there.
::Change the snowflake coordinates to that spot.
::Calculate random direction between left, right, or staying put.
::If the snowflake can move there,
:::Change the snowflake coordinates to that spot.
::Draw the snowflake where it belongs.
:End
-
Judging by your screenshot, your program would actually run a lot faster with a matrix, since it seems like you are only keeping track of one snowflake at a time. I didn't realize that until just now as I was about to post my attempt x.x Mine handles multiple flakes at a time :/
EDIT: Oops, now I see that it does handle multiple flakes. I am too sleepy.
-
I haven't checked both your code, but does your programs run through a list of numbers, looping through it using a For loop? Because the fastest way would probably be to repeat code for each snowflake and use no For loop. It would be a brutal, size-inefficient and bruteforce approach, though (which I think I demonstrated in a TI-BASIC Phoenix clone once, and some people probably remember the infamous screen inverter by Netham45). :P
If 1=[A](1,1:Output(1,1+B,"M
If 1=[A](1,2:Output(1,2+B,"M
If 1=[A](1,3:Output(1,3+B,"M
If 1=[A](1,4:Output(1,4+B,"M
If 1=[A](1,5:Output(1,5+B,"M
If 1=[A](2,1:Output(2,1+B,"M
If 1=[A](2,2:Output(2,2+B,"M
If 1=[A](2,3:Output(2,3+B,"M
If 1=[A](2,4:Output(2,4+B,"M
If 1=[A](2,5:Output(2,5+B,"M
If 1=[A](3,1:Output(3,1+B,"M
If 1=[A](3,2:Output(3,2+B,"M
If 1=[A](3,3:Output(3,3+B,"M
If 1=[A](3,4:Output(3,4+B,"M
If 1=[A](3,5:Output(3,5+B,"M
Not that I really recommend doing this, but just in case someone really wanted to make his program as fast as possible at any cost. :P
-
Mine draws the flakes when they are newly added at the top of the screen, then it searches the matrix for snowflakes that can move down. It erases those ones and draws their new position.
Also, DJ_O, you didn't need the "1=" part of those If statements./me runs
The way I test for flakes that can move is I store the matrix rotated so that column 1 is the first row of snow flakes. Then each snow flake is represented by the column number it is in (so if it is homescreen column 6, it has a 6 in the matrix). My code is then:
Matr>list([A],8,L2 ;get the last row
For(A,7,1,-1
Matr>list([A],A,L1
L1*(L1 and not(L2→L3 ;This checks if anything in L1 can move down into L2
;"not(L2" leaves a 0 where there is already a flake, else 1 if empty
;Then "L1 and not(L2" leaves a 1 if there is a snowflake above an empty space
L1-Ans→L1 ;remove the snowflakes that can move down from L1
While max(L3
max(L3→B ;location of the snowflake furthest to the right
0→L3(Ans ;remove the snowflake from L3, the list of moveable flakes
0→[A](B,A ;remove it from the matrix
Output(A,B," ;Erase it
min(16,max(1,B+1-2int(2rand ;randomly move left/right
If L2(Ans ;check if the space is occupied
B
Ans→[A](Ans,A+1 ;write the snowflake to the new coordinate
Output(A+1,Ans,"*
End
L1→L2 ;now This row becomes the new lower row
End
-
Pretty neat little demo here. :)
-
Yup, i like the falling snow too.
Maybe you could speed it a bit up by using axe and make it use pixels, more frequentley, that may look like an epic snow storm IMO :)
-
Mine draws the flakes when they are newly added at the top of the screen, then it searches the matrix for snowflakes that can move down. It erases those ones and draws their new position.
Also, DJ_O, you didn't need the "1=" part of those If statements./me runs
The way I test for flakes that can move is I store the matrix rotated so that column 1 is the first row of snow flakes. Then each snow flake is represented by the column number it is in (so if it is homescreen column 6, it has a 6 in the matrix). My code is then:
Matr>list([A],8,L2 ;get the last row
For(A,7,1,-1
Matr>list([A],A,L1
L1*(L1 and not(L2→L3 ;This checks if anything in L1 can move down into L2
;"not(L2" leaves a 0 where there is already a flake, else 1 if empty
;Then "L1 and not(L2" leaves a 1 if there is a snowflake above an empty space
L1-Ans→L1 ;remove the snowflakes that can move down from L1
While max(L3
max(L3→B ;location of the snowflake furthest to the right
0→L3(Ans ;remove the snowflake from L3, the list of moveable flakes
0→[A](B,A ;remove it from the matrix
Output(A,B," ;Erase it
min(16,max(1,B+1-2int(2rand ;randomly move left/right
If L2(Ans ;check if the space is occupied
B
Ans→[A](Ans,A+1 ;write the snowflake to the new coordinate
Output(A+1,Ans,"*
End
L1→L2 ;now This row becomes the new lower row
End
Can you give me the full code?
-
From Source Coder:
{16,8->dim([A]
DelVar EE[A]→[A]
ClrHome
2→S
Repeat E>=128 or getKey=45
For(B,1,S
Repeat not([A](Ans,1
randInt(1,16
End
Ans→[A](Ans,1
Output(1,Ans,"*
E+1→E
If E=128
S→B
End
Matr>list([A],8,L2
For(A,7,1,-1
Matr>list([A],A,L1
L1*(L1 and not(L2→L3
L1-Ans→L1
While max(L3
max(L3→B
0→L3(Ans
0→[A](B,A
Output(A,B,"
min(16,max(1,B+1-2int(2rand
If L2(Ans
B
Ans→[A](Ans,A+1
Ans→L2(Ans
Output(A+1,Ans,"*
End
L1→L2
End
End
EDIT: Forgot a line.
-
Sometimes, with your version, snowflakes appear to merge with other snowflakes. And it usually ends before the entire screen is filled. Just saying.
-
Uh, yup, I forgot to add one line:
Ans→L2(Ans
This should be inserted before (or after, doesn't really matter) the line redrawing the new location of the snowflake.
-
Works, except for one thing...
When there is only one opening in the top spot, it freezes. I recommend you just generate a snowflake position, and if a snowflake isn't there already, then and only then can you add it as a snowflake.
-
It shouldn't freeze... I mean, theoretically, with a perfect random number generator it can, but the probability that it hasn't found an opening after n iterations is (15/16)n.
It has always worked pretty quickly for me at finding the opening. Also, my program exits when the screen is full (or clear is pressed).
-
Let me explain it to you in the least complicated way I can...
The RNG makes a snowflake in two unfilled positions at the top.
Near the end, these positions become filled.
When there is only one unfilled position, it finds that position, makes a snowflake there, then checks for another unfilled position.
The problem is, there is no unfilled position.
So it keeps generating forever.
-
It generates 2 each cycle by default.
There are 128 positions.
This will never happen :P
And in case you wanted to do a number that doesn't evenly divide into 128, this piece of the code allows exiting as soon as 128 flakes are on screen:
E+1→E
If E=128
S→B
That exits the For() loop to prevent generating any more snow flakes, then if you look at the main Repeat loop conditions:
Repeat E>=128 or getKey=45
This exits if [Clear] is pressed or E is 128 or larger. E counts how many flakes have been drawn.
-
Really? Cause it has. :P
Try setting 100 as rand before starting the program. You'll see what I mean.
(http://img.ourl.ca/XedaSnow.gif)
-
That appears to be a bug with collision detection. Feel free to try to figure it out :P
Theoretically, the top spots should only be full if all the rest below are full.
-
And they are. :P
Really, the demo "fills" a top spot every iteration. Then, on the next iteration, it falls down.
If you wanna know how to fix it, I know.
-
[discussion in IRC]
[time passes]
Here is my program, it just does one at a time for competition and it spits out a new flake at each iteration with probability 1/2.
-
OK, it's settled.
Xeda and I are going to have a competition.
The rules:
We must modify our codes to be almost similar, except for mine using lists and hers using matrices. (i.e. either I generate my snowflakes one after another, or she generates hers at random times)
We must each test 3 values of rand: 0, 10, and 100.
We shall make another program in this format and run it:
startTmr -> Z
prgmOURSNOW
Disp checkTmr(Z
Whoever has a lower value for most of them is the winner.
-
Do you generate a new snowflake with probability .5 ?
-
int(2rand has a .5 probability of being 1 or 0, right? So yeah.
-
Yep, that is what I am using. By the way, I am just running through the program 3 times and timing it with the given rand seeds. (I am doing it all in one program, though)
-
So am I.
Here's what I got.
I dunno, it's really at the mercy of the generator. And how many times you use it.
-
This topic has kind of made me want to make one. :P Maybe I'll give it a try for giggles. :D
-
Go for it! ;D
-
Mine draws the flakes when they are newly added at the top of the screen, then it searches the matrix for snowflakes that can move down. It erases those ones and draws their new position.
Also, DJ_O, you didn't need the "1=" part of those If statements./me runs
Darn I knew I missed something. I optimized it since it was much worse, but I forgot that part x.x
-
Would it be possible to make snow even out so that it does not develop into pillars which then have an even higher chance of snow settling on them and growing even taller?
-
Possible.
-
That's pretty cool for BASIC. My BASIC skills are... Well... Much more basic ;)
-
Thanks. I got the idea from Builderboy.
-
Builderboy made a particule simulation post in his physics lesson thread, I reccomend you check it out (http://ourl.ca/4279/169816). You can also search online for how to program your automaton to simulate realistic snowflakes.
I might try doing this in Axe, see how that comes out.
-
My only snow (actually sand) simulation attempt ever was this (in Axe):
(http://www.omnimaga.org/index.php?action=dlattach;topic=1532.0;attach=1356;image)
However, it did not allow snow to pile up, so it was more for eye candy purposes. Also, the snow seemed to move up instead of down.
-
Seems slightly strange that some of the snowflakes sort of just get stuck in mid air. Is this a gif issue or is it meant to be there?
-
That is actually pretty cool O.o Almost looks like old TV snow... If the pixels rotated on an 8x8 buffer with a grid instead of scrolling, it would be a pretty helpful snippet for a lot of Axe Parser games (although I'm sure someone has already done so) :/
Seems slightly strange that some of the snowflakes sort of just get stuck in mid air. Is this a gif issue or is it meant to be there?
It doesn't seem to get stuck for me... I think it is a gif issue :) You might try reloading? IDK