Aegidius
 Plüss   Aplulogo
     
 www.aplu.ch      Print Text 
© 2021, V10.4
 
  JTurtleLib
 
 

 

Miscellaneous Examples

 

1 Debugging Android Apps

Programming errors are not a shame, but common to all programmers, not only beginners. The art of programming is not so much to avoid programming bugs, but to track them down rapidly without getting frustrated. Therefore debugging methods are essential and should be trained at every level of programming education. Debugging is a special challenge for App programmers, because the usual debugging techniques does not work. When a severe error happens (e.g. divide-by-zero), the application just dies without saying anything about the location in the source code. To get an insight what is going on in your program, we need a powerful debugging tool that reports run-time errors. Fortunately the Android development guys created a debugging environment called LogCat. During the development phase, when the device is connected to the development PC via USB, the system outputs important messages in a console window. Moreover you can display your own string message very simply by calling the static L.i() method (L stands for the LogCat class and is kept short for convenience). Its like writing your debug messages in a console using System.out.println().

First you install and start the LogCat console using the link here (link also found in the right column). (This is a WebStart signed by University of Berne that installs all necessary files in <userhome>.jdroidlib and starts ExeDebugRT.)

If an attached device is found, the LogCat window opens. Now you are ready to write your own debugging messages using the L.i() method. In the following example we consciously make the common error, not to increment the variable i in the while-loop. If we watch the value of i in the error console, we easily track the bug.

logcat

As you see there are many interesting system messages, most of them generated by our JTurtleLib library code.

package turtle.tut11;

import turtle.*;

public class Tut11 extends Playground
{
  public void main()
  {
    st();
    L.i("speed = " + getSpeed());
    int i = 0;
    while (i < 10)
    {
      fd(10).rt(90).fd(10).lt(90);
      L.i("i = " + i);
    }  
  }
}

sierpi

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut11.zip).
downlink Android app for installation on a smartphone or emulator.

 

2 Drag and Fill

With JTurtleLib it is extremely simple to use screen touch events. The event notification methods (also called callbacks) are part of the Playground class and declared there with an empty body. By simply overriding one of these methods in your application class (derived from Playground), you get your own notification. There is a drawback of this simple design: If you misspell the name of the notification method, the program compiles, but fails to work. (To overcome this difficulty, you could use the @override annotation.)

In the following example we draw a line by 'dragging' the turtle (moving the finger while remaining in contact with the screen). While moving the finger, playgroundDrag() notifications are called in frequent repetition. (To avoid system overload, the drag events are disabled by default. We must call setDragEnabled(true) to enable them.) When we lift the finger, the playgroundRelease() notification is invoked that fills a closed region with the current pen color. (The flood-fill algorithm implemented in our library looks for all pixels in a closed region defined by the given x-y position. The color of every pixel that currently has the playground color is then changed to the pen color (see here for more information). If unfortunately the turtle sits on its own trace, x-y is slightly modified).

package turtle.tut12;

import turtle.*;

public class Tut12 extends Playground
{
  public void main()
  {
    st();
    setSpeed(MAXSPEED);  // Necessary
    setDragEnabled(true);
  }
  
  public void playgroundDragged(double x, double y)
  {
   setPenColor(WHITE);
   if (distance(x, y) > 10)
    
 moveTo(x, y);
  }

  public void playgroundReleased(double x, double y)
  {
    setPenColor(RED);
    fill(x, y);
  }
}

sierpi


Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut12.zip).
downlink Android app for installation on a smartphone or emulator.


There is another fill strategy, where you select a point or a horizontal or vertical line. The filling is performed while the turtle is moving. If you call fillToPoint(x, y) it's like you attach a rubber band from the anchor point (x, y) to the turtle. When the turtle moves, the area the band moves through is colored with the pen color.

package turtle.tut12a;

import turtle.*;

public class Tut12a extends Playground
{
  public void main()
  {
    st();
    setSpeed(MAXSPEED);  // Necessary
    setPenColor(RED);
    fillToPoint(0, - 50);
    setDragEnabled(true);
  }
  
  public void playgroundDragged(double x, double y)
  {
    if (distance(x, y) > 10)
      moveTo(x, y);
  }
}

sierpi

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut12a.zip).
downlink Android app for installation on a smartphone or emulator.

3 Line drawing, coordinate-based graphics

Turtle graphics realizes the direction-based drawing concept where the drawing pen has a current direction and lines are drawn by specifying how much the pen is moved forward or back. It is well-known that this approach is more natural to the kid's notion of drawing than using a x-y coordinate system. On the other hand, coordinate-based graphics is widely used in many graphics applications. Here the most important method is line() that takes the starting and the end point of the line to draw.

If you need coordinate-based graphics you can fake the line method in turtle graphics by calling setPos() and moveTo() and in animation mode you even see the turtle drawing the line heading to the end point. Lean back while observing how the turtle draws the famous Moire pattern in the following example.

package turtle.tut13;

import turtle.*;

public class Tut13 extends Playground
{
  public void main()
  {
    st();
    setSpeed(MAXSPEED);
    int i, k;
    for (= 0; i <= 150; i += 15)
    {
      for (= 0; k <= 150; k += 15)
      {
        setPos(i, 0);
        moveTo(k, 150);
      }
    }

    for (= 0; i <= 150; i += 15)
    {
      for (= 0; k <= 150; k += 15)
      {
        setPos(0, i);
        moveTo(150, k);
      }
    }
  }
}

sierpi

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut13.zip).
downlink Android app for installation on a smartphone or emulator.

 

4 Point drawing, Monte-Carlo simulation, User Input/Output

It is evident that programming has a logical background and, in some way, the stringent way of thinking of an exact science. But, by its dynamical nature, computer science is definitely different from mathematics. This distinction may be demonstrated by calculating the number pi, a challenge that played a major role in the history of mathematics. A typical approach using the computer is to throw 'points' (or rain drops) randomly on a square of side 1 and determine how many of them falls in a quarter of radius 1. Obviously the ratio should approach the quotient of the two surfaces, the quarter (= pi / 4) to the square (= 1). For sure you guess right that, greater the total number of drops is, better is the approximation of pi. (What you probably don't know is, that the algorithm is unfortunately quite inefficient.)

By displaying a simple modal input dialog, you ask the user how many drops should fall on the square area. readInt() is a convenient method that stops the main thread, displays a modal input dialog and waits until the user clicks the Ok button. The user entry is validated to be an integer. If the validation fails, the dialog is shown again. When readInt() returns you are sure to get a validated integer value. Now the turtle draws the requested number of single points at its random current position by calling dot(). Finally the tired turtle writes out the result by displaying an output dialog using showValue().

package turtle.tut14;

import turtle.*;

public class Tut14 extends Playground
{
  public void main()
  {
    while (true)
    {
      int nbDrops = 
       readInt(
"Monte-Carlo Simulation",
               "Enter the number of drops:");
      double zx, zy;
      int nbHits = 0;
      for (int i = 0; i < nbDrops; i++)
      {
        zx = Math.random();
        zy = Math.random();

        if (zx * zx + zy * zy < 1)
        {
          setPenColor(GREEN);
          nbHits++;
        }
        else
          setPenColor(RED);
        setPos(150 * zx, 150 * zy);
        dot();
      }
      showValue("Result with " + nbDrops + " drops"
        "pi = " + 4.0 * nbHits / nbDrops);
      clear();
    }
  }
}

 

sierpi

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut14.zip).
downlink Android app for installation on a smartphone or emulator.

 

5 Active Turtles

Normally turtles methods are called in the main() method and thus are fully controlled by a Java thread called the main thread. During a turtle's forward() call, the execution of the main thread is paused until the forward method returns. In animated mode this may take a while. Other turtles have to wait until they get their method call. There is much more action, if several turtle objects perform their movement at the same time (we say "in parallel"). To achieve this behavior we must give a self-contained "life" to each turtle object by running the turtle methods in their own thread. We call this an active turtle object.

Because JTurtleLib is thread-safe, multi-threading causes no special problems like thread synchronization and deadlocks.

In the following example we show how easy it is to make a turtle active. We define a class VitalTurtle derived from the Turtle class that implements the interface Runnable. This simply says that we implement the method run() in this class. run() will be executed in a independent thread by passing a VitalTurtle reference to the Thread class constructor and calling start().

Despite the independence of each turtle we want to let them interact when they get close together. Each turtle has access to a global data structure zoo to find out where are other turtles on the playground. We could conceive some funny interactions like generating turtle babies, but in this example we just let them take flight in panic and changing their color.

In main() we generate 10 turtles in 2 s intervals and add them into the zoo. We take some provision to keep the turtles inside the playground be testing if they are at the playground border and let them move back.

package turtle.tut15;

import turtle.*;
import java.util.*;

public class Tut15 extends Playground
{
  private static ArrayList<VitalTurtle> zoo = 
    new ArrayList<VitalTurtle>();

  public void main()
  {
    for (int i = 0; i < 10; i++)
    {
      VitalTurtle t = new VitalTurtle();
      zoo.add(t);
      delay(2000);
    }
  }

  class VitalTurtle extends Turtle implements Runnable
  {
    public VitalTurtle()
    {
      super(RED);
      new Thread(this).start();
    }

    public void run()
    {
      while (true)
      {
        lt((int)(Math.random() * 180) - 90);
        fd(10);
        if (isOnBorder())
          rt(180).fd(20);
        if (isProximity())
        {
          lt(180).fd(40);
          if (getColor() == RED)
            setColor(GREEN);
          else
            setColor(RED);
        }
      }
    }

    private boolean isProximity()
    {
      for (VitalTurtle t : zoo)
      {
        if (!= this)
        {
          double x = t.getX() - getX();
          double y = t.getY() - getY();
          if (* x + y * y < 400)
            return true;
        }
      }
      return false;
    }
  }
}

 

sierpi

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut15.zip).
downlink Android app for installation on a smartphone or emulator.

6 Create your own turtle image

Turtle Graphics on most systems shows a turtle sprite image designed by the system developer. Because JTurtleLib is based on the more sophisticated JDroidLib game framework where each game actor may have its own sprite image, you may modify the default turtle image by an image created by your own. Proceed as follows:

Draw your picture with your favorite graphics editor in jpg, gif or png format on a transparent background. Consider that your picture will be inserted into the square turtle playground with the virtual size of -200 to 200. Therefore the size of your picture should be something in the range 30 to 100 pixels (not necessarily a square). This is a virtual size, because, like the playground, your turtle picture will be automatically zoomed according to the current screen resolution.

Keep in mind that image pixels that are exactly white (RGB (255,255,255) will be colored at runtime to the current turtle color (set by setColor() or the turtle constructor). Any other pixel color is unchanged. You should use the png image format.

Copy your image file to the sdcard, preferable in a dedicated subfolder. (In our example we use the image file turtlecar.gif (download here) and put it into the folder "sprites". To request your app to use your own turtle image, initialize the Playground constructor with the image path.

package turtle.tut16;

import turtle.*;

public class Tut16 extends Playground
{
  public Tut16()
  {
    super("sprites/turtlecar.png");
  }
  
  public void main()
  {
    Turtle car = new Turtle(170, 0, RED);
    car.setSpeed(MAXSPEED);
    while (true)
      car.fd(3).lt(1);
  }
}

sierpi

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut16.zip).
downlink Android app for installation on a smartphone or emulator.

7 Turtle Fling

Smartphone and tablet users often perform a "sweep" gesture by moving rapidly with one finger over the screen. The system's reaction depends on the direction and the speed of the sweep. With Android this action is called a "fling gesture" and is well supported by the Android API. As with touch events we implement the detection of a fling gesture as an event that triggers a callback playgroundFlung(double xStart, double yStart, double xEnd, double yEnd, double v, double dir) where (xStart, yStart) defines the point where the finger taps the screen, (xEnd, yEnd) the point where the finger is lifted (in Turtle coordinates (-200, 200)). v is a measure for the fling speed and dir the direction of the fling movement (in degrees, zero to north, clockwise positive). This callback has an empty implementation in the GameGrid class, so you easily get your own notification by overriding it in your application class that is derived from Playground. Moreover like the playground touch events the fling callback is executed in its own thread. In the following example with each fling you launch a new turtle that draws a left or right winded clothoid curve.

package turtle.tut17;

import turtle.*;

public class Tut17 extends Playground
{
  public void playgroundFlung(double xStart, double yStart, 
    double xEnd, double yEnd, double v, double dir)
  {
     Turtle t = new Turtle(xEnd, yEnd);
     t.setSpeed(MAXSPEED);
     t.setHeading(dir);
     t.setSpeed((int)(/ 100));
     cloth(t, 10(Math.random() < 0.5)true : false);
  }
  
  void cloth(Turtle t, int s, boolean isLeft)
  {
    if (> 1000)
      return;
    t.fd(5);
    if (isLeft)
      t.lt(0.025 * s);
    else
      t.rt(0.025 * s);
    cloth(t, s + 5, isLeft);
  }
}

fling

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut17.zip).
downlink Android app for installation on a smartphone or emulator.

 

It is common to fling an object selected by the location where you start the fling movement. In the next example we show how you select a turtle using the (xStart, yStart) location. The turtle is moved to the (xEnd, yEnd) location rapidly and then draws a straight line whose lengths depends on the fling speed. You may determine which turtles are near your finger tap by calling getTurtleNear(double centerX, double centerY, double radius). This convenient method returns a list of all turtles whose perimeter intersects with the passed circle. getTopTurtleNear() returns the last object of this list that is displayed on top. These methods may also be used to realize turtle collision applications.

package turtle.tut17a;

import turtle.*;

public class Tut17a extends Playground
{
  public void main()
  {
    new Turtle(-1000, RED);
    new Turtle(00, GREEN);
    new Turtle(1000, YELLOW);
  }

  public void playgroundFlung(double xStart, double yStart,
    double xEnd, double yEnd, double v, double dir)
  {
    Turtle t = getTopTurtleNear(xStart, yStart, 20);
    if (== null)
      return;
    t.setSpeed(MAXSPEED);
    t.setHeading(dir);
    t.moveTo(xEnd, yEnd);
    t.setSpeed((int)(v / 100));
    t.fd(/ 10);
  }
}

fling2

Open source in Online-Compiler. (You need the latest version of JRE.)
Create QR code to download Android app to your smartphone.

downlink source (Tut17a.zip).
downlink Android app for installation on a smartphone or emulator.