Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c9a7ac9551 | |||
| c6615cc817 | |||
| 4d981b62a4 | |||
| 05aae6e6cc | |||
| 5e42509f75 | |||
| e2bdf1e998 |
25
.gitignore
vendored
@@ -32,28 +32,3 @@ hs_err_pid*
|
||||
.DS_Store
|
||||
._*
|
||||
Thumbs.db
|
||||
|
||||
.gradle
|
||||
local.properties
|
||||
**/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
|
||||
|
||||
77
CHANGELOG.md
@@ -6,84 +6,11 @@ und diese Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## Added
|
||||
- Dokumentation erweitert.
|
||||
- Caching-Mechanismen in Klasse `util.Cache` ausgelagert.
|
||||
- `util.io.ImageLoader` und `util.io.FontLoader` verwenden `Cache`.
|
||||
- `mouseWheelMoved` Eventhandler für Mausrad.
|
||||
- `DrawingLayer.imageRotate(...)` Methoden, um Bilder um ihr Zentrum gedreht zu zeichnen.
|
||||
|
||||
## Changed
|
||||
- Die Methoden in `Validator` erwarten nun als zweiten Parameter den Namen des Parameters, der geprüft wird.
|
||||
- `DrawingLayer.image(...)` mit Größenänderung umbenannt zu `imageScale(...)`.
|
||||
- Klassen in `schule.ngb.zm.util.io` werfen nun nur eine Warnung ohne Stack-Trace, wenn die Ressource nicht gefunden werden konnte.
|
||||
|
||||
## Fixed
|
||||
- `Constants.choice(int...)` und `Constants.choice(double...)` wiederhergestellt.
|
||||
- Timing-Problem beim Aufruf von `AudioListener.playbackStopped()` in `Sound` behoben.
|
||||
|
||||
## Removed
|
||||
- `layers.Shape2DLayer` ist nur noch im Test-Paket verfügbar.
|
||||
|
||||
## Version 0.0.34
|
||||
|
||||
### Added
|
||||
- `Faker`-Klasse zur Erzeugung von Fake-Daten hinzugefügt.
|
||||
- Dokumentation unter [zeichenmaschine.xyz](https://zeichenmaschine.xyz) mit
|
||||
[MkDocs](https://www.mkdocs.org) und [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/).
|
||||
- Neue `image` methoden im `DrawingLayer`.
|
||||
|
||||
### 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.
|
||||
- Abstrakte Klasse `Zeichenobjekt` als einheitliche Oberklasse für Objekte in Projekten. Die Klasse erbt von `Constants` und implementiert `Drawabale` und `Updatable` mit leeren Methoden.
|
||||
|
||||
### 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.
|
||||
- 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).
|
||||
|
||||
153
build.gradle
@@ -1,153 +0,0 @@
|
||||
plugins {
|
||||
id 'idea'
|
||||
id 'java-library'
|
||||
id 'org.hidetake.ssh' version '2.10.1'
|
||||
}
|
||||
|
||||
group 'schule.ngb'
|
||||
version '0.0.35-SNAPSHOT'
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.release = 11
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
remotes {
|
||||
uberspace {
|
||||
host = 'westphal.uberspace.de'
|
||||
user = 'ngb'
|
||||
identity = file("${System.properties['user.home']}/.ssh/uberspace_rsa")
|
||||
knownHosts = allowAnyHosts
|
||||
}
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes 'Class-Path': '.'
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('jarMP3SPI', Jar) {
|
||||
group "build"
|
||||
description "Build jar with MP3SPI included"
|
||||
|
||||
archiveClassifier = 'mp3spi'
|
||||
duplicatesStrategy = 'exclude'
|
||||
// archivesBaseName = 'zeichenmaschine-mp3spi'
|
||||
from {
|
||||
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
with jar
|
||||
}
|
||||
|
||||
task buildAll {
|
||||
group "build"
|
||||
description "Build all jar packages"
|
||||
|
||||
dependsOn 'jar'
|
||||
dependsOn 'jarMP3SPI'
|
||||
dependsOn 'sourcesJar'
|
||||
dependsOn 'javadocJar'
|
||||
}
|
||||
|
||||
javadoc {
|
||||
options {
|
||||
encoding = "UTF-8"
|
||||
overview = "src/resources/java/overview.html"
|
||||
// title = "Die Zeichenmaschine"
|
||||
|
||||
// options.links 'https://docs.oracle.com/javase/8/docs/api/'
|
||||
// options.links 'https://docs.oracle.com/javaee/7/api'
|
||||
options.links 'https://docs.oracle.com/en/java/javase/11/docs/api'
|
||||
}
|
||||
options.addStringOption("charset", "UTF-8")
|
||||
}
|
||||
|
||||
task mkdocs(type: Exec) {
|
||||
group "documentation"
|
||||
description "Build MKDocs site"
|
||||
|
||||
workingDir "${projectDir}"
|
||||
commandLine ".venv/bin/python", "-m", "mkdocs", "build"
|
||||
}
|
||||
|
||||
task buildDocs {
|
||||
group "documentation"
|
||||
description "Run all documentation tasks"
|
||||
|
||||
dependsOn 'javadoc'
|
||||
dependsOn 'javadocJar'
|
||||
dependsOn 'mkdocs'
|
||||
}
|
||||
|
||||
task zipSite(type: Zip) {
|
||||
group "documentation"
|
||||
description "Create zip archives for documentations"
|
||||
|
||||
dependsOn 'mkdocs'
|
||||
|
||||
from fileTree("${buildDir}/docs/site")
|
||||
exclude '*.py'
|
||||
exclude '__pycache__'
|
||||
archiveName 'site.zip'
|
||||
destinationDir(file("${buildDir}/docs"))
|
||||
}
|
||||
|
||||
task zipJavadoc(type: Zip) {
|
||||
group "documentation"
|
||||
description "Create zip archives for javadoc"
|
||||
|
||||
dependsOn 'javadoc'
|
||||
|
||||
from fileTree("${buildDir}/docs/javadoc")
|
||||
archiveName 'javadoc.zip'
|
||||
destinationDir(file("${buildDir}/docs"))
|
||||
}
|
||||
|
||||
task uploadDocs {
|
||||
group "documentation"
|
||||
description "Run all documentation tasks and upload artifacts to zeichenmaschine.xyz"
|
||||
|
||||
dependsOn 'zipSite'
|
||||
dependsOn 'zipJavadoc'
|
||||
|
||||
doLast {
|
||||
ssh.run {
|
||||
session(remotes.uberspace) {
|
||||
execute 'rm -rf /var/www/virtual/ngb/zeichenmaschine.xyz/*', ignoreError: true
|
||||
|
||||
put from: "${buildDir}/docs/site.zip", into: '/var/www/virtual/ngb/zeichenmaschine.xyz', ignoreError: true
|
||||
execute 'unzip -o -q /var/www/virtual/ngb/zeichenmaschine.xyz/site.zip -d /var/www/virtual/ngb/zeichenmaschine.xyz'
|
||||
|
||||
put from: "${buildDir}/docs/javadoc.zip", into: '/var/www/virtual/ngb/zeichenmaschine.xyz', ignoreError: true
|
||||
execute 'unzip -o -q /var/www/virtual/ngb/zeichenmaschine.xyz/javadoc.zip -d /var/www/virtual/ngb/zeichenmaschine.xyz/docs'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
@@ -1,634 +0,0 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 152,
|
||||
"versionNonce": 1288225375,
|
||||
"isDeleted": false,
|
||||
"id": "fxk8rHocjpTteICJMa6n8",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 619.9963325816416,
|
||||
"y": 186.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fab005",
|
||||
"width": 150,
|
||||
"height": 46,
|
||||
"seed": 1339263918,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "JmEBjNProPAgJQZUvMGGa"
|
||||
},
|
||||
{
|
||||
"id": "eryKwAzIMcBMQP0Ybl1Mm",
|
||||
"type": "arrow"
|
||||
}
|
||||
],
|
||||
"updated": 1670307372550,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 264,
|
||||
"versionNonce": 1267158257,
|
||||
"isDeleted": false,
|
||||
"id": "wZLPkORf755_2Vp0J6I0V",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 566.9963325816416,
|
||||
"y": 289.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fab005",
|
||||
"width": 248,
|
||||
"height": 50,
|
||||
"seed": 359801906,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "9TujIdwDvtinylO3z50y6"
|
||||
},
|
||||
{
|
||||
"id": "eryKwAzIMcBMQP0Ybl1Mm",
|
||||
"type": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "Zc9GOJ8DsIQYo4WaGvvHy",
|
||||
"type": "arrow"
|
||||
}
|
||||
],
|
||||
"updated": 1670307379131,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 376,
|
||||
"versionNonce": 1807861489,
|
||||
"isDeleted": false,
|
||||
"id": "290mWFx31fA5smc5FqPUr",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 607.9963325816416,
|
||||
"y": 392.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#228be6",
|
||||
"width": 143,
|
||||
"height": 50,
|
||||
"seed": 1948766318,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "_ISR-LCZm2Hu2G57R_uxN"
|
||||
},
|
||||
{
|
||||
"id": "Zc9GOJ8DsIQYo4WaGvvHy",
|
||||
"type": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "hUUqTCXva-vZjnBeM-PR3",
|
||||
"type": "arrow"
|
||||
}
|
||||
],
|
||||
"updated": 1670307888001,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 518,
|
||||
"versionNonce": 2136415391,
|
||||
"isDeleted": false,
|
||||
"id": "kbEG_cCZadugfCPxYedhf",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 614.9963325816416,
|
||||
"y": 589.9758066195944,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#228be6",
|
||||
"width": 131,
|
||||
"height": 50,
|
||||
"seed": 97599794,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "6KjVrNy_dxGXJtntdqrjY"
|
||||
},
|
||||
{
|
||||
"id": "hUUqTCXva-vZjnBeM-PR3",
|
||||
"type": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "bplSSGA4kyy-Av7nKNK1B",
|
||||
"type": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "qukSk_W6enSdwERPEPkhZ",
|
||||
"type": "arrow"
|
||||
}
|
||||
],
|
||||
"updated": 1670307888001,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 110,
|
||||
"versionNonce": 1350901746,
|
||||
"isDeleted": false,
|
||||
"id": "JmEBjNProPAgJQZUvMGGa",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 643.9963325816416,
|
||||
"y": 199.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 102,
|
||||
"height": 20,
|
||||
"seed": 1889147762,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [],
|
||||
"updated": 1670164406970,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"text": "new Shapes()",
|
||||
"baseline": 14,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "fxk8rHocjpTteICJMa6n8",
|
||||
"originalText": "new Shapes()"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 245,
|
||||
"versionNonce": 1536101230,
|
||||
"isDeleted": false,
|
||||
"id": "9TujIdwDvtinylO3z50y6",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 584.9963325816416,
|
||||
"y": 304.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 212,
|
||||
"height": 20,
|
||||
"seed": 1297543150,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [],
|
||||
"updated": 1670164433291,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"text": "super(800, 800, \"Shapes\")",
|
||||
"baseline": 14,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "wZLPkORf755_2Vp0J6I0V",
|
||||
"originalText": "super(800, 800, \"Shapes\")"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 362,
|
||||
"versionNonce": 2069822514,
|
||||
"isDeleted": false,
|
||||
"id": "_ISR-LCZm2Hu2G57R_uxN",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 650.4963325816416,
|
||||
"y": 407.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 58,
|
||||
"height": 20,
|
||||
"seed": 525219186,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [],
|
||||
"updated": 1670164509204,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"text": "setup()",
|
||||
"baseline": 14,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "290mWFx31fA5smc5FqPUr",
|
||||
"originalText": "setup()"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 502,
|
||||
"versionNonce": 747611665,
|
||||
"isDeleted": false,
|
||||
"id": "6KjVrNy_dxGXJtntdqrjY",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 655.4963325816416,
|
||||
"y": 604.9758066195944,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 50,
|
||||
"height": 20,
|
||||
"seed": 1808016110,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [],
|
||||
"updated": 1670307245844,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"text": "draw()",
|
||||
"baseline": 14,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "kbEG_cCZadugfCPxYedhf",
|
||||
"originalText": "draw()"
|
||||
},
|
||||
{
|
||||
"type": "arrow",
|
||||
"version": 31,
|
||||
"versionNonce": 101778865,
|
||||
"isDeleted": false,
|
||||
"id": "eryKwAzIMcBMQP0Ybl1Mm",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 694.9963325816416,
|
||||
"y": 242.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#12b886",
|
||||
"width": 0,
|
||||
"height": 38,
|
||||
"seed": 1130444978,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"boundElements": [],
|
||||
"updated": 1670307364549,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"startBinding": {
|
||||
"elementId": "fxk8rHocjpTteICJMa6n8",
|
||||
"focus": 0,
|
||||
"gap": 10
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "wZLPkORf755_2Vp0J6I0V",
|
||||
"focus": 0.03225806451612903,
|
||||
"gap": 9
|
||||
},
|
||||
"lastCommittedPoint": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
38
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "arrow",
|
||||
"version": 160,
|
||||
"versionNonce": 1672489439,
|
||||
"isDeleted": false,
|
||||
"id": "Zc9GOJ8DsIQYo4WaGvvHy",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 686.7253597961584,
|
||||
"y": 347.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#12b886",
|
||||
"width": 0.3256260532492661,
|
||||
"height": 36,
|
||||
"seed": 1138446962,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"boundElements": [],
|
||||
"updated": 1670307364549,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"startBinding": {
|
||||
"elementId": "wZLPkORf755_2Vp0J6I0V",
|
||||
"gap": 8,
|
||||
"focus": 0.03595554587056003
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "290mWFx31fA5smc5FqPUr",
|
||||
"gap": 9,
|
||||
"focus": 0.09195903246894747
|
||||
},
|
||||
"lastCommittedPoint": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
-0.3256260532492661,
|
||||
36
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "arrow",
|
||||
"version": 616,
|
||||
"versionNonce": 447594705,
|
||||
"isDeleted": false,
|
||||
"id": "hUUqTCXva-vZjnBeM-PR3",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 684.6524492354905,
|
||||
"y": 452.97580661959455,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#228be6",
|
||||
"width": 1.5815106831711319,
|
||||
"height": 29.000000000000114,
|
||||
"seed": 1169930546,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"boundElements": [],
|
||||
"updated": 1670307888001,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"startBinding": {
|
||||
"elementId": "290mWFx31fA5smc5FqPUr",
|
||||
"focus": -0.044553538542618336,
|
||||
"gap": 10
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "5cG3FjQlYuIGPZMsIMgJU",
|
||||
"focus": 0.08947713014192164,
|
||||
"gap": 6.999999999999915
|
||||
},
|
||||
"lastCommittedPoint": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow",
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.5815106831711319,
|
||||
29.000000000000114
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 560,
|
||||
"versionNonce": 11022527,
|
||||
"isDeleted": false,
|
||||
"id": "5cG3FjQlYuIGPZMsIMgJU",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 616.4963325816416,
|
||||
"y": 488.9758066195945,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#228be6",
|
||||
"width": 131,
|
||||
"height": 50,
|
||||
"seed": 609895569,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "-Fl205ZvyGaxHAHt7C3r3"
|
||||
},
|
||||
{
|
||||
"id": "hUUqTCXva-vZjnBeM-PR3",
|
||||
"type": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "bplSSGA4kyy-Av7nKNK1B",
|
||||
"type": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "qukSk_W6enSdwERPEPkhZ",
|
||||
"type": "arrow"
|
||||
}
|
||||
],
|
||||
"updated": 1670307888001,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 551,
|
||||
"versionNonce": 685087263,
|
||||
"isDeleted": false,
|
||||
"id": "-Fl205ZvyGaxHAHt7C3r3",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 647.4963325816416,
|
||||
"y": 503.97580661959455,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 69,
|
||||
"height": 20,
|
||||
"seed": 415680767,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElements": null,
|
||||
"updated": 1670307260196,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"text": "update()",
|
||||
"baseline": 14,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "5cG3FjQlYuIGPZMsIMgJU",
|
||||
"originalText": "update()"
|
||||
},
|
||||
{
|
||||
"id": "bplSSGA4kyy-Av7nKNK1B",
|
||||
"type": "arrow",
|
||||
"x": 683.9963325816416,
|
||||
"y": 546.9758066195944,
|
||||
"width": 1,
|
||||
"height": 34,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#228be6",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1937189809,
|
||||
"version": 33,
|
||||
"versionNonce": 1639939761,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670307888001,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
-1,
|
||||
34
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "5cG3FjQlYuIGPZMsIMgJU",
|
||||
"focus": -0.044849023090586096,
|
||||
"gap": 7.999999999999858
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "kbEG_cCZadugfCPxYedhf",
|
||||
"focus": 0.022646536412078155,
|
||||
"gap": 9
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow"
|
||||
},
|
||||
{
|
||||
"id": "qukSk_W6enSdwERPEPkhZ",
|
||||
"type": "arrow",
|
||||
"x": 758.9963325816416,
|
||||
"y": 615.9758066195944,
|
||||
"width": 87,
|
||||
"height": 107.99999999999994,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 677436529,
|
||||
"version": 170,
|
||||
"versionNonce": 377207327,
|
||||
"isDeleted": false,
|
||||
"boundElements": [],
|
||||
"updated": 1670307315516,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
86,
|
||||
0
|
||||
],
|
||||
[
|
||||
83,
|
||||
-106.99999999999994
|
||||
],
|
||||
[
|
||||
-1,
|
||||
-107.99999999999994
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": {
|
||||
"elementId": "kbEG_cCZadugfCPxYedhf",
|
||||
"focus": 0.04,
|
||||
"gap": 13
|
||||
},
|
||||
"endBinding": {
|
||||
"elementId": "5cG3FjQlYuIGPZMsIMgJU",
|
||||
"focus": -0.26783652736088875,
|
||||
"gap": 10.5
|
||||
},
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": "arrow"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 258 KiB |
|
Before Width: | Height: | Size: 411 KiB |
@@ -1,375 +0,0 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"id": "Mhp-wQ2wZxCI4BYWvTvV2",
|
||||
"type": "ellipse",
|
||||
"x": 420,
|
||||
"y": 233,
|
||||
"width": 385.99999999999994,
|
||||
"height": 385.99999999999994,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#ffdf22",
|
||||
"fillStyle": "cross-hatch",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 474299186,
|
||||
"version": 149,
|
||||
"versionNonce": 2072559726,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158627399,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "SqZRA75ACKHo0lB799wpS",
|
||||
"type": "line",
|
||||
"x": 605,
|
||||
"y": 426,
|
||||
"width": 173.02018127597637,
|
||||
"height": 99.89324823492274,
|
||||
"angle": 0,
|
||||
"strokeColor": "#087f5b",
|
||||
"backgroundColor": "#ffdf22",
|
||||
"fillStyle": "cross-hatch",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 484805038,
|
||||
"version": 286,
|
||||
"versionNonce": 1603007154,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670159044301,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
173.02018127597637,
|
||||
-99.89324823492274
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": null
|
||||
},
|
||||
{
|
||||
"id": "7XVC5Wqiy62pN9Vc92bgl",
|
||||
"type": "text",
|
||||
"x": 645.7358370304399,
|
||||
"y": 356.14958623820286,
|
||||
"width": 86,
|
||||
"height": 20,
|
||||
"angle": 5.766085793504818,
|
||||
"strokeColor": "#087f5b",
|
||||
"backgroundColor": "#ffdf22",
|
||||
"fillStyle": "cross-hatch",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1883808110,
|
||||
"version": 228,
|
||||
"versionNonce": 627525998,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670159044301,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "moleRadius",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "moleRadius"
|
||||
},
|
||||
{
|
||||
"id": "zp9JMFpfOA6ZEWCCiqwW0",
|
||||
"type": "line",
|
||||
"x": 606,
|
||||
"y": 427,
|
||||
"width": 128.012747010704,
|
||||
"height": 208.02230726873202,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 224372978,
|
||||
"version": 81,
|
||||
"versionNonce": 563971630,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158772553,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
-128.012747010704,
|
||||
-208.02230726873202
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": null
|
||||
},
|
||||
{
|
||||
"id": "LIDFlKBUhkbZdzTUFT1qp",
|
||||
"type": "line",
|
||||
"x": 604.8240237554426,
|
||||
"y": 425.10629955596494,
|
||||
"width": 127.71248741178238,
|
||||
"height": 4.628286654564533,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 34525358,
|
||||
"version": 124,
|
||||
"versionNonce": 1131380590,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158787752,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
-127.71248741178238,
|
||||
-4.628286654564533
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": null
|
||||
},
|
||||
{
|
||||
"id": "-Of3RfHAvJDq0qHIwjm2U",
|
||||
"type": "ellipse",
|
||||
"x": 471.96813247323996,
|
||||
"y": 413.60866976111646,
|
||||
"width": 12,
|
||||
"height": 12,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#4c6ef5",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1050702514,
|
||||
"version": 384,
|
||||
"versionNonce": 1957432558,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158970885,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "NB4WGe-lT7XqLrsKX8jN8",
|
||||
"type": "ellipse",
|
||||
"x": 472,
|
||||
"y": 212,
|
||||
"width": 12,
|
||||
"height": 12,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 2059751730,
|
||||
"version": 277,
|
||||
"versionNonce": 756441010,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158769939,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "T1vEWEHV-1FM4A7Q7dTzy",
|
||||
"type": "ellipse",
|
||||
"x": 601.6117120882632,
|
||||
"y": 422.28007605476614,
|
||||
"width": 6.436664554034337,
|
||||
"height": 6.436664554034337,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#000000",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1983845742,
|
||||
"version": 376,
|
||||
"versionNonce": 1202556466,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158984089,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "eEMIGJ2Ag5HqWZLPmjXMM",
|
||||
"type": "text",
|
||||
"x": 551.4695946462369,
|
||||
"y": 432.8553279772536,
|
||||
"width": 108,
|
||||
"height": 20,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#000000",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 817794290,
|
||||
"version": 97,
|
||||
"versionNonce": 1438641266,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158980419,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "(moleX, moleY)",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "(moleX, moleY)"
|
||||
},
|
||||
{
|
||||
"id": "6cMmrU3lcJbub8sEKnVWe",
|
||||
"type": "text",
|
||||
"x": 409.80838527586974,
|
||||
"y": 186.48331271464983,
|
||||
"width": 135,
|
||||
"height": 20,
|
||||
"angle": 0,
|
||||
"strokeColor": "#c92a2a",
|
||||
"backgroundColor": "#000000",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 399694958,
|
||||
"version": 166,
|
||||
"versionNonce": 1571185842,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158939920,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "(mouseX, mouseY)",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "(mouseX, mouseY)"
|
||||
},
|
||||
{
|
||||
"id": "0idmv_zLtEYyctHB4lSWV",
|
||||
"type": "text",
|
||||
"x": 406.7568976895149,
|
||||
"y": 390.3911282833501,
|
||||
"width": 135,
|
||||
"height": 20,
|
||||
"angle": 0,
|
||||
"strokeColor": "#364fc7",
|
||||
"backgroundColor": "#000000",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"strokeStyle": "dashed",
|
||||
"roughness": 0,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1008210350,
|
||||
"version": 224,
|
||||
"versionNonce": 968376110,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670158975919,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "(mouseX, mouseY)",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "(mouseX, mouseY)"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 821 KiB |
@@ -1,375 +0,0 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"id": "HPGP8tbAPy0aGI3_MCE3D",
|
||||
"type": "diamond",
|
||||
"x": 491.42779164474496,
|
||||
"y": 479.56091158550765,
|
||||
"width": 432.03244941244884,
|
||||
"height": 55.325188818463005,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#868e96",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 1103578030,
|
||||
"version": 138,
|
||||
"versionNonce": 1150893294,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "vhIFJN3-91oJXV-RfFsBf",
|
||||
"type": "diamond",
|
||||
"x": 491.42779164474496,
|
||||
"y": 435.8942449188411,
|
||||
"width": 432.03244941244884,
|
||||
"height": 55.325188818463005,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fab005",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 618886834,
|
||||
"version": 198,
|
||||
"versionNonce": 1515704562,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "B2pM-4m_3Dk2w_6dY-hVJ",
|
||||
"type": "diamond",
|
||||
"x": 491.42779164474496,
|
||||
"y": 392.2275782521744,
|
||||
"width": 432.03244941244884,
|
||||
"height": 55.325188818463005,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#228be6",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 844345582,
|
||||
"version": 231,
|
||||
"versionNonce": 1954508590,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "Ge28XC9PqD26hknNaFXKP",
|
||||
"type": "diamond",
|
||||
"x": 491.42779164474496,
|
||||
"y": 348.5609115855077,
|
||||
"width": 432.03244941244884,
|
||||
"height": 55.325188818463005,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 1326657902,
|
||||
"version": 249,
|
||||
"versionNonce": 685040306,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"id": "PLU80s2TkyMEAOVgolwJx",
|
||||
"type": "line",
|
||||
"x": 506.9963325816415,
|
||||
"y": 507.9758066195945,
|
||||
"width": 0,
|
||||
"height": 132.00000000000006,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "dotted",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 1246804466,
|
||||
"version": 39,
|
||||
"versionNonce": 627399022,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
-132.00000000000006
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": null
|
||||
},
|
||||
{
|
||||
"id": "xDdJ5FnbMLIbN95FE3Iyc",
|
||||
"type": "line",
|
||||
"x": 910.9963325816416,
|
||||
"y": 506.9758066195945,
|
||||
"width": 0,
|
||||
"height": 132,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "dotted",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 1034568050,
|
||||
"version": 77,
|
||||
"versionNonce": 1363786866,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
-132
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": null
|
||||
},
|
||||
{
|
||||
"id": "clYu5Q9GzKbAfohBEsGwn",
|
||||
"type": "line",
|
||||
"x": 709.9963325816416,
|
||||
"y": 532.9758066195944,
|
||||
"width": 0,
|
||||
"height": 129.99999999999994,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "dotted",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 1798035246,
|
||||
"version": 42,
|
||||
"versionNonce": 244579246,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"points": [
|
||||
[
|
||||
0,
|
||||
0
|
||||
],
|
||||
[
|
||||
0,
|
||||
-129.99999999999994
|
||||
]
|
||||
],
|
||||
"lastCommittedPoint": null,
|
||||
"startBinding": null,
|
||||
"endBinding": null,
|
||||
"startArrowhead": null,
|
||||
"endArrowhead": null
|
||||
},
|
||||
{
|
||||
"id": "v2nD7_bvWJYHqs82XDWO2",
|
||||
"type": "text",
|
||||
"x": 935.9963325816416,
|
||||
"y": 497.2235059947391,
|
||||
"width": 159,
|
||||
"height": 20,
|
||||
"angle": 0,
|
||||
"strokeColor": "#343a40",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "dotted",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 1323260978,
|
||||
"version": 111,
|
||||
"versionNonce": 372528622,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "Ebene 0: ColorLayer",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "Ebene 0: ColorLayer"
|
||||
},
|
||||
{
|
||||
"id": "c6T2j8hozL3RZcNYGMgRl",
|
||||
"type": "text",
|
||||
"x": 935.9963325816416,
|
||||
"y": 453.55683932807256,
|
||||
"width": 172,
|
||||
"height": 20,
|
||||
"angle": 0,
|
||||
"strokeColor": "#e67700",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "dotted",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 1949746930,
|
||||
"version": 111,
|
||||
"versionNonce": 1448527858,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "Ebene 1: DrawingLayer",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "Ebene 1: DrawingLayer"
|
||||
},
|
||||
{
|
||||
"id": "bAmGMg2i4Hvv7t_obXSKn",
|
||||
"type": "text",
|
||||
"x": 935.9963325816416,
|
||||
"y": 409.8901726614059,
|
||||
"width": 174,
|
||||
"height": 20,
|
||||
"angle": 0,
|
||||
"strokeColor": "#1864ab",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "dotted",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 706529710,
|
||||
"version": 144,
|
||||
"versionNonce": 1968138286,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163691142,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "Ebene 2: ShapesLayer",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "Ebene 2: ShapesLayer"
|
||||
},
|
||||
{
|
||||
"id": "9-QieQt-nVqGCe5D4r15j",
|
||||
"type": "text",
|
||||
"x": 935.9963325816416,
|
||||
"y": 366.2235059947392,
|
||||
"width": 65,
|
||||
"height": 20,
|
||||
"angle": 0,
|
||||
"strokeColor": "#2b8a3e",
|
||||
"backgroundColor": "#40c057",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "dotted",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "round",
|
||||
"seed": 2100742126,
|
||||
"version": 179,
|
||||
"versionNonce": 289074606,
|
||||
"isDeleted": false,
|
||||
"boundElements": null,
|
||||
"updated": 1670163697684,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"text": "Ebene 3",
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 14,
|
||||
"containerId": null,
|
||||
"originalText": "Ebene 3"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 289 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 408 KiB |
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 457 KiB |
@@ -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;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block tabs %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
{% block footer %}{% endblock %}
|
||||
@@ -1,71 +0,0 @@
|
||||
<figure markdown>
|
||||
{ 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 grafische Ausgaben für Schülerinnen und Schüler im Unterricht
|
||||
leichter 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](schnellstart.md)
|
||||
* [Installation](installation.md)
|
||||
* [Javadoc]({{ javadoc() }})
|
||||
|
||||
## Über die Zeichenmaschine
|
||||
|
||||
Die _Zeichenmaschine_ ist aus dem Wunsch entstanden, nach einer Einführung in
|
||||
die Grundlagen der Programmiersprache Java mit Processing, einen Übergang zur
|
||||
objektorientierten Modellierung und Programmierung mit BlueJ zu leichter zu
|
||||
ermöglichen. Mit Processing kann zwar auch objektorientiert programmiert werden,
|
||||
aber mit Blick auf die Sekundarstufe II in NRW ist ein Wechsel zu einer
|
||||
generellen Programmierumgebung wie BlueJ wünschenswert.
|
||||
|
||||
Die Motivation von Processing, schnell grafische Ergebnisse der eigenen
|
||||
Programme zu sehen, sollte aber für den Übergang erhalten bleiben. So ist eine
|
||||
kleine Bibliothek mit minimalen Abhängigkeiten entstanden, die an Processing
|
||||
angelehnt einfache Schnittstellen bereitstellte, um Programmen eine grafische
|
||||
Ausgabe zu ermöglichen, ohne viel "Boilerplate" Code schreiben zu müssen.
|
||||
|
||||
Aus diesen Anfängen ist nach und nach eine umfassende Grafikbibliothek
|
||||
entstanden, die als _Zeichenmaschine_ veröffentlicht wurde.
|
||||
|
||||
### Was die Zeichenmaschine nicht ist
|
||||
|
||||
Die Bibliothek hat nicht den Anspruch, ein Konkurrent zu Processing oder
|
||||
anderen, seit Jahren etablierten und ausgereiften, Grafiksystemen zu sein. Vor
|
||||
allem ist die _Zeichenmaschine_ keine vollwertige Game Engine, die auf die
|
||||
Ausführung komplexer Spiele spezialisiert ist. Für diese Zwecke gibt es genügend
|
||||
Alternativen, von deren Nutzung gar nicht abgeraten werden soll.
|
||||
|
||||
## Aufbau der 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`.
|
||||
|
||||
@@ -1,45 +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/releases/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
|
||||
|
||||
## Unterstützung für MP3
|
||||
128
docs/macros.py
@@ -1,128 +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 = list()
|
||||
name = list()
|
||||
|
||||
for p in clazz.split('.'):
|
||||
if p[0].islower():
|
||||
path.append(p)
|
||||
else:
|
||||
name.append(p)
|
||||
|
||||
path = '/'.join(path) + '/' + '.'.join(name) + ".html"
|
||||
if target:
|
||||
path = f"{path}#{target}"
|
||||
return f"{javadoc_url}/{path}"
|
||||
|
||||
@env.macro
|
||||
def jd(cl: str = None, t: str = None) -> str:
|
||||
return javadoc(cl, t)
|
||||
|
||||
@env.macro
|
||||
def javadoc_link(
|
||||
clazz: str = None,
|
||||
target: str = None,
|
||||
strip_package: bool = True,
|
||||
strip_clazz: bool = False,
|
||||
strip_params: bool = True,
|
||||
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 m := re.match(r'^(.+?)\((.*)\)$', _target):
|
||||
if strip_params and m.group(2):
|
||||
params = m.group(2).split(',')
|
||||
for i, param in enumerate(params):
|
||||
dot = param.rfind('.')
|
||||
if dot >= 0:
|
||||
params[i] = param[dot+1:].strip()
|
||||
params = ", ".join(params)
|
||||
_target = f'{m.group(1)}({params})'
|
||||
|
||||
if strip_clazz:
|
||||
name = _target
|
||||
else:
|
||||
name = f"{name}.{_target}"
|
||||
if title:
|
||||
name = title
|
||||
|
||||
return f"[`{name}`]({javadoc(clazz, target)})"
|
||||
|
||||
@env.macro
|
||||
def jdl(
|
||||
cl: str = None,
|
||||
t: str = None,
|
||||
p: bool = False,
|
||||
c: bool = True,
|
||||
title: str = None
|
||||
) -> str:
|
||||
return javadoc_link(cl, t, strip_package=not p, strip_clazz=not c, strip_params=True, title=title)
|
||||
|
||||
@env.macro
|
||||
def jdc(
|
||||
cl: str,
|
||||
p: bool = False
|
||||
) -> str:
|
||||
return javadoc_link(cl, strip_package=not p)
|
||||
|
||||
@env.macro
|
||||
def jdm(
|
||||
cl: str,
|
||||
t: str,
|
||||
p: bool = False,
|
||||
c: bool = False
|
||||
) -> str:
|
||||
return javadoc_link(cl, t, strip_package=not p, strip_clazz=not c)
|
||||
|
||||
@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
|
||||
|
||||
@env.macro
|
||||
def jds(
|
||||
cl: str = None,
|
||||
m: str = None,
|
||||
pkg: str = None,
|
||||
params: List[str] = list(),
|
||||
) -> str:
|
||||
javadoc_signature(cl, m, pkg, params)
|
||||
|
||||
|
||||
# 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...)
|
||||
@@ -1,606 +0,0 @@
|
||||
# Schnellstart mit der Zeichenmaschine
|
||||
|
||||
Um die **Zeichenmaschine** in einem Projekt zu nutzen ist nicht mehr nötig, als
|
||||
die [JAR-Datei der aktuellen Version](https://github.com/jneug/zeichenmaschine/release/latest)
|
||||
herunterzuladen und
|
||||
dem [Classpath](https://www.delftstack.com/de/howto/java/java-classpath-/)
|
||||
hinzuzufügen. Eine Beschreibung für verschiedene Entwicklungsumgebungen findet
|
||||
sich im Abschnitt [Installation](installation.md).
|
||||
|
||||
## Die Basisklasse
|
||||
|
||||
Eine _Zeichenmaschine_ wird immer als Unterklasse von {{ javadoc_link("
|
||||
schule.ngb.zm.Zeichenmaschine") }} erstellt.
|
||||
|
||||
```java
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Die gezeigte Klasse ist schon eine lauffähige Zeichenmaschine und kann gestartet
|
||||
werden.
|
||||
|
||||
!!! note "main Methode"
|
||||
|
||||
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
|
||||
Abmessungen und den Titel des Fensters zu ändern, legen wir einen Konstruktor
|
||||
an.
|
||||
|
||||
???+ example "Quelltext"
|
||||
|
||||
```java
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
public Shapes() {
|
||||
super(800, 800, "Shapes");
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Starten wir das Projekt, wird eine Zeichenfläche in der Größe 800-mal-800 Pixel
|
||||
erstellt und in einem Fenster mit dem Titel „Shapes“ angezeigt.
|
||||
|
||||
<figure markdown>
|
||||
{ width=400 }
|
||||
</figure>
|
||||
|
||||
### Formen zeichnen
|
||||
|
||||
Eine Zeichenmaschine hat verschiedene Möglichkeiten Inhalte in das
|
||||
Zeichenfenster zu zeichnen. Um ein einfaches statisches Bild zu erzeugen,
|
||||
überschreiben wir die {{ jdl("schule.ngb.zm.Zeichenmaschine", "draw()",
|
||||
c=False) }} Methode.
|
||||
|
||||
???+ example "Quelltext"
|
||||
|
||||
```java
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
public Shapes() {
|
||||
super(800, 800, "Shapes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
background.setColor(BLUE);
|
||||
|
||||
drawing.setFillColor(255, 223, 34);
|
||||
drawing.noStroke();
|
||||
drawing.circle(400, 400, 100);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Wir sehen einen gelben Kreis (ohne Konturlinie) auf einem blauen Hintergrund.
|
||||
|
||||
<figure markdown>
|
||||
{ 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 bleiben, können wir sie statt in `draw()` auch in die {{
|
||||
jdl('Zeichenmaschine', 'setup()', c=False) }} Methode schreiben. Diese bereitet
|
||||
die Zeichenfläche vor dem ersten Zeichnen vor.
|
||||
|
||||
???+ example "Quelltext"
|
||||
|
||||
```java
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
public Shapes() {
|
||||
super(800, 800, "Shapes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
background.setColor(BLUE);
|
||||
|
||||
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>
|
||||
{ width=400 }
|
||||
</figure>
|
||||
|
||||
!!! tip ""
|
||||
|
||||
Mit {{ jdm("Constants", "canvasWidth") }} und
|
||||
{{ jdm("Constants", "canvasHeight") }} kannst du in der Zeichenmaschine
|
||||
auf die aktuelle Größe der Zeichenfläche zugreifen.
|
||||
{{ jdm("Constants", "random(int,int)") }} erzeugt eine Zufallszahl
|
||||
innerhalb der angegebenen Grenzen.
|
||||
|
||||
## Interaktionen mit der Maus: Whack-a-mole
|
||||
|
||||
Mit der Zeichenmaschine lassen sich Interaktionen mit der Maus leicht umsetzen.
|
||||
Wir wollen das Beispielprogramm zu einem
|
||||
[Whac-A-Mole](https://de.wikipedia.org/wiki/Whac-A-Mole) Spiel erweitern.
|
||||
|
||||
Auf der Zeichenfläche wird nur noch ein gelber Kreis an einer zufälligen Stelle
|
||||
angezeigt. Sobald die Spieler:in auf den Kreis klickt, soll dieser an eine neue
|
||||
Position springen.
|
||||
|
||||
Damit wir den Kreis an eine neue Position springen lassen können, müssen wir
|
||||
zufällige `x`- und `y`-Koordinaten generieren. Dazu erstellen wir zunächst zwei
|
||||
_Objektvariablen_ für die Koordinaten, die in der `setup()` Methode mit
|
||||
zufälligen Werte initialisiert werden. Diese benutzen wir, um die `draw
|
||||
()` Methode anzupassen.
|
||||
|
||||
??? example "Quelltext"
|
||||
|
||||
```Java
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
private int moleRadius = 20;
|
||||
|
||||
private int moleX;
|
||||
|
||||
private int moleY;
|
||||
|
||||
public Shapes() {
|
||||
super(800, 800, "Shapes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
background.setColor(BLUE);
|
||||
|
||||
drawing.setFillColor(255, 223, 34);
|
||||
drawing.noStroke();
|
||||
|
||||
moleX = random(50, canvasWidth - 50);
|
||||
moleY = random(50, canvasHeight - 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
drawing.clear();
|
||||
drawing.circle(moleX, moleY, moleRadius);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
<figure markdown>
|
||||
{ width=600 }
|
||||
</figure>
|
||||
|
||||
Als Nächstes prüfen wir bei jedem Mausklick, ob die Mauskoordinaten innerhalb
|
||||
des gelben Kreises (des Maulwurfs) liegen. Die Mauskoordinaten sind jederzeit
|
||||
über die Variablen `mouseX` und `mouseY` abrufbar. Um zu prüfen, ob diese
|
||||
Koordinaten innerhalb des Kreises liegen, vergleichen wir den Abstand zwischen
|
||||
Kreismittelpunkt `(moleX, moleY)` und den Mauskoordinaten
|
||||
`(mouseX, mouseY)` mit dem Radius des Kreises (im Bild grün). Ist die Entfernung
|
||||
kleiner als der Radius (blauer Kreis), wurde innerhalb des Kreises geklickt.
|
||||
Sonst außerhalb (roter Kreis).
|
||||
|
||||
<figure markdown>
|
||||
{ width=400 }
|
||||
</figure>
|
||||
|
||||
Den Abstand vom Mittelpunkt zur Maus lässt sich mithilfe des Satzes des
|
||||
Pythagoras leicht selber berechnen. Die Zeichenmaschine kann uns diese Arbeit
|
||||
aber auch abnehmen und stellt eine Methode dafür bereit
|
||||
({{ jdm("Constants", "distance(double,double,double,double)") }}).
|
||||
|
||||
Um auf einen Mausklick zu reagieren, ergänzen wir die
|
||||
{{ jdm("Zeichenmaschine", "mouseClicked()") }} Methode:
|
||||
|
||||
```java
|
||||
@Override
|
||||
public void mouseClicked() {
|
||||
if( distance(moleX, moleY, mouseX, mouseY) < moleRadius ) {
|
||||
moleX = random(50, canvasWidth - 50);
|
||||
moleY = random(50, canvasHeight - 50);
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
??? example "Quelltext"
|
||||
|
||||
```Java
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
private int moleRadius = 20;
|
||||
|
||||
private int moleX;
|
||||
|
||||
private int moleY;
|
||||
|
||||
public Shapes() {
|
||||
super(800, 800, "Shapes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
background.setColor(BLUE);
|
||||
|
||||
drawing.setFillColor(255, 223, 34);
|
||||
drawing.noStroke();
|
||||
|
||||
moleX = random(50, canvasWidth - 50);
|
||||
moleY = random(50, canvasHeight - 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
drawing.clear();
|
||||
drawing.circle(moleX, moleY, moleRadius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked() {
|
||||
if( distance(moleX, moleY, mouseX, mouseY) < moleRadius ) {
|
||||
moleX = random(50, canvasWidth - 50);
|
||||
moleY = random(50, canvasHeight - 50);
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
!!! warning ""
|
||||
|
||||
Der Aufruf von {{ jdm("Zeichenmaschine", "redraw()") }} zeichnet
|
||||
die Zeichenfläche neu, indem die `draw()` Methode erneut aufgerufen wird.
|
||||
Du solltest `draw()` niemals direkt aufrufen.
|
||||
|
||||
Nun springt der Kreis an eine andere Stelle, wenn er direkt mit der Maus
|
||||
angeklickt wird.
|
||||
|
||||
<figure markdown>
|
||||
{ width=400 }
|
||||
</figure>
|
||||
|
||||
## Ein paar Details zur Zeichenmaschine
|
||||
|
||||
Die _Zeichenmaschine_ wurde stark von der kreativen Programmierumgebung
|
||||
[Processing](https://processing.org) inspiriert. Wenn du Processing schon
|
||||
kennst, dann werden dir einige der Konzepte der _Zeichenmaschine_ schon bekannt
|
||||
vorkommen.
|
||||
|
||||
### Farben
|
||||
|
||||
Farben können auf verschiedene Weisen angegeben werden. Unser Beispiel nutzt
|
||||
bisher zwei Arten:
|
||||
|
||||
1. Die einfachste Möglichkeit sind die _Farbkonstanten_
|
||||
wie {{ jdm('Constants', 'BLUE') }} oder {{ jdm('Constants', 'RED') }}. Im
|
||||
Beispiel setzen wir den Hintergrund auf die Farbe `BLUE`.
|
||||
2. Farben werden häufig im RGB-Farbraum definiert. Dazu wird jeweils der Rot-,
|
||||
Grün- und Blauanteil der Farbe als Wert zwischen 0 und 255 angegeben. Im
|
||||
Beispiel setzen wir die Farbe der Kreise auf `255, 223, 34`, also viel Rot
|
||||
und Grün und nur ein wenig Blau.
|
||||
|
||||
### Ebenen
|
||||
|
||||
Die Zeichenfläche besteht aus einzelnen {{ jdl("Layer", title="Ebenen") }}, die
|
||||
auf übereinander liegen. Bis auf die unterste Ebene sind die Ebenen zunächst
|
||||
durchsichtig, wodurch die Zeichnungen unterer Ebenen durchscheinen.
|
||||
|
||||
<figure markdown>
|
||||
{ width=600 }
|
||||
</figure>
|
||||
|
||||
Eine _Zeichenmaschine_ besitzt zu Beginn drei Ebenen:
|
||||
|
||||
1. Die unterste Ebene ist ein {{ jdc("layers.ColorLayer") }}, die nur aus einer
|
||||
Farbe (oder einem Farbverlauf) besteht und keine durchsichtigen Bereiche
|
||||
besitzt. Im Beispiel setzen wir diese Ebene auf die Farbe `BLUE`.
|
||||
2. Die nächste Ebene ist ein {{ jdc("layers.DrawingLayer") }}, auf die wir
|
||||
unsere Formen zeichnen können. Die Ebene ist zunächst komplett durchsichtig.
|
||||
3. Die oberste Ebene ist ein {{ jdc("layers.ShapesLayer") }}, die zur
|
||||
Darstellung von Form-Objekten der Klasse {{ jdc("shapes.Shape") }} genutzt
|
||||
werden kann.
|
||||
|
||||
Du kannst einer Zeichenfläche aber auch beliebige neue oder selbst programmierte
|
||||
Ebenen hinzufügen.
|
||||
|
||||
### Ablauf
|
||||
|
||||
Die _Zeichenmaschine_ ruft nach dem Start die Methoden in einem festen Ablauf
|
||||
auf.
|
||||
|
||||
<figure markdown>
|
||||
{ width=500 }
|
||||
</figure>
|
||||
|
||||
Erstellst Du eine _Zeichenmaschine_ (beziehungsweise ein Objekt einer
|
||||
Unterklasse), dann wird zuerst die {{ jdm('Zeichenmaschine', 'setup()') }}
|
||||
Methode ausgeführt. Danach folgt einmalig die
|
||||
{{ jdm('Zeichenmaschine', 'draw()') }} Methode und dann endet das Hauptprogramm.
|
||||
|
||||
Die Eingaben der Maus werden in einem parallelen Ablauf (einem _Thread_)
|
||||
abgefangen und daraufhin die {{ jdm('Zeichenmaschine', 'mouseClicked()') }}
|
||||
Methode aufgerufen. In unserem Programm prüfen wir, ob mit der Maus
|
||||
innerhalb des Kreises geklickt wurde und rufen dann
|
||||
{{ jdm('Zeichenmaschine', 'redraw()') }} auf, woraufhin ein weiteres Mal
|
||||
`draw()` ausgeführt wird.
|
||||
|
||||
In _Processing_ wird dies der "statische" Modus genannt, weil das Programm nur
|
||||
einmal abläuft und dann stoppt. "Statisch" trifft es nicht ganz, da das Programm
|
||||
ja zum Beispiel durch Mauseingaben auch verändert werden kann. Wichtig ist aber,
|
||||
dass mit `redraw()` die Zeichenfläche manuell neu gezeichnet werden muss, damit
|
||||
sich der Inhalt ändert.
|
||||
|
||||
## Dynamische Programme
|
||||
|
||||
Wir wollen unser kleines Spiel dynamischer machen, indem die Kreise nur drei
|
||||
Sekunden angezeigt werden und dann von selbst an einen neuen Ort springen.
|
||||
Schafft man es, den Kreis in dieser Zeit anzuklicken, bekommt man einen Punkt.
|
||||
|
||||
Als zusätzliche Herausforderung lassen wir jeden Kreis in den drei Sekunden
|
||||
immer kleiner werden.
|
||||
|
||||
### Die Update-Draw-Schleifen
|
||||
|
||||
{ width=200 align=right }
|
||||
|
||||
Bisher hat die _Zeichenmaschine_ einmalig `draw()` aufgerufen und dann nur noch
|
||||
auf Benutzereingaben mit der Maus reagiert. Nun wollen wir das gezeichnete Bild
|
||||
aber laufend anpassen. Der Kreis soll schrumpfen und nach 3 Sekunden
|
||||
verschwinden.
|
||||
|
||||
Dazu ergänzen wir ein {{ jdl('Zeichenmaschine', 'update(double)', c=False) }}
|
||||
Methode in unserem Programm. Nun schaltet die _Zeichenmaschine_ in einen
|
||||
dynamischen Modus und startet die _Update-Draw-Schleife_. Das beduetet, nach
|
||||
Aufruf von `setup()` wird fortlaufend immer wieder zuerst `update()` und dann
|
||||
`draw()` aufgerufen.
|
||||
|
||||
Jeder Aufruf der `draw()` Methode zeichnet nun die Zeichenfläche neu. Jedes
|
||||
Bild, das gezeichnet wird (auch, wenn es genauso aussieht, wie das davor), nennt
|
||||
man ein _Frame_. Von Videospielen kennst Du vielleicht schon den Begriff "
|
||||
_Frames per second_" (Fps, dt. Bilder pro Sekunde). Er bedeutet, wie oft das
|
||||
Spiel neue Frames zeichnet, oder in der _Zeichenmaschine_, wie oft `draw()` pro
|
||||
Sekunde aufgerufen wird. Normalerweise passiert dies genau 60-mal pro Sekunde.
|
||||
|
||||
### Lebenszeit eines Kreises
|
||||
|
||||
Jeder Kreis soll drei Sekunden zu sehen sein. Daher fügen wir eine neue
|
||||
Objektvariable namens `moleTime` ein, die zunächst auf Drei steht. Da wir auch
|
||||
Bruchteile von Sekunden abziehen wollen, wählen wir als Datentyp `double`:
|
||||
|
||||
```Java
|
||||
private double moleTime=3.0;
|
||||
```
|
||||
|
||||
Der Parameter `delta` der `update()` Methode ist der Zeitraum in Sekunden seit
|
||||
dem letzten Frame. Subtrahieren wir diesen Wert bei jedem Frame von `moleTime`,
|
||||
wird der Wert immer kleiner. Dann müssen wir nur noch prüfen, ob er kleiner Null
|
||||
ist und in dem Fall den Kreis auf eine neue Position springen lassen.
|
||||
|
||||
Die Größe des Kreises passen wir so an, dass der Anteil der vergangenen Zeit die
|
||||
Größe des Kreises bestimmt:
|
||||
|
||||
```Java
|
||||
drawing.circle(moleX,moleY,moleRadius*(moleTime/3.0));
|
||||
```
|
||||
|
||||
??? example "Quelltext"
|
||||
|
||||
```Java
|
||||
import schule.ngb.zm.Zeichenmaschine;
|
||||
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
private int moleRadius = 20;
|
||||
|
||||
private int moleX;
|
||||
|
||||
private int moleY;
|
||||
|
||||
private double moleTime;
|
||||
|
||||
public Shapes() {
|
||||
super(800, 800, "Shapes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
background.setColor(BLUE);
|
||||
|
||||
drawing.setFillColor(255, 223, 34);
|
||||
drawing.noStroke();
|
||||
|
||||
randomizeMole();
|
||||
}
|
||||
|
||||
private void randomizeMole() {
|
||||
moleX = random(moleRadius*2, canvasWidth - moleRadius*2);
|
||||
moleY = random(moleRadius*2, canvasHeight - moleRadius*2);
|
||||
moleTime = 3.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update( double delta ) {
|
||||
moleTime -= delta;
|
||||
|
||||
if( moleTime <= 0 ) {
|
||||
randomizeMole();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
drawing.clear();
|
||||
drawing.circle(moleX, moleY, moleRadius * (moleTime / 3.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked() {
|
||||
if( distance(moleX, moleY, mouseX, mouseY) < moleRadius ) {
|
||||
randomizeMole();
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main( String[] args ) {
|
||||
new Shapes();
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
<figure markdown>
|
||||
{ width=400 }
|
||||
</figure>
|
||||
|
||||
!!! tip ""
|
||||
|
||||
Der Maulwurf muss mittlerweile an drei verschiedenen Stellen im Programm
|
||||
auf eine zufällige Position gesetzt werden (am Anfang, wenn er angeklickt
|
||||
wurde und wenn die drei Sekunden abgelaufen sind). Daher wurde das Versetzen
|
||||
in eine eigene Methode `randomizeMole()` ausgelagert.
|
||||
|
||||
### Punktezähler
|
||||
|
||||
Zum Schluss wollen wir noch bei jedem Treffer mit der Maus die Punkte zählen und
|
||||
als Text auf die Zeichenfläche schreiben.
|
||||
|
||||
Dazu ergänzen wir eine weitere Objektvariable `score`, die in `mouseClicked()`
|
||||
erhöht wird, falls der Kreis getroffen wurde.
|
||||
|
||||
Um den Punktestand anzuzeigen ergänzen wir in `draw()` einen Aufruf von
|
||||
{{ jdl('layers.DrawingLayer', 'text(java.lang.String,double,double,schule.ngb.zm.Options.Direction)') }}
|
||||
mit dem Inhalt von `score` und den Koordinaten, an denen der Text gezeigt
|
||||
werden soll.
|
||||
Die Zeichenebene zeichnet im Moment alle Formen und Text ausgehend vom Zentrum
|
||||
der Form. Damit der Text 10 Pixel vom Rand entfernt links oben angezeigt wird,
|
||||
können wir der Text Methode (und allen anderen, die etwas zeichnen) eine {{
|
||||
jdl('Options.Direction', title='Richtung') }} übergeben, die festlegt, von
|
||||
welchem Ausgangspunkt (oder _Ankerpunkt_) die Form gezeichnet werden soll.
|
||||
|
||||
```Java
|
||||
drawing.setFillColor(BLACK);
|
||||
drawing.text("Punkte: "+score,10,10,NORTHWEST);
|
||||
```
|
||||
|
||||
<figure markdown>
|
||||
{ width=400 }
|
||||
</figure>
|
||||
|
||||
??? example "Quelltext"
|
||||
|
||||
```Java
|
||||
import schule.ngb.zm.Zeichenmaschine;
|
||||
|
||||
public class Shapes extends Zeichenmaschine {
|
||||
|
||||
private int moleRadius = 20;
|
||||
|
||||
private int moleX;
|
||||
|
||||
private int moleY;
|
||||
|
||||
private double moleTime;
|
||||
|
||||
private int score = 0;
|
||||
|
||||
public Shapes() {
|
||||
super(800, 800, "Shapes");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
background.setColor(BLUE);
|
||||
|
||||
drawing.noStroke();
|
||||
drawing.setFontSize(24);
|
||||
|
||||
randomizeMole();
|
||||
}
|
||||
|
||||
private void randomizeMole() {
|
||||
moleX = random(moleRadius*2, canvasWidth - moleRadius*2);
|
||||
moleY = random(moleRadius*2, canvasHeight - moleRadius*2);
|
||||
moleTime = 3.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update( double delta ) {
|
||||
moleTime -= delta;
|
||||
|
||||
if( moleTime <= 0 ) {
|
||||
randomizeMole();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
drawing.clear();
|
||||
|
||||
drawing.setFillColor(255, 223, 34);
|
||||
drawing.circle(moleX, moleY, moleRadius * (moleTime / 3.0));
|
||||
|
||||
drawing.setFillColor(BLACK);
|
||||
drawing.text("Punkte: " + score, 10, 10, NORTHWEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked() {
|
||||
if( distance(moleX, moleY, mouseX, mouseY) < moleRadius ) {
|
||||
score += 1;
|
||||
randomizeMole();
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main( String[] args ) {
|
||||
new Shapes();
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Wie es weitergehen kann
|
||||
|
||||
In diesem Schnellstart-Tutorial hast du die Grundlagen der _Zeichenmaschine_
|
||||
gelernt. Um weiterzumachen, kannst du versuchen, das Whack-a-mole Spiel um diese
|
||||
Funktionen zu erweitern:
|
||||
|
||||
- Mehrere "Maulwürfe" gleichzeitig.
|
||||
- Unterschiedliche Zeiten pro Maulwurf.
|
||||
|
||||
Wenn du mehr über die Möglichkeiten lernen möchtest, die dir die
|
||||
_Zeichenmaschine_ bereitstellt, kannst du dir die weiteren Tutorials in dieser
|
||||
Dokumentation ansehen. Ein guter Startpunkt ist das
|
||||
[Aquarium](tutorials/aquarium/aquarium1.md).
|
||||
|
||||
Viele verschiedene Beispiele, ohne detailliertes Tutorial, findest du in der
|
||||
Kategorie Beispiele und auf GitHub im Repository
|
||||
[jneug/zeichenmaschine-examples](https://github.com/jneug/zeichenmaschine-examples).
|
||||
@@ -1,19 +0,0 @@
|
||||
# Tutorial: Aquarium
|
||||
|
||||
In diesem Tutorial wollen wir mithilfe der _Zeichenmaschine_ ein (bonbonbuntes)
|
||||
interaktives Aquarium entwickeln. Dabei werden wir in verschiedenen Ausbaustufen
|
||||
zunächst das System Modellieren und dann implementieren.
|
||||
|
||||
!!! info "Mein bonbonbuntes Aquarium"
|
||||
|
||||
Das Projekt [Mein bonbonbuntes Aquarium](http://blog.schockwellenreiter.de/2021/02/2021021201.html)
|
||||
stammt ursprünglich aus dem Blog [Schockwellenreiter](http://blog.schockwellenreiter.de)
|
||||
von [Jörg Kantel](http://cognitiones.kantel-chaos-team.de/cv.html).
|
||||
|
||||
Das Endprodukt soll folgendes umfassen:
|
||||
|
||||
- Darstellung eines hübschen Aquariums mit Fischen, die hin und her schwimmen.
|
||||
- Zur Darstellung wollen wir wie im Original die Sprites aus dem [Fish Pack von Kenny.nl](https://www.kenney.nl/assets/fish-pack) nutzen.
|
||||
- Das Aquarium soll durch passende Geräusche untermalt werden.
|
||||
- Bei einem Klick in das Aquarium soll ein zufälliger Fisch erscheinen.
|
||||
- Bei einem Druck auf die Leertaste soll ein Hai durch das Aquarium schwimmen und alle Fische auf seinem Weg auffressen.
|
||||
53
examples/zm_aquarium/Aquarium.java
Normal 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
59
examples/zm_aquarium/Background.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
72
examples/zm_aquarium/Fish.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
55
examples/zm_aquarium/package.bluej
Normal 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
|
||||
BIN
examples/zm_aquarium/tiles/fish1.png
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
examples/zm_aquarium/tiles/fish1gs.png
Executable file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
examples/zm_aquarium/tiles/fish2.png
Executable file
|
After Width: | Height: | Size: 785 B |
BIN
examples/zm_aquarium/tiles/fish2gs.png
Executable file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
examples/zm_aquarium/tiles/fish3.png
Executable file
|
After Width: | Height: | Size: 982 B |
BIN
examples/zm_aquarium/tiles/fish3gs.png
Executable file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
examples/zm_aquarium/tiles/fish4.png
Executable file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/zm_aquarium/tiles/fish4gs.png
Executable file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
examples/zm_aquarium/tiles/fish5.png
Executable file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
examples/zm_aquarium/tiles/fish5gs.png
Executable file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
examples/zm_aquarium/tiles/fish6.png
Executable file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
examples/zm_aquarium/tiles/fish6gs.png
Executable file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/zm_aquarium/tiles/fish7.png
Executable file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
examples/zm_aquarium/tiles/fish7gs.png
Executable file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
examples/zm_aquarium/tiles/floor1.png
Executable file
|
After Width: | Height: | Size: 817 B |
BIN
examples/zm_aquarium/tiles/floor2.png
Executable file
|
After Width: | Height: | Size: 821 B |
BIN
examples/zm_aquarium/tiles/floor3.png
Executable file
|
After Width: | Height: | Size: 886 B |
BIN
examples/zm_aquarium/tiles/floor4.png
Executable file
|
After Width: | Height: | Size: 904 B |
BIN
examples/zm_aquarium/tiles/floor5.png
Executable file
|
After Width: | Height: | Size: 757 B |
BIN
examples/zm_aquarium/tiles/floor6.png
Executable file
|
After Width: | Height: | Size: 861 B |
BIN
examples/zm_aquarium/tiles/floor7.png
Executable file
|
After Width: | Height: | Size: 732 B |
BIN
examples/zm_aquarium/tiles/floor8.png
Executable file
|
After Width: | Height: | Size: 798 B |
BIN
examples/zm_aquarium/tiles/plant1.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/zm_aquarium/tiles/plant10.png
Executable file
|
After Width: | Height: | Size: 769 B |
BIN
examples/zm_aquarium/tiles/plant11.png
Executable file
|
After Width: | Height: | Size: 1012 B |
BIN
examples/zm_aquarium/tiles/plant12.png
Executable file
|
After Width: | Height: | Size: 689 B |
BIN
examples/zm_aquarium/tiles/plant13.png
Executable file
|
After Width: | Height: | Size: 1013 B |
BIN
examples/zm_aquarium/tiles/plant14.png
Executable file
|
After Width: | Height: | Size: 1012 B |
BIN
examples/zm_aquarium/tiles/plant2.png
Executable file
|
After Width: | Height: | Size: 890 B |
BIN
examples/zm_aquarium/tiles/plant3.png
Executable file
|
After Width: | Height: | Size: 930 B |
BIN
examples/zm_aquarium/tiles/plant4.png
Executable file
|
After Width: | Height: | Size: 752 B |
BIN
examples/zm_aquarium/tiles/plant5.png
Executable file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/zm_aquarium/tiles/plant6.png
Executable file
|
After Width: | Height: | Size: 886 B |
BIN
examples/zm_aquarium/tiles/plant7.png
Executable file
|
After Width: | Height: | Size: 925 B |
BIN
examples/zm_aquarium/tiles/plant8.png
Executable file
|
After Width: | Height: | Size: 741 B |
BIN
examples/zm_aquarium/tiles/plant9.png
Executable file
|
After Width: | Height: | Size: 653 B |
BIN
examples/zm_aquarium/tiles/shark.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
examples/zm_aquarium/tiles/skeleton1.png
Executable file
|
After Width: | Height: | Size: 711 B |
BIN
examples/zm_aquarium/tiles/skeleton10.png
Executable file
|
After Width: | Height: | Size: 821 B |
BIN
examples/zm_aquarium/tiles/skeleton2.png
Executable file
|
After Width: | Height: | Size: 941 B |
BIN
examples/zm_aquarium/tiles/skeleton3.png
Executable file
|
After Width: | Height: | Size: 581 B |
BIN
examples/zm_aquarium/tiles/skeleton4.png
Executable file
|
After Width: | Height: | Size: 729 B |
BIN
examples/zm_aquarium/tiles/skeleton5.png
Executable file
|
After Width: | Height: | Size: 624 B |
BIN
examples/zm_aquarium/tiles/skeleton6.png
Executable file
|
After Width: | Height: | Size: 848 B |
BIN
examples/zm_aquarium/tiles/skeleton7.png
Executable file
|
After Width: | Height: | Size: 745 B |
BIN
examples/zm_aquarium/tiles/skeleton8.png
Executable file
|
After Width: | Height: | Size: 1014 B |
BIN
examples/zm_aquarium/tiles/skeleton9.png
Executable file
|
After Width: | Height: | Size: 629 B |
BIN
examples/zm_aquarium/tiles/water.png
Executable file
|
After Width: | Height: | Size: 103 B |
128
examples/zm_boids/Boid.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
78
examples/zm_boids/Boids.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
77
examples/zm_boids/Creature.java
Normal 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;
|
||||
}
|
||||
}
|
||||
97
examples/zm_boids/Predator.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
55
examples/zm_boids/package.bluej
Normal 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
|
||||
BIN
examples/zm_boids/pointer.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
101
examples/zm_cookieclicker/Cookieclicker.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
33
examples/zm_cookieclicker/NumberParticle.java
Normal 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
111
examples/zm_cookieclicker/NumberParticleEmitter.java
Normal 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;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
36
examples/zm_cookieclicker/ParticleTest.java
Normal 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());
|
||||
}
|
||||
|
||||
}
|
||||
BIN
examples/zm_cookieclicker/assets/Cookie.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
55
examples/zm_cookieclicker/package.bluej
Normal 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
|
||||
51
examples/zm_follow/Eye.java
Normal 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);
|
||||
}
|
||||
}
|
||||
38
examples/zm_follow/Eyes.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
examples/zm_follow/package.bluej
Normal 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
|
||||
94
examples/zm_forces/Atoms.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
110
examples/zm_forces/Attractor.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
92
examples/zm_forces/Gravity.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
186
examples/zm_forces/Mover.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
55
examples/zm_forces/package.bluej
Normal 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
|
||||
33
examples/zm_formen/Dreieck.java
Normal 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;
|
||||
}
|
||||
}
|
||||