• »Monkey Guardian« ist der Autor dieses Themas

Motto: So lasset uns kein Trübsal sinnieren und gar königlich dinieren!

  • Nachricht senden

1

Dienstag, 30. September 2014, 15:52

Frage zu Arrays

Hallo,
ich sitze jetzt schon länger daran und komme nicht dahinter, was im Folgenden passiert:

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Item_Keys = [Array mit Input-Keys]
class Fight
  attr_reader :item_keys
  def initialize
    @item_keys = Item_Keys
  end
class Game_Actor < Game_Battler
  attr_accessor :item_hotkeys
  def setup(actor_id)
    @item_hotkeys  = {}
    $Fight.item_keys.each  { |i| @item_hotkeys[i]  = 0 }
  end
 
class Scene_Item < Scene_Base
  def update_item_selection
    for button in @actor.item_hotkeys.keys
      next unless Input.trigger?(button)
      @actor.item_hotkeys[button] = @item_window.item.id
    end
  end


Kann mir jemand erklären, was vor allem Zeile 11 macht? Was steht anschließend im Array? Es sind 3 Input-Keys, also: {0,0,0}?
Falls ja, verstehe ich nicht, was Zeile 18 macht. Es wird ja letzten Endes ein Button aus dem Array zu einem Item zugewiesen.
Es funktioniert auch alles so weit, aber da ich daran Änderungen vornehmen will, muss ich wissen, was da genau passiert, denn nicht jede Art Input-Key wird angenommen.
  • :cake: So lasset uns beginnen! :new:

    • Ein Abenteuer, wie du es noch nie erlebt hast!
      Tauche ein in die wunderbare Welt des Königs und erlebe auf deiner Reise die verrücktesten Dinge!
      NICHT MEHR LANGE! :navigation-right: Hier gibt es weitere Informationen! :navigation-left:
    • Jetzt die Demo herunterladen!
      Bild
      Euch erwartet eine Welt, wie sie nur ein exzentrischer König veralbern könnte...
    • Titelbild
      Bild
  • :fires: XBOX 360 Bild

    Bild
  • :new: Avatar im Großformat

    Bild

Reborn

hat beim Stromkonzern schon Rabatt

Motto: Wer noch was vom Wochenende weis, hat es nie erlebt!

  • Nachricht senden

2

Dienstag, 30. September 2014, 19:17

$Fight ist eine globala Variable welche eine Instanz der Klasse Fight enthält. item_hotkey in Zeile 11 enthält eine Array. Die Klasse Array besitzt eine definierte Methode welche each heißt. Die implementation der each-Methode könnte z. B. so aussehen (was vermutlich das für dich komplizierte daran ist):

Ruby Quellcode

1
2
3
4
5
6
7
8
class Array
    #...
    def each(&block)
        for i in 0..size
            yield(self[i])
        end
    end
end

yield ruft dabei den Block welcher in Zeile 11 definiert wird ( "{ |i| @item_hotkeys = 0 }") auf, i ist der Parameter. In diesem Block wird nun der inhalt der Array @item_keys als Keys für die Hash @item_hotkeys benutzt.
Das mit den Blöcken nennt sich lambdas und gibt es in Sprachen wie C++ ab C++11 und Java ab Java 8 auch.
Mehr als a Allgäuer ka a Mensch it wera.


Wie soll ich wissen was ich denke, bevor ich nicht höre was ich sage?


Spoiler: OpenSource-Projects
NES-Emulator - a simple NES-Emulator
ERDL - a embedded Ruby Interpreter with the abilltiy to render images with DirectX ERDL shall be 100% compatible to RPGXP-Ruby Scripts
zum Lesen den Text mit der Maus markieren

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Reborn« (30. September 2014, 19:13)


3

Dienstag, 30. September 2014, 20:59

Spoiler: @Reborn

Ruby Quellcode

10
@item_hotkeys  = {}
Es ist ein Hash.
zum Lesen den Text mit der Maus markieren


@Topic:
Du hast immer das end vom class...end Block ausgesparrt, aber das nur nebenbei.

Jeder Game_Actor hat einen @hotkey_items Hash. Der Hash kann jeder Taste, ein Item zuordnen und beim Setup wird diese Zuordnung erstmal initialisiert, bzw. zurückgesetzt, indem jedem Hotkey erstmal ItemID Null, also kein Item zugeordnet wird.

Ruby Quellcode

1
$Fight.item_keys.each  { |i| @item_hotkeys[i]  = 0 }
Das kann man ja zerlegen:
Ruby Code
Erklärung

Ruby Quellcode

1
$Fight.item_keys.each{ |i|

Für jede Taste/jeden Input-Key i

Ruby Quellcode

1
 @item_hotkeys[i]  = 0 }

Speichere in den @item_hotkeys Hash zum Input-Key i den Wert Null (was später so ausgewertet wird, dass diesem Hotkey bisher kein Item zugeordnet ist)


Ruby Quellcode

1
2
3
4
5
6
  def update_item_selection                # Update die Hotkey-Zuordnung
    for button in @actor.item_hotkeys.keys # Für jede Taste, der im Hash etwas zugeordnet ist
      next unless Input.trigger?(button)   # Tu nichts, wenn die Taste nicht gedrückt wird
      @actor.item_hotkeys[button] = @item_window.item.id # Ansonsten ordne der Taste das aktuell selektierte Item zu
    end
  end


Gerade am Ende siehst Du, das nur die Input-Keys funktionieren, die von der Methode Input#trigger? Unterstützt werden.

  • »Monkey Guardian« ist der Autor dieses Themas

Motto: So lasset uns kein Trübsal sinnieren und gar königlich dinieren!

  • Nachricht senden

4

Dienstag, 30. September 2014, 23:39

Angenommen wir haben Folgendes:

Ruby Quellcode

1
Item_Keys = [Input::A, Input::B]


Dann passiert hier:

Ruby Quellcode

1
2
$Fight.item_keys.each  { |Input::A| @item_hotkeys[Input::A]  = 0 }
$Fight.item_keys.each  { |Input::B| @item_hotkeys[Input::B]  = 0 }


Ruby Quellcode

1
2
3
4
    for {Input::A, Input::B}
      next unless Input.trigger?(Input::A)
      @actor.item_hotkeys[Input::A] = 50
    end


Wenn ich jetzt anstatt Input::A und Input::B ein anderes Input-Modul (ich kann es zwar hier zeigen, aber das würde es komplizierter machen) verwende, sollte das dann immer noch irgendwie funktionieren?
Denn es scheint nicht einfach so zu gehen.

Es kann nicht an Input.trigger? liegen, da es an anderen stellen mit dem Modul funktioniert, wo die Zuordnung eindeutig ist.
In diesem Fall erfolgt die Zuordnung aber während des Spiels.
Es ist irgendwie seltsam und die einzige Erklärung liegt nun mal bei diesen Code-Schnipseln mit Arrays.

Ach ja, das end von class hatte ich vergessen. ;)
Liegt daran, dass das nicht der komplette Code ist.
  • :cake: So lasset uns beginnen! :new:

    • Ein Abenteuer, wie du es noch nie erlebt hast!
      Tauche ein in die wunderbare Welt des Königs und erlebe auf deiner Reise die verrücktesten Dinge!
      NICHT MEHR LANGE! :navigation-right: Hier gibt es weitere Informationen! :navigation-left:
    • Jetzt die Demo herunterladen!
      Bild
      Euch erwartet eine Welt, wie sie nur ein exzentrischer König veralbern könnte...
    • Titelbild
      Bild
  • :fires: XBOX 360 Bild

    Bild
  • :new: Avatar im Großformat

    Bild

5

Dienstag, 30. September 2014, 23:58

Uhm, dein Pseudocode verwirrt etwas.
Man kann das alles auch undynamisch ohne Schleifen machen:
  • Mit Schleifen und dynamisch

    Ruby Quellcode

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    Item_Keys = [Input::A, Input::B]
    class Fight
      attr_reader :item_keys
      def initialize
        @item_keys = Item_Keys
      end
    class Game_Actor < Game_Battler
      attr_accessor :item_hotkeys
      def setup(actor_id)
        @item_hotkeys  = {}
        $Fight.item_keys.each  { |i| @item_hotkeys[i]  = 0 }
     
      end
     
    class Scene_Item < Scene_Base
      def update_item_selection
        for button in @actor.item_hotkeys.keys
          next unless Input.trigger?(button)
          @actor.item_hotkeys[button] = @item_window.item.id
        end
     
     
      end
  • Ohne Schleifen und alles vorgegeben

    Ruby Quellcode

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    Item_Keys = [Input::A, Input::B]
    class Fight
      attr_reader :item_keys
      def initialize
        @item_keys = Item_Keys
      end
    class Game_Actor < Game_Battler
      attr_accessor :item_hotkeys
      def setup(actor_id)
        @item_hotkeys  = {}
        @item_hotkeys[Input::A]  = 0
        @item_hotkeys[Input::B]  = 0
      end
     
    class Scene_Item < Scene_Base
      def update_item_selection
        if Input.trigger?(Input::A)
          @actor.item_hotkeys[Input::A] = @item_window.item.id
        end
        if Input.trigger?(Input::B)
          @actor.item_hotkeys[Input::B] = @item_window.item.id
        end
      end


Zitat

Wenn ich jetzt anstatt Input::A und Input::B ein anderes Input-Modul (ich kann es zwar hier zeigen, aber das würde es komplizierter machen) verwende, sollte das dann immer noch irgendwie funktionieren?
Denn es scheint nicht einfach so zu gehen.
Sollange das neue Input Modul auch jedes Frame geupdatet wird, sollte es gehen.
Ansonsten zeig mal den Quellcode. Oder lass dir anzeigen, wie der Wert von Input.trigger?(...) ist, vielleicht hilft dir das weiter.

  • »Monkey Guardian« ist der Autor dieses Themas

Motto: So lasset uns kein Trübsal sinnieren und gar königlich dinieren!

  • Nachricht senden

6

Mittwoch, 1. Oktober 2014, 15:10

Danke! Wenn man es vorgibt, funktioniert es (fast) einwandfrei.
Das seltsame ist nur noch, dass einige Inputs, die ich gebe zu unglaublichen Lags (10 FPS) führen und andere wiederum zu gar keinem Lag.
Könnte das an den jeweiligen Nummern liegen, die man einem Button zuordnet? (z.B. Input.press?(20))
Falls so eine Nummer doppelt belegt ist, führt es zu den Störungen. Das ist das einzige, was mir einfällt.

Zitat

Oder lass dir anzeigen, wie der Wert von Input.trigger?(...) ist, vielleicht hilft dir das weiter.

Meinst du evtl. diese Nummer mit dem Wert?
Wie finde ich das denn am besten heraus? Verstehe nicht ganz, was du meinst.

Jedenfalls lag es wohl an

Ruby Quellcode

1
$Fight.item_keys.each  { |i| @item_hotkeys[i]  = 0 }

Im späteren Verlauf des Scripts, wo item_hotkeys noch einige male aufgerufen wird, funktioniert alles.
  • :cake: So lasset uns beginnen! :new:

    • Ein Abenteuer, wie du es noch nie erlebt hast!
      Tauche ein in die wunderbare Welt des Königs und erlebe auf deiner Reise die verrücktesten Dinge!
      NICHT MEHR LANGE! :navigation-right: Hier gibt es weitere Informationen! :navigation-left:
    • Jetzt die Demo herunterladen!
      Bild
      Euch erwartet eine Welt, wie sie nur ein exzentrischer König veralbern könnte...
    • Titelbild
      Bild
  • :fires: XBOX 360 Bild

    Bild
  • :new: Avatar im Großformat

    Bild

Irrlicht

Leuchtendes Irgendwas

Motto: Keep shining!

  • Nachricht senden

7

Donnerstag, 2. Oktober 2014, 01:56

Zitat

In diesem Fall erfolgt die Zuordnung aber während des Spiels.

Ich bin mir nicht sicher was damit gemeint ist, solltest während des Spiels die belegbaren Tasten ändern wollen reicht es nicht aus $Fight.item_keys zu modifizieren:

Wenn $Fight.item_keys = [Input::X, Input::Y, Input::Z] sein sollte dann werden in Zeile 11 für den Hash diese Zuordnungen angelegt:

Input::X => 0,
Input::Y => 0,
Input::Z => 0

Wobei die 0 später durch die ID eines Skills ersetzt werden kann, der dieser Schnelltaste zugewiesen ist.
Der Hash hat damit in diesem Beispiel 3 Einträge. Auch wenn $Fight.item_keys im Nachhinein modifiziert würde ändern sich diese Einträge nicht automatisch.

Wie Playm bereits beschrieb lassen sich in Zeile 18/19 den Einträgen neue Werte zuweisen. Dafür werden alle Schlüssel des Hashes in einem Update durchlaufen. Wird für einen Schlüssel die zugehörige Taste gedrückt, wird der Wert für diesen Eintrag durch die ID des gerade ausgewählten Skills ersetzt.

Was genau den Lag verursacht ist wohl schwer zu sagen, ansich reicht ein platziertes
loop {} if Input.trigger?(Input::C)
um das Spiel beim Drücken der Entertaste aufzuhängen... Der Grund ist vermutlich weniger die gedrückte Taste, sondern was auch immer durch diese Taste ausgelöst wird.

  • »Monkey Guardian« ist der Autor dieses Themas

Motto: So lasset uns kein Trübsal sinnieren und gar königlich dinieren!

  • Nachricht senden

8

Donnerstag, 2. Oktober 2014, 15:22

Das lustige an dem Lag ist ja, dass es nur bei ganz bestimmten Tasten passiert. Das einzige, was mir dazu eben einfällt, ist, dass, diese Taste irgendwo anders schon belegt ist (wohl denselben key hat) und an allen möglichen Stellen abgefragt wird.
Noch interessanter wurde es dann aber, als ich dieselbe Taste in einem ähnlichen, aber doch leicht anderen Code verwendete und alles super flüssig lief. Es war auch eine Tastenzuweisung während des Spiels, die ich genauso modifiziert habe, wie Playm es geschrieben hatte (also undynamisch).
Habe letzten Endes die Tasten so belegt, dass alles flüssig läuft.
Eine loop konnte ich nirgends finden.

Aber wie finde ich denn heraus, was der Wert von Input.trigger?(...) ist. Kann ich mir das irgendwie anzeigen lassen? Z.B. Input.trigger?(Input::A) oder Input.press?(20).
  • :cake: So lasset uns beginnen! :new:

    • Ein Abenteuer, wie du es noch nie erlebt hast!
      Tauche ein in die wunderbare Welt des Königs und erlebe auf deiner Reise die verrücktesten Dinge!
      NICHT MEHR LANGE! :navigation-right: Hier gibt es weitere Informationen! :navigation-left:
    • Jetzt die Demo herunterladen!
      Bild
      Euch erwartet eine Welt, wie sie nur ein exzentrischer König veralbern könnte...
    • Titelbild
      Bild
  • :fires: XBOX 360 Bild

    Bild
  • :new: Avatar im Großformat

    Bild

9

Donnerstag, 2. Oktober 2014, 21:33

Zitat

Aber wie finde ich denn heraus, was der Wert von Input.trigger?(...) ist. Kann ich mir das irgendwie anzeigen lassen? Z.B. Input.trigger?(Input::A) oder Input.press?(20).

Die Konstanten (wie Input::A) sind ja nur symbolische Platzhalter, die kannst Du dir ja einfach ausgeben lassen:

Ruby Quellcode

1
2
3
4
5
6
output = ""
Input.constants.each do |c|
  output += sprintf("%s\t%d\n", c, Input.const_get(c))
end
print output
exit
Spoiler: Ergebnis

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
DOWN  2
ALT   23
L     17
C     13
F7    27
RIGHT 6
CTRL  22
Z     16
B     12
F6    26
UP    8
SHIFT 21
Y     15
F9    29
A     11
F5    25
LEFT  4
R     18
X     14
F8    28

zum Lesen den Text mit der Maus markieren

Und genauso kannst Du dir auch die Tastendrücke ausgeben lassen:

Ruby Quellcode

1
print Input.trigger?(Input::A)
Wobei ich dir empfehlen würde, dafür nicht immer eine Box aufploppen zu lassen, sondern den Rückgabewert in der Konsole auszugeben oder auf einen Sprite zu schreiben, das stell ich mir übersichtlicher vor.

Zitat

Das lustige an dem Lag ist ja, dass es nur bei ganz bestimmten Tasten passiert. Das einzige, was mir dazu eben einfällt, ist, dass, diese Taste irgendwo anders schon belegt ist (wohl denselben key hat) und an allen möglichen Stellen abgefragt wird.
Welche denn?

Zitat

Habe letzten Endes die Tasten so belegt, dass alles flüssig läuft.
Inwiefern?

Vielleicht könntest Du die Sachlage etwas ausschweifender erklären, oder mehr vom tatsächlichen Quellcode zeigen, wenn Du nicht weißt, wie Du es bechreiben sollst.

  • »Monkey Guardian« ist der Autor dieses Themas

Motto: So lasset uns kein Trübsal sinnieren und gar königlich dinieren!

  • Nachricht senden

10

Freitag, 3. Oktober 2014, 01:20

Würde ich alles posten, was ihr braucht, um es selbst zu testen, wäre es zu viel und zu unübersichtlich.
Ich kann probieren, das Wichtigste rauszusuchen.

Die Taste, die nicht mitspielen wollte ist unter einem eigenen Input-Modul so belegt: R2 = 47

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def self.keyboard_key?(button)
	return button < 30
end
def self.key_holds(button_id, pad_index)
	return 0 if keyboard_key?(button_id)
        #@holds hält fest, wie lange ein button gedrückt wird
	return @holds[pad_index, button_id - 30]
end
def self.press?(button, pad_index = 0)
	return key_holds(button, pad_index) > 0
end
def self.trigger?(button, pad_index = 0)
	return key_holds(button, pad_index) == 1
end

Bin mir nicht sicher, ob man daraus schon was erkennen kann.
Das normale Input-Modul scheint ja buttons bis 28 zu reservieren und in diesem Input-Modul beginnt es ab 30.
  • :cake: So lasset uns beginnen! :new:

    • Ein Abenteuer, wie du es noch nie erlebt hast!
      Tauche ein in die wunderbare Welt des Königs und erlebe auf deiner Reise die verrücktesten Dinge!
      NICHT MEHR LANGE! :navigation-right: Hier gibt es weitere Informationen! :navigation-left:
    • Jetzt die Demo herunterladen!
      Bild
      Euch erwartet eine Welt, wie sie nur ein exzentrischer König veralbern könnte...
    • Titelbild
      Bild
  • :fires: XBOX 360 Bild

    Bild
  • :new: Avatar im Großformat

    Bild

Ähnliche Themen

Social Bookmarks