Continue german translation
This commit is contained in:
parent
dcdf4c3520
commit
b70cc8329b
357
_de/map/objects.md
Normal file
357
_de/map/objects.md
Normal file
@ -0,0 +1,357 @@
|
||||
---
|
||||
title: Objekte, Spieler, und Entities
|
||||
layout: default
|
||||
root: ../..
|
||||
idx: 3.4
|
||||
description: Nutzung eines ObjectRef
|
||||
degrad:
|
||||
level: warning
|
||||
title: Grad and Radiant
|
||||
message: Die Drehung von Anbauteilen wird in Grad angegeben, während die Drehung von Objekten in Radiant
|
||||
angegeben wird. Stellen Sie sicher, dass Sie das richtige Winkelmaß verwenden.
|
||||
---
|
||||
|
||||
## Einleitung <!-- omit in toc -->
|
||||
|
||||
In diesem Kapitel lernen Sie, wie man Objekte manipuliert und eigene Objekte
|
||||
definiert.
|
||||
|
||||
- [Was sind Objekte, Spieler, und Entities?](#was-sind-objekte-spieler-und-entities)
|
||||
- [Position und Geschwindigkeit](#position-und-geschwindigkeit)
|
||||
- [Objekt-Eigenschaften](#objekt-eigenschaften)
|
||||
- [Entities](#entities)
|
||||
- [Leben und Schaden](#leben-und-schaden)
|
||||
- [Attachments](#attachments)
|
||||
- [Your Turn](#your-turn)
|
||||
|
||||
## Was sind Objekte, Spieler, und Entities?
|
||||
|
||||
Spieler und Entities sind beide Arten von Objekten. Ein Objekt ist etwas, das sich unabhängig
|
||||
vom Block-Raster bewegen kann und Eigenschaften wie Geschwindigkeit und Skalierung besitzt.
|
||||
Objekte sind keine Gegenstände, und sie haben ihr eigenes Registrierungssystem.
|
||||
|
||||
Es gibt ein paar Unterschiede zwischen Spielern und Entities.
|
||||
Der größte ist, dass Spieler von Spielern gesteuert werden, während Entities von Mods gesteuert werden.
|
||||
Das bedeutet, dass die Geschwindigkeit eines Spielers nicht von Mods eingestellt werden kann -
|
||||
Spieler sind client-seitig, und Entities sind serverseitig.
|
||||
Ein weiterer Unterschied ist, dass Spieler das Laden von Kartenblöcken verursachen, während Entities
|
||||
nur gespeichert werden und inaktiv werden.
|
||||
|
||||
Diese Unterscheidung wird durch die Tatsache erschwert, dass Entities über eine Tabelle
|
||||
gesteuert werden, die als Lua entity bezeichnet wird, wie später erläutert wird.
|
||||
|
||||
## Position und Geschwindigkeit
|
||||
|
||||
`get_pos` und `set_pos` existieren, um die Position eines Entitys zu ermitteln und zu setzen.
|
||||
|
||||
```lua
|
||||
local objekt = minetest.get_player_by_name("bob")
|
||||
local pos = objekt:get_pos()
|
||||
objekt:set_pos({ x = pos.x, y = pos.y + 1, z = pos.z })
|
||||
```
|
||||
|
||||
`set_pos` setzt die Position sofort und ohne Animation. Wenn Sie ein Objekt
|
||||
sanft an die neue Position animieren möchten, sollte man `move_to` verwenden.
|
||||
Dies funktioniert leider nur für Entities.
|
||||
|
||||
```lua
|
||||
objekt:move_to({ x = pos.x, y = pos.y + 1, z = pos.z })
|
||||
```
|
||||
|
||||
Ein wichtiger Punkt beim Umgang mit Entities ist die Latenzzeit im Netz.
|
||||
In einer idealen Welt würden Nachrichten über Entitybewegungen sofort ankommen,
|
||||
in der richtigen Reihenfolge und in einem ähnlichen Intervall ankommen, wie Sie sie gesendet haben.
|
||||
Solange man sich jedoch nicht im Einzelspielermodus befindet, ist dies keine ideale Welt.
|
||||
Nachrichten brauchen eine Weile, bis sie ankommen. Positionsnachrichten können in der falschen Reihenfolge ankommen,
|
||||
was dazu führt, dass einige `set_pos`-Aufrufe übersprungen werden, da es keinen Sinn macht, zu einer
|
||||
Position zu gehen, die älter ist als die aktuell bekannte Position.
|
||||
Bewegungen können nicht in ähnlichen Abständen erfolgen, was es schwierig macht, sie für Animationen zu verwenden.
|
||||
All dies führt dazu, dass der Client andere Dinge sieht als der Server, und das ist etwas
|
||||
das Sie beachten müssen.
|
||||
|
||||
## Objekt-Eigenschaften
|
||||
|
||||
Objekt-Eigenschaften werden verwendet, um dem Client mitzuteilen, wie ein Objekt zu rendern und zu behandeln ist.
|
||||
Es ist nicht möglich, benutzerdefinierte Eigenschaften zu definieren, denn die Eigenschaften sind
|
||||
per Definition von der Engine zu verwenden.
|
||||
|
||||
Im Gegensatz zu Blöcken haben Objekte ein dynamisches und kein festes Aussehen.
|
||||
Sie können unter anderem das Aussehen eines Objekts jederzeit ändern, indem Sie
|
||||
seine Eigenschaften ändern.
|
||||
|
||||
```lua
|
||||
object:set_properties({
|
||||
visual = "mesh",
|
||||
mesh = "character.b3d",
|
||||
textures = {"character_texture.png"},
|
||||
visual_size = {x=1, y=1},
|
||||
})
|
||||
```
|
||||
|
||||
Die aktualisierten Eigenschaften werden an alle Spieler in Reichweite gesendet.
|
||||
Dies ist sehr nützlich, um eine große Menge an Vielfalt sehr billig zu bekommen, wie zum Beispiel
|
||||
verschiedene Skins pro Spieler.
|
||||
|
||||
Wie im nächsten Abschnitt gezeigt wird, können Entities Erst-Eigenschaften haben
|
||||
die in ihrer Definition angegeben werden.
|
||||
Die Standardeigenschaften des Spielers sind jedoch in der Engine definiert, so dass man
|
||||
`on_joinplayer` die Funktion `set_properties()` verwenden kann, um die Eigenschaften für neue
|
||||
Spieler zu setzen.
|
||||
|
||||
## Entities
|
||||
|
||||
Ein Entity hat eine Definitionstabelle, die einer Objektdefinitionstabelle ähnelt.
|
||||
Diese Tabelle kann Callback-Methoden, anfängliche Objekteigenschaften und benutzerdefinierte
|
||||
Mitglieder enthalten.
|
||||
|
||||
```lua
|
||||
local MeinEntity = {
|
||||
initial_properties = {
|
||||
hp_max = 1,
|
||||
physical = true,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3},
|
||||
visual = "wielditem",
|
||||
visual_size = {x = 0.4, y = 0.4},
|
||||
textures = {""},
|
||||
spritediv = {x = 1, y = 1},
|
||||
initial_sprite_basepos = {x = 0, y = 0},
|
||||
},
|
||||
|
||||
message = "Default message",
|
||||
}
|
||||
|
||||
function MeinEntity:set_message(msg)
|
||||
self.message = msg
|
||||
end
|
||||
```
|
||||
|
||||
Entity-Definitionen unterscheiden sich in einem sehr wichtigen Punkt von Item-Definitionen.
|
||||
Wenn ein Entity auftaucht (d.h.: geladen oder erstellt wird), wird eine neue Tabelle für
|
||||
diese Entity erstellt, die von der Definitionstabelle *erbt*.
|
||||
|
||||
<!--
|
||||
Diese Vererbung wird mit Hilfe von Metatabellen durchgeführt.
|
||||
Metatabellen sind eine wichtige Lua-Funktion, die Sie kennen müssen, da sie
|
||||
ist ein wesentlicher Bestandteil der Lua-Sprache. Laienhaft ausgedrückt, erlaubt eine Metatabelle
|
||||
zu steuern, wie sich die Tabelle bei der Verwendung bestimmter Lua-Syntaxen verhält. Die häufigste
|
||||
Verwendung von Metatabellen ist die Möglichkeit, eine andere Tabelle als Prototyp zu verwenden,
|
||||
Eigenschaften und Methoden der anderen Tabelle zu verwenden,
|
||||
wenn sie in der aktuellen Tabelle nicht vorhanden sind.
|
||||
Angenommen, Sie wollen auf `a.x` zugreifen. Wenn die Tabelle `a` dieses Element hat, dann wird es
|
||||
normal zurückgegeben. Wenn die Tabelle jedoch nicht über dieses Element verfügt und die
|
||||
metatable eine Tabelle `b` als Prototyp aufführt, wird die Tabelle `b` daraufhin überprüft
|
||||
um zu sehen, ob sie dieses Mitglied hat.
|
||||
-->
|
||||
|
||||
Sowohl ein ObjectRef als auch eine Entity-Tabelle bieten Möglichkeiten, das Gegenstück zu erhalten:
|
||||
|
||||
```lua
|
||||
local entity = object:get_luaentity()
|
||||
local objekt = entity.objekt
|
||||
print("Entity ist bei " .. minetest.pos_to_string(objekt:get_pos()))
|
||||
```
|
||||
|
||||
Es gibt eine Reihe von Callbacks für die Verwendung mit Entities.
|
||||
Eine vollständige Liste findet sich in [lua_api.txt](https://minetest.gitlab.io/minetest/minetest-namespace-reference/#registered-definition-tables).
|
||||
|
||||
```lua
|
||||
function MeinEntity:on_step(dtime)
|
||||
local pos = self.object:get_pos()
|
||||
local pos_drunter = vector.subtract(pos, vector.new(0, 1, 0))
|
||||
|
||||
local delta
|
||||
if minetest.get_node(pos_drunter).name == "air" then
|
||||
delta = vector.new(0, -1, 0)
|
||||
elseif minetest.get_node(pos).name == "air" then
|
||||
delta = vector.new(0, 0, 1)
|
||||
else
|
||||
delta = vector.new(0, 1, 0)
|
||||
end
|
||||
|
||||
delta = vector.multiply(delta, dtime)
|
||||
|
||||
self.object:move_to(vector.add(pos, delta))
|
||||
end
|
||||
|
||||
function MeinEntity:on_punch(hitter)
|
||||
minetest.chat_send_player(hitter:get_player_name(), self.message)
|
||||
end
|
||||
```
|
||||
|
||||
Wenn Sie nun diese Entity spawnen und verwenden würden, würden Sie feststellen, dass die Nachricht
|
||||
vergessen wird, wenn die Entity inaktiv und dann wieder aktiv wird.
|
||||
Das liegt daran, dass die Nachricht nicht gespeichert wird.
|
||||
Anstatt alles in der Entity-Tabelle zu speichern, gibt Minetest Ihnen die Kontrolle darüber
|
||||
wie die Dinge gespeichert werden sollen.
|
||||
Staticdata ist ein String, der alle benutzerdefinierten Informationen enthält, die
|
||||
gespeichert werden müssen.
|
||||
|
||||
```lua
|
||||
function MeinEntity:get_staticdata()
|
||||
return minetest.write_json({
|
||||
message = self.message,
|
||||
})
|
||||
end
|
||||
|
||||
function MeinEntity:on_activate(staticdata, dtime_s)
|
||||
if staticdata ~= "" and staticdata ~= nil then
|
||||
local data = minetest.parse_json(staticdata) or {}
|
||||
self:set_message(data.message)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
Minetest kann `get_staticdata()` so oft wie gewünscht und zu jeder Zeit aufrufen.
|
||||
Der Grund dafür ist, dass Minetest nicht darauf wartet, dass ein MapBlock inaktiv wird,
|
||||
um ihn zu speichern, da dies zu Datenverlusten führen würde. MapBlocks werden ungefähr alle 18
|
||||
Sekunden gespeichert, also sollten Sie ein ähnliches Intervall für den Aufruf von `get_staticdata()` feststellen.
|
||||
|
||||
`on_activate()` wird dagegen nur aufgerufen, wenn eine Entity
|
||||
aktiv wird, entweder wenn der MapBlock aktiv wird oder wenn die Entity spawnen wird.
|
||||
Dies bedeutet, dass staticdata leer sein könnte.
|
||||
|
||||
Schließlich müssen Sie die Typentabelle mit der treffenden Bezeichnung `register_entity` registrieren.
|
||||
|
||||
```lua
|
||||
minetest.register_entity("meinemod:entity", MeinEntity)
|
||||
```
|
||||
|
||||
Die Entity kann von einem Mod wie folgt erzeugt werden:
|
||||
|
||||
```lua
|
||||
local pos = { x = 1, y = 2, z = 3 }
|
||||
local obj = minetest.add_entity(pos, "meinemod:entity", nil)
|
||||
```
|
||||
|
||||
Der dritte Parameter sind die anfänglichen statischen Daten.
|
||||
Um die Nachricht einzustellen, können Sie die Methode der Entity-Tabelle verwenden:
|
||||
|
||||
```lua
|
||||
obj:get_luaentity():set_message("hello!")
|
||||
```
|
||||
|
||||
Spieler mit den *give* [privilege](../players/privileges.html) können
|
||||
einen [chat command](../players/chat.html) zum spawnen von entities benutzen:
|
||||
|
||||
/spawnentity mymod:entity
|
||||
|
||||
|
||||
## Leben und Schaden
|
||||
|
||||
### Lebenspunkte (HP)
|
||||
|
||||
Jedes Objekt hat eine Anzahl von Lebenspunkten (HP), die die aktuelle Gesundheit darstellt.
|
||||
Spieler haben eine maximale Lebenspunktzahl, die mit der Objekteigenschaft `hp_max` festgelegt wird.
|
||||
Ein Objekt stirbt, wenn seine HP 0 erreichen.
|
||||
|
||||
```lua
|
||||
local hp = object:get_hp()
|
||||
object:set_hp(hp + 3)
|
||||
```
|
||||
|
||||
### Punch, Damage Groups, and Armor Groups
|
||||
|
||||
Damage is the reduction of an object's HP. An object can *punch* another object to
|
||||
inflict damage. A punch isn't necessarily an actual punch - it can be an
|
||||
explosion, a sword slash, or something else.
|
||||
|
||||
The total damage is calculated by multiplying the punch's damage groups with the
|
||||
target's vulnerabilities. This is then limited depending on how recent the last
|
||||
punch was. We will go over an example of this calculation in a bit.
|
||||
|
||||
Just like [node dig groups](../items/nodes_items_crafting.html#tools-capabilities-and-dig-types),
|
||||
these groups can take any name and do not need to be registered. However, it's
|
||||
common to use the same group names as with node digging.
|
||||
|
||||
How vulnerable an object is to particular types of damage depends on its
|
||||
`armor_groups` [object property](#object-properties). Despite its misleading
|
||||
name, `armor_groups` specify the percentage damage taken from particular damage
|
||||
groups, not the resistance. If a damage group is not listed in an object's armor
|
||||
groups, that object is completely invulnerable to it.
|
||||
|
||||
```lua
|
||||
target:set_properties({
|
||||
armor_groups = { fleshy = 90, crumbly = 50 },
|
||||
})
|
||||
```
|
||||
|
||||
In the above example, the object will take 90% of `fleshy` damage and 50% of
|
||||
`crumbly` damage.
|
||||
|
||||
When a player punches an object, the damage groups come from the item they are
|
||||
currently wielding. In other cases, mods decide which damage groups are used.
|
||||
|
||||
### Example Damage Calculation
|
||||
|
||||
Let's punch the `target` object:
|
||||
|
||||
```lua
|
||||
local tool_capabilities = {
|
||||
full_punch_interval = 0.8,
|
||||
damage_groups = { fleshy = 5, choppy = 10 },
|
||||
|
||||
-- This is only used for digging nodes, but is still required
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
fleshy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=30, maxlevel=2},
|
||||
},
|
||||
}
|
||||
|
||||
local time_since_last_punch = tool_capabilities.full_punch_interval
|
||||
target:punch(object, time_since_last_punch, tool_capabilities)
|
||||
```
|
||||
|
||||
Now, let's work out what the damage will be. The punch's damage groups are
|
||||
`fleshy=5` and `choppy=10`, and `target` will take 90% damage from fleshy and 0%
|
||||
from choppy.
|
||||
|
||||
First, we multiply the damage groups by the vulnerability and sum the result.
|
||||
We then multiply by a number between 0 or 1 depending on the `time_since_last_punch`.
|
||||
|
||||
```lua
|
||||
= (5*90/100 + 10*0/100) * limit(time_since_last_punch / full_punch_interval, 0, 1)
|
||||
= (5*90/100 + 10*0/100) * 1
|
||||
= 4.5
|
||||
```
|
||||
|
||||
As HP is an integer, the damage is rounded to 5 points.
|
||||
|
||||
|
||||
|
||||
## Attachments
|
||||
|
||||
Attached objects will move when the parent - the object they are attached to -
|
||||
is moved. An attached object is said to be a child of the parent.
|
||||
An object can have an unlimited number of children, but at most one parent.
|
||||
|
||||
```lua
|
||||
child:set_attach(parent, bone, position, rotation)
|
||||
```
|
||||
|
||||
An object's `get_pos()` will always return the global position of the object, no
|
||||
matter whether it is attached or not.
|
||||
`set_attach` takes a relative position, but not as you'd expect.
|
||||
The attachment position is relative to the parent's origin as scaled up by 10 times.
|
||||
So, `0,5,0` would be half a node above the parent's origin.
|
||||
|
||||
{% include notice.html notice=page.degrad %}
|
||||
|
||||
For 3D models with animations, the bone argument is used to attach the entity
|
||||
to a bone.
|
||||
3D animations are based on skeletons - a network of bones in the model where
|
||||
each bone can be given a position and rotation to change the model, for example,
|
||||
to move the arm.
|
||||
Attaching to a bone is useful if you want to make a character hold something:
|
||||
|
||||
```lua
|
||||
obj:set_attach(player,
|
||||
"Arm_Right", -- default bone
|
||||
{x=0.2, y=6.5, z=3}, -- default position
|
||||
{x=-100, y=225, z=90}) -- default rotation
|
||||
```
|
||||
|
||||
## Your Turn
|
||||
|
||||
* Make a windmill by combining nodes and an entity.
|
||||
* Make a mob of your choice (using just the entity API, and without using any other mods).
|
@ -4,16 +4,23 @@ bulk = bulk
|
||||
Chapter = Kapitel
|
||||
Cubic Nodes = Würfelförmiger Block
|
||||
craft slots = Handwerksplätze
|
||||
Damage = Schaden
|
||||
database = Datenbank
|
||||
Degrees = Grad
|
||||
detached inventory = freistehendes Inventar
|
||||
dig = abbauen
|
||||
drawtype = Zeichnungstyp
|
||||
Entities = Entities
|
||||
Entity = Entity
|
||||
Folder = Verzeichnis
|
||||
games = Spiele
|
||||
getter = Getter
|
||||
glasslike = Glasartig
|
||||
grid = Raster
|
||||
Health = Leben
|
||||
HP = HP
|
||||
Health Points = Lebenspunkte
|
||||
initial properties = Erst-Eigenschaften
|
||||
insecure environment = unsichere Umgebung
|
||||
Introduction = Einleitung
|
||||
Inventory = Inventar
|
||||
@ -24,6 +31,7 @@ Item metadata = Item-Metadaten
|
||||
ItemStack = ItemStack
|
||||
key = Schlüssel
|
||||
large data = große Daten
|
||||
Lua entity = Lua entity
|
||||
main inventory = Hauptinventar
|
||||
map = Karte
|
||||
MapBlock = Map-Block
|
||||
@ -36,18 +44,21 @@ mod's folder = Mod-Verzeichnis
|
||||
mods = Mods
|
||||
Mod storage = Mod-Storage
|
||||
module = Modul
|
||||
node = Block
|
||||
Node metadata = Block-Metadaten
|
||||
network latency = Latenzzeit im Netz
|
||||
node = Node
|
||||
Node metadata = Node-Metadaten
|
||||
nodes = Blöcke
|
||||
nodebox = Nodebox
|
||||
nodeboxes = Nodeboxen
|
||||
Node inventory = Blockinventar
|
||||
node timer = Blocktimer
|
||||
Object properties = Objekt-Eigenschaften
|
||||
path = Verzeichnis
|
||||
placer = plazierer
|
||||
player inventory = Spielerinventar
|
||||
player reference = Spielerreferenz
|
||||
pointed_thing = angeschautes_ding
|
||||
Radians = Radiant
|
||||
small data = kleine Daten
|
||||
Stack = Stack
|
||||
storage = Storage
|
||||
|
Loading…
Reference in New Issue
Block a user