3import java.awt.AlphaComposite;
5import java.awt.Graphics2D;
6import java.awt.Rectangle;
7import java.awt.geom.AffineTransform;
8import java.awt.image.BufferedImage;
9import java.util.ArrayList;
26 private List<Costume>
costumes =
new ArrayList<>();
35 private List<Runnable>
clickListeners =
new java.util.concurrent.CopyOnWriteArrayList<>();
36 private List<java.util.function.BiConsumer<Double, Double>>
scaleListeners =
new java.util.concurrent.CopyOnWriteArrayList<>();
40 BufferedImage img =
new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
41 Graphics2D g = img.createGraphics();
43 g.fillRect(0, 0, w, h);
44 g.setColor(Color.BLACK);
45 g.drawRect(0, 0, w - 1, h - 1);
54 public double getX() {
return x; }
55 public double getY() {
return y; }
73 if (img ==
null)
return false;
76 java.awt.geom.AffineTransform tx =
new java.awt.geom.AffineTransform();
77 double screenX =
x +
stage.getWidth() / 2.0;
78 double screenY =
stage.getHeight() / 2.0 -
y;
80 tx.translate(screenX, screenY);
84 tx.rotate(Math.toRadians(
direction - 90));
90 java.awt.geom.AffineTransform inv = tx.createInverse();
91 java.awt.geom.Point2D local = inv.transform(
new java.awt.geom.Point2D.Double(mx, my),
null);
93 int ix = (int) local.getX();
94 int iy = (int) local.getY();
96 if (ix >= 0 && ix < img.getWidth() && iy >= 0 && iy < img.getHeight()) {
97 int argb = img.getRGB(ix, iy);
98 return ((argb >> 24) & 0xff) > 0;
100 }
catch (Exception e) {
117 for (java.util.function.BiConsumer<Double, Double> listener :
scaleListeners) {
118 startScript(() -> listener.accept(oldScale, newScale));
123 public void draw(Graphics2D g) {
127 if (img ==
null)
return;
129 AffineTransform old = g.getTransform();
130 double screenX =
x +
stage.getWidth() / 2.0;
131 double screenY =
stage.getHeight() / 2.0 -
y;
133 g.translate(screenX, screenY);
137 g.rotate(Math.toRadians(
direction - 90));
143 float alpha = (float) Math.max(0, Math.min(1, 1.0 - (
ghostEffect / 100.0)));
144 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
149 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (
float)(Math.abs(
brightnessEffect)/200.0)));
157 g.setComposite(AlphaComposite.SrcOver);
167 return new Rectangle((
int)(
x +
stage.getWidth()/2.0 - w/2), (
int)(
stage.getHeight()/2.0 -
y - h/2), w, h);
171 public void move(
double steps) {
172 double rad = Math.toRadians(90 -
direction);
173 x += steps * Math.cos(rad);
174 y += steps * Math.sin(rad);
179 public void goTo(
double x,
double y) { this.x =
x; this.y =
y; }
183 public void glide(
double sec,
double tx,
double ty) {
184 long dur = (long)(sec * 1000), start = System.currentTimeMillis();
185 double sx =
x, sy =
y;
186 while (System.currentTimeMillis() - start < dur) {
187 double p = (System.currentTimeMillis() - start) / (double)dur;
188 x = sx + (tx - sx) * p;
y = sy + (ty - sy) * p;
195 int w =
stage.getWidth()/2, h =
stage.getHeight()/2;
196 x = (Math.random()*w*2)-w;
y = (Math.random()*h*2)-h;
200 int w =
stage.getWidth()/2, h =
stage.getHeight()/2;
209 if (effect.equalsIgnoreCase(
"ghost"))
ghostEffect = value;
213 if (effect.equalsIgnoreCase(
"ghost"))
ghostEffect += amount;
218 public void say(String text) { System.out.println(
name +
": " + text); }
233 if (b ==
null)
return false;
234 int sx = (int)(
x +
stage.getWidth()/2.0), sy = (int)(
stage.getHeight()/2.0 -
y);
235 if (sx < 0 || sx >= b.
getImage().getWidth() || sy < 0 || sy >= b.
getImage().getHeight())
return false;
236 return new Color(b.
getImage().getRGB(sx, sy)).equals(c);
244 switch(
name.toLowerCase()) {
250 case "size":
return size;
252 return super.getVariable(
name);
ScratchObject(String name)
void startScript(Runnable script)
List< Runnable > clickListeners
RotationStyle rotationStyle
void turnRight(double deg)
void goToRandomPosition()
void clearGraphicsEffects()
boolean isTouching(Sprite o)
void whenClicked(Runnable action)
static BufferedImage createPlaceholder(Color c, int w, int h)
void setEffect(String effect, double value)
void handleScaleChange(double oldScale, double newScale)
void glide(double sec, double tx, double ty)
void handleMouseClick(int mx, int my)
boolean containsPoint(int mx, int my)
void setScaleY(double sy)
void changeEffectBy(String effect, double amount)
List< java.util.function.BiConsumer< Double, Double > > scaleListeners
void setStage(Stage stage)
void whenScaleChanged(java.util.function.BiConsumer< Double, Double > action)
void setScaleX(double sx)
void setRotationStyle(RotationStyle s)
void changeXBy(double dx)
boolean isTouchingColor(Color c)
Object getVariable(String name)
void switchCostume(String n)
void say(String text, double sec)
void changeYBy(double dy)
void changeSizeBy(double a)
void pointInDirection(double dir)
void goTo(double x, double y)
void turnLeft(double deg)
void addCostume(Costume c)