GM-versie:
Pro vereist: Nee
Niveau: Gemiddeld
Er wordt heel vaak gevraagd naar een script om van alle instanties van een bepaald object
obj die instantie te vinden met de hoogste waarde van een bepaalde variabele
variable. Logisch, want dat kun je voor heel veel dingen gebruiken:
Toepassingen- AI-beestjes kunnen op zoek naar healthpacks met de grootste healthwaarde.
- AI-beestjes kunnen op zoek naar vijanden met de minste hitpoints.
- AI-beestjes kunnen op zoek naar healthpacks met de grootste waarde voor (healthwaarde / afstand).
- In een torenbouwspel is de instantie die je score bepaalt diegene die het hoogst ligt; dat is de instantie met de kleinste waarde van y.
- De oudste instantie is die met de laagste waarde van id.

- De oudste instantie is die met de laagste waarde van het creatietijdstip, of de hoogste waarde van je leeftijdsvariabele.
- Als je instanties bijhoudt voor geluiden, kun je als dat nodig is het geluid met het laagste volume stoppen.
- Als je instanties bijhoudt voor plaatjes, kun je als dat nodig is het plaatje met de laagste alpha-waarde weghalen.
- Als je van NPC's bijhoudt hoe veel ze gesproken hebben, kun je de NPC die het minst gesproken heeft iets laten doen.
- Je kan soms een spel spannender maken door de speler met de minste punten een kleine beloning te geven.
- Als inventory-items een gewicht hebben kun je het zwaarste item vinden.
- Als shop-items een prijs hebben kun je het goedkoopste item vinden.
- Je kan de speler met de hoogste score apart weergeven.
- Als je alle blokken netjes op het scherm wil laten passen, vind de laagste en hoogste x- en y-waardes van alle blokken en stel je de view daar op af.
Zoals je ziet zijn er genoeg toepassingen te bedenken.
Hieronder vind je onder andere dit script, maar ook een heleboel andere handige kleine scriptjes voor het werken met instanties:
ScriptsVind die instantie van een opgegeven object met hoogste waarde van variabele v, manier 1.Dit script gaat simpelweg alle instanties af en controleert of v groter is dan de grootste tot nog toe gevonden waarde, zo ja, bewaart de id. Verder wat voorzorgsmaatregelen als er geen instantie bestaat.
//instance_maximize(obj) geeft de id van de instantie van object obj
//met de hoogste waarde van v; noone als er geen instanties van obj zijn.
var best_instance, best_value, obj;
obj = argument0;
if not instance_exists(obj) {return noone;}
best_instance = obj.id;
best_value = best_instance.v;
with obj {
if v > best_value {
best_value = v;
best_instance = id;
}
}
return best_instance;
Edit 3 augustus 2014: bugfixVind die instantie van een opgegeven object met hoogste waarde van variabele v, manier 2.Verschil met manier 1 is dat manier 2 begint met een andere beginwaarde voor maxv; die je zelf opgeeft. Die waarde moet een
ondergrens zijn, zodat alle instanties altijd een grotere v-waarde hebben dan die beginwaarde en dus opgemerkt worden. De reden dat deze er bij staat is omdat dit script makkelijker aan te passen is naar scripts hier verder onder. Het voordeel van deze aanpak is dat je geen instance_exists test meer nodig hebt, omdat het automatisch zo is dat als er geen instanties van het opgegeven object zijn, dat dan noone wordt teruggegeven (beginwaarde van maxinst). Dit hebben we straks nodig voor de aangepaste scripts.
//instance_maximize_alt(obj, v_lower_limit) geeft de id van de instantie van object obj
//met de hoogste waarde van v; noone als er geen instanties van obj zijn.
var maxinst, maxv;
maxinst = noone
maxv = argument1
with argument0 {
if v > maxv {
maxv = v
maxinst = id
}
}
return maxinst
Als je de
minimale waarde van
v zoekt, vervang dan ">" door "<".
Vind die instantie van een opgegeven object met hoogste waarde van variabele v, manier 3.Hier nog een iets anders opgebouwde manier:
//instance_maximize_alt2(obj) geeft de id van de instantie van object obj
//met de hoogste waarde van v; noone als er geen instanties van obj zijn.
var Q;
Q = ds_priority_create()
with argument0 {
ds_priority_add(Q, id)
}
if ds_priority_empty(Q) {choice = noone}
else {choice = ds_priority_find_max(Q)}
ds_priority_destroy(Q)
return choice
Als je de
minimale waarde van
v zoekt, vervang dan "max" door "min".
Vind die hoogste waarde van v voor alle instanties van een opgegeven object.Het enige wat ik veranderd heb aan manier 1 hierboven is dat ik niet maxinst, maar maxv als returnwaarde geef. Deze truc werkt voor alle scripts, als je niet de instantie nodig hebt maar de relevante v-waarde.
//instance_maximize(obj) geeft de id van de instantie van object obj
//met de hoogste waarde van v; noone als er geen instanties van obj zijn.
var maxinst, maxv;
if not instance_exists(argument0) {return noone}
maxinst = obj.id
maxv = inst.v
with argument0 {
if v > maxv {
maxv = v
maxinst = id
}
}
return maxv
Vind die instantie van een opgegeven object die voldoet aan voorwaarde X, met de hoogste waarde van variabele v van alle instanties van dit object die voldoen aan voorwaarde X.Het enige verschil mer manier 2 van het originele script hierboven, is de extra voorwaarde if
X. Net als manier 2 geeft het script dus automatisch noone als er geen instanties van het opgegeven object bestaan die voldoen aan
X. We kunnen hier nu niet meer zomaar instance_exists voor gebruiken. Vandaar dat we manier 2 nodig hadden. Je kan manier 3 op dezelfde manier aanpassen.
//instance_maximize_if_x(obj, v_lower_limit) geeft de id van de instantie van object obj
//die voldoet aan X, met de hoogste waarde van v van alle instanties van object obj
//die voldoen aan X; noone als er geen instanties van obj zijn die voldoen aan [i]X[/i].
var maxinst, maxv;
maxinst = noone
maxv = argument1
with argument0 {
if X {
if v > maxv {
maxv = v
maxinst = id
}
}
}
return maxinst
Als je de minimale waarde van
v zoekt, vervang ">" door "<", en vervang
v_lower_limit door
v_upper_limit, oftewel, geef een
bovengrens op als beginwaarde.
Vind die instantie van een opgegeven object waarvoor script S "waar" geeft, met de hoogste waarde van variabele v van alle instanties van dit object waarvoor script S "waar" geeft.Het enige verschil met bovenstaande is dat het script nu een argument geworden is.
//instance_maximize_if_script(obj, v_lower_limit, filtering_script)
//geeft de id van de instantie van object obj waarvoor filtering_script() waar is,
//met de hoogste waarde van v van alle instanties van object obj waarvoor filtering_script() waar is;
//noone als er geen instanties van obj zijn waarvoor filtering_script() waar is.
var maxinst, maxv;
maxinst = noone
maxv = argument1
with argument0 {
if script_execute(argument2) {
if v > maxv {
maxv = v
maxinst = id
}
}
}
return maxinst
Geef of er instanties bestaan van een opgegeven object die voldoen aan voorwaarde X.Doordat het return-statement het script afbreekt wordt bij de eerste instantie die voldoet aan
X, het script meteen gestaakt. Het script kost dus alleen veel rekentijd als er veel instanties zijn die niet voldoen aan
X.
//instance_exists_where_x(obj) geeft een instantie van object obj die voldoet
//aan X; noone als geen enkele instantie van object obj voldoet aan X.
with argument0 {
if X {
return true
}
}
return false
Geef een instantie van een opgegeven object die voldoet aan voorwaarde X.//instance_find_where_x(obj) geeft een instantie van object obj
//die voldoet aan X; noone als geen enkele instantie van object obj voldoet aan X
with argument0 {
if X {
return id
}
}
return noone
Geef een willekeurige instantie van een opgegeven object die voldoet aan voorwaarde X.Om willekeurig te laten zijn zul je alle instanties moeten afgaan die voldoen aan
X.
//instance_choose_where_x(obj)
var li, choice;
li = ds_lists_create()
with argument0 {
if X {
ds_list_add(li, id)
}
}
if ds_list_empty(li) {choice = noone}
else {choice = ds_list_choose(li)}
ds_list_destroy(li)
return choice
Zie
Randomscripts voor ds_list_choose.
Tel het aantal instanties van een opgegeven object die voldoen aan voorwaarde X.Om te kunnen tellen zul je de voorwaarde op alle instanties moeten toetsen. Er is geen kortere weg.
//instance_count_where_x(obj)
var count;
count = 0
with argument0 {
if X {
count += 1
}
}
return count
Bereken de som van alle waardes van v van alle instanties van een opgegeven object.Ook hier moet je alle instanties afgaan, want je hebt ze allemaal nodig.
//instance_sum_v(obj)
var sum;
sum = 0
with argument0 {
sum += v
}
return sum
OpmerkingenVoor het argument
obj kun je een objectnaam opgeven, of het gereserveerde woord
all, als je alle objecten wil testen.
Als je een objectnaam opgeeft, worden van alle
kindobjecten van dat object ook alle instanties afgegaan. Als je bijvoorbeeld alle vijanden wil afgaan, maak dan een nieuw vijandouderobject en geef al je vijandobjecten dat vijandouderobject als ouder (parent). Wil je van een geretourneerde instantie weten van welk objecttype die is, gebruik dan de variabele
object_index.
Laatst bijgewerkt 14 mei: script toegevoegd dat instanties telt die voldoen aan een voorwaarde en dat een variabele uit meerdere instanties optelt