6 Commits

Author SHA1 Message Date
c9a7ac9551 Partikel Beispiel 2022-06-19 22:45:53 +02:00
c6615cc817 Sprache zu Englisch geändert 2022-06-19 22:37:08 +02:00
4d981b62a4 Merge branch 'main' into partikel 2022-06-19 22:30:40 +02:00
05aae6e6cc Merge branch 'main' into partikel 2021-12-23 11:17:55 +01:00
5e42509f75 Partikel Test Programm 2021-12-23 11:13:59 +01:00
e2bdf1e998 Partikelsystem 2021-12-23 09:26:27 +01:00
289 changed files with 9078 additions and 22244 deletions

24
.gitignore vendored
View File

@@ -32,27 +32,3 @@ hs_err_pid*
.DS_Store
._*
Thumbs.db
.gradle
**/build/
!src/**/build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Avoid ignore Gradle wrappper properties
!gradle-wrapper.properties
# Cache of project
.gradletasknamecache
# Python mkdocs
.venv
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

View File

@@ -6,57 +6,11 @@ und diese Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased]
### Changed
- `FilledShape` und `StrokedShape` durch `Fillable` und `Strokeable` Interfaces ersetzt.
- `Shape` erweitert nun `BasisDrawable` als abstrakte Grundlage.
- `io` Klassen nutzen nun mehr der `java.nio` Funktionen.
- Package-Struktur angepasst.
## Version 0.0.23
### Added
- System für EventListener.
- `AudioListener` und `AnimationListener` als erste Anwendungsfälle.
- Pakete für Animationen und Maschinelles-Lernen.
- Farbverläufe als Füllung.
### Changed
- `update(double)` und `draw()` werden nun in einem eigenen Thread aufgerufen.
- Die Standardwerte in `Constants` wurden mit dem Prefix `DEFAULT_` benannt (vorher `STD_`).
- Die Standardwerte sind nun nicht mehr `final` und können vom Nutzer manuell gesetzt werden.
## Version 0.0.22
### Added
- Interface `Audio` extrahiert, mit Basisfunktionen von `Sound` und `Music`.
- Klasse `Mixer` steuert mehrere Audio-Objekte gleichzeitig.
- Klasse `tasks.RateLimitedTask`, `tasks.FramerateLimitedTask`, `tasks.FrameSynchronizedTask` und `tasks.DelayedTask`.
### Changed
- Neue Package-Struktur:
- `schule.ngb.zm.media` für Audio-Klassen (und ggf. zukünftig Video).
- `schule.ngb.zm.util.tasks` für alles Rund um Parallelität.
- `Zeichenthread` und `TaskRunner` setzen die Namen der Threads für besseres Debugging.
### Removed
- Beispielprojekte in [eigenes Repository](https://github.com/jneug/zeichenmaschine-examples) verschoben.
## Version 0.0.21
### Added
- Parameter `stop_after_draw` im Konstruktor der `Zeichenmaschine` erlaubt es beim Erstellen festzulegen, ob nach dem ersten Frame die Zeichenmaschine gestoppt wird.
- `Picture.tint(Color)` färbt ein Bild ein.
- `Picture.flip(Options.Direction)` spiegelt ein Bild entlang einer Achse (`LEFT`/`RIGHT` für horizontal, `UP`/`DOWN` für vertikal).
- Abstrakte Klasse `Zeichenobjekt` als einheitliche Oberklasse für Objekte in Projekten. Die Klasse erbt von `Constants` und implementiert `Drawabale` und `Updatable` mit leeren Methoden.
- Klasse `java.util.Validator` übernimmt intern Parametervalidierung.
- Klasse `Log` implementiert eine einfache Logging-API über `java.util.logging`.
- Klasse `TaskRunner` führt parallele Prozesse aus.
- `Zeichenmaschine#scheduleTask(Runnable, int)` führt eine Aufgabe nach einer Wartezeit im Gameloop aus.
- Neue Klasse `util.ResourceStreamProvider` sucht Resourcen und öffnet `InputStream`s.
### Changed
- Objektvariablen der `Zeichenmaschine`, die von Unterklassen genutzt werden sollen, sind nun statisch in `Constants`. Dadurch können auch andere Klasse, die von `Constants` erben ohne Umwege auf diese Werte zugreifen (z.B. `width`/`height` der Zeichenleinwand).
- `ImageLoader` und `FontLoader` wurden überarbeitet.
- Nutzung von `Log`
- Nutzung von `ResourceStreamProvider`
- Verarbeitung von Swing `InputEvent`s in einer eigenen interne EventQueue synchron zur Framerate.

View File

@@ -1,42 +0,0 @@
plugins {
id 'idea'
id 'java-library'
}
group 'schule.ngb'
version '0.0.32-SNAPSHOT'
compileJava {
options.release = 11
}
repositories {
mavenCentral()
}
dependencies {
runtimeOnly 'com.googlecode.soundlibs:jlayer:1.0.1.4'
runtimeOnly 'com.googlecode.soundlibs:tritonus-share:0.3.7.4'
runtimeOnly 'com.googlecode.soundlibs:mp3spi:1.9.5.4'
compileOnlyApi 'colt:colt:1.2.0'
//api 'colt:colt:1.2.0'
//api 'net.sourceforge.parallelcolt:parallelcolt:0.10.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}
test {
useJUnitPlatform()
}
tasks.register('jarMP3SPI', Jar) {
archiveClassifier = 'all'
duplicatesStrategy = 'exclude'
archivesBaseName = 'zeichenmaschine-mp3spi'
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

View File

@@ -1,12 +0,0 @@
h1.title {
text-align: center;
color: #363636;
margin-bottom: .25rem;
}
h2.subtitle {
text-align: center;
font-size: 1rem;
color: #4a4a4a;
margin-top: -.25rem;
margin-bottom: -1.25rem;
}

View File

@@ -1,7 +0,0 @@
{% extends "base.html" %}
{% block tabs %}
{{ super() }}
{% endblock %}
{% block content %}{% endblock %}
{% block footer %}{% endblock %}

View File

@@ -1,43 +0,0 @@
<figure markdown>
![Zeichenmaschine.xyz](assets/icon_512.png){ width=128 }
</figure>
<h1 class="title">Zeichenmaschine.xyz</h1>
<h2 class="subtitle">Eine kleine Java-Bibliothek für grafische Programmierung im
Informatikunterricht.</h2>
## Projektidee
Die **Zeichenmaschine** ist eine für den Informatikunterricht entwickelte Bibliothek,
die unter anderem an [Processing](https://processing.org/) angelehnt ist. Die
Bibliothek soll einige der üblichen Anfängerschwierigkeiten mit Java vereinfachen
und für Schülerinnen und Schüler im Unterricht nutzbar machen.
!!! warning
Das Projekt befindet sich noch in der Entwicklungsphase und auch wenn die
aktuelle Version schon funktionsfähig ist und einen Großteil der angestrebten
Funktionen enthält, ist noch keine stabile Version 1.0 erreicht. Vor allem
am Umfang und konsistenten Design der APIs gilt es noch zu arbeiten und es
können sich Änderungen ergeben.
Feedback und Vorschläge zu diesem Prozess (oder auch eine Beteiligung an der
Entwicklung) können sehr gerne über [Github](https://github.com/jneug) oder
[Mastodon](https://bildung.social/@ngb) an mich kommuniziert werden.
(Gleiches gilt für diese Webseite zum Projekt.)
## Dokumentation
* [Schnellstart](quickstart.md)
* [Installation](install.md)
* {{ javadoc_link() }}
## Über die Zeichenmaschine
!!! info
In der Zeichenmaschine werden bewusst nur englischsprachige Bezeichner für
Klassen, Methoden und Variablen verwendet. Ausnahme sind einzelne Klassen,
die im Zusammnehang mit dem Namen der Bibliothek stehen, wie die
Hauptklasse `Zeichenmaschine`.

View File

@@ -1,44 +0,0 @@
# Installation
Um ein einfaches Projekt mit der **Zeichenmaschine** aufzusetzen ist nicht mehr
nötig, als
die [JAR-Datei der aktuellen Version](https://github.com/jneug/zeichenmaschine/release/latest)
herunterzuladen und dem *Classpath* des Projekts hinzuzufügen. Beschreibungen
für
verschiedene Entwicklungsumgebungen sind hier aufgelistet.
## Integration in Entwicklungsumgebungen
### BlueJ
[BlueJ](https://bluej.org) sucht an drei Orten nach Bibliotheken, die für ein
Projekt in den Classpath aufgenommen werden:
- Für ein einzelnes Projekt im Projektordner im Unterordner `+libs`.
- Im Reiter "Bibliotheken" der BlueJ-Einstellungen.
Hier können Programmbibliotheken hinzugefügt werden, die dann allen Projekten
zur Verfügung stehen.
- Für alle Projekte und alle Nutzer dieser BlueJ-Version im
Unterordner `userlib` des Programmordners.
Auf Windows-Systemen ist dieser im Order `lib` des Installationsordners von BlueJ zu finden.
Auf macos-Systemen muss via Rechtsklick auf die Programmdatei `BlueJ.app` über den Menüpunkt "Paketinhalt zeigen" in den Ordner `Contents/Resources/Java/` navigiert werden.
### VSCode / VSCodium
> Coming soon
### IntelliJ
> Coming soon
### Eclipse
> Coming soon
### NetBeans
> Coming soon

View File

@@ -1,63 +0,0 @@
import re
from typing import List
def define_env(env):
@env.macro
def javadoc(clazz: str = None, target: str = None) -> str:
if not "javadoc_url" in env.variables:
return clazz
if not clazz:
return f"{env.variables['javadoc_url'].rstrip('/')}/index.html"
else:
if "javadoc_default_package" in env.variables and not clazz.startswith(env.variables['javadoc_default_package']):
clazz = f"{env.variables['javadoc_default_package'].rstrip('.')}.{clazz}"
javadoc_url = env.variables["javadoc_url"].rstrip("/")
path = clazz.replace(".", "/") + ".html"
if target:
path = f"{path}#{target}"
return f"{javadoc_url}/{path}"
@env.macro
def javadoc_link(
clazz: str = None, target: str = None, strip_package: bool = True, strip_clazz: bool = False, title: str = None
) -> str:
name = clazz or "Javadoc"
if strip_package:
if clazz and clazz.rfind(".") > -1:
name = clazz[clazz.rfind(".") + 1 :]
if target:
# _target = re.sub(r"([^(][^,]*?\.)*?([^)]+)", lambda m: m.group(2), target)
_target = target
if strip_clazz:
name = _target
else:
name = f"{name}.{_target}"
if title:
name = title
return f"[{name}]({javadoc(clazz, target)})"
@env.macro
def javadoc_signature(
clazz: str = None,
member: str = None,
package: str = None,
params: List[str] = list(),
) -> str:
sig = clazz or ""
if clazz and package:
sig = f"{package}.{sig}"
if member:
sig = f"{sig}#{member}"
pparams = ",".join(params)
sig = f"{sig}({pparams})"
return sig
# schule/ngb/zm/Zeichenmaschine.html#setCursor(java.awt.Image,int,int)
# schule/ngb/zm/Zeichenmaschine.html#getLayer(java.lang.Class)
# schule/ngb/zm/DrawableLayer.html#add(schule.ngb.zm.Drawable...)

View File

@@ -1,130 +0,0 @@
# Schnellstart mit der Zeichenmaschine
Um ein einfaches Projekt mit der **Zeichenmaschine** aufzusetzen ist nicht mehr
nötig, als die [JAR-Datei der aktuellen Version](https://github.com/jneug/zeichenmaschine/release/latest)
herunterzuladen und dem *Classpath* des Projekts hinzuzufügen. Eine Beschreibung
für verschiedene Entwicklungsumgebungen findet sich im Abschnitt [Installation](install.md).
## Die Basisklasse
Um eine Zeichenmaschine zu erstellen, muss eine Unterklasse von {{ javadoc_link("schule.ngb.zm.Zeichenmaschine") }}
erstellt werden.
```java
public class Shapes extends Zeichenmaschine {
}
```
Die gezeigte Klasse ist schon eine lauffähige Zeichenmaschine und kann gestartet
werden.
!!! note
Bei einigen Entwicklungsumgebungen muss noch eine `main`-Methode erstellt
werden, um die Zeichenmaschine zu starten:
```java
public static void main(String[] args) {
new Shapes();
}
```
Es öffnet sich ein Zeichenfenster in einer vordefinierten Größe. Um die Größe und
den Titel des Fensters zu ändern, legen wir einen Konstruktor an.
```java
public class Shapes extends Zeichenmaschine {
public Shapes() {
super(800, 800, "Shapes");
}
}
```
Starten wir das Projekt nun, wird das Zeichenfenster in der Größe 800x800 mit
dem Titel "Shapes" angezeigt.
<figure markdown>
![Shapes 2](assets/quickstart/shapes_2.png){ width=400 }
</figure>
### Formen zeichnen
Eine Zeichenmaschine hat verschiedene Möglichkeiten, Inhalte in das Zeichenfenster
zu zeichnen. Um einfach nur ein statisches Bild zu erzeugen, überschreiben wir die
{{ javadoc_link("schule.ngb.zm.Zeichenmaschine", "draw()") }} Methode.
```java
public class Shapes extends Zeichenmaschine {
public Shapes() {
super(800, 800, "Shapes");
}
@Override
public void draw() {
background.setColor(43, 128, 243);
drawing.setFillColor(255, 223, 34);
drawing.noStroke();
drawing.circle(400, 400, 100);
}
}
```
Nun haben wir einen gelben Kreis (ohne Konturlinie) auf einem blauen Hintergrund
gezeichnet.
<figure markdown>
![Shapes 3](assets/quickstart/shapes_3.png){ width=400 }
</figure>
### Vorbereitung der Zeichenfläche
Im Beispiel oben setzen wir die Hintergrundfarbe auf Blau, die Füllfarbe auf Gelb
und deaktivieren die Konturlinie. Wenn diese Einstellungen für alle Zeichenobjekte
gleich sind, können wir sie statt in `draw()` auch in die `setup()` Methode schreiben.
Diese bereitet die Zeichenfläche vor dem ersten Zeichnen vor.
```java
public class Shapes extends Zeichenmaschine {
public Shapes() {
super(800, 800, "Shapes");
}
@Override
public void setup() {
background.setColor(43, 128, 243);
drawing.setFillColor(255, 223, 34);
drawing.noStroke();
}
@Override
public void draw() {
for( int i = 0; i < 10; i++ ) {
drawing.circle(
random(0, canvasWidth),
random(0, canvasHeight),
random(50, 200)
);
}
}
}
```
Im Beispiel setzen wir nun die Grundeinstellungen in der `setup()` Methode. In
`draw()` werden zehn gelbe Kreise an Zufallskoordinaten gezeichnet.
<figure markdown>
![Shapes 4](assets/quickstart/shapes_4.1.png){ width=400 }
</figure>
!!! tip ""
Mit {{ javadoc_link("Constants", "canvasWidth", title="canvasWidth") }} und {{ javadoc_link("Constants", "canvasHeight", strip_clazz=True) }} kannst du in der Zeichenmaschine auf
die aktuelle Größe der Zeichenfläche zugreifen. {{ javadoc_link("Constants", "random(int,int)") }}
erzeugt eine Zufallszahl innerhalb der angegebenen Grenzen.

View File

@@ -0,0 +1,53 @@
import schule.ngb.zm.Zeichenmaschine;
import schule.ngb.zm.util.ImageLoader;
public class Aquarium extends Zeichenmaschine {
public static final int N_FISHES = 25;
public static void main( String[] args ) {
new Aquarium();
}
private Fish[] fish;
public Aquarium() {
super(800, 600, "Aquarium");
}
@Override
public void setup() {
canvas.addLayer(1, new Background());
fish = new Fish[N_FISHES];
for( int i = 1; i <= 7; i++ ) {
ImageLoader.preloadImage("fish"+i, "tiles/fish"+i+"gs.png");
}
for( int i = 0; i < N_FISHES; i++ ) {
fish[i] = new Fish();
shapes.add(fish[i]);
}
}
@Override
public void update( double delta ) {
for( int i = 0; i < fish.length; i++ ) {
fish[i].update(delta);
}
}
@Override
public void draw() {
}
@Override
public void mouseClicked() {
for( int i = 0; i < fish.length; i++ ) {
fish[i].randomize();
}
}
}

View File

@@ -0,0 +1,59 @@
import schule.ngb.zm.Layer;
import java.awt.Graphics2D;
import java.awt.Image;
public class Background extends Layer {
private static final int TILE_SIZE = 64;
private int tile_width;
private Image[] floor, plants;
private Image water;
public Background() {
super();
}
public Background( int width, int height ) {
super(width, height);
}
@Override
public void setSize( int width, int height ) {
super.setSize(width, height);
generateBackground();
}
public void generateBackground() {
tile_width = (int)(ceil(getWidth()/(double)TILE_SIZE));
floor = new Image[tile_width];
plants = new Image[tile_width];
for ( int i = 0; i < tile_width; i++ ) {
floor[i] = loadImage("tiles/floor"+random(1,8)+".png");
if( random(1,10) < 4 ) {
plants[i] = loadImage("tiles/plant"+random(1,14)+".png");
}
}
water = loadImage("tiles/water.png");
for ( int i = 0; i < getHeight(); i += TILE_SIZE ) {
for ( int j = 0; j < getWidth(); j += TILE_SIZE ) {
drawing.drawImage(water, j, i, null);
}
}
for ( int i = 0; i < tile_width; i++ ) {
if( plants[i] != null ) {
drawing.drawImage(plants[i], i*TILE_SIZE, getHeight() - (2*TILE_SIZE) + 10,TILE_SIZE,TILE_SIZE, null);
}
drawing.drawImage(floor[i], i*TILE_SIZE, getHeight() - TILE_SIZE,TILE_SIZE,TILE_SIZE, null);
}
}
}

View File

@@ -0,0 +1,72 @@
import schule.ngb.zm.*;
import schule.ngb.zm.shapes.Picture;
import schule.ngb.zm.shapes.Shape;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
public class Fish extends Shape implements Updatable {
private int speed;
private Picture img;
public Fish() {
randomize();
}
public void randomize() {
int i = random(1, 7);
speed = random(-2, 2);
img = new Picture("fish" + i);
img.setAnchor(NORTHWEST);
img.scale(random(0.8, 1.0));
img.tint(randomNiceColor());
//img.scale(0.5);
if( speed < 0 ) {
img.flip(LEFT);
}
img.moveTo(random(10, width-img.getWidth()), random(30, height-120));
}
@Override
public boolean isActive() {
return true;
}
@Override
public void update( double delta ) {
img.move(speed, .5 * sin(tick / (speed * 10.0)));
if( img.getX() <= 0 || img.getX()+img.getWidth() >= 800 ) {
speed *= -1;
img.flip(LEFT);
}
}
@Override
public void draw( Graphics2D graphics, AffineTransform transform ) {
img.draw(graphics, transform);
}
@Override
public double getWidth() {
return img.getWidth();
}
@Override
public double getHeight() {
return img.getHeight();
}
@Override
public Shape copy() {
return img.copy();
}
@Override
public java.awt.Shape getShape() {
return img.getShape();
}
}

View File

@@ -0,0 +1,55 @@
#BlueJ package file
dependency1.from=Attractor
dependency1.to=Gravity
dependency1.type=UsesDependency
dependency2.from=Gravity
dependency2.to=Mover
dependency2.type=UsesDependency
dependency3.from=Gravity
dependency3.to=Attractor
dependency3.type=UsesDependency
editor.fx.0.height=728
editor.fx.0.width=1037
editor.fx.0.x=95
editor.fx.0.y=53
objectbench.height=94
objectbench.width=776
package.divider.horizontal=0.6
package.divider.vertical=0.8305369127516778
package.editor.height=488
package.editor.width=661
package.editor.x=374
package.editor.y=158
package.frame.height=660
package.frame.width=800
package.numDependencies=3
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=60
readme.name=@README
readme.width=48
readme.x=10
readme.y=10
target1.height=70
target1.name=Mover
target1.showInterface=false
target1.type=ClassTarget
target1.width=120
target1.x=380
target1.y=220
target2.height=70
target2.name=Attractor
target2.showInterface=false
target2.type=ClassTarget
target2.width=120
target2.x=380
target2.y=350
target3.height=70
target3.name=Gravity
target3.showInterface=false
target3.type=ClassTarget
target3.width=120
target3.x=120
target3.y=120

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1013 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

128
examples/zm_boids/Boid.java Normal file
View File

@@ -0,0 +1,128 @@
import schule.ngb.zm.*;
import java.util.List;
public class Boid extends Creature {
public static final double COHESION_FACTOR = .5;
public static final double SEPARATION_FACTOR = .5;
public static final double ALIGNMENT_FACTOR = .5;
public static final double FLIGHT_FACTOR = .5;
public static final double VELOCITY_LIMIT = 3.0;
public static final double FORCE_LIMIT = .1;
public static final int FLOCK_RADIUS = 100;
public static final boolean SHOW_RADIUS = false;
public static final int BOID_WIDTH = 8;
public static final int BOID_HEIGHT = 16;
private boolean highlight = false;
public Boid() {
// Generate random Boid
super(
Vector.random(BOID_WIDTH, width-BOID_WIDTH, BOID_HEIGHT, height-BOID_HEIGHT),
Vector.random(-1, 1).scale(random(VELOCITY_LIMIT))
);
senseRange = FLOCK_RADIUS;
}
public Boid( Vector pos, Vector vel ) {
super(pos, vel);
senseRange = FLOCK_RADIUS;
}
public void toggleHighlight() {
highlight = !highlight;
}
public void draw( DrawingLayer drawing ) {
drawing.setFillColor(251, 241, 195);
drawing.setStrokeColor(239, 191, 77);
drawing.setStrokeWeight(2);
drawing.pushMatrix();
drawing.translate(position.x, position.y);
drawing.rotate(90 + velocity.angle());
drawing.triangle(BOID_WIDTH / -2.0, BOID_HEIGHT / 2.0, 0, BOID_HEIGHT / -2.0, BOID_WIDTH / 2.0, BOID_HEIGHT / 2.0);
if( SHOW_RADIUS || highlight ) {
drawing.setFillColor(251, 241, 195, 33);
drawing.noStroke();
drawing.circle(0, 0, FLOCK_RADIUS);
}
drawing.popMatrix();
}
public void update( List<Creature> creatures ) {
Vector cohesion = new Vector();
Vector separation = new Vector();
Vector alignment = new Vector();
Vector flight = new Vector();
int boids = 0, predators = 0;
for( Creature c: creatures ) {
if( isInRange(c) ) {
if( Predator.class.isInstance(c) ) {
double distSq = position.distanceSq(c.getPosition());
flight.add(Vector.sub(position, c.getPosition()).div(distSq));
predators += 1;
} else {
cohesion.add(c.getPosition());
alignment.add(c.getVelocity());
double distSq = position.distanceSq(c.getPosition());
separation.add(Vector.sub(position, c.getPosition()).div(distSq));
boids += 1;
}
}
}
if( boids > 0 ) {
// Cohesion
cohesion.div(boids).sub(position);
cohesion.setLength(VELOCITY_LIMIT).sub(velocity);
cohesion.limit(FORCE_LIMIT);
cohesion.scale(COHESION_FACTOR);
// Separation
separation.div(boids);
separation.setLength(VELOCITY_LIMIT).sub(velocity);
separation.limit(FORCE_LIMIT);
separation.scale(SEPARATION_FACTOR);
// Alignment
alignment.div(boids);
alignment.setLength(VELOCITY_LIMIT).sub(velocity);
alignment.limit(FORCE_LIMIT);
alignment.scale(ALIGNMENT_FACTOR);
}
if( predators > 0 ) {
flight.div(predators);
flight.setLength(VELOCITY_LIMIT).sub(velocity);
flight.limit(FORCE_LIMIT*4.0);
flight.scale(FLIGHT_FACTOR);
}
acceleration
.scale(0.0)
.add(separation)
.add(cohesion)
.add(alignment)
.add(flight);
position.add(velocity);
limitPosition();
velocity.add(acceleration).limit(VELOCITY_LIMIT);
}
}

View File

@@ -0,0 +1,78 @@
import schule.ngb.zm.*;
import schule.ngb.zm.util.ImageLoader;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
public class Boids extends Zeichenmaschine {
public static void main( String[] args ) {
new Boids();
}
public static final boolean BORDER_WRAP = true;
public static final int N_BOIDS = 200;
public static final int N_PREDATORS = 0;
private List<Creature> creatures;
public Boids() {
super(1280, 720, "ZM: Boids");
}
@Override
public void setup() {
setFullscreen(true);
setCursor(ImageLoader.loadImage("pointer.png"), 0, 0);
creatures = new ArrayList<Creature>();
synchronized( creatures ) {
for( int i = 0; i < N_BOIDS; i++ ) {
creatures.add(new Boid());
}
for( int i = 0; i < N_PREDATORS; i++ ) {
creatures.add(new Predator());
}
}
}
@Override
public void update( double delta ) {
synchronized( creatures ) {
for( Creature c : creatures ) {
c.update(creatures);
}
}
}
@Override
public void draw() {
drawing.clear(0, 125, 182);
synchronized( creatures ) {
for( Creature c : creatures ) {
c.draw(drawing);
}
}
}
@Override
public void mouseClicked() {
synchronized( creatures ) {
creatures.add(new Predator(
Vector.mouse(), Vector.ZERO
));
}
}
@Override
public void keyPressed() {
if( keyCode == KeyEvent.VK_G ) {
setSize(800, 800);
}
}
}

View File

@@ -0,0 +1,77 @@
import schule.ngb.zm.Constants;
import schule.ngb.zm.DrawingLayer;
import schule.ngb.zm.Vector;
import java.util.List;
public abstract class Creature extends Constants {
protected Vector position, velocity, acceleration;
protected int senseRange = 100;
public Creature( Vector pos, Vector vel ) {
position = pos.copy();
velocity = vel.copy();
acceleration = new Vector();
}
public Vector getPosition() {
return position;
}
public Vector getVelocity() {
return velocity;
}
public abstract void draw( DrawingLayer drawing );
public abstract void update( List<Creature> creatures );
protected void limitPosition() {
if( position.x < 0 ) {
if( Boids.BORDER_WRAP ) {
position.x = width;
} else {
position.x = 0;
//velocity.mult(-1);
acceleration.add(Vector.scale(velocity, -2));
}
} else if( position.x > width ) {
if( Boids.BORDER_WRAP ) {
position.x = 0;
} else {
position.x = width;
//velocity.mult(-1);
acceleration.add(Vector.scale(velocity, -2));
}
}
if( position.y < 0 ) {
if( Boids.BORDER_WRAP ) {
position.y = height;
} else {
position.y = 0;
//velocity.mult(-1);
acceleration.add(Vector.scale(velocity, -2));
}
} else if( position.y > height ) {
if( Boids.BORDER_WRAP ) {
position.y = 0.0;
} else {
position.y = height;
//velocity.mult(-1);
acceleration.add(Vector.scale(velocity, -2));
}
}
}
protected boolean isInRange( Creature otherCreature ) {
if( otherCreature == this || otherCreature == null ) {
return false;
}
if( abs(position.x-otherCreature.getPosition().x) > senseRange ) {
return false;
}
return position.distanceSq(otherCreature.getPosition()) < senseRange*senseRange;
}
}

View File

@@ -0,0 +1,97 @@
import schule.ngb.zm.DrawingLayer;
import schule.ngb.zm.Vector;
import java.util.List;
public class Predator extends Creature {
public static final int SENSE_RADIUS = 180;
public static final double AVOIDANCE_FACTOR = .65;
public static final double HUNTING_FACTOR = .65;
public static final double VELOCITY_LIMIT = 5.0;
public static final double FORCE_LIMIT = .1;
public static final int PREDATOR_WIDTH = 12;
public static final int PREDATOR_HEIGHT = 26;
public static final boolean SHOW_RADIUS = true;
public Predator() {
// Generate random Predator
super(
Vector.random(PREDATOR_WIDTH, width - PREDATOR_WIDTH, PREDATOR_HEIGHT, height - PREDATOR_HEIGHT),
Vector.random(-1, 1).scale(random(VELOCITY_LIMIT))
);
senseRange = SENSE_RADIUS;
}
public Predator( Vector pos, Vector vel ) {
super(pos, vel);
senseRange = SENSE_RADIUS;
}
public void draw( DrawingLayer drawing ) {
drawing.setFillColor(152, 61, 83);
drawing.setStrokeColor(225, 33, 32);
drawing.setStrokeWeight(2);
drawing.pushMatrix();
drawing.translate(position.x, position.y);
drawing.rotate(90 + velocity.angle());
drawing.triangle(PREDATOR_WIDTH / -2.0, PREDATOR_HEIGHT / 2.0, 0, PREDATOR_HEIGHT / -2.0, PREDATOR_WIDTH / 2.0, PREDATOR_HEIGHT / 2.0);
if( SHOW_RADIUS ) {
drawing.setFillColor(152, 61, 83, 33);
drawing.noStroke();
drawing.circle(0, 0, SENSE_RADIUS);
}
drawing.popMatrix();
}
public void update( List<Creature> creatures ) {
Vector hunting = new Vector();
Vector separation = new Vector();
double boids = 0, predators = 0;
for( Creature c : creatures ) {
if( isInRange(c) ) {
if( Boid.class.isInstance(c) ) {
hunting.add(c.getPosition());
boids += 1;
} else {
double distSq = position.distanceSq(c.getPosition());
separation.add(Vector.sub(position, c.getPosition()).div(distSq));
predators += 1;
}
}
}
if( boids > 0 ) {
hunting.div(boids).sub(position);
hunting.setLength(VELOCITY_LIMIT).sub(velocity);
hunting.limit(FORCE_LIMIT);
hunting.scale(HUNTING_FACTOR);
}
if( predators > 0 ) {
separation.div(predators);
separation.setLength(VELOCITY_LIMIT).sub(velocity);
separation.limit(FORCE_LIMIT);
separation.scale(AVOIDANCE_FACTOR);
}
acceleration
.scale(0.0)
.add(hunting)
.add(separation);
position.add(velocity);
limitPosition();
velocity.add(acceleration).limit(VELOCITY_LIMIT);
}
}

View File

@@ -0,0 +1,55 @@
#BlueJ package file
dependency1.from=Attractor
dependency1.to=Gravity
dependency1.type=UsesDependency
dependency2.from=Gravity
dependency2.to=Mover
dependency2.type=UsesDependency
dependency3.from=Gravity
dependency3.to=Attractor
dependency3.type=UsesDependency
editor.fx.0.height=728
editor.fx.0.width=1037
editor.fx.0.x=95
editor.fx.0.y=53
objectbench.height=94
objectbench.width=776
package.divider.horizontal=0.6
package.divider.vertical=0.8305369127516778
package.editor.height=488
package.editor.width=661
package.editor.x=374
package.editor.y=158
package.frame.height=660
package.frame.width=800
package.numDependencies=3
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=60
readme.name=@README
readme.width=48
readme.x=10
readme.y=10
target1.height=70
target1.name=Mover
target1.showInterface=false
target1.type=ClassTarget
target1.width=120
target1.x=380
target1.y=220
target2.height=70
target2.name=Attractor
target2.showInterface=false
target2.type=ClassTarget
target2.width=120
target2.x=380
target2.y=350
target3.height=70
target3.name=Gravity
target3.showInterface=false
target3.type=ClassTarget
target3.width=120
target3.x=120
target3.y=120

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,101 @@
import schule.ngb.zm.GraphicsLayer;
import schule.ngb.zm.Options;
import schule.ngb.zm.Zeichenmaschine;
import schule.ngb.zm.shapes.Picture;
import schule.ngb.zm.shapes.Text;
import java.util.ArrayList;
public class Cookieclicker extends Zeichenmaschine {
public static void main( String[] args ) {
new Cookieclicker();
}
private int cookies = 0;
private int cookiesPerClick = 1;
private int grandmas = 0;
private int autoclicker = 12, autoclickerTimer = 0, autoClickerDelay = 600;
private Text tCookies, tShopGrandma, tShopAutoclicker;
private Picture pCookie;
private boolean cookieDown = false;
public Cookieclicker() {
super(1280, 900, "Cookieclicker");
}
@Override
public void setup() {
pCookie = new Picture(width / 2, height / 2, "assets/cookie.png");
pCookie.scale(.5);
shapes.add(pCookie);
tCookies = new Text(width - 60, 60, "" + cookies);
tCookies.setAnchor(NORTHEAST);
tCookies.setStrokeColor(255);
tCookies.setFontsize(36);
shapes.add(tCookies);
background.setColor(0);
}
@Override
public void update( double delta ) {
tCookies.setText("" + cookies);
autoclickerTimer -= (int)(delta * 1000.0);
if( autoclickerTimer <= 0 ) {
cookies += autoclicker;
autoclickerTimer += autoClickerDelay;
}
synchronized( particles ) {
ArrayList<NumberParticle> remove = new ArrayList<>();
for( NumberParticle p : particles ) {
if( p.isActive() ) {
p.update(delta);
} else {
remove.add(p);
}
}
for( NumberParticle p : remove ) {
particles.remove(p);
}
}
}
@Override
public void draw() {
}
ArrayList<NumberParticle> particles = new ArrayList<>();
@Override
public void mousePressed() {
if( pCookie.getBounds().contains(mouseX, mouseY) ) {
cookieDown = true;
cookies += cookiesPerClick;
pCookie.scale(.95);
synchronized( particles ) {
NumberParticle p = new NumberParticle(mouseX, mouseY, cookiesPerClick);
particles.add(p);
shapes.add(p);
}
}
}
@Override
public void mouseReleased() {
if( cookieDown ) {
pCookie.scale(1 / .95);
}
}
}

View File

@@ -0,0 +1,33 @@
import schule.ngb.zm.Updatable;
import schule.ngb.zm.shapes.Text;
public class NumberParticle extends Text implements Updatable {
double sinOffset, life = 0;
public NumberParticle( double x, double y, int number ) {
super(x,y,"+"+number);
sinOffset = random(0.0, PI);
life = 1.5;
setStrokeColor(255);
setFontsize(36);
}
@Override
public boolean isActive() {
return (life > 0);
}
@Override
public void update( double delta ) {
if( isActive() ) {
double deltaX = sin(sinOffset + life);
x += deltaX;
y -= 100*delta;
life -= delta;
setStrokeColor(strokeColor, (int) interpolate(0, 255, life / 1.5));
}
}
}

View File

@@ -0,0 +1,111 @@
import schule.ngb.zm.Drawable;
import schule.ngb.zm.Updatable;
import schule.ngb.zm.shapes.Text;
import java.awt.Graphics2D;
import java.util.ArrayList;
public class NumberParticleEmitter implements Updatable, Drawable {
public class NumberParticle extends Text implements Updatable {
double velX = 0, velY = 0, accX = 0, accY = 0;
double life = 0;
public NumberParticle() {
super(0, 0, "0");
// life = particleLifespan;
}
@Override
public boolean isActive() {
return (life <= 0);
}
public void activate() {
x = emitterX;
y = emitterY;
life = particleLifespan;
}
@Override
public void update( double delta ) {
if( isActive() ) {
velX += accX;
velY += accY;
x += velX;
y += velY;
life -= delta;
setFillColor(fillColor, (int) interpolate(0, 255, life / particleLifespan));
}
}
}
private int particlesPerSecond, maxParticles;
private double particleLifespan;
private ArrayList<NumberParticle> particles;
private int activeParticles = 0;
private double lastEmit = 0.0;
private double emitterX, emitterY;
public NumberParticleEmitter( double x, double y, int particlesPerSecond, double particleLifespan ) {
emitterX = x;
emitterY = y;
this.particlesPerSecond = particlesPerSecond;
this.particleLifespan = particleLifespan;
maxParticles = (int) Math.ceil(particlesPerSecond * particleLifespan);
particles = new ArrayList<>(maxParticles);
for( int i = 0; i < maxParticles; i++ ) {
particles.add(new NumberParticle());
}
}
@Override
public boolean isVisible() {
return activeParticles > 0;
}
@Override
public void draw( Graphics2D graphics ) {
for( NumberParticle p : particles ) {
if( p.isActive() ) {
p.draw(graphics);
}
}
}
@Override
public boolean isActive() {
return isVisible();
}
public void emitParticle( int number ) {
particles.add(new NumberParticle());
}
@Override
public void update( double delta ) {
//lastEmit -= delta;
for( NumberParticle p : particles ) {
if( p.isActive() ) {
p.update(delta);
} /*else if( lastEmit <= 0 ) {
p.activate();
lastEmit += 1/(double)particlesPerSecond;
}*/
}
}
}

View File

@@ -0,0 +1,36 @@
import schule.ngb.zm.GraphicsLayer;
import schule.ngb.zm.Zeichenmaschine;
public class ParticleTest extends Zeichenmaschine {
public static void main( String[] args ) {
new ParticleTest();
}
private NumberParticleEmitter emitter;
private GraphicsLayer graphics;
public ParticleTest() {
super(800,800, "Particles");
}
@Override
public void setup() {
graphics = new GraphicsLayer();
canvas.addLayer(graphics);
emitter = new NumberParticleEmitter(400, 400, 1, 10);
}
@Override
public void update( double delta ) {
emitter.update(delta);
}
@Override
public void draw() {
emitter.draw(graphics.getGraphics());
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -0,0 +1,55 @@
#BlueJ package file
dependency1.from=Attractor
dependency1.to=Gravity
dependency1.type=UsesDependency
dependency2.from=Gravity
dependency2.to=Mover
dependency2.type=UsesDependency
dependency3.from=Gravity
dependency3.to=Attractor
dependency3.type=UsesDependency
editor.fx.0.height=728
editor.fx.0.width=1037
editor.fx.0.x=95
editor.fx.0.y=53
objectbench.height=94
objectbench.width=776
package.divider.horizontal=0.6
package.divider.vertical=0.8305369127516778
package.editor.height=488
package.editor.width=661
package.editor.x=374
package.editor.y=158
package.frame.height=660
package.frame.width=800
package.numDependencies=3
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=60
readme.name=@README
readme.width=48
readme.x=10
readme.y=10
target1.height=70
target1.name=Mover
target1.showInterface=false
target1.type=ClassTarget
target1.width=120
target1.x=380
target1.y=220
target2.height=70
target2.name=Attractor
target2.showInterface=false
target2.type=ClassTarget
target2.width=120
target2.x=380
target2.y=350
target3.height=70
target3.name=Gravity
target3.showInterface=false
target3.type=ClassTarget
target3.width=120
target3.x=120
target3.y=120

View File

@@ -0,0 +1,51 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.DrawingLayer;
import schule.ngb.zm.Vector;
import schule.ngb.zm.Zeichenobjekt;
public class Eye extends Zeichenobjekt {
private Vector position;
private double size;
private Color color;
public Eye() {
position = Vector.random(0, width, 0, height);
size = random(10.0, 25.0);
color = null;
}
public Eye( float x, float y ) {
position = new Vector(x, y);
size = random(10.0, 25.0);
color = null;
}
public Eye( float x, float y, Color color ) {
position = new Vector(x, y);
size = random(10.0, 25.0);
this.color = color;
}
@Override
public void draw( DrawingLayer drawing ) {
Vector dir = Vector.sub(new Vector(mouseX, mouseY), position);
double len = dir.length();
drawing.setStrokeColor(0);
if( color == null ) {
drawing.setFillColor(colorHsb(354, 100.0 - limit(len, 0.0, 100.0), 100));
} else {
drawing.setFillColor(color);
}
drawing.circle(position.x, position.y, size);
Vector pupil = Vector.add(position, dir.limit(size*.4));
drawing.setFillColor(0);
drawing.circle(pupil.x, pupil.y, size*.4);
}
}

View File

@@ -0,0 +1,38 @@
import schule.ngb.zm.Zeichenmaschine;
public class Eyes extends Zeichenmaschine {
public static final int N_EYES = 30;
public static void main( String[] args ) {
new Eyes();
}
Eye[] eyes;
public Eyes() {
super(600, 600, "Eyes");
}
@Override
public void setup() {
eyes = new Eye[N_EYES];
for( int i = 0; i < eyes.length; i++ ) {
eyes[i] = new Eye();
}
}
@Override
public void update( double delta ) {
}
@Override
public void draw() {
drawing.clear(200);
for( int i = 0; i < eyes.length; i++ ) {
eyes[i].draw(drawing);
}
}
}

View File

@@ -0,0 +1,55 @@
#BlueJ package file
dependency1.from=Attractor
dependency1.to=Gravity
dependency1.type=UsesDependency
dependency2.from=Gravity
dependency2.to=Mover
dependency2.type=UsesDependency
dependency3.from=Gravity
dependency3.to=Attractor
dependency3.type=UsesDependency
editor.fx.0.height=728
editor.fx.0.width=1037
editor.fx.0.x=95
editor.fx.0.y=53
objectbench.height=94
objectbench.width=776
package.divider.horizontal=0.6
package.divider.vertical=0.8305369127516778
package.editor.height=488
package.editor.width=661
package.editor.x=374
package.editor.y=158
package.frame.height=660
package.frame.width=800
package.numDependencies=3
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=60
readme.name=@README
readme.width=48
readme.x=10
readme.y=10
target1.height=70
target1.name=Mover
target1.showInterface=false
target1.type=ClassTarget
target1.width=120
target1.x=380
target1.y=220
target2.height=70
target2.name=Attractor
target2.showInterface=false
target2.type=ClassTarget
target2.width=120
target2.x=380
target2.y=350
target3.height=70
target3.name=Gravity
target3.showInterface=false
target3.type=ClassTarget
target3.width=120
target3.x=120
target3.y=120

View File

@@ -0,0 +1,94 @@
import schule.ngb.zm.Zeichenmaschine;
import java.util.LinkedList;
public class Atoms extends Zeichenmaschine {
/**
* Liste der beweglichen Objekte in der Welt.
*/
private LinkedList<Mover> movers = new LinkedList<>();
/**
* Liste der Gravitationsquellen in der Welt.
*/
private LinkedList<Attractor> attractors = new LinkedList<>();
/**
* Erstellt die {@link Mover}- und {@link Attractor}-Objekte.
*/
public void setup() {
addAttractor( width / 2, height / 2, 20 );
attractors.getFirst().setMovable(false);
attractors.getFirst().setActive(false);
attractors.getFirst().hide();
addAttractor( width*.4, height*.4, 8 );
addAttractor( width*.6, height*.6, 8 );
for( int i = 0; i < 10; i++ ) {
Mover m = new Mover(random(10, width - 10), random(10, height - 10));
movers.add(m);
shapes.add(m);
}
}
private void addAttractor( double pX, double pY, int pMass ) {
Attractor a = new Attractor((int)pX, (int)pY, pMass);
attractors.add(a);
movers.add(a);
shapes.add(a);
}
/**
* Aktualisiert die Beschleunigung der {@link Mover}-Objekte durch Anwenden
* der einwirkenden Kräfte und aktualisiert dann die Position entsprechend
* der Beschleunigung.
* <p>
* Die Position des ersten {@link Attractor} wird auf die Mausposition
* gesetzt.
*
* @param delta
*/
public void update( double delta ) {
// Erste Gravitationsquelle auf Mausposition setzen.
Attractor mouseFollow = attractors.get(0);
if( mouseFollow.isActive() ) {
mouseFollow.moveTo(mouseX, mouseY);
}
// Kräfte anwenden
for( Attractor a : attractors ) {
if( a.isActive() ) {
for( Mover m : movers ) {
if( m.isActive() ) {
a.attract(m);
}
}
}
}
// Position aktualisieren
for( Mover m : movers ) {
if( m.isActive() ) {
m.update(delta);
}
}
}
/**
* Setzt die Position und Beschleunigung aller {@link Mover}-Objekte in der
* Welt zurück.
*/
public void mouseClicked() {
for( Mover m : movers ) {
m.moveTo(random(10, width - 10), random(10, height - 10));
m.setVelocity(0, 0);
}
}
public static void main( String[] args ) {
new Atoms();
}
}

View File

@@ -0,0 +1,110 @@
import schule.ngb.zm.Vector;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
/**
* Gravitationsquelle in der Simulation.
* <p>
* Eine Gravitationsquelle zieht mit einer Anziehungskraft proportional zu
* seiner Masse alle {@link Mover}-Objekte an. Dabei kommt die Newtonsche
* Gravitationsformel zur Anwendung.
* <p>
* Ein <code>Attractor</code> ist auch ein {@link Mover} und wird von anderen
* Gravitationsquellen beeinflusst. Dieses Verhalten kann durch Setzen von
* <code>setMovable(false)</code> abgeschaltet werden.
*/
public class Attractor extends Mover {
/**
* Gravitationskonstante
* <p>
* Beeinflusst die Stärke der Anziehungskraft der {@link Attractor}en.
*/
public static final int G = 25;
/**
* Ob dieser <code>Attractor</code> auch von anderen Kräften beeinflusst wird.
*/
private boolean movable = true;
/**
* Erstellt einen <code>Attractor</code> an der angegebenen Position mit der angegebenen
* Masse.
*
* @param pX x-Koordinate des Objektes.
* @param pY y-Koordinate des Objektes.
* @param pMass Masse des Objektes.
*/
public Attractor( int pX, int pY, int pMass ) {
this(pX, pY, pMass, new Vector());
}
/**
* Erstellt einen <code>Attractor</code> an der angegebenen Position
*
* @param pX x-Koordinate des Objektes.
* @param pY y-Koordinate des Objektes.
* @param pMass Masse des Objektes.
* @param pVelocity Initialgeschwindigkeit des Objektes.
*/
public Attractor( int pX, int pY, int pMass, Vector pVelocity ) {
super(pX, pY, pVelocity);
mass = pMass;
setFillColor(randomColor());
}
/**
* Stellt ein, ob dieser <code>Attractor</code> auch von anderen Kräften
* beeinflusst wird, oder ob er starr an einer Position bleibt.
*
* @param pMovable <code>true</code> oder <code>false</code>.
*/
public void setMovable( boolean pMovable ) {
this.movable = pMovable;
}
/**
* Wendet die Anziehungskraft des <code>Attractor</code> auf einen
* <code>Mover</code> an.
*
* @param pMover Das Objekt, das angezogen wird.
*/
public void attract( Mover pMover ) {
if( pMover != this && isActive() ) {
Vector force = new Vector(this.x, this.y);
force.sub(pMover.getX(), pMover.getY());
double v = G * mass / force.lengthSq();
force.setLength(v).limit(1.0, 4 * G);
pMover.applyForce(force);
}
}
/**
* Aktualisiert die momentante Geschwindigkeit und Position des Objektes und
* setzt die Beschleunigung zurück.
*
* @param delta Zeitintervall seit dem letzten Aufruf (in Sekunden).
*/
@Override
public void update( double delta ) {
if( movable ) {
super.update(delta);
}
}
@Override
public void draw( Graphics2D graphics, AffineTransform transform ) {
double m = 2.0*mass;
AffineTransform at = graphics.getTransform();
graphics.transform(transform);
graphics.setColor(new java.awt.Color(255,193,64,66));
graphics.fillOval((int)(-.5*m), (int)(-.5*m), (int)(2*getRadius()+m), (int)(2*getRadius()+m));
graphics.setTransform(at);
super.draw(graphics, transform);
}
}

View File

@@ -0,0 +1,92 @@
import schule.ngb.zm.Vector;
import schule.ngb.zm.Zeichenmaschine;
import java.util.LinkedList;
/**
* Hauptklasse der Simulation.
*/
public class Gravity extends Zeichenmaschine {
/**
* Liste der beweglichen Objekte in der Welt.
*/
private LinkedList<Mover> movers = new LinkedList<>();
private final Vector gravity = new Vector(0, 6.734);
/**
* Erstellt die {@link Mover}-Objekte.
*/
public void setup() {
for( int i = 0; i < 4; i++ ) {
//Mover m = new Mover(random(10, width - 10), 30);
Mover m = new Mover(10 + (i*30), 30, 5*(i+1));
movers.add(m);
shapes.add(m);
}
}
/**
* Aktualisiert die Beschleunigung der {@link Mover}-Objekte durch Anwenden
* der einwirkenden Kräfte und aktualisiert dann die Position entsprechend
* der Beschleunigung.
* <p>
* Die Position des ersten {@link Attractor} wird auf die Mausposition
* gesetzt.
*
* @param delta
*/
public void update( double delta ) {
// Kräfte anwenden
for( Mover m : movers ) {
if( m.isActive() ) {
m.applyForce(gravity);
}
}
// Position aktualisieren
for( Mover m : movers ) {
if( m.isActive() ) {
m.update(delta);
// Abprallen Boden
if( m.getY() >= height ) {
m.setY(height-1);
m.getVelocity().y *= -1;
double s = 9.0 / m.getMass();
m.getVelocity().scale(limit(s, 0.0, 1.0));
}
// Abprallen rechter Rand
if( m.getX() >= width ) {
m.setX(width-1);
m.getVelocity().x *= -1;
}
// Abprallen linker Rand
if( m.getX() <= 0) {
m.setX(1);
m.getVelocity().x *= -1;
}
}
}
}
/**
* Setzt die Position und Beschleunigung aller {@link Mover}-Objekte in der
* Welt zurück.
*/
public void mouseClicked() {
background.setColor(randomNiceColor());
for( Mover m : movers ) {
m.moveTo(random(10, width - 10), 30);
m.setVelocity(mouseX-m.getX(), mouseY-m.getY());
m.getVelocity().setLength(4.0);
}
}
public static void main( String[] args ) {
new Gravity();
}
}

View File

@@ -0,0 +1,186 @@
import schule.ngb.zm.Updatable;
import schule.ngb.zm.Vector;
import schule.ngb.zm.shapes.Arrow;
import schule.ngb.zm.shapes.Circle;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
/**
* Ein bewegliches Objekt in der Simulation.
*
* <code>Mover</code> werden durch Kräfte beeinflusst. Diese Kräfte können von
* unterschiedlichen Quellen ausgehen. Die {@link Attractor}en wirken zum
* Beispiel mit ihrer Anziehungskraft auf die <code>Mover</code> ein.
*/
public class Mover extends Circle implements Updatable {
/**
* Größe der Objekte in der Simulation.
*/
public static final int SIZE = 10;
/**
* Ob die momentane Geschwindigkeit der Objekte als Pfeil dargestellt werden soll.
*/
public static final boolean SHOW_VELOCITY = true;
/**
* Masse des Objektes.
*/
protected double mass = 10.0;
/**
* Ob dieses Objekt an der Simulation beteiligt ist.
*/
protected boolean active = true;
/**
* Momentane Geschwindigkeit des Objektes.
*/
private Vector velocity;
/**
* Momentane Beschleunigung des Objektes.
*/
private Vector acceleration = new Vector();
/**
* Erstellt einen Mover an der angegebenen Position mit der momentanen
* Geschwindigkeit <code>(0, 0)</code>.
*
* @param pX x-Position des Objektes.
* @param pY y-Position des Objektes.
*/
public Mover( int pX, int pY ) {
this(pX, pY, new Vector());
}
/**
* Erstellt einen <code>Attractor</code> an der angegebenen Position mit der angegebenen
* Masse.
*
* @param pX x-Koordinate des Objektes.
* @param pY y-Koordinate des Objektes.
* @param pMass Masse des Objektes.
*/
public Mover( int pX, int pY, int pMass ) {
this(pX, pY, pMass, new Vector());
}
/**
* Erstellt einen Mover an der angegebenen Position mit der angegebenen
* Initialgeschwindigkeit.
*
* @param pX x-Position des Objektes.
* @param pY y-Position des Objektes.
* @param pVelocity Momentane Geschwindigkeit des Objektes.
*/
public Mover( int pX, int pY, Vector pVelocity ) {
super(pX, pY, SIZE);
velocity = pVelocity.copy();
}
/**
* Erstellt einen <code>Attractor</code> an der angegebenen Position
*
* @param pX x-Koordinate des Objektes.
* @param pY y-Koordinate des Objektes.
* @param pMass Masse des Objektes.
* @param pVelocity Initialgeschwindigkeit des Objektes.
*/
public Mover( int pX, int pY, int pMass, Vector pVelocity ) {
super(pX, pY, SIZE);
mass = pMass;
velocity = pVelocity.copy();
}
/**
* Gibt die Masse des Objektes zurück.
*
* @return Die Masse des Objektes.
*/
public double getMass() {
return mass;
}
/**
* Gibt die momentane Geschwindigkeit zurück.
* @return Die momentane Geschwindigkeit als Vektor.
*/
public Vector getVelocity() {
return velocity;
}
/**
* Setzt die momentane Geschwindigkeit des Objektes.
*
* @param pDx Momentane Geschwindigkeit in x-Richtung.
* @param pDy Momentane Geschwindigkeit in y-Richtung.
*/
public void setVelocity( double pDx, double pDy ) {
velocity.set(pDx, pDy);
}
/**
* Addiert eine Kraft zur momentanen Beschleunigung des Objektes. Die
* Beschleunigung wird einmal pro Update auf die Geschwindigkeit angewandt
* und dann wieder auf <code>(0, 0)</code> gesetzt.
*
* @param force Ein Vektor, der die Kraft darstellt.
*/
public void applyForce( Vector force ) {
acceleration.add(force);
}
/**
* Ob dieses Objekt aktiv ist und Updates erhalten soll.
*
* @return Ob das Objekt simuliert wird.
*/
public boolean isActive() {
return active;
}
/**
* Aktiviert / Deaktiviert das Objekt.
* @param pActive
*/
public void setActive( boolean pActive ) {
this.active = pActive;
}
/**
* Aktualisiert die momentante Geschwindigkeit und Position des Objektes und
* setzt die Beschleunigung zurück.
*
* @param delta Zeitintervall seit dem letzten Aufruf (in Sekunden).
*/
public void update( double delta ) {
acceleration.scale(delta);
velocity.add(acceleration);
acceleration.scale(0.0);
if( velocity.length() > 0.5 ) {
this.x += velocity.x;
this.y += velocity.y;
}
}
@Override
public void draw( Graphics2D graphics, AffineTransform transform ) {
if( SHOW_VELOCITY ) {
Vector v = velocity.copy().scale(10);
Arrow ar = new Arrow(v);
AffineTransform af = new AffineTransform(transform);
af.translate(radius, radius);
ar.draw(graphics, af);
}
super.draw(graphics, transform);
}
}

View File

@@ -0,0 +1,55 @@
#BlueJ package file
dependency1.from=Attractor
dependency1.to=Gravity
dependency1.type=UsesDependency
dependency2.from=Gravity
dependency2.to=Mover
dependency2.type=UsesDependency
dependency3.from=Gravity
dependency3.to=Attractor
dependency3.type=UsesDependency
editor.fx.0.height=728
editor.fx.0.width=1037
editor.fx.0.x=95
editor.fx.0.y=53
objectbench.height=94
objectbench.width=776
package.divider.horizontal=0.6
package.divider.vertical=0.8305369127516778
package.editor.height=488
package.editor.width=661
package.editor.x=374
package.editor.y=158
package.frame.height=660
package.frame.width=800
package.numDependencies=3
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=60
readme.name=@README
readme.width=48
readme.x=10
readme.y=10
target1.height=70
target1.name=Mover
target1.showInterface=false
target1.type=ClassTarget
target1.width=120
target1.x=380
target1.y=220
target2.height=70
target2.name=Attractor
target2.showInterface=false
target2.type=ClassTarget
target2.width=120
target2.x=380
target2.y=350
target3.height=70
target3.name=Gravity
target3.showInterface=false
target3.type=ClassTarget
target3.width=120
target3.x=120
target3.y=120

View File

@@ -0,0 +1,33 @@
/**
* Beschreiben Sie hier die Klasse Dreieck.
*
* @author (Ihr Name)
* @version (eine Versionsnummer oder ein Datum)
*/
public class Dreieck
{
// Instanzvariablen - ersetzen Sie das folgende Beispiel mit Ihren Variablen
private int x;
/**
* Konstruktor für Objekte der Klasse Dreieck
*/
public Dreieck()
{
// Instanzvariable initialisieren
x = 0;
}
/**
* Ein Beispiel einer Methode - ersetzen Sie diesen Kommentar mit Ihrem eigenen
*
* @param y ein Beispielparameter für eine Methode
* @return die Summe aus x und y
*/
public int beispielMethode(int y)
{
// tragen Sie hier den Code ein
return x + y;
}
}

View File

@@ -0,0 +1,88 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.Drawable;
import java.awt.Graphics2D;
public class Kreis implements Drawable {
private int x;
private int y;
private int radius;
private Color farbe;
private Color linienfarbe;
private boolean sichtbar;
public Kreis() {
x = 420;
y = 420;
radius = 80;
farbe = Color.BLUE;
linienfarbe = Color.BLACK;
sichtbar = true;
}
public void anzeigen() {
sichtbar = true;
}
public void verstecken() {
sichtbar = false;
}
public void setPosition( int pX, int pY ) {
x = pX;
y = pY;
}
public void links() {
x -= 10;
}
public void rechts() {
x += 10;
}
public void hoch() {
y -= 10;
}
public void runter() {
y += 10;
}
public void setRadius( int pRadius ) {
radius = pRadius;
}
public void setFarbe( String pFarbe ) {
farbe = Color.parseString(pFarbe);
}
public void setLinienfarbe( String pLinienfarbe ) {
linienfarbe = Color.parseString(pLinienfarbe);
}
@Override
public boolean isVisible() {
return sichtbar;
}
@Override
public void draw( Graphics2D graphics ) {
if( x-(radius/2.0) > 0 && x+(radius/2.0) < 800 && y-(radius/2.0) > 0 && y+(radius/2.0) < 800 ) {
graphics.setColor(farbe.getJavaColor());
graphics.fillOval(x, y, radius, radius);
graphics.setColor(linienfarbe.getJavaColor());
graphics.drawOval(x, y, radius, radius);
}
}
}

View File

@@ -0,0 +1,29 @@
import schule.ngb.zm.Drawable;
import schule.ngb.zm.DrawableLayer;
import schule.ngb.zm.Zeichenmaschine;
public class Leinwand {
private final Zeichenmaschine zm;
private final DrawableLayer zeichenflaeche;
public Leinwand() {
zm = new Zeichenmaschine(800, 800, "ZM: Shapes", false);
zeichenflaeche = new DrawableLayer();
zm.addLayer(zeichenflaeche);
}
public void anzeigen( Drawable pForm ) {
zeichenflaeche.add(pForm);
}
public void beenden() {
zm.exit();
}
public void zeichnen() {
zm.redraw();
}
}

View File

@@ -0,0 +1,95 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.Drawable;
import java.awt.Graphics2D;
public class Rechteck implements Drawable {
private int x;
private int y;
private int breite;
private int hoehe;
private Color farbe;
private Color linienfarbe;
private boolean sichtbar;
public Rechteck() {
x = 320;
y = 240;
breite = 100;
hoehe = 60;
farbe = Color.RED;
linienfarbe = Color.BLACK;
sichtbar = true;
}
public void anzeigen() {
sichtbar = true;
}
public void verstecken() {
sichtbar = false;
}
public void setPosition( int pX, int pY ) {
x = pX;
y = pY;
}
public void links() {
x -= 10;
}
public void rechts() {
x += 10;
}
public void hoch() {
y -= 10;
}
public void runter() {
y += 10;
}
public void setBreite( int pBreite ) {
breite = pBreite;
}
public void setHoehe( int pHoehe ) {
hoehe = pHoehe;
}
public void setFarbe( String pFarbe ) {
farbe = Color.parseString(pFarbe);
}
public void setLinienfarbe( String pLinienfarbe ) {
linienfarbe = Color.parseString(pLinienfarbe);
}
@Override
public boolean isVisible() {
return sichtbar;
}
@Override
public void draw( Graphics2D graphics ) {
if( x-(breite/2.0) > 0 && x+(breite/2.0) < 800 && y-(hoehe/2.0) > 0 && y+(hoehe/2.0) < 800 ) {
graphics.setColor(farbe.getJavaColor());
graphics.fillRect(x, y, breite, hoehe);
graphics.setColor(linienfarbe.getJavaColor());
graphics.drawRect(x, y, breite, hoehe);
}
}
}

View File

@@ -0,0 +1,53 @@
#BlueJ package file
editor.fx.0.height=728
editor.fx.0.width=800
editor.fx.0.x=488
editor.fx.0.y=107
objectbench.height=94
objectbench.width=776
package.divider.horizontal=0.6
package.divider.vertical=0.8305369127516778
package.editor.height=488
package.editor.width=661
package.editor.x=36
package.editor.y=155
package.frame.height=660
package.frame.width=800
package.numDependencies=0
package.numTargets=4
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=60
readme.name=@README
readme.width=48
readme.x=10
readme.y=10
target1.height=30
target1.name=Rechteck
target1.showInterface=false
target1.type=ClassTarget
target1.width=70
target1.x=190
target1.y=50
target2.height=30
target2.name=Dreieck
target2.showInterface=false
target2.type=ClassTarget
target2.width=70
target2.x=190
target2.y=170
target3.height=30
target3.name=Kreis
target3.showInterface=false
target3.type=ClassTarget
target3.width=70
target3.x=190
target3.y=110
target4.height=60
target4.name=Leinwand
target4.showInterface=false
target4.type=ClassTarget
target4.width=120
target4.x=40
target4.y=100

View File

@@ -0,0 +1,257 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.Zeichenmaschine;
/**
* Eine Bildergallerie von Bildern eines Informatikkurses des 10. Jahrgangs.
*/
public class Gallery extends Zeichenmaschine {
public static void main(String[] args) {
new Gallery();
}
public void setup() {
setSize(600, 600);
setTitle("ZM: Gallery");
}
/**
* Wählt ein zufälliges Bild aus und zeigt es an.
*/
public void draw() {
drawRandom();
}
/**
* Zeigt ein zufälliges Bild an.
*/
public void drawRandom() {
switch (random(0, 4)) {
case 0:
rainbow();
break;
case 1:
snowman();
break;
case 2:
deathstar();
break;
case 3:
prideflag();
break;
}
}
/**
* Bei Betätigen der Leertaste ein Zufallsbild anzeigen.
*/
public void keyPressed() {
if (keyCode == 32) {
drawRandom();
}
}
/**
* Startet eine fortlaufende Präsentation aller Bilder.
*
* @param pWartezeit Die Wartezeit zum nächsten Bildwechsel in Millisekunden.
*/
public void slideshow(int pWartezeit) {
int i = 0;
while (true) {
switch (i) {
case 0:
rainbow();
break;
case 1:
snowman();
break;
case 2:
deathstar();
break;
case 3:
prideflag();
break;
}
i = (i + 1) % 4;
delay(pWartezeit);
}
}
/**
* Regenbogen
* <p>
* von
*/
public void rainbow() {
// Blauer Hintergrund
drawing.clear(60, 155, 217);
// Einige Werte berechnen, um Bild an Bildgröße anzupassen
double size = (width + height) * 0.03333;
double r = width / 2.0;
// Kleiner werdende Kreise in den Farben des Bogens zeichnen
drawing.noStroke();
drawing.setFillColor(207, 71, 67);
drawing.circle(width / 2.0, height, r - 1 * size);
drawing.setFillColor(235, 134, 42);
drawing.circle(width / 2.0, height, r - 2 * size);
drawing.setFillColor(234, 181, 58);
drawing.circle(width / 2.0, height, r - 3 * size);
// Mitte mit "himmelfarbe" übermalen, um Ringe zu erzeugen
drawing.setFillColor(60, 155, 217);
drawing.circle(width / 2.0, height, r - 4 * size);
// Sonne zeichnen
drawing.setFillColor(232, 200, 52);
drawing.circle(width * 0.8333, size * 2.6666, size * 2);
// Bild auf Leinwand übertragen
redraw();
}
/**
* LGBTQ-Flagge
* <p>
* von
*/
public void prideflag() {
// Schwarzer Hintergrund
drawing.clear(0);
drawing.setStrokeColor(0);
// Farben der Streifen festlegen
Color[] colors = new Color[] {
RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE
};
// Breite der Streifen an Bildgröße anpassen
double size = height * 0.06666;
double borderX = width / 6.0, borderY = height / 6.0;
// Flaggenstab zeichnen
drawing.setFillColor(BROWN);
drawing.rect(borderX, borderY, size, height - 2 * borderY, NORTHWEST);
// Streifen zeichnen
for (int i = 0; i < colors.length; i++) {
drawing.setFillColor(colors[i]);
drawing.rect(borderX, borderY + i * size, width - 2 * borderX, size, NORTHWEST);
}
// Bild auf Leinwand übertragen
redraw();
}
/**
* Todesstern
* <p>
* von Niklas, Henry und Ben
*/
public void deathstar() {
// Sternenhimmel zeichnen
drawing.clear(0);
drawing.noStroke();
drawing.setFillColor(WHITE);
// Zufällig erzeugte Sterne
for (int i = 0; i < (width + height) / 4; i++) {
drawing.circle(random(0.0, width), random(0.0, height), random(1, 3));
}
// Einige Werte berechnen, die später verwendet werden, um
// die Zeichnung an die Bildschirmgröße anzupassen.
double radius = limit(width * 0.6666, 0.0, height * 0.6666) / 2.0;
double w2 = width / 2.0, h2 = height / 2.0;
double r2 = radius / 2.0,
r3 = radius / 3.0, r4 = radius / 4.0,
r5 = radius / 5.0, r10 = radius / 10.0;
// Korpus zeichnen
drawing.setFillColor(128);
drawing.circle(width / 2.0, height / 2.0, radius);
// Graben am Äquator zeichnen
drawing.setStrokeColor(0);
drawing.setStrokeWeight(1.4);
drawing.arc(width / 2.0, height / 2.0, radius + radius, r2, 180, 360);
// Schüssel zeichnen
drawing.setFillColor(96);
drawing.circle(w2 + r2, h2 - r3, r4);
drawing.setFillColor(84);
drawing.circle(w2 + r2 + 2, h2 - r3 - 2, r10);
// Strahlen des Lasers zeichnen
int beams = 8; // Anzahl Strahlen
for (int i = 0; i < beams; i++) {
drawing.setStrokeColor(GREEN);
drawing.setStrokeType(SOLID);
drawing.setStrokeWeight(1.6);
drawing.line(
w2 + r2 - r4 * cos(radians(360 / beams * i)),
h2 - r3 + r4 * sin(radians(360 / beams * i)),
w2 + r2 + 2 + r5,
h2 - r3 - 2 - r5);
drawing.setStrokeType(DASHED);
drawing.setStrokeWeight(3.0);
drawing.line(
w2 + r2 - r4 * cos(radians(360 / beams * i)),
h2 - r3 + r4 * sin(radians(360 / beams * i)),
w2 + r2 + 2 + r5,
h2 - r3 - 2 - r5);
drawing.setStrokeColor(WHITE);
drawing.setStrokeType(SOLID);
drawing.setStrokeWeight(1.0);
drawing.line(
w2 + r2 - r4 * cos(radians(360 / beams * i)),
h2 - r3 + r4 * sin(radians(360 / beams * i)),
w2 + r2 + 2 + r5,
h2 - r3 - 2 - r5);
}
// Hauptstrahl
drawing.setStrokeColor(GREEN);
drawing.setStrokeType(SOLID);
drawing.setStrokeWeight(4);
drawing.line(w2 + r2 + 2 + r5, h2 - r3 - 2 - r5, width, h2 - w2 + radius / 6.0);
drawing.setStrokeWeight(1);
drawing.setStrokeColor(255);
drawing.line(w2 + r2 + 2 + r5, h2 - r3 - 2 - r5, width, h2 - w2 + radius / 6.0);
// Bild auf Leinwand übertragen
redraw();
}
/**
* Schneemann
* <p>
* von
*/
public void snowman() {
// Hellblauer Hintergrund
drawing.clear(219, 253, 255);
drawing.noStroke();
drawing.setFillColor(255);
// Drei Schneekugeln
drawing.circle(width / 2.0, height - 100, 100);
drawing.circle(width / 2.0, height - 180 - 60, 60);
drawing.circle(width / 2.0, height - 180 - 110 - 40, 40);
// Zwei Augen
drawing.setFillColor(0);
drawing.circle(width / 2.0 - 15, height - 345, 4);
drawing.circle(width / 2.0 + 15, height - 345, 4);
// Nase
drawing.setFillColor(255, 147, 0);
drawing.triangle(width / 2.0, height - 335, width / 2.0 - 5, height - 330, width / 2.0 + 5, height - 330);
// Bild auf Leinwand übertragen
redraw();
}
}

View File

@@ -0,0 +1,22 @@
# Zeichenmaschine: Gallery
Die Bildergallerie ist eine Sammlung statischer Bilder, die mit der
Zeichenmaschine programmiert wurden.
Die Bilder selbst wurden von einem Informatikkurs des Jahrgangs 10 in
Processing (https://processing.org) erstellt und für dieses Beispielprojekt
auf die Zeichenmaschine angespasst.
Die Autoren der Bilder sind:
- Schneemann:
- Todesstern
- Regenbogen:
- LGBTQ-Flagge:
## Verwendung
Beim Start wird eines der vorhandenen Bilder ausgewählt und angezeigt.
Mit der Methode "slideshow()" wird eine fortlaufende Präsentation der Bilder
gestartet. Die Wartezeit bis zum nächsten Bildwechsel kann als Parameter in
Millisekunden angegeben werden.

View File

@@ -0,0 +1,32 @@
#BlueJ package file
editor.fx.0.height=0
editor.fx.0.width=0
editor.fx.0.x=0
editor.fx.0.y=0
objectbench.height=94
objectbench.width=776
package.divider.horizontal=0.6
package.divider.vertical=0.8305369127516778
package.editor.height=488
package.editor.width=661
package.editor.x=0
package.editor.y=0
package.frame.height=660
package.frame.width=800
package.numDependencies=0
package.numTargets=1
package.showExtends=true
package.showUses=true
project.charset=UTF-8
readme.height=60
readme.name=@README
readme.width=48
readme.x=10
readme.y=10
target1.height=70
target1.name=Gallery
target1.showInterface=false
target1.type=ClassTarget
target1.width=120
target1.x=70
target1.y=10

View File

@@ -0,0 +1,77 @@
import schule.ngb.zm.Vector;
import schule.ngb.zm.Zeichenmaschine;
public class BouncingLine extends Zeichenmaschine {
public static void main( String[] args ) {
new BouncingLine();
}
private Vector start, end, dStart, dEnd;
private int r, g, b;
private boolean mouseFollow = false;
public BouncingLine() {
super(800, 800, "Bouncing Lines");
}
@Override
public void setup() {
start = Vector.random(0, width, 0, height);
end = Vector.random(0, width, 0, height);
dStart = Vector.random(-5, 5);
dEnd = Vector.random(-5, 5);
r = random(255);
g = random(255);
b = random(255);
}
@Override
public void update( double delta ) {
start.add(dStart);
end.add(dEnd);
if( start.x > width || start.x < 0 ) {
dStart.x *= -1;
}
if( end.x > width || end.x < 0 ) {
dEnd.x *= -1;
}
if( start.y > width || start.y < 0 ) {
dStart.y *= -1;
}
if( end.y > width || end.y < 0 ) {
dEnd.y *= -1;
}
r += limit(random(-5, 5), 0, 255);
g += limit(random(-5, 5), 0, 255);
b += limit(random(-5, 5), 0, 255);
}
@Override
public void draw() {
drawing.setStrokeColor(r, g, b);
drawing.line(start.x, start.y, end.x, end.y);
// bezier(0, 0, startX, startY, endX, endY, width, height);
}
@Override
public void mouseClicked() {
mouseFollow = !mouseFollow;
}
@Override
public void mouseMoved() {
if( mouseFollow ) {
dStart = new Vector(mouseX - start.x, mouseY - start.y);
dStart.setLength(5);
dEnd = new Vector(mouseX - end.x, mouseY - end.y);
dEnd.setLength(5);
}
}
}

View File

@@ -0,0 +1,40 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.Zeichenmaschine;
public class GenColors extends Zeichenmaschine {
public static void main( String[] args ) {
new GenColors();
}
public GenColors() {
super(800, 800, "Nice Colors");
}
@Override
public void setup() {
genPattern();
}
public void genPattern() {
drawing.noStroke();
int SIZE = 40;
for( int i = 0; i < width/SIZE; i++ ) {
for( int j = 0; j < height/SIZE; j++ ) {
Color c = randomNiceColor();
float[] hsl = Color.RGBtoHSL(c.getRGBA(), null);
System.out.printf("%f, %f, %f\n", hsl[0], hsl[1], hsl[2]);
drawing.setFillColor(c);
drawing.square(i*SIZE, j*SIZE, SIZE, NORTHWEST);
}
}
}
@Override
public void mouseClicked() {
genPattern();
redraw();
}
}

View File

@@ -0,0 +1,122 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.Constants;
import schule.ngb.zm.Options;
import schule.ngb.zm.Zeichenmaschine;
public class GenHitomezashi extends Zeichenmaschine {
public static final int TILE_SIZE = 20;
public static final int COLUMNS = 30;
public static final int ROWS = 30;
public static final double P = 0.5;
public static final Color[] colors = new Color[]{
randomNiceColor(),
randomNiceColor(),
color(241, 124, 55),
color(62, 156, 191)
};
private int[] stitchesX, stitchesY;
public static void main( String[] args ) {
new GenHitomezashi();
}
public GenHitomezashi() {
super(TILE_SIZE*COLUMNS, TILE_SIZE*ROWS, "Hitomezashi Pattern");
}
@Override
public void setup() {
drawing.setStrokeColor(0);
drawing.setFillColor(0);
generatePattern();
pause();
}
public void generatePattern() {
stitchesX = new int[COLUMNS];
for ( int i = 0; i < COLUMNS; i++ ) {
stitchesX[i] = random(0, 1) < P ? 1 : 0;
}
stitchesY = new int[COLUMNS];
for ( int j = 0; j < ROWS; j++ ) {
stitchesY[j] = random(0, 1) < P ? 1 : 0;
}
}
public boolean hasStitch( int i, int j, Options.Direction dir ) {
switch( dir ) {
case UP:
return (j > 0 && (stitchesY[j-1]+i)%2 == 1);
case DOWN:
return (j >= 0 && (stitchesY[j]+i)%2 == 1);
case LEFT:
return (i > 0 && (stitchesX[i-1]+j)%2 == 1);
case RIGHT:
return (i >= 0 && (stitchesX[i]+j)%2 == 1);
default:
return false;
}
}
@Override
public void update( double delta ) {
}
@Override
public void draw() {
drawing.clear(200);
int clr = random(1), clr2 = clr;
drawing.noStroke();
for ( int i = 0; i < COLUMNS; i++ ) {
if ( hasStitch(i, 0, LEFT) ) {
clr = (clr2+1)%2;
clr2 = clr;
} else {
clr = clr2;
}
for ( int j = 0; j < ROWS; j++ ) {
drawing.setFillColor(colors[clr]);
drawing.rect(i*TILE_SIZE, j*TILE_SIZE, TILE_SIZE, TILE_SIZE, NORTHWEST);
if ( hasStitch(i, j, DOWN) ) {
clr = (clr+1)%2;
}
}
}
drawing.setStrokeColor(0);
drawing.setStrokeWeight(2);
for ( int i = 0; i < COLUMNS; i++ ) {
for ( int j = 0; j < ROWS; j++ ) {
boolean stitchX = (stitchesX[i]+j)%2 == 1;
if ( i < COLUMNS-1 && stitchX ) {
drawing.line((i+1)*TILE_SIZE, j*TILE_SIZE, (i+1)*TILE_SIZE, (j+1)*TILE_SIZE);
}
boolean stitchY = (stitchesY[j]+i)%2 == 1;
if ( j < ROWS-1 && stitchY ) {
drawing.line(i*TILE_SIZE, (j+1)*TILE_SIZE, (i+1)*TILE_SIZE, (j+1)*TILE_SIZE);
}
}
}
}
@Override
public void mousePressed() {
generatePattern();
redraw();
}
}

View File

@@ -0,0 +1,62 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.Zeichenmaschine;
public class GenLines extends Zeichenmaschine {
public static final int BORDER = 16;
public static final int SIZE = 400;
public static Color[] colors = new Color[]{
color(62, 156, 191),
color(167, 236, 242),
color(242, 196, 61),
color(241, 124, 55),
color(242, 109, 80)
};
public static void main( String[] args ) {
new GenLines();
}
private int i = 0;
public GenLines() {
super(SIZE, SIZE, "Lines");
}
@Override
public void setup() {
setFramesPerSecond(10);
drawing.clear(33);
}
@Override
public void update( double delta ) {
}
@Override
public void draw() {
int a = random(BORDER, SIZE-BORDER);
//drawing.setStrokeColor(random(50, 200));
drawing.setStrokeColor(colors[random(colors.length-1)]);
drawing.setStrokeWeight(random(4,12));
int d;
if( a > SIZE*0.5 ) {
d = random(1, (SIZE - a) - BORDER);
} else {
d = random(1, a - BORDER);
}
drawing.line(a - d, a + d, a + d, a - d);
i += 1;
if( i == SIZE ) {
stop();
}
}
}

View File

@@ -0,0 +1,60 @@
import schule.ngb.zm.Color;
import schule.ngb.zm.Zeichenmaschine;
public class GenSpiral extends Zeichenmaschine {
public static final int SIZE = 800;
public static final double D_SCALE = .33;
public static final double A_SCALE = 6.0;
public static Color[] colors = new Color[]{
color(62, 156, 191, 44),
color(167, 236, 242, 44),
color(242, 196, 61, 44),
color(241, 124, 55, 44),
color(242, 109, 80, 44)
};
public static void main( String[] args ) {
new GenSpiral();
}
private int i = 0;
public GenSpiral() {
super(SIZE, SIZE, "Lines");
}
@Override
public void setup() {
setFramesPerSecond(60);
drawing.clear(33);
drawing.translate(SIZE/2, SIZE/2);
}
@Override
public void update( double delta ) {
}
@Override
public void draw() {
double d = (tick * D_SCALE); // + random(0,3);
double a = radians(tick * tick / A_SCALE);
// a = radians(tick * A_SCALE / D_SCALE);
// a = radians(d * A_SCALE);
int x = (int)(d * cos(a));
int y = (int)(d * sin(a));
drawing.setFillColor(colors[random(colors.length - 1)]);
drawing.noStroke();
drawing.circle(x, y, 10);
if( d > SIZE+SIZE ) {
stop();
}
}
}

View File

@@ -0,0 +1,43 @@
import schule.ngb.zm.DrawingLayer;
import schule.ngb.zm.Zeichenmaschine;
public class GenWalk extends Zeichenmaschine {
public static final int N_WALKERS = 8;
private Walker[] walkers;
public static void main( String[] args ) {
new GenWalk();
}
public GenWalk() {
super(800, 800, "Randomwalk");
}
@Override
public void setup() {
this.walkers = new Walker[N_WALKERS];
for( int i = 0; i < walkers.length; i++ ) {
this.walkers[i] = new Walker(width/2, height/2, drawing);
}
drawing.clear(0);
}
@Override
public void update( double delta ) {
for( Walker walker: walkers ) {
walker.update();
}
}
@Override
public void draw() {
drawing.clear(0, 5);
for( Walker walker: walkers ) {
walker.draw();
}
}
}

Some files were not shown because too many files have changed in this diff Show More