3.6Misc
9.0
top
← prev up next →

py-fizzπŸ”— i

Fun with fizzics!

Py-fizz is a language for creating physics simulations and games. Compiles to Python and runs in the context of Pygame and Pymunk. But Racket is the compile-time language, and provides a purely functional API for doing awesome physics stuff.

Py-fizz is divided into two languages. The first is a higher-level one, used for creating levels and simulations out of pre-built gadgets: e.g. Bowling balls, balloons, motors, etc. Eg.:

(simulate
(wooden-level
(bowling-ball)))

[画像:image]

There is also a lower-level language for defining your own such gadgets. For example, the bowling-ball gadget might be defined as:

(define(bowling-ball)
(mass100000
(make-dynamic(h:bitmap"./imgs/bowling-ball.png"))))

These docs describe both the high and low level languages.

1Basic vocabularyπŸ”— i

Before we start, there are a few basic concepts.

First of all, everything in py-fizz is some kind of physical object. There are three basic kinds: cosmetic, dynamic, and static.

Cosmetic objects do not collide with anything. They are just for show.

Dynamic objects do collide. Also, they can move around.

Static objects also collide, but they do not move around.

There is one other kind of object, which is a "composite" object. This just means that the object is composed of more basic objects.

For example, the car object is composed of three wheels and a crate. The wheels and crate are all dynamic objects. The car is a composite object.

(simulate
(wooden-level
(car)))

[画像:image]

One last critical concept! Objects can be parameterized. For example, the car is a function that takes a speed and/or ANOTHER OBJECT.

(simulate
(wooden-level
(car1(bowling-ball))))

[画像:image]

Or...

(simulate
(wooden-level
(car1(balloon))))

[画像:image]

Or...

(simulate
(wooden-level
(car1(enemy))))

[画像:image]

And so on. You can pass in any basic object to the car function, and you’ll get a new composite object back. You could then pass this new car into any other function that takes a composite object.

For example, maybe you want to be able to shoot a balloon-car out of a cannon...

(simulate
(wooden-level
(cannon(car1(balloon)))))

[画像:image]

The image above probably doesn’t communicate exactly how cool this is. Let’s check out a gif...

So that’s the basic idea. You create objects. You make those into composite objects. And you can combine composite objects to get even cooler composite objects.

And so on.

Exercise: Can you figure out how to make a car with a cannon on top that shoots out other cars?

2py-fizz High LevelπŸ”— i

The High Level library consists of various gadgets (composite and basic) that all tend to have a consistent look and feel, as well as physical properties that work well together. Many of the gadgets are parameterized, so you can make your own new gadgets with them (like that balloon car shooter seen above).

This part of the documentation lists the provided gadgets and shows you how to compose them to make new ones.

2.1Basic GadgetsπŸ”— i

procedure

(wooden-levelobject)composite?

object:(or/cstatic?dynamic?cosmetic?composite?)

This is just a pretty-looking space for running simulations. There are static walls on all sides, and a cosmetic (wooden) background in the middle. It will dynamically resize if what’s inside doesn’t fit in the default 600x600 space.

procedure

(bowling-ball)dynamic?

Simple bowling ball. High mass.

No parameters on this one. But you can alter its properties with functions like toggle-static, mass, initial-velocity, etc.

procedure

(crate)dynamic?

Dynamic crate. Falls by default. If you want to use it as a platform, call toggle-static on it to convert it to a static object.

procedure

(wheel)dynamic?

Low mass, circular object.

procedure

(balloon)dynamic?

Floats. (Obeys opposite gravity.)

If it is attached to other objects, it will pull them upward.

procedure

(breakable-balloon)dynamic?

Like a regular balloon, but it can be destroyed by clicking on it.

It can also be destroyed if it collides strongly with other objects.

procedure

(friend)dynamic?

A dynamic object that causes you to lose the game if any of them are destroyed. Useful when building puzzles.

procedure

(enemy)dynamic?

A dynamic object that causes you to win the game if all of them are destroyed. Useful when building puzzles.

procedure

(motorcolorspeed)dynamic?

color:string?
speed:number?

(motor"red"1)

(motor"green"1)

(motor"blue"1)

A dynamic object that rotates continually. Good for vehicles.

Use negative numbers to make it rotate the other direction.

procedure

(pinned-motorcolorspeed)dynamic?

color:string?
speed:number?

(pinned-motor"red"1)

(pinned-motor"green"1)

(pinned-motor"blue"1)

A dynamic object that rotates continually. It’s pinned to one spot. Good for conveyor belts.

Use negative numbers to make it rotate the other direction.

procedure

(catpultobject)composite?

object:(or/cstatic?dynamic?cosmetic?composite?)

(catapult(crate))

(catapult(car))

(catapult(above(bowling-ball)(bowling-ball)))

Makes a see-saw contraption, on one side is a bowling ball with a strong downward starting velocity. On the other side is whatever object you supply.

Note that although this function accepts static, dynamic, cosmetic, or composite objects, it is most exciting when you pass in a dynamic object (or a composite object that contains dynamic objects).

procedure

(car[speedobject]join-object)composite?

speed:number?=1
object:(or/cstatic?dynamic?composite?)=(crate)
join-object:(or/cstatic?dynamic?composite?)

(car)

Makes a car. You can control speed and direction with the speed parameter (negative numbers go counter clockwise).

The second parameter controls what object is on top of the car. Passing in a dynamic object is the simplest thing.

(car1(bowling-ball))

If you pass in a static object, the car will be stuck in the air, "pinned" by the static object. Usually not what you want. (Use toggle-static to switch your static object to a dynamic one before passing it into the car function.)

(car1(toggle-static(cannon)))

ADVANCED USAGE: If you pass in a composite object, you pust also pass in a join-object as the third parameter. This determines which part of the composite object to connect the wheels to.

(let([c(crate)])
(car1
(balloons-pulling10c)
c))

(let([c(crate)])
(car1
(car1c)
c))

Let’s take a moment to see how cool it is to be able to make flying cars...

procedure

(pipewidthheight)dynamic?

width:number?
height:number?

(pipe10010)

image

Makes a dynamic rectangle that looks like a pipe. Good for platforms, walls, falling pipes, etc.

procedure

(balloons-pullingnumobject[string-length])composite?

num:number?
object:(or/cdynamic?static?)
string-length:number?=100
(balloons-pulling4
(pipe10010)
50)

Attaches the given number of balloons to the given object. The length of the balloon string can also be configured.

procedure

(conveyor-beltnum[speed])composite?

num:number?
speed:number?=10

(conveyor-belt5-10)

(conveyor-belt510)

Creates the given number of motors in a horizontal row. The speed determines three things: the speed (obviously), the direction (negative is counter-clockwise), and the color (blue for counter-clockwise, red for clockwise).

procedure

(v-spacenum)cosmetic?

num:number?
Creates transparent vertical space. Good for positioning things.

(above(bowling-ball)
(v-space10)
(bowling-ball))

procedure

(h-spacenum)cosmetic?

num:number?
Creates transparent vertical space. Good for positioning things.

(beside(bowling-ball)
(h-space10)
(bowling-ball))

procedure

(fragments object
resolution
[ energy
destroy-after])composite?
object:(or/cdynamic?static?cosmetic?composite?)
resolution:number?
energy:number?=100000
destroy-after:number?=50

(fragments(car)4)

Takes the object and returns a composite object that looks like the original, but is really a bunch of dynamic objects constructed from a sliced up image of the original.

This is how breakable-balloons explode when destroyed.

Note that fragments are computationally expensive. Keep the resolution and the destroy-after parameters low.

procedure

(cannonobject[energyangle])static?

object:(or/cdynamic?static?cosmetic?composite?)
energy:number?=10000
angle:number?=0

(cannon(car))

Returns a static cannon that shoots the provided object when clicked.

The angle and the power of the shot can be adjusted.

procedure

(builderobject[destroy-self?])static?

object:(or/cdynamic?static?cosmetic?composite?)
destroy-self?:boolean?=#t

(builder(car))

Returns a static treasure chest that turns into the provided object when clicked. Good for puzzles.

An icon of the provided object is displayed above the chest, so the user knows what to anticipate.

3py-fizz Low LevelπŸ”— i

3.1Top LevelπŸ”— i

procedure

(previewobject)image?

object:(or/cdynamic?static?cosmetic?composite?)
Any object or composite you make can be passed into the preview function to get an image of what it will look like.

procedure

(simulateobject)void?

object:(or/cdynamic?static?cosmetic?composite?)
This triggers the actual compilation to Python and runs the game/simulation.

3.2Basic ConstructorsπŸ”— i

procedure

(make-staticobject[#:collidercollider])static?

object:(or/ch:image?cosmetic?layout?physical?)
collider:collider?=circle-collider

procedure

(make-dynamicobject[#:collidercollider])dynamic?

object:(or/ch:image?cosmetic?layout?physical?)
collider:collider?=circle-collider

procedure

(make-cosmeticobject)cosmetic?

object:(or/ch:image?cosmetic?layout?)

procedure

(make-pivotobject)pivot?

object:(or/ch:image?cosmetic?)

procedure

(circleradiusfill-modecolor)cosmetic?

radius:number?
fill-mode:mode?
color:color?
A lifted version of the 2htdp/image function (see those docs for details). Returns a cosmetic.

procedure

(rectanglewidthheightfill-modecolor)cosmetic?

width:number?
height:number?
fill-mode:mode?
color:color?
A lifted version of the 2htdp/image function (see those docs for details). Returns a cosmetic.

procedure

(squaresizefill-modecolor)cosmetic?

size:number?
fill-mode:mode?
color:color?
A lifted version of the 2htdp/image function (see those docs for details). Returns a cosmetic.

3.3Setting Physical Properties of ObjectsπŸ”— i

procedure

(motorizespeedobject)dynamic?

speed:number?
object:dynamic?

procedure

(gravitydirectionobject)dynamic?

direction:(list/cnumber?number?)
object:dynamic?

procedure

(elasticityamountobject)dynamic?

amount:number?
object:dynamic?

procedure

(angleamountobject)dynamic?

amount:number?
object:(or/cdynamic?static?)

procedure

(frictionobject[energyangle])static?

object:(or/cdynamic?static?)
energy:number?=10000
angle:number?=0

procedure

(ttltimeobject)dynamic?

time:number?
object:(or/cdynamic?static?cosmetic?)

procedure

(massamountobject)dynamic?

amount:number?
object:dynamic?

procedure

(initial-velocitydirectionobject)dynamic?

direction:(list/cnumber?number?)
object:dynamic?

procedure

(toggle-staticobject)(or/cdynamic?static?)

object:(or/cdynamic?static?)

procedure

(widthobject)number?

object:(or/cdynamic?static?cosmetic?composite?)

procedure

(heightobject)number?

object:(or/cdynamic?static?cosmetic?composite?)

3.4Making composite objectsπŸ”— i

The easiest way to make a composite object is to use a spatial layout function: above, beside, or overlay.

These place two objects in a spatial relation to each other.

Additionally, objects can be associated with physical properties: e.g. they might have a joint connecting them. If this is the case, you’ll create the composite object with a two-step process – 1) establish the physical relation ship (e.g. with the spring-joint function), and then place the two objects into a spatial relationship (e.g. with the above function).

(let*([b1(bowling-ball)]
[b2(bowling-ball)]
[b1-with-connection
(pinb1b2)])
(simulate
(aboveb1-with-connectionb2)))

Note that the pin function takes b1 and returns a new version of b1 that has a pin joint relationship to b2. But you still need to place both b1-with-connection and b2 into a relation with each other.

(You’ll get a runtime error if you don’t.)

3.4.1Spatial Relations for Composite ObjectsπŸ”— i

Spatial relations may be established between any two objects. They do not need to be related to each other physically.

procedure

(aboveobject...)composite?

object:(or/cdynamic?static?cosmetic?composite?)

procedure

(besideobject...)composite?

object:(or/cdynamic?static?cosmetic?composite?)

procedure

(overlayobject...)composite?

object:(or/cdynamic?static?cosmetic?composite?)

3.4.2Physical Relations for Composite ObjectsπŸ”— i

As stated above, spatial relations may be established between any two objects. They do not need to be related to each other physically.

The opposite, however, is not true. If you create a physical relationship between two objects, you must ALSO relate them spatially.

Think of it this way: If you say that two objects are physically related (e.g. they have a connecting joint), you also need to say where those objects are in the universe. The only way to place things into the universe is to relate them spatially to each other.

Keep that in mind with all of the functions in this subsection.

procedure

(gearobject1object2)dynamic?

object1:dynamic?
object2:dynamic?
The two objects will rotate together.

Returns a new version of the first object.

procedure

(connect-pivotpivotobject)pivot?

pivot:pivot?
object:(or/cdynamic?static?)
Causes the object to swing around the pivot point.

Returns a new version of the pivot.

procedure

(pinobject1object2)dynamic?

object1:(or/cdynamic?static?)
object2:(or/cdynamic?static?)
Establishes a rigid "rod" between the two objects.

Returns a new version of the first object.

procedure

(springobject1object2distance)dynamic?

object1:(or/cdynamic?static?)
object2:(or/cdynamic?static?)
distance:number?
Establishes a springy connection between two objects. (Used for balloon strings.)

Returns a new version of the first object.

procedure

(angle-spring object1
object2
[ angle
stiffness
damping])dynamic?
object1:(or/cdynamic?static?)
object2:(or/cdynamic?static?)
angle:number?=0
stiffness:number?=0
damping:number?=0
The two objects will prefer to be at the same angle. They will spring back to that angle if forces do not prevent it.

3.5Runtime BehavioursπŸ”— i

procedure

(on-collide object
callback
#:frictionfriction-thresh
#:energy-lossenergy-loss-thresh)
(or/cdynamic?static?cosmetic?composite?)
object:(or/cdynamic?static?cosmetic?composite?)
callback:callback?
friction-thresh:0
energy-loss-thresh:0
If the object suffers a collision, the callback is triggered.

Collisions can be filtered out based on friction and kinetic energy loss.

procedure

(on-clickobjectcallback)

(or/cdynamic?static?cosmetic?composite?)
object:(or/cdynamic?static?cosmetic?composite?)
callback:callback?
If the object is clicked, the callback is triggered.

procedure

(spawnobject[destroy-self?])callback?

object:(or/cdynamic?static?cosmetic?composite?)
destroy-self?:boolean?=#f
Spawns a new object. Only useful in the context of on-click or on-collide.

procedure

(must-surviveobject)(or/cdynamic?static?)

object:(or/cdynamic?static?)
The given object triggers a lose screen if it is destroyed.

procedure

(must-dieobject)(or/cdynamic?static?)

object:(or/cdynamic?static?)
The given object triggers a win screen if all such objects are destroyed.

3.6MiscπŸ”— i

procedure

(set-package-path!path)void?

path:string?
If you have the py-fizz package installed in a weird place (like I do when I’m developing it).

top
← prev up next →

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /