• Anmelden

1

Freitag, 8. Januar 2010, 14:47

Item-Werte auslesen

Hi,

ich hätte mal wieder eine Frage, und zwar: Wie kann einzelne Angaben zu Items (Name, Icon-Name, ...) die die Party im moment im Inventar hat auslesen und in jeweils einzelne Arrays schreiben?

Folgenden Lösungsansatz habe ich bereits:

Quellcode

1
2
3
4
5
6
7
8
9
10
class Items
  def items_auflisten
  @truhenitems = []
  for i in 1...$data_items.size
      if $game_party.item_number(i) > 0
        @truhenitems.push($data_items[i])
      end
    end
  end
end


Das schreibt jetzt mal alle einzelnen Werte der Items in ein Array rein. Herauskommen tut, wenn ich z.B. zwei Standard-Items des Makers ins Inventar gebe, folgendes:
Bild

So, jetzt meine Fragen dazu:

1. Wie lese ich jetzt einzelne Werte hieraus aus? Ich möchte dann z.B. für den Anfang mal nachher in einem Array @itemname nacheinander die namen der beiden Items haben und im Array @iconname möchte ich die Namen der Icons drinhaben. Wie stelle ich das an? Die einzige Möglichkeit die mir einfiele wäre zuerst erneut per for-Schleife anhand der IDs eines der beiden Items in einen eigenen Array rauszuziehen, und dann nochmal anhand der IDs jeweils Name/Iconname in diesem neuen Array suchen. Aber da muss es doch etwas einfacheres geben, oder? Falls nicht, bitte einfach informieren, falls es doch etwas einfacheres hierfür gibt, wäre ich über jede Hilfe froh.


2. Jetzt möchte ich das ganze nur noch ein bisschen geordnet haben, und zwar in der Reihenfolge wie ich die Items bekommen habe. Ist das überhaupt möglich? Da $game_party.items ja ein Hash ist und die Elemtente keinen Index haben, müsste man vmtl dort irgendwas ändern... falls jemand eine Lösung hat, pls pls pls nur her damit^^

Danke im Vorraus,

mfg
The King

Edit: okay, Frage 1 hat sich soweit erledigt, die Lösung ist eben

Quellcode

1
$data_items[i].name

in allen Variationen.
Trotzdem bleibt immer noch die Sache 2 übrig. Wäre schon cool wenn die Items so gereit werden wie man sie erhält, und nicht wie sie in der Database drinnenstehen.
Terranigma 2 - Episode I - Open Beta out now!

RPC - Rpg-Maker Community Platform - Spielübergreifende Erfolge und mehr!

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »The King« (8. Januar 2010, 16:59)


2

Freitag, 8. Januar 2010, 18:52

Eine Definition zu der RPG::Item Klasse findest du in der Makerhilfe, noch zu Frage1.

Wegen Frage2: Wenn du Item#1 dann Item#4 und dann Item#1 und zum Schluss Item#2 bekommst - soll dann im Inventar die Items:
Item1-Item4-Item1-Item2 aufgelistet werden
oder
2x(Item1) - 1x(Item4) - 1x(Item2)
?
Und welches Item Menu nutzt du?
Die Item-Hashspeicherung würde ich nämlich nicht ändern, sondern eher einen Reihenfolgearray hinzufügen. Aber dazu müsstest du sagen was für ein ItemMenusystem du hast und die Frage oben wegen der Gruppen- oder Einzelspeicherung beantworten.

3

Freitag, 8. Januar 2010, 19:00

Ja, mittlerweile habe ich die Hilfe schon gesehen, danke^^ Werd da in Zukunft immer vorher nachschauen bevor ich was frage...

Und zur Frage zwei: Es sollte so aufgelistet sein: 2x(Item1) - 1x(Item4) - 1x(Item2)

Als Itemmenü verwende ich etwas komplett selbtgeschriebenes, und ich bin wie gesagt noch nicht ganz fertig. Deswegen denke ich dass man da ja so ziemlich alles realisiern könnte, vorrausgesetzt man weiß, wie^^ Hilft es dir wenn ich mal hochlade was ich bisher hab? Items werden schon angezeigt, und man kann sie bereits bedingt nutzen...
Terranigma 2 - Episode I - Open Beta out now!

RPC - Rpg-Maker Community Platform - Spielübergreifende Erfolge und mehr!

Neo-Bahamut

Himmelsgleicher

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

4

Freitag, 8. Januar 2010, 19:09

Also, du möchtest einen Hash 'sortieren'?

Ruby Quellcode

1
2
3
4
5
hash = $game_party.items
values = []
hash.keys.sort.each do |n|
values << "Item#{n} x#{hash[n]}"
end
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

5

Freitag, 8. Januar 2010, 19:18

@Neo: ich denke nicht.
@King:
Du könntest beim Game_Party#initialize einen Array erstellen.
@reihenfolge_item = []
Und bei der "Item hinzufügen"-Methode einfach so was in der Art einfügen.
@reihenfolge_item.push(id) if(!@reihenfolge_item.include?(id))
Und beim Itemmenu, wo du die Items hinzufügst, gehst du anstatt der gesammten Database nur diesen Array durch.
Ist zwar nicht die beste Lösung, aber die, welche mir spontan einfällt.

6

Freitag, 8. Januar 2010, 19:31

@Neo: Bist du dir sicher dass es so funktioniert? Bzw dass du mein Problem korrekt betrachtest? Es geht ja darum dass der Hash so sortiert wird, dass die Items in der Reihenfolge stehen, in der ich sie erhalten habe. Beispiel: Ich erhalte aus einer Schatzkiste einen Heiltrank (Id in der Db #31) und wenig später von einem NPC einen Manatrank (#11). Normalerweise würde jetzt der Manatrank vor dem Heiltrank im Menü stehen, auch wenn ich den Heiltrank vorher bekommen haben.

Vllt hab ich dein Script auch einfach nicht (komplett) verstanden? Wonach sortiert es denn genau? Ich muss glaub ich die Iterationen nochmal durchgehen :schock:

@Playm: Nun, das wäre sicher eine Lösung, nur ich suche etwas mehr... ähm, wie soll ich das jetzt ausdrücken... kompatibles? Ich wills mal erklären:

An sich würde deine Option ja (vom drüberschauen her) mal gehen. Nur jetzt hab ich ein Problem, und zwar verwende ich zum entfernen eines Items folgende Methode:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
  def items_interaktion
     $posdraw = -1
    for i in 0...$item_namen.size do
      if $item_namen[i] != nil
        $posdraw += 1
      if $spritex == $itemposX[$posdraw] && $spritey == $itemposY[$posdraw]
        if $item_paramt[i] != 0
          p("Parameter erhöht")
        else
          if $item_recovH[i] != 0
            $game_party.actors[0].hp += $item_recovH[i]
            $game_party.lose_item(i+1, 1)
            $itemSp.dispose
            items_auflisten
            break
          else
            if $item_recovS[i] != 0
              $game_party.actors[0].sp += $item_recovS[i]
              $game_party.lose_item(i+1, 1)
              $itemSp.dispose
              items_auflisten
              break
            else
              p("Item kann nicht genutzt werden")
              break
            end
          end
        end
      end
    end
  end
end


Ich weiß, Anfängercode, aber ich üb mich gerade mal ein... und funzen tut er ja^^
Der Großteil ist für das Problem unwichtig, nur

$game_party.lose_item(i+1, 1)

Ich entferne benutze Items also dahingehend dass ich sage: "Wenn Item 8 aus der Liste vorhander Items verwendet wird, entferne ein Item Nummer 8". Das System funktioniert, da ich für jedes nicht vorhande Item nil in die Liste eintragen lasse, und da ich ganz einfach für die Positionsbestimmung des Cursors eine extra Variable verwende ganz gut. Wenn ich jedoch die Liste sortieren würde, ohne ganz $game_party.items zu sortieren, würde das System nicht mehr funktionieren. Hab, falls Interesse besteht sich das ganze mal näher anzuschauen, eine Demo angehängt. Mit dem Typen auf der Karte quatschen um Items zu erhalten, und Leertaste öffnet/schließt das Menü. Wenn ihr mit dem Cursor auf die mittlere Tür oben navigiert und Enter drückt, kommt ihr zu den Items. Funktioniert so weit schon, es gibt noch keine Textausgabe, aber vllt hilft dass beim Lösen des Problems... (wobei ich mich echt frage ob jemand mit meinem Code zurechtkommt^^
»The King« hat folgende Datei angehängt:
  • Ruby-Menü.rar (485,69 kB - 3 mal heruntergeladen - zuletzt: 21. Januar 2011, 21:38)
Terranigma 2 - Episode I - Open Beta out now!

RPC - Rpg-Maker Community Platform - Spielübergreifende Erfolge und mehr!

Neo-Bahamut

Himmelsgleicher

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

7

Samstag, 9. Januar 2010, 01:56

Na den Teil hab ich wohl überlesen :)
Du müsstest es so machen wie Playm gesagt hat, einen Array erstellen der die Ordnung speichert.
Soweit ich weiß dürfte das auch ziemlich kompatibel sein ;)

Ruby Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Game_Party
  attr_reader :item_gained_list
  alias_method :alias_method_game_party_initialize_item_gained_list, :initialize
  def initialize(*args)
	@item_gained_list = []
	alias_method_game_party_initialize_item_gained_list(*args)
  end
 
  alias_method :alias_method_game_party_gain_item_item_gained_list, :gain_item
  def gain_item(id, num)
	@item_gained_list.delete(id)
	@item_gained_list << id
	alias_method_game_party_gain_item_item_gained_list(id, num)
  end
end
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

8

Samstag, 9. Januar 2010, 15:04

Okay, danke, ich werde das mal ausprobieren. Falls ich noch Fragen habe melde ich mich.
Terranigma 2 - Episode I - Open Beta out now!

RPC - Rpg-Maker Community Platform - Spielübergreifende Erfolge und mehr!

9

Samstag, 9. Januar 2010, 15:25

Zitat

Ich muss glaub ich die Iterationen nochmal durchgehen
Das wäre hilfreich. Du machst dir nämlich viele Sachen unnötig umständlich. Alle Item-Objekte, die der Spieler im Inventar hast, kannst du z.B. auch so bekommen:

Ruby Quellcode

1
items = $data_items.find_all {|item| $game_party.item_number(item.id) > 0}

Wenn du davon nun alle Namen haben willst, schreibst du einfach

Ruby Quellcode

1
namen = items.map {|item| item.name}


Alles Einzeiler ohne irgendwelche For-Schleifen. An der Stelle noch eine Warnung: Speichere keine Itemobjekte ab. Ganz sicher gehst du damit, lieber nur IDs von Items zu speichern.

Ruby Quellcode

1
@item_ids = items.map {|item| item.id}

Danach kannst du dir jederzeit wieder das Item mit der map-Funktion zurückholen, wenn du irgendwelche Werte auslesen willst.

Ruby Quellcode

1
itemnamen = @item_ids.map {|item_id| $data_items[item_id].name}


Zu deinem Menü: So wie ich das sehe, möchtest du deine Items in einer festen Reihenfolge abspeichern, so dass jedes Item als Symbol in einem Menü zu sehen ist. Darum funktioniert, wie du gesagt hast, ein Hash nicht gut. Also verwende halt einfach einen Array. Die Game_Party Klasse kapselt vorbildlich ihre item-Variable über die Methode item_number, gain_item und loose_item, so dass du problemlos die Variable abändern kannst.
Andererseits finde ich die Idee von Playm mit dem zusätzlichen Reihenfolge-Array ziemlich gut. Damit solltest du wohl die geringsten Kompatibilitätsprobleme bekommen.

Zitat

Ich weiß, Anfängercode, aber ich üb mich gerade mal ein... und funzen tut er ja^^

Nur zwei Kommentare:
- verwende lieber keine globalen Variablen. Glaub mir, du handelst dir damit nur Probleme ein. Schreib einfach rein

Ruby Quellcode

1
$item_data[i].recover_hp
, auch wenn das erstmal etwas mehr Schreibaufwand ist.
- mische niemals Grafik und Funktionalität! Schreib dir eine Spriteset_ItemMenu Klasse und für alle Komponenten deines Itemmenüs eine Sprite_KomponentXYZ Klasse. Schreib dir eine Controller_ItemMenu Klasse die den Cursor etc. steuert und Methoden wie gain_item und loose_item aufruft. Und vor allem: Speichere keine Grafiken in globale Variablen
Es verlangt zwar etwas Übung ein paar Designprinzipien einzuhalten und den Code in mehrere Klassen aufzuteilen, aber am Ende bekommst du ein sichereres und saubereres Ergebnis.
Bild
RMXP Grundkurs
1 2 3
Ruby/RGSS-Kurs

10

Sonntag, 10. Januar 2010, 16:25

@=Kai=:
danke für die vielen Tipps. Ich werde glaube ich aber damit erstmal warten bis ich zumindestens mit dem Itemraum fertig bin. Für gröbere Korrekturen ist ja (teilweise auch dank der Replace-Funktion) immer noch Zeit.

Aber mal eine andere Frage, wie erhöhe ich denn per Ruby eine Wert (Str, MaxHp, etc...) um ein gewisses maß?

Ich habs mal so probiert:

Quellcode

1
$game_party.actors[0].parameters[$itemparamt[i], $game_actors[0].level] += 1


Ich bekomme hier aber immer einen Fehler: "Undefinded Method "parameters" for <irgendwas-Actor>. Wer weiß (oder wer kann mir am schnellsten sagen^^) woran es liegt? Geht das überhaupt so, oder muss ich das ganz anders angehen? Und genügt es wenn ich den Wert für das jetzige Level erhöhe, um für einen dauerhaften Bonus zu sorgen, oder muss ich dass dann für jedes Level machen?

($itemparamt steht für den Paramter-Typ.)

schonmal danke^^

The King
Terranigma 2 - Episode I - Open Beta out now!

RPC - Rpg-Maker Community Platform - Spielübergreifende Erfolge und mehr!

Neo-Bahamut

Himmelsgleicher

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

11

Sonntag, 10. Januar 2010, 18:02

Ruby Quellcode

1
$game_party.actors[0].str += 1

._.
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

12

Sonntag, 10. Januar 2010, 18:07

Ah okay, so geht es natürlich auch, danke^^

Gibts aber eventuell auch ne Methode wo ich $data_items.parameter_type direkt verwenden kann? Würde mir einen unnötigen "Case" ersparen^^
Terranigma 2 - Episode I - Open Beta out now!

RPC - Rpg-Maker Community Platform - Spielübergreifende Erfolge und mehr!

Neo-Bahamut

Himmelsgleicher

Motto: Wer anderen eine Bratwurst brät, der hat ein Bratwurstbratgerät.

  • Nachricht senden

13

Sonntag, 10. Januar 2010, 18:48

Ruby Quellcode

1
2
3
pm = $data_items[1].parameter_type
sym = pm == 1 ? :maxhp : pm == 2 ? :maxsp : pm == 3 ? :str : pm == 4 ? :dex : pm == 5 ? :agi : :int
$game_party.actors[0].send("#{sym.to_s + '='}".to_sym, $game_party.actors[0].send(sym))


Anders gehts nicht (außer mit case eben) :)
Spoiler: Wurstinator
zum Lesen den Text mit der Maus markieren

Spoiler: Lazer-Wurst
zum Lesen den Text mit der Maus markieren

Spoiler: Hallowurst
zum Lesen den Text mit der Maus markieren

Social Bookmarks