AI2 Component  (Version nb184)
Sprite.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2009-2011 Google, All Rights reserved
3 // Copyright 2011-2019 MIT, All rights reserved
4 // Released under the Apache License, Version 2.0
5 // http://www.apache.org/licenses/LICENSE-2.0
6 
7 package com.google.appinventor.components.runtime;
8 
20 
21 import android.os.Handler;
22 
23 import java.util.HashSet;
24 import java.util.Set;
25 
36 @SimpleObject
37 public abstract class Sprite extends VisibleComponent
39  private static final String LOG_TAG = "Sprite";
40  private static final boolean DEFAULT_ENABLED = true; // Enable timer for movement
41  private static final int DEFAULT_HEADING = 0; // degrees
42  private static final int DEFAULT_INTERVAL = 100; // ms
43  private static final float DEFAULT_SPEED = 0.0f; // pixels per interval
44  private static final boolean DEFAULT_VISIBLE = true;
45  private static final double DEFAULT_Z = 1.0;
46  protected static final boolean DEFAULT_ORIGIN_AT_CENTER = false;
47 
48  protected final Canvas canvas; // enclosing Canvas
49  private final TimerInternal timerInternal; // timer to control movement
50  private final Handler androidUIHandler; // for posting actions
51 
52  // Keeps track of which other sprites are currently colliding with this one.
53  // That way, we don't raise CollidedWith() more than once for each collision.
54  // Events are only raised when sprites are added to this collision set. They
55  // are removed when they no longer collide.
56  private final Set<Sprite> registeredCollisions;
57 
58  // This variable prevents events from being raised before construction of
59  // all components has taken place. This was added to fix bug 2262218.
60  protected boolean initialized = false;
61 
62  // Properties: These are protected, instead of private, both so they
63  // can be used by subclasses and tests.
64  protected int interval; // number of milliseconds until next move
65  protected boolean visible = true;
66  protected double xLeft; // leftmost x-coordinate
67  protected double yTop; // uppermost y-coordinate
68  protected double zLayer; // z-coordinate, higher values go in front
69  protected float speed; // magnitude in pixels
70 
71  // Added to support having coordinates at center.
72  protected boolean originAtCenter;
73  protected double xCenter;
74  protected double yCenter;
75 
76  protected Form form;
77 
84  protected double userHeading;
85 
91  protected double heading;
92  protected double headingRadians; // heading in radians
93  protected double headingCos; // cosine(heading)
94  protected double headingSin; // sine(heading)
95 
103  protected Sprite(ComponentContainer container, Handler handler) {
104  super();
105  androidUIHandler = handler;
106 
107  // Add to containing Canvas.
108  if (!(container instanceof Canvas)) {
109  throw new IllegalArgumentError("Sprite constructor called with container " + container);
110  }
111  this.canvas = (Canvas) container;
112  this.canvas.addSprite(this);
113 
114  // Maintain a list of collisions.
115  registeredCollisions = new HashSet<Sprite>();
116 
117  // Set in motion.
118  timerInternal = new TimerInternal(this, DEFAULT_ENABLED, DEFAULT_INTERVAL, handler);
119 
120  this.form = container.$form();
121 
122  // Set default property values.
124  Heading(0); // Default initial heading
125  Enabled(DEFAULT_ENABLED);
126  Interval(DEFAULT_INTERVAL);
127  Speed(DEFAULT_SPEED);
128  Visible(DEFAULT_VISIBLE);
129  Z(DEFAULT_Z);
130 
131  container.$form().registerForOnDestroy(this);
132  }
133 
140  protected Sprite(ComponentContainer container) {
141  // Note that although this is creating a new Handler, there is
142  // only one UI thread in an Android app and posting to this
143  // handler queues up a Runnable for execution on that thread.
144  this(container, new Handler());
145  }
146 
147  public void Initialize() {
148  initialized = true;
149  canvas.registerChange(this);
150  }
151 
152  // Properties (Enabled, Heading, Interval, Speed, Visible, X, Y, Z, OriginAtCenter)
153  // The SimpleProperty annotations for X and Y appear in the concrete
154  // subclasses so each can have its own description. Currently, OriginAtCenter
155  // is a property of Ball only.
156 
164  description = "Controls whether the %type% moves and can be interacted with " +
165  "through collisions, dragging, touching, and flinging.")
166  public boolean Enabled() {
167  return timerInternal.Enabled();
168  }
169 
178  defaultValue = DEFAULT_ENABLED ? "True" : "False")
180  public void Enabled(boolean enabled) {
181  timerInternal.Enabled(enabled);
182  }
183 
191  description = "Returns the %type%'s heading in degrees above the positive " +
192  "x-axis. Zero degrees is toward the right of the screen; 90 degrees is toward the " +
193  "top of the screen.")
194  public double Heading() {
195  return userHeading;
196  }
197 
209  defaultValue = DEFAULT_HEADING + "")
210  public void Heading(double userHeading) {
211  this.userHeading = userHeading;
212  // Flip, because y increases in the downward direction on Android canvases
213  heading = -userHeading;
214  headingRadians = Math.toRadians(heading);
215  headingCos = Math.cos(headingRadians);
216  headingSin = Math.sin(headingRadians);
217  // changing the heading needs to force a redraw for image sprites that rotate
218  registerChange();
219  }
220 
229  description = "The interval in milliseconds at which the %type%'s " +
230  "position is updated. For example, if the interval is 50 and the speed is 10, " +
231  "then every 50 milliseconds the sprite will move 10 pixels in the heading direction.")
232  public int Interval() {
233  return timerInternal.Interval();
234  }
235 
244  defaultValue = DEFAULT_INTERVAL + "")
246  public void Interval(int interval) {
247  timerInternal.Interval(interval);
248  }
249 
258  description = "The number of pixels that the %type% should move every interval, if enabled.")
261  defaultValue = DEFAULT_SPEED + "")
262  public void Speed(float speed) {
263  this.speed = speed;
264  }
265 
274  description = "The speed at which the %type% moves. The %type% moves " +
275  "this many pixels every interval if enabled.")
276  public float Speed() {
277  return speed;
278  }
279 
286  @SimpleProperty(description = "Whether the %type% is visible.")
287  public boolean Visible() {
288  return visible;
289  }
290 
299  defaultValue = DEFAULT_VISIBLE ? "True" : "False")
301  public void Visible(boolean visible) {
302  this.visible = visible;
303  registerChange();
304  }
305 
306  public double X() {
307  return originAtCenter ? xCenter : xLeft;
308  }
309 
310  private double xLeftToCenter(double xLeft) {
311  return xLeft + Width() / 2;
312  }
313 
314  private double xCenterToLeft(double xCenter) {
315  return xCenter - Width() / 2;
316  }
317 
318  // Note that this does not call registerChange(). This was pulled out of X()
319  // so both X and Y could be changed with only a single call to registerChange().
320  private void updateX(double x) {
321  if (originAtCenter) {
322  xCenter = x;
323  xLeft = xCenterToLeft(x);
324  } else {
325  xLeft = x;
326  xCenter = xLeftToCenter(x);
327  }
328  }
329 
330  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_FLOAT,
331  defaultValue = "0.0")
332  @SimpleProperty(
333  category = PropertyCategory.APPEARANCE)
334  public void X(double x) {
335  updateX(x);
336  registerChange();
337  }
338 
339  private double yTopToCenter(double yTop) {
340  return yTop + Width() / 2;
341  }
342 
343  private double yCenterToTop(double yCenter) {
344  return yCenter - Width() / 2;
345  }
346 
347  // Note that this does not call registerChange(). This was pulled out of Y()
348  // so both X and Y could be changed with only a single call to registerChange().
349  private void updateY(double y) {
350  if (originAtCenter) {
351  yCenter = y;
352  yTop = yCenterToTop(y);
353  } else {
354  yTop = y;
355  yCenter = yTopToCenter(y);
356  }
357  }
358 
359  @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_FLOAT,
360  defaultValue = "0.0")
361  @SimpleProperty
362  public void Y(double y) {
363  updateY(y);
364  registerChange();
365  }
366 
367  public double Y() {
368  return originAtCenter ? yCenter : yTop;
369  }
370 
381  defaultValue = DEFAULT_Z + "")
382  public void Z(double layer) {
383  this.zLayer = layer;
384  canvas.changeSpriteLayer(this); // Tell canvas about change
385  }
386 
388  description = "How the %type% should be layered relative to other Balls and ImageSprites, " +
389  "with higher-numbered layers in front of lower-numbered layers.")
390  public double Z() {
391  return zLayer;
392  }
393 
394  // This gets overridden in Ball with the @SimpleProperty and @DesignerProperty
395  // annotations so it can be made a property for Ball but not for ImageSprite.
396  protected void OriginAtCenter(boolean b) {
397  originAtCenter = b;
398  }
399 
400  // Methods for event handling: general purpose method postEvent() and
401  // Simple events: CollidedWith, Dragged, EdgeReached, Touched, NoLongerCollidingWith,
402  // Flung, TouchUp, and TouchDown.
403 
415  protected void postEvent(final Sprite sprite,
416  final String eventName,
417  final Object... args) {
418  androidUIHandler.post(new Runnable() {
419  public void run() {
420  EventDispatcher.dispatchEvent(sprite, eventName, args);
421  }});
422  }
423 
424  // TODO(halabelson): Fix collision detection for rotated sprites.
434  @SimpleEvent
435  public void CollidedWith(Sprite other) {
436  if (!registeredCollisions.contains(other)) {
437  registeredCollisions.add(other);
438  postEvent(this, "CollidedWith", other);
439  }
440  }
441 
459  @SimpleEvent(
460  description = "Event handler called when a %type% is dragged. " +
461  "On all calls, the starting coordinates " +
462  "are where the screen was first touched, and the \"current\" coordinates " +
463  "describe the endpoint of the current line segment. On the first call " +
464  "within a given drag, the \"previous\" coordinates are the same as the " +
465  "starting coordinates; subsequently, they are the \"current\" coordinates " +
466  "from the prior call. Note that the %type% won't actually move " +
467  "anywhere in response to the Dragged event unless MoveTo is explicitly called. " +
468  "For smooth movement, each of its coordinates should be set to the sum of its " +
469  "initial value and the difference between its current and previous values.")
470  public void Dragged(float startX, float startY,
471  float prevX, float prevY,
472  float currentX, float currentY) {
473  postEvent(this, "Dragged", startX, startY, prevX, prevY, currentX, currentY);
474  }
475 
483  @SimpleEvent(
484  description = "Event handler called when the %type% reaches an edge of the screen. " +
485  "If Bounce is then called with that edge, the %type% will appear to " +
486  "bounce off of the edge it reached. Edge here is represented as an integer that " +
487  "indicates one of eight directions north (1), northeast (2), east (3), southeast (4), " +
488  "south (-1), southwest (-2), west (-3), and northwest (-4).")
489  public void EdgeReached(int edge) {
490  if (edge == Component.DIRECTION_NONE
491  || edge < Component.DIRECTION_MIN
492  || edge > Component.DIRECTION_MAX) {
493  // This should never be reached.
494  return;
495  }
496  postEvent(this, "EdgeReached", edge);
497  }
498 
510  @SimpleEvent(
511  description = "Event handler called when a pair of sprites (Balls and ImageSprites) are no " +
512  "longer colliding.")
513  public void NoLongerCollidingWith(Sprite other) {
514  registeredCollisions.remove(other);
515  postEvent(this, "NoLongerCollidingWith", other);
516  }
517 
525  @SimpleEvent(
526  description = "Event handler called when the user touches an enabled " +
527  "%type% and then immediately lifts their finger. The provided x and y coordinates " +
528  "are relative to the upper left of the canvas.")
529  public void Touched(float x, float y) {
530  postEvent(this, "Touched", x, y);
531  }
532 
547  @SimpleEvent(
548  description = "Event handler called when a fling gesture (quick swipe) is made on " +
549  "an enabled %type%. This provides the x and y coordinates of the start of the " +
550  "fling (relative to the upper left of the canvas), the speed (pixels per millisecond), " +
551  "the heading (0-360 degrees), and the x and y velocity components of " +
552  "the fling's vector.")
553  public void Flung(float x, float y, float speed, float heading, float xvel, float yvel) {
554  postEvent(this, "Flung", x, y, speed, heading, xvel, yvel);
555  }
556 
565  @SimpleEvent(
566  description = "Event handler called when the user stops touching an enabled %type% " +
567  "(lifting their finger after a TouchDown event). This provides the " +
568  "x and y coordinates of the touch, relative to the upper left of the canvas.")
569  public void TouchUp(float x, float y) {
570  postEvent(this, "TouchUp", x, y);
571  }
572 
581  @SimpleEvent(
582  description = "Event handler called when the user begins touching an enabled %type% " +
583  "(placing their finger on a %type% and leaving it there). This provides the " +
584  "x and y coordinates of the touch, relative to the upper left of the canvas.")
585  public void TouchDown(float x, float y) {
586  postEvent(this, "TouchDown", x, y);
587  }
588 
589  // Methods providing Simple functions:
590  // Bounce, CollidingWith, MoveIntoBounds, MoveTo, PointTowards.
591 
608  description = "Makes the %type% bounce, as if off a wall. " +
609  "For normal bouncing, the edge argument should be the one returned by EdgeReached.")
610  public void Bounce (int edge) {
611  MoveIntoBounds();
612 
613  // Normalize heading to [0, 360)
614  double normalizedAngle = userHeading % 360;
615  // The following step is necessary because Java's modulus operation yields a
616  // negative number if the dividend is negative and the divisor is positive.
617  if (normalizedAngle < 0) {
618  normalizedAngle += 360;
619  }
620 
621  // Only transform heading if sprite was moving in that direction.
622  // This avoids oscillations.
623  if ((edge == Component.DIRECTION_EAST
624  && (normalizedAngle < 90 || normalizedAngle > 270))
625  || (edge == Component.DIRECTION_WEST
626  && (normalizedAngle > 90 && normalizedAngle < 270))) {
627  Heading(180 - normalizedAngle);
628  } else if ((edge == Component.DIRECTION_NORTH
629  && normalizedAngle > 0 && normalizedAngle < 180)
630  || (edge == Component.DIRECTION_SOUTH && normalizedAngle > 180)) {
631  Heading(360 - normalizedAngle);
632  } else if ((edge == Component.DIRECTION_NORTHEAST
633  && normalizedAngle > 0 && normalizedAngle < 90)
634  || (edge == Component.DIRECTION_NORTHWEST
635  && normalizedAngle > 90 && normalizedAngle < 180)
636  || (edge == Component.DIRECTION_SOUTHWEST
637  && normalizedAngle > 180 && normalizedAngle < 270)
638  || (edge == Component.DIRECTION_SOUTHEAST && normalizedAngle > 270)) {
639  Heading(180 + normalizedAngle);
640  }
641  }
642 
643  // This is primarily used to enforce raising only
644  // one {@link #CollidedWith(Sprite)} event per collision but is also
645  // made available to the Simple programmer.
655  description = "Indicates whether a collision has been registered between this %type% " +
656  "and the passed sprite (Ball or ImageSprite).")
657  public boolean CollidingWith(Sprite other) {
658  return registeredCollisions.contains(other);
659  }
660 
669  description = "Moves the %type% back in bounds if part of it extends out of bounds, " +
670  "having no effect otherwise. If the %type% is too wide to fit on the " +
671  "canvas, this aligns the left side of the %type% with the left side of the " +
672  "canvas. If the %type% is too tall to fit on the canvas, this aligns the " +
673  "top side of the %type% with the top side of the canvas.")
674  public void MoveIntoBounds() {
676  }
677 
678  // Description is different for Ball and ImageSprite so overridden and described in subclasses.
685  public void MoveTo(double x, double y) {
686  updateX(x);
687  updateY(y);
688  registerChange();
689  }
690 
698  description = "Turns the %type% to point towards a designated " +
699  "target sprite (Ball or ImageSprite). The new heading will be parallel to the line joining " +
700  "the centerpoints of the two sprites.")
701  public void PointTowards(Sprite target) {
702  Heading(-Math.toDegrees(Math.atan2(target.yCenter - yCenter, target.xCenter - xCenter)));
703  }
704 
712  description = "Sets the heading of the %type% toward the point " +
713  "with the coordinates (x, y).")
714  public void PointInDirection(double x, double y) {
715  Heading(-Math.toDegrees(Math.atan2(y - yCenter, x - xCenter)));
716  }
717 
718  // Internal methods supporting move-related functionality
719 
728  protected void registerChange() {
729  // This was added to fix bug 2262218, where Ball.CollidedWith() was called
730  // before all components had been constructed.
731  if (!initialized) {
732  // During REPL, components are not initalized, but we still want to repaint the canvas.
733  canvas.getView().invalidate();
734  return;
735  }
736  int edge = hitEdge();
737  if (edge != Component.DIRECTION_NONE) {
738  EdgeReached(edge);
739  }
740  canvas.registerChange(this);
741  }
742 
751  protected int hitEdge() {
752  if (!canvas.ready()) {
753  return Component.DIRECTION_NONE;
754  }
755 
756  return hitEdge(canvas.Width(), canvas.Height());
757  }
758 
766  protected final void moveIntoBounds(int canvasWidth, int canvasHeight) {
767  boolean moved = false;
768 
769  // We set the xLeft and/or yTop fields directly, instead of calling X(123) and Y(123), to avoid
770  // having multiple calls to registerChange.
771 
772  // Check if the sprite is too wide to fit on the canvas.
773  if (Width() > canvasWidth) {
774  // Sprite is too wide to fit. If it isn't already at the left edge, move it there.
775  // It is important not to set moved to true if xLeft is already 0. Doing so can cause a stack
776  // overflow.
777  if (xLeft != 0) {
778  xLeft = 0;
779  xCenter = xLeftToCenter(xLeft);
780  moved = true;
781  }
782  } else if (overWestEdge()) {
783  xLeft = 0;
784  xCenter = xLeftToCenter(xLeft);
785  moved = true;
786  } else if (overEastEdge(canvasWidth)) {
787  xLeft = canvasWidth - Width();
788  xCenter = xLeftToCenter(xLeft);
789  moved = true;
790  }
791 
792  // Check if the sprite is too tall to fit on the canvas. We don't want to cause a stack
793  // overflow by moving the sprite to the top edge and then to the bottom edge, repeatedly.
794  if (Height() > canvasHeight) {
795  // Sprite is too tall to fit. If it isn't already at the top edge, move it there.
796  // It is important not to set moved to true if yTop is already 0. Doing so can cause a stack
797  // overflow.
798  if (yTop != 0) {
799  yTop = 0;
800  yCenter = yTopToCenter(yTop);
801  moved = true;
802  }
803  } else if (overNorthEdge()) {
804  yTop = 0;
805  yCenter = yTopToCenter(yTop);
806  moved = true;
807  } else if (overSouthEdge(canvasHeight)) {
808  yTop = canvasHeight - Height();
809  yCenter = yTopToCenter(yTop);
810  moved = true;
811  }
812 
813  // Then, call registerChange (just once!) if necessary.
814  if (moved) {
815  registerChange();
816  }
817  }
818 
823  protected void updateCoordinates() {
824  xLeft += speed * headingCos;
825  xCenter = xLeftToCenter(xLeft);
826  yTop += speed * headingSin;
827  yCenter = yTopToCenter(yTop);
828  }
829 
830  // Methods for determining collisions with other Sprites and the edge
831  // of the Canvas.
832 
833  private final boolean overWestEdge() {
834  return xLeft < 0;
835  }
836 
837  private final boolean overEastEdge(int canvasWidth) {
838  return xLeft + Width() > canvasWidth;
839  }
840 
841  private final boolean overNorthEdge() {
842  return yTop < 0;
843  }
844 
845  private final boolean overSouthEdge(int canvasHeight) {
846  return yTop + Height() > canvasHeight;
847  }
848 
849  protected int hitEdge(int canvasWidth, int canvasHeight) {
850  // Determine in which direction(s) we are out of bounds, if any.
851  // Note that more than one boolean value can be true. For example, if
852  // the sprite is past the northwest boundary, north and west will be true.
853  boolean west = overWestEdge();
854  boolean north = overNorthEdge();
855  boolean east = overEastEdge(canvasWidth);
856  boolean south = overSouthEdge(canvasHeight);
857 
858  // If no edge was hit, return.
859  if (!(north || south || east || west)) {
860  return Component.DIRECTION_NONE;
861  }
862 
863  // Move the sprite back into bounds. Note that we don't just reverse the
864  // last move, since that might have been multiple pixels, and we'd only need
865  // to undo part of it.
866  MoveIntoBounds();
867 
868  // Determine the appropriate return value.
869  if (west) {
870  if (north) {
872  } else if (south) {
874  } else {
875  return Component.DIRECTION_WEST;
876  }
877  }
878 
879  if (east) {
880  if (north) {
882  } else if (south) {
884  } else {
885  return Component.DIRECTION_EAST;
886  }
887  }
888 
889  if (north) {
890  return Component.DIRECTION_NORTH;
891  }
892  if (south) {
893  return Component.DIRECTION_SOUTH;
894  }
895 
896  // This should never be reached.
897  return Component.DIRECTION_NONE;
898  }
899 
908  public BoundingBox getBoundingBox(int border) {
909  return new BoundingBox(xLeft - border, yTop - border,
910  xLeft + Width() - 1 + border, yTop + Height() - 1 + border);
911  }
912 
922  public static boolean colliding(Sprite sprite1, Sprite sprite2) {
923  // If the bounding boxes don't intersect, there can be no collision.
924  BoundingBox rect1 = sprite1.getBoundingBox(1);
925  BoundingBox rect2 = sprite2.getBoundingBox(1);
926  if (!rect1.intersectDestructively(rect2)) {
927  return false;
928  }
929 
930  // If we get here, rect1 has been mutated to hold the intersection of the
931  // two bounding boxes. Now check every point in the intersection to see if
932  // both sprites contain that point.
933  // TODO(user): Handling abutting sprites properly
934  for (double x = rect1.getLeft(); x <= rect1.getRight(); x++) {
935  for (double y = rect1.getTop(); y <= rect1.getBottom(); y++) {
936  if (sprite1.containsPoint(x, y) && sprite2.containsPoint(x, y)) {
937  return true;
938  }
939  }
940  }
941  return false;
942  }
943 
950  public boolean intersectsWith(BoundingBox rect) {
951  // If the bounding boxes don't intersect, there can be no intersection.
952  BoundingBox rect1 = getBoundingBox(0);
953  if (!rect1.intersectDestructively(rect)) {
954  return false;
955  }
956 
957  // If we get here, rect1 has been mutated to hold the intersection of the
958  // two bounding boxes. Now check every point in the intersection to see if
959  // the sprite contains it.
960  for (double x = rect1.getLeft(); x < rect1.getRight(); x++) {
961  for (double y = rect1.getTop(); y < rect1.getBottom(); y++) {
962  if (containsPoint(x, y)) {
963  return true;
964  }
965  }
966  }
967  return false;
968  }
969 
978  public boolean containsPoint(double qx, double qy) {
979  return qx >= xLeft && qx < xLeft + Width() &&
980  qy >= yTop && qy < yTop + Height();
981  }
982 
983  // Convenience methods for dealing with hitting the screen edge and collisions
984 
985  // AlarmHandler implementation
986 
990  public void alarm() {
991  // This check on initialized is currently redundant, since registerChange()
992  // checks it too.
993  if (initialized && speed != 0) {
995  registerChange();
996  }
997  }
998 
999  // Component implementation
1000 
1001  @Override
1003  return canvas.$form();
1004  }
1005 
1006  // OnDestroyListener implementation
1007 
1008  @Override
1009  public void onDestroy() {
1010  timerInternal.Enabled(false);
1011  }
1012 
1013  // Deleteable implementation
1014 
1015  @Override
1016  public void onDelete() {
1017  timerInternal.Enabled(false);
1018  canvas.removeSprite(this);
1019  }
1020 
1021  // Abstract methods that must be defined by subclasses
1022 
1028  protected abstract void onDraw(android.graphics.Canvas canvas);
1029 }
com.google.appinventor.components.runtime.EventDispatcher
Definition: EventDispatcher.java:22
com.google.appinventor.components.runtime.util.BoundingBox.getTop
double getTop()
Definition: BoundingBox.java:78
com.google.appinventor.components.runtime.Sprite.onDestroy
void onDestroy()
Definition: Sprite.java:1009
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_FLOAT
static final String PROPERTY_TYPE_FLOAT
Definition: PropertyTypeConstants.java:76
com.google.appinventor.components.runtime.Sprite.getBoundingBox
BoundingBox getBoundingBox(int border)
Definition: Sprite.java:908
com.google.appinventor.components.runtime.Sprite.hitEdge
int hitEdge(int canvasWidth, int canvasHeight)
Definition: Sprite.java:849
com.google.appinventor.components.runtime.Sprite.headingRadians
double headingRadians
Definition: Sprite.java:92
com.google.appinventor.components.runtime.Sprite.moveIntoBounds
final void moveIntoBounds(int canvasWidth, int canvasHeight)
Definition: Sprite.java:766
com.google.appinventor.components.annotations.SimpleFunction
Definition: SimpleFunction.java:23
com.google.appinventor.components.runtime.Sprite.visible
boolean visible
Definition: Sprite.java:65
com.google.appinventor.components.runtime.Sprite.Dragged
void Dragged(float startX, float startY, float prevX, float prevY, float currentX, float currentY)
Definition: Sprite.java:470
com.google.appinventor.components.runtime.Sprite.Interval
void Interval(int interval)
Definition: Sprite.java:246
com.google.appinventor.components.runtime.Sprite.updateCoordinates
void updateCoordinates()
Definition: Sprite.java:823
com.google.appinventor.components.runtime.HandlesEventDispatching
Definition: HandlesEventDispatching.java:15
com.google.appinventor.components.runtime.Form.registerForOnDestroy
void registerForOnDestroy(OnDestroyListener component)
Definition: Form.java:817
com.google.appinventor.components.runtime.Sprite.CollidingWith
boolean CollidingWith(Sprite other)
Definition: Sprite.java:657
com.google.appinventor.components.runtime.Sprite.Sprite
Sprite(ComponentContainer container)
Definition: Sprite.java:140
com.google.appinventor.components.runtime.Sprite.heading
double heading
Definition: Sprite.java:91
com.google.appinventor.components.runtime.util
-*- mode: java; c-basic-offset: 2; -*-
Definition: AccountChooser.java:7
com.google.appinventor.components.runtime.Sprite.PointTowards
void PointTowards(Sprite target)
Definition: Sprite.java:701
com.google.appinventor.components.runtime.Sprite.Bounce
void Bounce(int edge)
Definition: Sprite.java:610
com.google.appinventor.components.runtime.Sprite.Y
void Y(double y)
Definition: Sprite.java:362
com.google.appinventor.components.runtime.Sprite.zLayer
double zLayer
Definition: Sprite.java:68
com.google.appinventor.components.runtime.Sprite.canvas
final Canvas canvas
Definition: Sprite.java:48
com.google.appinventor.components.runtime.AlarmHandler
Definition: AlarmHandler.java:14
com.google.appinventor.components.runtime.util.BoundingBox
Definition: BoundingBox.java:13
com.google.appinventor.components.runtime.Sprite.userHeading
double userHeading
Definition: Sprite.java:84
com.google.appinventor.components.annotations.DesignerProperty
Definition: DesignerProperty.java:25
com.google.appinventor.components.runtime.Sprite.colliding
static boolean colliding(Sprite sprite1, Sprite sprite2)
Definition: Sprite.java:922
com.google.appinventor.components.runtime.Canvas.$form
Form $form()
Definition: Canvas.java:877
com.google.appinventor.components.runtime.Sprite.originAtCenter
boolean originAtCenter
Definition: Sprite.java:72
com.google.appinventor.components.runtime.VisibleComponent.Width
abstract int Width()
com.google.appinventor.components
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_NON_NEGATIVE_INTEGER
static final String PROPERTY_TYPE_NON_NEGATIVE_INTEGER
Definition: PropertyTypeConstants.java:206
com.google.appinventor.components.runtime.util.BoundingBox.getBottom
double getBottom()
Definition: BoundingBox.java:96
com.google.appinventor.components.runtime.Sprite.headingSin
double headingSin
Definition: Sprite.java:94
com.google.appinventor.components.runtime.Sprite.EdgeReached
void EdgeReached(int edge)
Definition: Sprite.java:489
com.google.appinventor.components.runtime.Sprite.Flung
void Flung(float x, float y, float speed, float heading, float xvel, float yvel)
Definition: Sprite.java:553
com.google.appinventor.components.runtime.Component.DIRECTION_SOUTH
static final int DIRECTION_SOUTH
Definition: Component.java:139
com.google.appinventor.components.common.PropertyTypeConstants.PROPERTY_TYPE_BOOLEAN
static final String PROPERTY_TYPE_BOOLEAN
Definition: PropertyTypeConstants.java:35
com.google.appinventor.components.runtime.Sprite
Definition: Sprite.java:37
com.google.appinventor.components.runtime.Canvas.getView
View getView()
Definition: Canvas.java:792
com.google.appinventor.components.runtime.util.BoundingBox.getLeft
double getLeft()
Definition: BoundingBox.java:69
com.google.appinventor.components.runtime.Component.DIRECTION_NORTHWEST
static final int DIRECTION_NORTHWEST
Definition: Component.java:142
com.google.appinventor.components.runtime.Sprite.OriginAtCenter
void OriginAtCenter(boolean b)
Definition: Sprite.java:396
com.google.appinventor.components.runtime.Sprite.yCenter
double yCenter
Definition: Sprite.java:74
com.google.appinventor.components.runtime.Sprite.TouchDown
void TouchDown(float x, float y)
Definition: Sprite.java:585
com.google.appinventor.components.annotations.SimpleEvent
Definition: SimpleEvent.java:20
com.google.appinventor.components.runtime.Sprite.speed
float speed
Definition: Sprite.java:69
com.google.appinventor.components.runtime.util.BoundingBox.intersectDestructively
boolean intersectDestructively(BoundingBox bb)
Definition: BoundingBox.java:43
com.google.appinventor.components.runtime.Component.DIRECTION_WEST
static final int DIRECTION_WEST
Definition: Component.java:141
com.google.appinventor.components.runtime.errors.IllegalArgumentError
Definition: IllegalArgumentError.java:17
com.google.appinventor.components.runtime.Sprite.Y
double Y()
Definition: Sprite.java:367
com.google.appinventor.components.runtime.Component.DIRECTION_MAX
static final int DIRECTION_MAX
Definition: Component.java:146
com.google.appinventor.components.runtime.Sprite.Touched
void Touched(float x, float y)
Definition: Sprite.java:529
com.google.appinventor.components.runtime.util.TimerInternal.Interval
int Interval()
Definition: TimerInternal.java:72
com.google.appinventor.components.runtime.Sprite.CollidedWith
void CollidedWith(Sprite other)
Definition: Sprite.java:435
com.google.appinventor.components.runtime.errors.AssertionFailure
Definition: AssertionFailure.java:16
com.google.appinventor.components.runtime.Sprite.containsPoint
boolean containsPoint(double qx, double qy)
Definition: Sprite.java:978
com.google.appinventor.components.runtime.Sprite.Sprite
Sprite(ComponentContainer container, Handler handler)
Definition: Sprite.java:103
com.google.appinventor.components.runtime.Component.DIRECTION_NONE
static final int DIRECTION_NONE
Definition: Component.java:144
com.google.appinventor.components.runtime.Sprite.DEFAULT_ORIGIN_AT_CENTER
static final boolean DEFAULT_ORIGIN_AT_CENTER
Definition: Sprite.java:46
com.google.appinventor.components.runtime.VisibleComponent
Definition: VisibleComponent.java:20
com.google.appinventor.components.runtime.util.TimerInternal.Enabled
boolean Enabled()
Definition: TimerInternal.java:95
com.google.appinventor.components.runtime.Sprite.Z
double Z()
Definition: Sprite.java:390
com.google.appinventor.components.runtime.Sprite.yTop
double yTop
Definition: Sprite.java:67
com.google.appinventor.components.runtime.Sprite.headingCos
double headingCos
Definition: Sprite.java:93
com.google.appinventor.components.runtime.Sprite.onDraw
abstract void onDraw(android.graphics.Canvas canvas)
com.google.appinventor.components.runtime.EventDispatcher.dispatchEvent
static boolean dispatchEvent(Component component, String eventName, Object...args)
Definition: EventDispatcher.java:188
com.google.appinventor.components.runtime.Component.DIRECTION_SOUTHWEST
static final int DIRECTION_SOUTHWEST
Definition: Component.java:140
com.google.appinventor.components.runtime.Sprite.MoveIntoBounds
void MoveIntoBounds()
Definition: Sprite.java:674
com.google.appinventor.components.annotations.SimpleProperty
Definition: SimpleProperty.java:23
com.google.appinventor.components.runtime.Sprite.form
Form form
Definition: Sprite.java:76
com.google.appinventor.components.runtime.Sprite.MoveTo
void MoveTo(double x, double y)
Definition: Sprite.java:685
com.google.appinventor.components.annotations.PropertyCategory
Definition: PropertyCategory.java:13
com.google.appinventor.components.runtime.Sprite.registerChange
void registerChange()
Definition: Sprite.java:728
com.google.appinventor.components.runtime.Sprite.onDelete
void onDelete()
Definition: Sprite.java:1016
com.google.appinventor.components.runtime.VisibleComponent.Height
abstract int Height()
com.google.appinventor.components.runtime.ComponentContainer
Definition: ComponentContainer.java:16
com.google.appinventor.components.runtime.Sprite.initialized
boolean initialized
Definition: Sprite.java:60
com.google.appinventor.components.runtime
Copyright 2009-2011 Google, All Rights reserved.
Definition: AccelerometerSensor.java:8
com.google.appinventor.components.runtime.Component.DIRECTION_NORTH
static final int DIRECTION_NORTH
Definition: Component.java:135
com.google.appinventor.components.runtime.Component
Definition: Component.java:17
com.google.appinventor.components.runtime.Sprite.intersectsWith
boolean intersectsWith(BoundingBox rect)
Definition: Sprite.java:950
com.google.appinventor.components.runtime.Deleteable
Definition: Deleteable.java:15
com.google.appinventor.components.runtime.Sprite.Visible
boolean Visible()
Definition: Sprite.java:287
com.google.appinventor.components.runtime.Sprite.postEvent
void postEvent(final Sprite sprite, final String eventName, final Object... args)
Definition: Sprite.java:415
com.google.appinventor.components.runtime.Sprite.PointInDirection
void PointInDirection(double x, double y)
Definition: Sprite.java:714
com.google.appinventor.components.common
Definition: ComponentCategory.java:7
com.google.appinventor.components.runtime.Sprite.X
double X()
Definition: Sprite.java:306
com.google.appinventor.components.runtime.Sprite.Initialize
void Initialize()
Definition: Sprite.java:147
com.google.appinventor.components.runtime.Sprite.NoLongerCollidingWith
void NoLongerCollidingWith(Sprite other)
Definition: Sprite.java:513
com.google.appinventor.components.runtime.Component.DIRECTION_NORTHEAST
static final int DIRECTION_NORTHEAST
Definition: Component.java:136
com.google.appinventor.components.runtime.util.TimerInternal
Definition: TimerInternal.java:17
com.google.appinventor.components.runtime.Sprite.hitEdge
int hitEdge()
Definition: Sprite.java:751
com.google.appinventor.components.runtime.Canvas
Definition: Canvas.java:132
com.google.appinventor.components.annotations.SimpleObject
Definition: SimpleObject.java:23
com.google.appinventor.components.runtime.util.BoundingBox.getRight
double getRight()
Definition: BoundingBox.java:87
com.google.appinventor.components.runtime.Sprite.alarm
void alarm()
Definition: Sprite.java:990
com.google
com.google.appinventor.components.runtime.Sprite.xLeft
double xLeft
Definition: Sprite.java:66
com
com.google.appinventor.components.runtime.Sprite.xCenter
double xCenter
Definition: Sprite.java:73
com.google.appinventor.components.runtime.Canvas.ready
boolean ready()
Definition: Canvas.java:820
com.google.appinventor.components.runtime.Sprite.TouchUp
void TouchUp(float x, float y)
Definition: Sprite.java:569
com.google.appinventor.components.runtime.errors
Definition: ArrayIndexOutOfBoundsError.java:7
com.google.appinventor.components.runtime.Canvas.Height
void Height(int height)
Definition: Canvas.java:997
com.google.appinventor.components.runtime.ComponentContainer.$form
Form $form()
com.google.appinventor.components.runtime.Component.DIRECTION_MIN
static final int DIRECTION_MIN
Definition: Component.java:145
com.google.appinventor.components.runtime.Component.DIRECTION_EAST
static final int DIRECTION_EAST
Definition: Component.java:137
com.google.appinventor.components.runtime.Sprite.Visible
void Visible(boolean visible)
Definition: Sprite.java:301
com.google.appinventor.components.runtime.Component.DIRECTION_SOUTHEAST
static final int DIRECTION_SOUTHEAST
Definition: Component.java:138
com.google.appinventor.components.runtime.Sprite.Speed
float Speed()
Definition: Sprite.java:276
com.google.appinventor.components.runtime.Sprite.Interval
int Interval()
Definition: Sprite.java:232
com.google.appinventor.components.runtime.Sprite.interval
int interval
Definition: Sprite.java:64
com.google.appinventor.components.runtime.Form
Definition: Form.java:126
com.google.appinventor.components.runtime.Sprite.getDispatchDelegate
HandlesEventDispatching getDispatchDelegate()
Definition: Sprite.java:1002
com.google.appinventor.components.runtime.Sprite.Enabled
boolean Enabled()
Definition: Sprite.java:166
com.google.appinventor.components.runtime.Canvas.Width
void Width(int width)
Definition: Canvas.java:973
com.google.appinventor.components.common.PropertyTypeConstants
Definition: PropertyTypeConstants.java:14
com.google.appinventor.components.runtime.OnDestroyListener
Definition: OnDestroyListener.java:15
com.google.appinventor.components.runtime.Sprite.Heading
double Heading()
Definition: Sprite.java:194
com.google.appinventor.components.annotations
com.google.appinventor.components.runtime.Sprite.Enabled
void Enabled(boolean enabled)
Definition: Sprite.java:180
com.google.appinventor