📄 spheres.jc
字号:
// spheres.jc
// An applet for the ScriptApp application.
// To run this script, simply drag it onto the ScriptApp's icon.
// import native types
import stdlib;
import Screen;
import Bitmap;
import RectLayer;
import TextLayer;
import BitmapLayer;
// kNumberOfSpheres
// Reduce this value if the script runs too slow on your computer.
const long kNumberOfSpheres = 30;
// kMaximumSpeed
// Reduce this value to make the spheres move slower
const float kMaximumSpeed = 7.0;
// kNumberOfTilesPerAxis
// Number of tiles the background is made of (minimum 2)
const long kNumberOfTilesPerAxis = 8;
// kTimerTicks
// Number of milliseconds until next tip is shown
const long kTimerTicks = 3000;
// TheBigMessage
// The text message shown by this applet
const string& kBigMessage = "This applet is written in JewelScript!";
// kTipArray
// Contains the tips given by the Applet
const array& kTipArray = {
"Click into the window for a surprise...",
"Cool eh? Now try to click a sphere...",
"Nice huh? Now click the background...",
"Amazing! Now what happens if you hit a key...?",
"Whoa! Hit that key again...",
"Ok, that's all!",
"Have fun! :-)",
"For information on the JewelScript language\nvisit www.jewe.org"
};
// kBitmaps
// An array of sphere images
const array& kBitmaps = {
new Bitmap("spheres/sphere16.png", true),
new Bitmap("spheres/sphere20.png", true),
new Bitmap("spheres/sphere24.png", true),
new Bitmap("spheres/sphere28.png", true),
new Bitmap("spheres/sphere32.png", true),
new Bitmap("spheres/sphere36.png", true),
new Bitmap("spheres/sphere40.png", true),
new Bitmap("spheres/sphere44.png", true),
new Bitmap("spheres/sphere48.png", true)
};
// class SphereApplet
// An applet for the ScriptApp application
class SphereApplet : interface Applet
{
method SphereApplet(Screen&);
method OnOpen();
method OnClose();
method OnClick(long button, long x, long y);
method OnKey(long key);
method Idle();
method ArrangeTiles();
Screen& m_Screen;
array& m_Tiles;
array& m_Spheres;
TextLayer& m_Head;
TextLayer& m_Tip;
long m_OldWidth;
long m_OldHeight;
long m_TipIndex;
long m_Timer;
}
// class Sphere
class Sphere
{
method Sphere(Layer& layer);
method Move(const Screen& screen);
method ResetAt(long x, long y);
method KickOff();
float m_PosX;
float m_PosY;
float m_SignX;
float m_SignY;
float m_Speed;
float m_Velocity;
Layer& m_Layer;
}
// function CreateApplet
// The Application calls this function to create our applet.
// We need to implement this function and return an instance of our applet.
function Applet& CreateApplet(Screen& screen)
{
return new SphereApplet( screen );
}
// class SphereApplet
// constructor
method SphereApplet::SphereApplet(Screen& screen)
{
m_Screen = screen;
m_Screen.BackColor( 70, 90, 110 );
m_OldWidth = 0;
m_OldHeight = 0;
m_TipIndex = 0;
m_Timer = 0;
m_Tiles = new array;
m_Spheres = new array;
// create background tiles
long n = (kNumberOfTilesPerAxis / 2) * kNumberOfTilesPerAxis;
for( long j = 0; j < n; j++ )
{
RectLayer& tile = new RectLayer();
tile.SetColor( 150, 170, 190 );
tile.Show();
m_Screen.AddLayer( tile );
m_Tiles += tile;
}
// create text layers
m_Head = new TextLayer();
m_Head.Text( kBigMessage );
m_Head.SetColor( 255, 250, 240 );
m_Head.Font( 8 );
m_Head.AutoSize();
m_Head.Show();
m_Screen.AddLayer( m_Head );
m_Spheres += new Sphere( m_Head );
m_Tip = new TextLayer();
m_Tip.Text( kTipArray[0] );
m_Tip.SetColor( 255, 255, 0 );
m_Tip.Font( 0 );
m_Tip.AutoSize();
m_Tip.Show();
m_Screen.AddLayer( m_Tip );
m_Spheres += new Sphere( m_Tip );
// create the spheres
float fb = 9.0 / kNumberOfSpheres;
float fi = 0;
for( long i = 0; i < kNumberOfSpheres; i++ )
{
// create bitmap layer
BitmapLayer bmLayer = new BitmapLayer();
bmLayer.Bitmap( kBitmaps[fi + 0.5] );
bmLayer.AutoSize();
bmLayer.Show();
m_Screen.AddLayer( bmLayer );
m_Spheres += new Sphere( bmLayer );
fi += fb;
}
}
// OnOpen
// Called when the ScriptApp window is opened.
method SphereApplet::OnOpen()
{
}
// OnClose
// Called when the ScriptApp window is closed.
method SphereApplet::OnClose()
{
}
// OnClick
// Called when the user clicks with a mouse button
method SphereApplet::OnClick(long button, long x, long y)
{
long resetAll = false;
// try to find layer under mouse cursor
Layer& layer = m_Screen.LayerAt(x, y);
if( layer == null )
{
resetAll = true;
}
else
{
// reset Sphere owning the clicked layer
long index = layer.Index() - m_Tiles.length;
if( index >= 0 )
{
Sphere& sphere = m_Spheres[index];
sphere.KickOff();
sphere.m_Speed = kMaximumSpeed;
}
else
{
resetAll = true;
}
}
if( resetAll )
{
if( m_TipIndex == 0 )
m_TipIndex = 1;
else if( m_TipIndex == 2 )
m_TipIndex = 3;
// reset all positions to click position
for( long i = 0; i < m_Spheres.length; i++ )
m_Spheres[i].Sphere::ResetAt(x, y);
}
else
{
if( m_TipIndex == 0 )
m_TipIndex = 2;
else if( m_TipIndex == 1 )
m_TipIndex = 3;
}
if( m_TipIndex <= 3 )
{
m_Tip.Text( kTipArray[m_TipIndex] );
m_Tip.AutoSize();
}
}
// OnKey
// Called when the user presses a key
method SphereApplet::OnKey(long key)
{
if( m_TipIndex >= 3 and m_TipIndex < 5 )
{
m_Tip.Text( kTipArray[++m_TipIndex] );
m_Tip.AutoSize();
m_Timer = stdlib::GetTicks() + kTimerTicks;
}
if( m_Head.IsVisible() )
{
m_Head.Hide();
for( long i = 0; i < m_Tiles.length; i++ )
m_Tiles[i].Layer::Hide();
}
else
{
m_Head.Show();
for( long i = 0; i < m_Tiles.length; i++ )
m_Tiles[i].Layer::Show();
}
}
// Idle
// Called in regular intervals when nothing else to do
method SphereApplet::Idle()
{
if( m_TipIndex >= 5 and m_Timer < stdlib::GetTicks() )
{
m_TipIndex++;
if( m_TipIndex < kTipArray.length - 1 )
{
m_Tip.Text( kTipArray[m_TipIndex] );
m_Tip.AutoSize();
m_Timer = stdlib::GetTicks() + kTimerTicks;
}
else if( m_TipIndex < kTipArray.length )
{
m_Tip.Text( kTipArray[m_TipIndex] );
m_Tip.ResizeTo( 250, 40 );
m_Timer = stdlib::GetTicks() + 10000;
}
else
{
m_Tip.Hide();
m_Head.Text( "www.jewe.org" );
m_Head.AutoSize();
}
}
// did the screen change size?
if( m_OldWidth != m_Screen.Width() or m_OldHeight != m_Screen.Height() )
{
m_OldWidth = m_Screen.Width();
m_OldHeight = m_Screen.Height();
// re-arrange background tiles
ArrangeTiles();
}
// iterate over all spheres in the array and move them
for( long i = 0; i < m_Spheres.length; i++ )
m_Spheres[i].Sphere::Move(m_Screen);
// tell screen to redraw itself
m_Screen.Redraw();
}
// ArrangeTiles
// Calculate positions and sizes of the background tiles
method SphereApplet::ArrangeTiles()
{
long w = m_Screen.Width();
long h = m_Screen.Height();
long tw = w / kNumberOfTilesPerAxis;
long th = h / kNumberOfTilesPerAxis;
long i = 0, x, y, useTile = true;
for( y = 0; y < h; y += th )
{
if( y + th > h )
break;
for( x = 0; x < w; x += tw )
{
if( x + tw > w )
break;
if( useTile )
{
Layer& tile = m_Tiles[i++];
tile.MoveTo( x, y );
tile.ResizeTo( tw, th );
if( i == m_Tiles.length )
break;
useTile = false;
}
else
{
useTile = true;
}
}
if( i == m_Tiles.length )
break;
useTile = not useTile;
}
}
// class Sphere
// constructor
method Sphere::Sphere(Layer& layer)
{
m_PosX = 320 - layer.Width() / 2;
m_PosY = 240 - layer.Height() / 2;
m_Speed = 0.0;
m_SignX = 0.0;
m_SignY = 0.0;
m_Velocity = 0.0;
m_Layer = layer;
KickOff();
}
// Move
method Sphere::Move(const Screen& screen)
{
float w = screen.Width() - m_Layer.Width();
float h = screen.Height() - m_Layer.Height();
if( m_PosX < 0.0 )
{
m_PosX = 0.0;
m_SignX = -m_SignX;
m_Velocity -= 0.01;
}
else if( m_PosX > w )
{
m_PosX = w;
m_SignX = -m_SignX;
m_Velocity -= 0.01;
}
if( m_PosY < 0.0 )
{
m_PosY = 0.0;
m_SignY = -m_SignY;
m_Velocity -= 0.01;
}
else if( m_PosY > h )
{
m_PosY = h;
m_SignY = -m_SignY;
m_Velocity -= 0.01;
}
m_Velocity -= 0.001;
if( m_Velocity <= 0.0 )
KickOff();
float sp = m_Velocity * m_Velocity * m_Speed;
m_PosX += sp * m_SignX;
m_PosY += sp * m_SignY;
m_Layer.MoveTo(m_PosX, m_PosY);
}
// ResetAt
method Sphere::ResetAt(long x, long y)
{
m_PosX = x - m_Layer.Width() / 2;
m_PosY = y - m_Layer.Height() / 2;
KickOff();
}
// KickOff
method Sphere::KickOff()
{
if( typeof(m_Layer) == typeof(TextLayer) )
m_Speed = 1.0;
else
m_Speed = stdlib::Rand() * kMaximumSpeed + 1.0;
m_SignX = stdlib::Rand() * 0.75 + 0.25;
if( stdlib::Rand() < 0.5 )
m_SignX *= -1.0;
m_SignY = stdlib::Rand() * 0.75 + 0.25;
if( stdlib::Rand() < 0.5 )
m_SignY *= -1.0;
m_Velocity = stdlib::Rand() * 0.25 + 0.75;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -