Erkennen ob sich jmd nähert & Inventar-Items als Variable

Fragen zu "Adventure Game Studio"? Hier rein!
Antworten
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Erkennen ob sich jmd nähert & Inventar-Items als Variable

Beitrag von Rexxar »

Hallo,
ist es eigentlich möglich, das ActiveInventory in einer Variable zu speichern?
Und dann auch später player.ActiveInventory = Variable1; zu machen?
Ich habe bisher versucht, die ID zu speichern, aber das war erfolglos, weil ich nicht weiß wie ich AGS sagen kann dass das ActiveInventory die gespeicherte ID aus der Variable sein soll. (Also die variable bringt mir nichts, weil ich mit der ID nichts anfangen kann)

Ich hoffe, dass mir jemand antworten kann.
Da ich das gelöst habe, ergänze ich mal den Thread Titel. (ich hoffe das ist OK)
Wie kann ich einen feindlichen Charakter erkennen lassen, ob ein Spieler sich nähert?
Hinweis: Alle Charaktere sind gleich groß.
Muss ich das ausrechnen lassen oder geht das auch anders?
Per Region oder Hotspot kann ich es nicht machen, weil die Feinde den Spieler verfolgen sollen.
Zuletzt geändert von Rexxar am 19.04.2015, 11:41, insgesamt 1-mal geändert.
Mfg Rexxar
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Inventar-Items als Variable

Beitrag von Rexxar »

Ich habe es geschafft:
InventoryItem *inv = player.ActiveInventory;
Mfg Rexxar
Benutzeravatar
KhrisMUC
Adventure-Gott
Adventure-Gott
Beiträge: 4674
Registriert: 14.03.2005, 00:55
Wohnort: München

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von KhrisMUC »

Genau so gehts, wäre aber auch mit der ID möglich gewesen:

Code: Alles auswählen

  int tmp = player.ActiveInventory.ID;
  ...
  player.ActiveInventory = inventory[tmp];
Bzgl. des Abstandes zweier Charaktere brauchst Du ein bisschen Pythagoras:

Code: Alles auswählen

int distFrom(this Character*, Character* other) {
  float dx = IntToFloat(this.x - other.x);
  float dy = IntToFloat(this.y - other.y) * 2.0;  // Perspektivenkorrektur*
  return FloatToInt(Maths.Sqrt(dx*dx + dy*dy), eRoundNearest);
}
Jetzt einfach:

Code: Alles auswählen

  if (cEnemy.distFrom(player) < 50) ... 
* Der Y-Abstand sollte korrigiert werden, da ein Charakter, der sich 50 pixel "über" dem Spieler befindet, üblicherweise viel weiter weg ist, als ein Spieler, der sich 50 Pixel links oder rechts neben dem Charakter befindet. Es sei denn natürlich, es handelt sich im ein Draufsicht-Spiel.
Use gopher repellent on funny little man
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von Rexxar »

Vielen vielen Dank, Khris!

Auf so einen Code wäre ich garnicht gekommen! (Von solche Berechnungen habe ich wenig Ahnung :oops: :D )
=D>
Allerdings habe ich die Perspektivenkorrektur entfernt, da das Spiel aus der Vogelperspektive (schräg oben) sein soll und ich ohne die besten Resultate erzielt habe.
Ich hätte schon fast mit Dummy-Charakteren und AreThingsOverlapping gearbeitet, das wäre natürlich wenig elegant gewesen.
Mfg Rexxar
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von Rexxar »

Wie ist es eigentlich möglich, die Charakter-Klasse um einen Parameter zu erweitern?

Ich stelle mir da in etwa sowas vor:

Code: Alles auswählen

player.health = 20;
if (player.health == 20) Display("tesst");
Ich poste mal bisherigen Code:

Code: Alles auswählen

int charhealth[];
function game_start() {
  charhealth = new int [Game.CharacterCount];
}

int health(this Character*) {
  int test;
  test = charhealth[this.ID];
  return test;
}
ich hatte in der health-Funktion erst nur "return charhealth[this.id]" stehen, dann noch zur Sicherheit das mit dem test-Int eingebaut.


Aber wenn ich nun sowas wie player.health() = 100; probiere, kommt nur ein Error, das man hinter health() ein ; erwartet hätte.
Ich verstehe nicht, wieso das nicht klappen will. Ich kann player.health() anscheinend keinen Wert zuweisen und das ist sehr wichtig für mich dass dies möglich ist.
Weiß jemand Rat?
Mfg Rexxar
Benutzeravatar
KhrisMUC
Adventure-Gott
Adventure-Gott
Beiträge: 4674
Registriert: 14.03.2005, 00:55
Wohnort: München

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von KhrisMUC »

Es gibt die sogenannten extender functions, damit kann man einer bestehenden Klasse zusätzliche Funktionen verpassen.
Leider geht das aber nicht mit Variablen, Du müsstest also Folgendes machen:

Code: Alles auswählen

int getHealth(this Character*) {
  return charhealth[this.ID];
}

void setHealth(this Character*, int value) {
  charhealth[this.ID] = value;
}
Und dann:

Code: Alles auswählen

  // auf 20 setzen:
  player.setHealth(20);

  // verringern um 5:
  player.setHealth(player.getHealth() - 5);
player.health() = 100; ergibt keinen Sinn, denn a) steht links keine Variable und b) würde das auf etwas wie 20 = 100; hinauslaufen.

Eine andere Alternative wäre eine eigene Charakterklasse:

Code: Alles auswählen

// header
struct mychar {
  Character *c;
  int health;
}
Jetzt kannst Du Folgendes machen:

Code: Alles auswählen

mychar hero;

  // game_start
  hero.c = cHero;  // AGS-Charakter
  hero.health = 20;
Jetzt muss man halt immer "hero.c.Say("Bla");" schreiben, um AGS-Befehle zu verwenden.

Oder man treibt es auf die Spitze und macht eigene Funktionen ins struct:

Code: Alles auswählen

// header
struct mychar {
  Character *c;
  int health;
  import void Walk(int x, int y);
}

// script
void mychar::Walk(int x, int y) {
  this.c.Walk(x, y);
}
Jetzt kann man "hero.Walk(123, 45);" verwenden.
Use gopher repellent on funny little man
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von Rexxar »

Erstmal vielen Dnak für deine Antwort, funktioniert sehr gut.
Ja, vielleicht mache ich ein struct für die Charaktere, wäre vielleicht auf dei Dauer besser und übersichtlicher.
Das sehe ich dann noch etwas später, wie ich das mache.
Mfg Rexxar
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von Rexxar »

Mir fällt noch eine Frage nach einer Zeit des Codens ein.

Wie kann ich dem Spiel mitteilen, dass wenn sich irgendein Charakter in der Nähe des Spielers befindet, welcher als Custom Property hat, dass er ein Feind ist, dass dann Code ausgeführt werden soll?

Ist das überhaupt möglich?

Also ich möchte eine Art Character Pointer, der zu jedem Charakter den es gibt pointed...
Ich hoffe es ist halbwegs verständlich, was ich meine...
Oder zumindest eine Liste von allen Charaketeren im Raum des Spielers erstellen und prüfen, ob ein Mitglied der Liste näher als 150 ist.
Ich weiß leider nicht, wie das möglich ist, eventuell mit einem Array?
Mfg Rexxar
Benutzeravatar
KhrisMUC
Adventure-Gott
Adventure-Gott
Beiträge: 4674
Registriert: 14.03.2005, 00:55
Wohnort: München

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von KhrisMUC »

AGS hat für alle wichtigen Klassen einen globalen Array.

Code: Alles auswählen

void checkForEnemies() {
  int i = 0;
  Character *c;
  while (i < Game.CharacterCount) {
    c = character[i];
    if (c != player && c.Room == player.Room) {
      // NPC im selben Raum
      if (c.GetProperty("enemy") == 1 && c.distFrom(player) < 150) {
        // Angriff
        c.ShootAt(player);
      }
    }
    i++;
  }
}
Das dann einfach in repeatedly_execute aufrufen.
Use gopher repellent on funny little man
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von Rexxar »

Danke für deine Antwort.
Was passiert wenn zwei Charaktere Nähe als 150 sind?
Mfg Rexxar
Benutzeravatar
KhrisMUC
Adventure-Gott
Adventure-Gott
Beiträge: 4674
Registriert: 14.03.2005, 00:55
Wohnort: München

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von KhrisMUC »

Was genau meinst Du?
Ich hab als Beispielcode mal das hier:

Code: Alles auswählen

        // Angriff
        c.ShootAt(player);
eingesetzt, Du müsstest das nur ersetzen.
Use gopher repellent on funny little man
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von Rexxar »

Naja wenn zwei Gegner da stehen und näher als 150 sind. Schießen die dann beide auf den Spieler?
(Das wäre erwünscht)
Mfg Rexxar
Benutzeravatar
KhrisMUC
Adventure-Gott
Adventure-Gott
Beiträge: 4674
Registriert: 14.03.2005, 00:55
Wohnort: München

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von KhrisMUC »

Die Funktion geht alle Charaktere durch (per while-Schleife), und "c" enthält jeweils den aktuellen Charakter.
.ShootAt(player) wird also für alle Charaktere ausgeführt, die näher als 150 sind, egal, wie viele es insgesamt sind.
Use gopher repellent on funny little man
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

Re: Erkennen ob sich jmd nähert & Inventar-Items als Variabl

Beitrag von Rexxar »

Gut, dann weiß ich bescheid.
Wenn ich nochmal eine Frage habe,
melde ich mich wieder.
Mfg Rexxar
Rexxar
Verpackungs-Wegwerfer
Verpackungs-Wegwerfer
Beiträge: 68
Registriert: 02.08.2012, 11:27

While-Loop-Probleme

Beitrag von Rexxar »

Nun,
da bin ich wieder. :)
Ich möchte, dass eine Gui ins Bild fadet und wieder hinaus.
Wichtig ist, dass bei diesem Vorgang das Spiel nicht blockiert werden darf.

Code: Alles auswählen

function fadein(this GUI*) {
  this.Transparency = 100;
  this.Visible = true;
  while(this.Transparency != 0) {
    this.Transparency = this.Transparency - 2;
  }
}
Problematischerweise stürtzt dann das Spiel ab, mit der Meldung, die while-Schleife zu oft hinereinander gelaufen ist und das Spiel beendet wurde, damit es sich nicht festfährt.
Wenn ich aber ein Wait(1); in die while-Schleife packe, sieht das resultat aus wie erwünscht, aber das Spiel ist dann geblockt.
Das ist nicht erwünscht.
Ebenfalls sorgen machen mir die Timer. Ersteinmal unübersichtlich zu scripten, und dann auch nur 50 Stück.
Wenn ich nur 10 Zauber in mein Spiel einbaue, würden zum Beispiel die Zauber einen Timer benötigen, um ihren Effekt nach einer Zeit wieder rückgängig zu machen oder soetwas (zum Beispiel erhöhte Lauf-Geschwindigkeit).
Dann noch 5 Timer, da es eine Art Schnellleiste gibt, in der 5 Zauber abgelegt werden können, die man nutzen möchte, und da müstten 5 Timer den Cooldown speichern. Das wäre wieder aufwändig, zumal dann mit ungelenken bool-Konstruktion überprüft werden müsste, ob der Cooldown schon abgelaufen ist.
Dann sollte man noch bedenken, dass jeder Feind eine Schlaggeschwindigkeit hat. Wenn man für die einen Timer benutzt, läuft das bei einem Feind noch gut, bei mehreren wird es dann schwierig. Da bräuchte ja jeder seinen eigenen.
Also Bei 10 Feinden hätten wir 10 Timer, dann noch 15 für ein paar Zauber.
Schon 35 Timer. Und viel komplizierten Code.
Eventuell kann man das auch mit einem kleinen while-Loop lösen, aber auch der dürfte dann nur 1-mal pro Loop laufen und das Spiel nicht blocken.
Ich hoffe, man kann mir da helfen. [-o<
Mfg Rexxar
Antworten