Você está na página 1de 8

%Particle engine by Michael Yu

Mouse.ButtonChoose ("multibutton")
const *MAXX := "max"
const *MAXY := "max"
const *MAXNUMCOLOUR := 64
const
const
const
const

*Math_2PI := 2 * Math.PI
*Math_PI2 := Math.PI / 2
*Math_PI4 := Math.PI / 4
*Math_3PI4 := Math.PI * 3 / 4

const
const
const
const

*OPTION := 1
*LIFE := 20
*FRAMETIME := 0
*SPAWNRATE := 400

const *SHELLRADIUS := 200


const *ATOMSIZE := 200 %not actual atom size, but just constant factor for the e
lectron distribution
const *ELECTRONSIZE := 1
const *ELECTRONCOLOUR := 2
const *WALL := 1
const *ORBITAL := 0
var *maxscrx : string := MAXX
var *maxscry : string := MAXY
var
var
var
var
var

*electroncolour := ELECTRONCOLOUR
*shellradius : int := SHELLRADIUS
*electronsize : int := ELECTRONSIZE
*atomsize : int := ATOMSIZE %not used
*wall : int := WALL %0 means white wall, 1 means black wall

var *orbital : int := ORBITAL %0 is s, 1 is p


fcn * MidScrX () : int
result maxx div 2
end MidScrX
fcn * MidScrY () : int
result maxy div 2
end MidScrY
fcn * lg (x : real) : real
result ln (x) / ln (2)
end lg
proc * Input_KeyDown (var chars : array char of boolean)
Input.KeyDown (chars)
end Input_KeyDown
type * Int2 : %int pair
record
x : int
y : int
end record

type * Property : %particle property


record
loc_0 : Int2
loc : Int2
t : int
end record
/*
fcn * Location1 (x, y, b : int) : Int2
%Electron orbital simulator
var seed : real := Rand.Real %random number seed for our electron orbital
seed := Math.PI * seed - Math_PI2 %saving variables here
seed := atomsize * sign (seed) * sqrt (abs (tan (seed))) + 0.1 * cos (round (5
* tan (seed)))
var loc : Int2
var angle : real := Math_2PI * Rand.Real
loc.x := MidScrX () + round (seed * cos (angle))
loc.y := MidScrY () + round (seed * sin (angle))
result loc
end Location1
*/
fcn * sLocation1 (x, y, b : int) : Int2
var seed1 : real
seed1 := Rand.Real
var loc : Int2
var angle : real := Math_2PI * Rand.Real
seed1 := 0.2 * shellradius * abs (ln (seed1)) ** 0.66 %saving variables
loc.x := MidScrX () + round (seed1 * cos (angle))
loc.y := MidScrY () + round (seed1 * sin (angle))
result loc
end sLocation1
fcn * sLocation2 (x, y, b : int) : Int2
var seed1, seed2 : real
seed1 := Rand.Real
seed2 := Rand.Real
seed1 := 0.35 * shellradius * (floor (0.3 * abs (tan ((1.4 + Math_PI2) * (se
ed1 + 0.2) - 1.4) + 5.798)) + (arcsin (2 * seed2 - 1) / Math.PI + 0.5)) %saving
variables here
var loc : Int2
var angle : real := Math_2PI * Rand.Real
loc.x := MidScrX () + round (seed1 * cos (angle))
loc.y := MidScrY () + round (seed1 * sin (angle))
result loc
end sLocation2
fcn * sLocation3 (x, y, b : int) : Int2
var seed1, seed2 : real
seed1 := Rand.Real
seed2 := Rand.Real
seed1 := 0.4 * shellradius * (floor (0.45 * abs (tan ((1.4 + Math_PI2) * (se
ed1 + 0.2) - 1.4) + 5.798)) + (arcsin (2 * seed2 - 1) / Math.PI + 0.5)) %saving
variables here
var loc : Int2
var angle : real := Math_2PI * Rand.Real
loc.x := MidScrX () + round (seed1 * cos (angle))

loc.y := MidScrY () + round (seed1 * sin (angle))


result loc
end sLocation3
fcn * pLocation1 (x, y, b : int) : Int2
var seed1 : real
seed1 := Rand.Real
var loc : Int2
var angle : real := Math_2PI * Rand.Real
seed1 := 2 * shellradius * abs (ln (seed1)) ** 0.55 %saving variables
if Rand.Real > 0.5 then
loc.x := MidScrX () + round (0.66 * (3 * shellradius + seed1 * cos (angl
e)))
loc.y := MidScrY () + round (0.4 * seed1 * sin (angle))
else
loc.x := MidScrX () + round (0.66 * (-3 * shellradius + seed1 * cos (ang
le)))
loc.y := MidScrY () + round (0.4 * seed1 * sin (angle))
end if
result loc
end pLocation1
fcn * pLocation2 (x, y, b : int) : Int2
var seed1 : real
seed1 := Rand.Real
var loc : Int2
var angle : real := Math_2PI * Rand.Real
seed1 := 2 *
if Rand.Real
loc.x :=
loc.y :=

shellradius * abs (ln (seed1)) ** 0.55 %saving variables


> 0.5 then
MidScrX () + round (0.4 * seed1 * cos (angle))
MidScrY () + round (0.66 * (3 * shellradius + seed1 * sin (angl

e)))
else
loc.x := MidScrX () + round (0.4 * seed1 * cos (angle))
loc.y := MidScrY () + round (0.66 * (-3 * shellradius + seed1 * sin (ang
le)))
end if
result loc
end pLocation2
fcn Location (x, y, b : int) : Int2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%derp
case orbital of
label 0 :
result sLocation1 (x, y, b)
label 1 :
result sLocation2 (x, y, b)
label 2 :
result pLocation1 (x, y, b)
label 3 :
result pLocation2 (x, y, b)
label 4 :
result sLocation3 (x, y, b)
end case

end Location
fcn * Move (obj : Property) : Int2
result obj.loc
end Move
fcn * Size (obj : Property) : Int2
var out : Int2
out.x := electronsize
out.y := electronsize
result out
end Size
fcn * Colour (obj : Property, life : int) : int
var ratio, ratio2 : real
if wall = 0 then
ratio := 0.5 + 0.5 * obj.t / life
case electroncolour of
label 0 :
result RGB.AddColor (ratio, 0, 0)
label 1 :
result RGB.AddColor (0, ratio, 0)
label 2 :
result RGB.AddColor (0, 0, ratio)
end case
elsif wall = 1 then
ratio := 1 - obj.t / life
ratio2 := ratio / 2
case electroncolour of
label 0 :
result RGB.AddColor (ratio, ratio2, ratio2)
label 1 :
result RGB.AddColor (ratio2, ratio, ratio2)
label 2 :
result RGB.AddColor (ratio2, ratio2, ratio)
end case
end if
end Colour
/*
var elecol : array 0 .. 1 of array
lours of electrons
%var x,y,b:int
proc CreateColours ()
for i : 0 .. MAXNUMCOLOUR
elecol (0) (0) (i) := RGB.AddColor
elecol (0) (1) (i) := RGB.AddColor
elecol (0) (2) (i) := RGB.AddColor
elecol (1) (0) (i) := RGB.AddColor
elecol (1) (1) (i) := RGB.AddColor
elecol (1) (2) (i) := RGB.AddColor
end for
end CreateColours

0 .. 2 of array 0 .. MAXNUMCOLOUR of int %co

(0.5 + 0.5 * i / MAXNUMCOLOUR, 0, 0)


(0, 0.5 + 0.5 * i / MAXNUMCOLOUR, 0)
(0, 0, 0.5 + 0.5 * i / MAXNUMCOLOUR)
(1 - i / MAXNUMCOLOUR, 0, 0)
(0, 1 - i / MAXNUMCOLOUR, 0)
(0, 0, 1 - i / MAXNUMCOLOUR)

fcn * Colour (obj : Property, life : int) : int


result elecol (wall) (electroncolour) (round (obj.t / life * MAXNUMCOLOUR))
end Colour
*/
class BasicEngine %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%
var particle :
record
prop :
last :
next :
end record
var head, tail
or deleted
var n : int :=

collection of
Property
^particle
^particle
: ^particle %head is the "first" particle but is never drawn
0 %num of particles

proc Spawn (obj : Property)


var pt : ^particle
new particle, pt
pt -> prop := obj
pt -> next := nil
pt -> last := tail
tail -> next := pt
tail := pt
n += 1
end Spawn
proc Delete (var pt : ^particle)
if pt = tail then
tail := pt -> last
end if
pt -> last -> next := pt -> next
if pt -> next not= nil then
pt -> next -> last := pt -> last
end if
free particle, pt
end Delete
end BasicEngine
class SimpleEngine %simple engine %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%
inherit BasicEngine
export Main
var shape : int := 0 %0=circle
var option : int := OPTION %0 is particles don't disappear, 1 is they do
var life : int := LIFE %time until particle dissappears
var frametime : int := FRAMETIME % how many milliseconds between frames
var spawnrate : int := SPAWNRATE %how many particles created per frame
proc User (chars : array char of boolean, xo, yo, bo, x, y, b : int, fcn Loc
ation (x, y, b : int) : Int2) %user's action per frame
var obj : Property
var button : int := b
var buttono : int := bo
if button >= 100 and buttono < 100 then %%%%%%%%%%%%%%%%%legit
option := 1 - option
end if
button := button mod 100
buttono := buttono mod 100
if button >= 10 and buttono < 10 then %%%%%%%%%%%%%%%legit
wall := 1 - wall

electroncolour := (electroncolour + 1) mod 3


end if
button := button mod 10
buttono := buttono mod 10
if button = 1 then %%%%%%%%%%%%%%%%%%%legit
for i : 1 .. spawnrate
obj.loc_0 := Location (x, y, b)
obj.loc := obj.loc_0
obj.t := 0
Spawn (obj)
end for
end if
if chars ('0') then
orbital := 0
elsif chars ('1') then
orbital := 1
elsif chars ('2') then
orbital := 2
elsif chars ('3') then
orbital := 3
elsif chars ('4') then
orbital := 4
elsif chars ('5') then
orbital := 5
elsif chars ('6') then
orbital := 6
elsif chars ('7') then
orbital := 7
elsif chars ('8') then
orbital := 8
elsif chars ('9') then
orbital := 9
end if
end User
proc Frame (fcn Move (obj : Property) : Int2, fcn Size (obj : Property) : In
t2, fcn Colour (obj : Property, lifearg : int) : int)
%Size gives x/ size, Colour gives colour, Move gives final coordinates o
f particle
var pt : ^particle := head
var coor, size : Int2
% coordinate of particle and zie of particle
var col : int
%colour
var x_0, y_0, r_x, r_y : int
var temp : ^particle
loop
pt := pt -> next
if pt = nil then
exit
end if
coor := Move (pt -> prop)
size := Size (pt -> prop)
col := Colour (pt -> prop, life)
x_0 := coor.x
y_0 := coor.y
r_x := size.x
r_y := size.y
if r_x = 0 and r_y = 0 then
drawdot (x_0, y_0, col)
else

case shape of
label 0 :
drawfilloval (x_0, y_0, r_x, r_y, col)
label :
end case
end if
pt -> prop.loc := coor
pt -> prop.t += 1
case option of
label 0 :
if pt -> prop.t > 0 then
temp := pt -> last
Delete (pt)
pt := temp
end if
label 1 :
if pt -> prop.t > life then
temp := pt -> last
Delete (pt)
pt := temp
end if
end case
end loop
end Frame
fcn Flag (x, y, b : int) : boolean
%how to tell if user wants to quit ma
in loop; true if quit
if x ** 2 + y ** 2 < 100 and b not= 0 then
result true
end if
result false
end Flag
proc Initialize ()
new particle, head
head -> next := nil
tail := head
end Initialize
proc GetParameters ()
put "x resolution"
get maxscrx
put "y resolution"
get maxscry
put "shellradius"
get shellradius
put "electronsize"
get electronsize
put "life"
get life
put "frametime"
get frametime
put "spawnrate"
get spawnrate
end GetParameters
proc Background ()
if wall = 1 then
drawfillbox (0, 0, maxx, maxy, 7)
end if

end Background
proc Main (fcn Location (x, y, b : int) : Int2, fcn Move (obj : Property) :
Int2, fcn Size (obj : Property) : Int2, fcn Colour (obj : Property, lifearg : in
t) : int)
Initialize ()
GetParameters ()
cls
setscreen ("graphics:" + maxscrx + ";" + maxscry)
var xo, yo, bo, x, y, b : int
var chars : array char of boolean
Background ()
View.Set ("offscreenonly")
mousewhere (xo, yo, bo)
loop
mousewhere (x, y, b)
Input_KeyDown (chars)
if Flag (x, y, b) then
exit
end if
if option = 1 then
Background ()
end if
User (chars, xo, yo, bo, x, y, b, Location)
Frame (Move, Size, Colour)
View.Update
if option = 1 then
cls
end if
xo := x
yo := y
bo := b
end loop
View.Set ("nooffscreenonly")
end Main
end SimpleEngine
var pt : ^SimpleEngine
new SimpleEngine, pt
var garbage : string
%CreateColours ()
loop
pt -> Main (Location, Move, Size, Colour)
cls
put "continue?"
get garbage
if garbage = "no" then
exit
end if
cls
end loop

Você também pode gostar