Author Topic: Physics Lessons  (Read 34013 times)

0 Members and 1 Guest are viewing this topic.

Offline DJ Omnimaga

  • Former TI programmer
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55858
  • Rating: +3151/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • DJ Omnimaga Music
Re: Physics Lessons
« Reply #45 on: May 16, 2010, 10:08:56 pm »
A text display lib using custom fonts in Axe would be cool

Nice to hear this is still alive btw :)
In case you are wondering where I went, I left Omni back in 2015 to form CodeWalrus due to various reasons explained back then, but I stopped calc dev in 2016 and am now mostly active on the CW Discord server at https://discord.gg/cuZcfcF



Official Website |T-Shirt store | Reverbnation | Facebook | Youtube | Twitter | Spotify

Offline Builderboy

  • Physics Guru
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5673
  • Rating: +613/-9
  • Would you kindly?
    • View Profile
Re: Physics Lessons
« Reply #46 on: January 31, 2011, 09:28:57 pm »
Cellular Automata

Cellular Automata is described by a grid of pixels, where each pixel has a certain amount of rules determining what happens to it.  The Game Of Life is a great example of this type of simulation, but how can this be used for physics?  Using pixel based rules is a great way to simulate large scale effects that would normally be difficult to program.  Things like fluid dynamics, sand, fire, and acid, sounds complicated?  Well all of these things are possible with cellular automata, and will be covered in this tutorial on how to use pixel rules to simulate all of your effects needs.

We are going to base our tutorial off of the water simulation, since that is a simulation that will cover the basics of everything else to come.  Water sounds like an extremely difficult thing to implement on a calculator; it’s so dynamic and hard to define!  How would you even go about storing the data?  Well cellular automata provides a great method for us to solve this.  First, we need to come up with our expectations:

1) The water must be affected by gravity
2) Water must flow


Now that we have our expectations, we need to find some rules that we can apply to our pixels.  In our simulation, each pixel will represent a small part of water, and each pixel will move corresponding to our rules.  I would like to introduce a 3rd rule:

3) Pixels cannot intersect eachother!

This is very important!  If one pixel moves itself onto another pixel, those pixels merge and become a single pixel, and we will lose a small piece of water.  This is fine if that’s what you want, but we want our water to stay at a constant volume, we don’t want to lose any pieces of water.  So no matter what, if a pixel moves, it must always move to an empty space!

With this, we can devise some simple rules:

Code: [Select]
Rule # Condition Action
1 Space below empty Move down
2 Spaces to the sides empty Move either left or right
3 Single empty space to a side Move into that empty space

These rules are followed top to bottom.  This means that first rule 1 is checked, if the condition is satisfied, we do the action.  If not, we move onto the next rule and continue.  If no conditions are satisfied, the pixel stays where it is and we move onto the next pixel.

That’s it!  Those are the rules!  Simple rules right? And yet they can yield surprisingly advanced responses…



Pretty impressive eh?  Let’s look at some other sample rules that we could apply:

Sand:
Code: [Select]
Rule # Condition Action
1 Space below empty Move down
2 Space to the bottom-right/left empty Move to that empty space

Fire:
Code: [Select]
Rule # Condition Action
1 Space above is empty Move up
2 Space above is filled Move left/right
3 rand<.05 End life of this pixel

Acid:
Code: [Select]
Rule # Condition Action
1 Space below is not Acid Move down
2 Spaces to the sides is not acid Move either left or right
3 Single non-Acid space to a side Move into that empty space

Note that these are not the only way to achieve the effects desired, this is not a precise art, and many different rules can be applied to achieve many different effects, the best way to find out what works is to try everything yourself!

How To Use It:

Well that’s nice, how do I implement this in my program?  Well, it would be tempting to rely on pixel commands alone, but a more elegant solution is to have a list of pixel locations, and to loop through them.  This allows for better speed and a larger area of simulation.

Here is some sample code in Axe format:

Code: [Select]
For(F,0,N For N+1 Pixels
D*2+L1->L Find their location in L1
{L}->X X location in first Byte
{L+1}->Y Y location in second bytes
Pxl-Off(X,Y

If Pxl-Test(X,Y+1) If ground below is solid
  Rand^2*2-1->A Choose a random direction
  !If Pxl-Test(X+A,Y If that direction is empty
    X+A->X Move there
  Else!If Pxl-Test(X-A,Y Else, if the opposite direction is empty
    X-A->X Move there instead
  End
Else
  Y+1->Y If all else fails and ground below is empty, move down
End

Pxl-On(X,Y
X->{L}
Y->{L+1}
End
Note that this code won’t work by itself; you still need a way to put the pixels into L1, and to remove them.  You will also need to create the environment and everything, but this I leave up to you.

What to look out for:

I presented an option to store the pixels in an array, which takes a fair amount of memory.  It is tempting to just work off of the screen as a buffer, and loop through every pixel on it, but there is an inherent problem with this.  Not only does it limit the size of your screen, but the fact that you are either going to pass through the screen left to right, or right to left, introduces a bias into the simulation that might make fluids tend to flow left, or for smoke to drift right.  The results are unpredictable, and unless you know that the rules you introduce will not interfere, and that you have a small enough space to keep speed up, you should stick with the pixel buffer.

Offline squidgetx

  • Food.
  • CoT Emeritus
  • LV10 31337 u53r (Next: 2000)
  • *
  • Posts: 1881
  • Rating: +503/-17
  • rawr.
    • View Profile
Re: Physics Lessons
« Reply #47 on: January 31, 2011, 09:37:07 pm »
O.o great explanation!! The screenie is amazing too. I'll be sure to remember this whenever I want to do something physics based XD

Maybe I'll try and make a powdertoy....sorry qwerty :P nah I don't know the chem behind the he interactions of substances... Meh idk
« Last Edit: January 31, 2011, 09:54:05 pm by squidgetx »

Offline Builderboy

  • Physics Guru
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5673
  • Rating: +613/-9
  • Would you kindly?
    • View Profile
Re: Physics Lessons
« Reply #48 on: January 31, 2011, 09:54:24 pm »
Thanks :D I'm about to come out with a second about advanced pixel testing as well :) Building my way up to collision :P

EDIT: Interactions could simply be handled by rules :) Like if a piece of sand touches a piece of fire, it could become glass, or maybe become fire itself.  You would be free to decide how all the objects react and interact, independent of chemistry :)
« Last Edit: January 31, 2011, 09:55:59 pm by Builderboy »

Offline Builderboy

  • Physics Guru
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5673
  • Rating: +613/-9
  • Would you kindly?
    • View Profile
Re: Physics Lessons
« Reply #49 on: January 31, 2011, 10:00:54 pm »
Virtual Pixel Testing

We all know about the basic command Pxl-Test() right?  It tests a pixel on the screen/buffer and returns whether or not the pixel is on or off.  This seems simple enough, but actually can be used to provide some fairly quick alternatives to using matrix based collision detection.  Not only are we eliminating the need to a matrix, but by simply drawing to the screen, we have already generated the data we will need for collision.  Eliminating the Matrix, as well as the time needed to spend writing to it, mean that pxl-testing is a formidable way to speed up your Basic or Axe game!

But, there are some issues with this.  What happens when your game requires tiles that might not be solid black?  We run into problems fast if we have complicated graphics, and have to resort to complex trickery in order to get collision to work.  One option is to have a single pixel in each tile of a tilemap be the indicator on whether or not the tile is filled or not, but this is hardly a perfect solution.  What if we wanted to be able to detect alternate things?  Like for instance certain tiles might slow down your character, or make them enter a swimming animation. Certainly we can’t assign properties to all of the pixels of a sprite, that would be both slow and limiting in the graphics we could choose.  The solution lies in Virtual Pixel Testing.

A virtual pixel test is a test that behaves like a pixel test, but returns a value that doesn’t have to do with the pixels color.  Instead, it has to do with any attributes that the pixel has.  If we make this simple, we can have the virtual test determine whether or not the pixel is solid or not, independent of its color.  We could even expand this to return a value that relates to something like friction or temperature.  But how to implement such a function?  In this tutorial, I am going to be focusing on Tile Based Virtual Pixels, and Mask Based Virtual Pixels.

Tile Based Virtual Testing:

Say you have a tilemap, for any sort of game, sidescroller, top down, platform, you name it.  Chances are some of your tiles are going to need to be solid.  Now up until now, you have might gone by using some tricky byte testing mixed with modular arithmetic, wishing it were as simple as using a pxl-test() command.  Well, using virtual tests, it can be just as simple:

Code: [Select]
Lbl TST
{r2/8*W + (r1/8)+L1}
Return

Given a byte based matrix array located in L1, that represents a tilemap with width W, this function will return the tile number associated with any given pixel.  Note that r2/8*W is essential, r2*W/8 would not work.  

This simple function, coupled with clever ordering of your tiles, can make for very simple collision checking.  When you design your game, order the tiles so that all the solid ones come first, followed by all of the empty tiles.  This way, checking for a solid tile is as simple as a comparison test.  

Code: [Select]
Lbl TST
{r2/8*W + (r1/8)+L1}<N
Return

Where r1 is the X position, r2 is the Y position, N is the tile number where your empty tiles start, and L1 is the location of your matrix data buffer.

Using this routine will allow you to test a pixel and either get the tile number associated with that pixel (which could tell you any number of things) or test whether or not the tile is solid.  Using this information for accurate physics is now easier, and will be addressed in a later chapter.

Masked Virtual Buffer Testing:

This is all fine and dandy for tile based physics, but what about tiles that are not square?  Say you were making a sonic game, and you needed ramps and loops and things like that?  How could you modify this code such that it would work correctly?  The answer lies in Masks.

All a mask is, is an alternate sprite that tells you where your main sprite is solid.  If this is your normal sprite:

Code: [Select]
-------O
------OO
-----O-O
----O--O
---OOOOO
--O----O
-O-----O
OOOOOOOO

A simple ramp like sprite, then this is your sprite mask:

Code: [Select]
-------O
------OO
-----OOO
----OOOO
---OOOOO
--OOOOOO
-OOOOOOO
OOOOOOOO

Note that your regular sprite can be any design it wants to be, and your mask is black where it is solid and white where it is not.  The code for testing this is as follows:

Code: [Select]
Lbl MSK
{{r2/8*W+(r1/8)+L1}*8+(r2^8)+Str1}e r1
Return

Where r1 is your X position, r2 is your Y position, W is the width of your tilemap (in tiles), L1 is the location of your matrix data buffer, and Str1 is the start of your Mask Sprite table.

Your mask sprite table is identical to your sprite table, but instead of normal sprites, it includes the masked sprites.  This code will return the value of the bit in the mask sprite where your pixel is located, which can make for pixel based physics and terrain, in a tile based world.

What to watch out for:

Make sure that instead of using a variable W, use a constant!  Also try to make sure it is a power of 2, as this makes for very quick and simple multiplication.  You can further speed up both subroutines by changing the /8 into /2/2/2, although this will create an increase in size.  Also, the e in the mask operation is the euler's constant e found on the divide button.

Also note that all of the code in this lesson is based on the assumption that your pixel coordinates are based off of the upper left hand corner of your matrix, and that your matrix follows the left-to-right moving-down standard.  It also assumes you are using 8x8 sprites, although 16x16 sprites would not be difficult to accommodate.
« Last Edit: September 06, 2011, 10:36:51 pm by Builderboy »

Offline ruler501

  • Meep
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2475
  • Rating: +66/-9
  • Crazy Programmer
    • View Profile
Re: Physics Lessons
« Reply #50 on: January 31, 2011, 11:02:47 pm »
this is wonderful it makes me want to go write a game. I'm amazed at how simple some of these things end up being.
I currently don't do much, but I am a developer for a game you should totally try out called AssaultCube Reloaded download here https://assaultcuber.codeplex.com/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCM/CS/M/S d- s++: a---- C++ UL++ P+ L++ E---- W++ N o? K- w-- o? !M V?
PS+ PE+ Y+ PGP++ t 5? X R tv-- b+++ DI+ D+ G++ e- h! !r y

Offline Builderboy

  • Physics Guru
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5673
  • Rating: +613/-9
  • Would you kindly?
    • View Profile
Re: Physics Lessons
« Reply #51 on: February 01, 2011, 12:18:55 am »
Everything is simple if it is explained in the right way :) I'm glad my tutorials are helping you :D

Offline DJ Omnimaga

  • Former TI programmer
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55858
  • Rating: +3151/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • DJ Omnimaga Music
Re: Physics Lessons
« Reply #52 on: February 01, 2011, 12:28:08 am »
Looks great. Shouldn't this be in the Axe sub-forum, though? Physics in BASIC would be kinda slow ???
In case you are wondering where I went, I left Omni back in 2015 to form CodeWalrus due to various reasons explained back then, but I stopped calc dev in 2016 and am now mostly active on the CW Discord server at https://discord.gg/cuZcfcF



Official Website |T-Shirt store | Reverbnation | Facebook | Youtube | Twitter | Spotify

Offline Builderboy

  • Physics Guru
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5673
  • Rating: +613/-9
  • Would you kindly?
    • View Profile
Re: Physics Lessons
« Reply #53 on: February 01, 2011, 12:33:10 am »
Good idea, I think i'll move it.  Some of the ideas are applicable, but its really only for Axe and Asm.  Do you think I should sticky it?
« Last Edit: February 01, 2011, 12:34:37 am by Builderboy »

Offline ruler501

  • Meep
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2475
  • Rating: +66/-9
  • Crazy Programmer
    • View Profile
Re: Physics Lessons
« Reply #54 on: February 01, 2011, 09:03:03 am »
Since i don't know axe, asm, or basic I'll try to use these for a python game. Physics this will be interesting
I currently don't do much, but I am a developer for a game you should totally try out called AssaultCube Reloaded download here https://assaultcuber.codeplex.com/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCM/CS/M/S d- s++: a---- C++ UL++ P+ L++ E---- W++ N o? K- w-- o? !M V?
PS+ PE+ Y+ PGP++ t 5? X R tv-- b+++ DI+ D+ G++ e- h! !r y

Offline Binder News

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 785
  • Rating: +46/-3
  • Zombie of Tomorrow
    • View Profile
Re: Physics Lessons
« Reply #55 on: February 01, 2011, 10:22:45 am »
Good idea, I think i'll move it.  Some of the ideas are applicable, but its really only for Axe and Asm.  Do you think I should sticky it?
Definitely sticky it.
Spoiler For userbars:







Hacker-in-training!   Z80 Assembly Programmer     Axe Programmer
C++ H4X0R             Java Coder                           I <3 Python!

Perdidisti ludum     Cerebrum non habes

"We are humans first, no matter what."
"Fame is a vapor, popularity an accident, and riches take wings. Only one thing endures, and that is character."
Spoiler For Test Results:





Offline XVicarious

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 485
  • Rating: +45/-28
  • I F**king Love Twisty Puzzles
    • View Profile
    • XVicarious
Re: Physics Lessons
« Reply #56 on: February 01, 2011, 06:57:52 pm »
I was about to make a game involving falling objects too builderboy. nice. This is gonna help.
God... I wish i could redo this marking quarter in Physics. Screwed me over... 69...

Offline AngelFish

  • Is this my custom title?
  • Administrator
  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3242
  • Rating: +270/-27
  • I'm a Fishbot
    • View Profile
Re: Physics Lessons
« Reply #57 on: February 01, 2011, 07:58:17 pm »
O.o great explanation!! The screenie is amazing too. I'll be sure to remember this whenever I want to do something physics based XD

Maybe I'll try and make a powdertoy....sorry qwerty :P nah I don't know the chem behind the he interactions of substances... Meh idk

My engine is quite different from what Builderboy is describing, although the rules themselves are similar, so it's okay.

On a side note, be careful about array bounds. If you overflow, you can cause a pretty severe crash. But, even more than that, applying the rules to a lot of particles takes a lot of processing power. Keep the number of objects to a minimum.
∂²Ψ    -(2m(V(x)-E)Ψ
---  = -------------
∂x²        ℏ²Ψ

Offline ruler501

  • Meep
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2475
  • Rating: +66/-9
  • Crazy Programmer
    • View Profile
Re: Physics Lessons
« Reply #58 on: February 03, 2011, 07:17:56 pm »
Another good one to go here I believe is projectile motion. To get it realistic and efficient frame by frame can be complicated(at least to me)
I currently don't do much, but I am a developer for a game you should totally try out called AssaultCube Reloaded download here https://assaultcuber.codeplex.com/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCM/CS/M/S d- s++: a---- C++ UL++ P+ L++ E---- W++ N o? K- w-- o? !M V?
PS+ PE+ Y+ PGP++ t 5? X R tv-- b+++ DI+ D+ G++ e- h! !r y

Offline Calcaholic

  • LV1 Newcomer (Next: 20)
  • *
  • Posts: 13
  • Rating: +2/-0
    • View Profile
Re: Physics Lessons
« Reply #59 on: February 03, 2011, 07:24:27 pm »
Do yout mean projectiles that are affected by gravity?
Otherwise I think that it would'nt be anything else than a routine like that (which is expressed in a general way):

Code: [Select]
loop
{
     [refresh position]
     [position+velocity]
}

Wouldn't it?

All in all doesn't projectile motion just include some of the tutorials that are already given?
(I ask dumb for my programming experiences are limitted to mostly personal experiments without any serious profession)
« Last Edit: February 03, 2011, 07:37:40 pm by Calcaholic »