Bienvenue visiteur !
|
Désactiver la neige
Statistiques
Liste des membres
Contact
Mentions légales
339 connectés actuellement
30912551 visiteurs depuis l'ouverture
2187 visiteurs aujourd'hui
Partenaires
Tous nos partenaires
Devenir partenaire
|
Aurora -
posté le 14/05/2020 à 08:40:20 (437 messages postés)
| | Domaine concerné: Script
Logiciel utilisé: RMXP
Hello,
je me confronte à un petit problème:
Je travaille sur un petit puzzle game qui utilise le clonage d'évènement, ces évènement sont "effacés" en cliquant dessus mais au bout d'une centaine d’événements effacés je subis une chute du framerate.
Nous savons tous (je pense) que la commande "Effacer cet évènement" sur RMXP efface visuellement le dit évènement mais qu'il reste stocké en mémoire, d’où le lag.
Je pensais avoir trouvé la commande magique
1
2
| e = $game_map.events.delete(@event_id)
e.erase unless e.nil? |
mais elle ne solutionne pas le problème.
La solution d'activer un switch local ne fonctionne pas vu que même s'il ne tourne plus, l'évènement est toujours présent.
Y a-t-il une solution pour effacer un évènement de la mémoire ou ne tenir compte que de ceux actifs en processus parallèle sur l'écran ou encore de rafraichir l'écran (comme quand on appelle un menu, le framerate revient à la normale)? sachant que l'écran est un 20*15, un script anti-lag est inutile.
Merci.
|
| Chanter l'hyperchleuasme | Pour supprimer un événement en script, j’utilise la commande erase. Je ne sais pas s’il est vraiment retiré de la mémoire. Je travaille sur des petites maps, et j’invoque peu de clones, donc je n’atteins jamais la chute de framerate dont tu parles.
|
Es-tu une star ? | Kujira no Hara | Muma|Rope | Polaris 03 | La 7e porte |
Aurora -
posté le 14/05/2020 à 09:15:11 (437 messages postés)
| | Roi of the Suisse a dit:
Pour supprimer un événement en script, j’utilise la commande erase. Je ne sais pas s’il est vraiment retiré de la mémoire. Je travaille sur des petites maps, et j’invoque peu de clones, donc je n’atteins jamais la chute de framerate dont tu parles.
|
1
| $game_map.events.erase(@event_id) |
Ceci? (j'ai un "undefined method 'erase' for...")
N'est-ce pas la commande script équivalente à "Effacer cet évènement"?
|
| Chanter l'hyperchleuasme | Si.
Si tu veux que ton objet soit complètement détruit de la mémoire par le garbage collector, il faut qu'il n'y ait plus aucune référence à lui.
Tu as ressayé ?:
Peut-être qu'il y a encore un tableau (genre $game_map.events[] ) qui mentionne toujours ton évènement, empêchant de libérer la mémoire.
Si tu fais :
1
| $game_map.events.delete(mon_event) |
il devrait être retiré du tableau. Je ne sais pas si quelqu'un d'autre mentionne les évènements, empêchant leur suppression.
Il me semble (mais je peux me tromper) que la fonction delete() fonctionne par valeur, non pas par id : on y met la valeur qu'on veut voir retirée du tableau, et non pas le numéro. Ce qui expliquerait pourquoi ça ne fonctionne pas quand tu fais delete(@event_id). => faux, la méthode delete() fonctionne bien par clé
|
Es-tu une star ? | Kujira no Hara | Muma|Rope | Polaris 03 | La 7e porte |
Aurora -
posté le 14/05/2020 à 09:26:27 (437 messages postés)
| | Ouch, le fait de devoir insérer un numéro d'event est un souci je pense. Chaque clone a sans doute son propre numéro, à moins qu'il garde l'id de de l'event original de la map source, mais j'en doute. (Je vais essayer).
Mais c'est déjà un début de piste, merci.
Ma demande est honteuse mais rien de ce que j'essaie ne fonctionne et je ne suis pas assez bon pour comprendre pourquoi.. Quel bout de code écririez-vous si vous deviez supprimer définitivement un event d'une map et que toutes traces de lui ne soit plus référencées.
|
xvw -
posté le 14/05/2020 à 12:20:42 (736 messages postés)
| yo | Si tu joues cette commande (dans un appel de script), cela devrait purger les événements "supprimés".
1
| $game_map.events.delete_if {|id, event| event.erased? } |
Est-ce que ça améliore ton framerate ?
|
https://xvw.lol |
Aurora -
posté le 14/05/2020 à 13:08:37 (437 messages postés)
| | xvw a dit:
Si tu joues cette commande (dans un appel de script), cela devrait purger les événements "supprimés".
1
| $game_map.events.delete_if {|id, event| event.erased? } |
Est-ce que ça améliore ton framerate ?
|
j'ai inséré dans l'event (en processus parallèle) qui est cloné cette commande via la commande d'évènement "insérer un script", après avoir effacer l'évènement (sans ça sa bug).
Si c'est cette façon de faire qui est correcte, non ça n'a rien changé, j'ai toujours une grosse chute de framerate (20 / 40) après environs 200 events effacés.
J'ai aussi tenté cette commande par appel de script dans une page d'évènement commun, ça ne fonctionne pas.
Voici le script de clonage que j'utilise, si ça peut aider. Il est adapté pour XP :
Spoiler (cliquez pour afficher)
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#==============================================================================
#
# ▼ Yanfly Engine Ace - Spawn Event v1.00
# -- Last Updated: 2012.02.08
# -- Level: Normal, Hard
# -- Requires: n/a
#
#==============================================================================
# ▼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2012.02.08 - Started Script and Finished.
# Edited for RPG Maker XP by Wrinkle
# Credit to Modern Algebra for fixing the graphic refresh bug
#
#==============================================================================
# ▼ Introduction
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# For those who would like to spawn pre-made events from the current map or
# even other maps, this script allows you to do so. With the option of spawning
# the events at specific locations or a random spot marked by a certain region,
# you can have events spawn using simple script calls. The events remain until
# a map change.
#
# -----------------------------------------------------------------------------
# Script Calls - These commands are used with script calls.
# -----------------------------------------------------------------------------
# spawn_event_location(x, y, event_id)
# spawn_event_location(x, y, event_id, map_id)
# This causes a new event to be created at location x,y on the current map with
# the data from the corresponding event and map ID.
# The map_id is where the event will be called from according to event_id.
# If no map_id is included it will call the event from your current map.
#
#==============================================================================
#==============================================================================
# ■ Game_Map
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# new method: spawn_event
#--------------------------------------------------------------------------
# def spawn_event(dx, dy, event_id, map_id)
# map_id = @map_id if map_id == 0
# map = load_data(sprintf("Data/Map%03d.rxdata", map_id))
# event = generated_event(map, event_id)
# return if event.nil?
# key_id = @events.keys.max + 1
#@events[key_id] = Game_Event.new(@map_id, event)
#@events[key_id].moveto(dx, dy)
#$scene.spriteset.wrinkle_refresh_event(@events[key_id])
#end
#--------------------------------------------------------------------------
# new method: spawn_event
#--------------------------------------------------------------------------
def spawn_event(dx, dy, event_id, map_id)
map_id = @map_id if map_id == 0
map = load_data(sprintf("Data/Map%03d.rxdata", map_id))
event = generated_event(map, event_id)
return if event.nil?
key_id = @events.keys.max + 1
event.id = key_id
@events[key_id] = Game_Event.new(@map_id, event)
@events[key_id].moveto(dx, dy)
$scene.spriteset.wrinkle_refresh_event(@events[key_id])
end
#--------------------------------------------------------------------------
# new method: generated_event
#--------------------------------------------------------------------------
def generated_event(map, event_id)
for key in map.events
event = key[1]
next if event.nil?
return event if event.id == event_id
end
return nil
end
end # Game_Map
#==============================================================================
# ■ Game_Interpreter
#==============================================================================
class Interpreter
#--------------------------------------------------------------------------
# new method: spawn_event_location
#--------------------------------------------------------------------------
def spawn_event_location(dx, dy, event_id, map_id = 0)
$game_map.spawn_event(dx, dy, event_id, map_id)
end
end # Game_Interpreter
#==============================================================================
# ■ Scene_Map
#==============================================================================
class Scene_Map
#--------------------------------------------------------------------------
# public instance variables
#--------------------------------------------------------------------------
attr_accessor :spriteset
attr_accessor :x
attr_accessor :y
end # Scene_Map
class Spriteset_Map
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Refresh Event
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def wrinkle_refresh_event(event)
# Refresh new region event
index = @character_sprites.size - 1
@character_sprites.insert(index, Sprite_Character.new(@viewport1, event))
end
end
#==============================================================================
#
# ▼ End of File
#
#==============================================================================
|
|
| Chanter l'hyperchleuasme | Y a peut-être du ménage à faire dans @character_sprites aussi ?
Je n'ai pas regardé dans le détail, je dis ce qui me passe par la tête, ça mériterait une analyse.
|
Es-tu une star ? | Kujira no Hara | Muma|Rope | Polaris 03 | La 7e porte |
xvw -
posté le 14/05/2020 à 14:05:27 (736 messages postés)
| yo | Citation:
j'ai inséré dans l'event (en processus parallèle) qui est cloné cette commande via la commande d'évènement "insérer un script", après avoir effacer l'évènement (sans ça sa bug). |
Euh. L'idée c'est de s'en servir quand tu décides de supprimer un événement.
Après, le script est assez ennuyant parce que, a chaque fois que tu insères un événement... il doit lire la carte dans lequel se trouve l'évènement. Je pense qu'il vaudrait mieux utiliser un script mieux fait.
Mais sinon; comme le dit Roi de La Belgique, tu peux essayer d'ajouter ce script :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| class Spriteset_Map
def purge_character(id)
@character_sprites[id].dispose
end
end
class Game_Map
def purge_event(id)
@events[id].erase
$scene.spriteset.purge_character(id)
end
end
class Interpreter
def purge_event
$game_map.purge_event(@event_id)
end
end |
Et dans un évènement invoqué, tu peux utiliser l'appel de Script
(n'ayant pas XP et ne le connaissant pas très bien... il est possible qu'il y ait quelques bugs :P)
|
https://xvw.lol |
Aurora -
posté le 14/05/2020 à 14:15:55 (437 messages postés)
| | EDIT : Tu as posté le script pendant ma réponse, je teste. Merci.
xvw a dit:
Euh. L'idée c'est de s'en servir quand tu décides de supprimer un événement.
|
Ici, cliquer sur l'event déclenche son effacement et j'ai donc inséré le bout de code que tu m'as donné en dessous.
xvw a dit:
Après, le script est assez ennuyant parce que, a chaque fois que tu insères un événement... il doit lire la carte dans lequel se trouve l'évènement. Je pense qu'il vaudrait mieux utiliser un script mieux fait.
|
Je peux aussi cloner des events qui se trouvent sur la même map.
|
xvw -
posté le 14/05/2020 à 14:20:25 (736 messages postés)
| yo | Dans son script... même s'il se trouve sur la même map... il devra quand même lire le fichier de la carte... parce que ... Yanfly :P
Le script que j'ai "tenté d'écrire, tu peux remplacer tes deux lignes "effacer cet evenement; $game_map.events.delete_if" par "appel de script > purge_event"
|
https://xvw.lol |
Aurora -
posté le 14/05/2020 à 22:45:55 (437 messages postés)
| | xvw a dit:
Dans son script... même s'il se trouve sur la même map... il devra quand même lire le fichier de la carte... parce que ... Yanfly :P
Le script que j'ai "tenté d'écrire, tu peux remplacer tes deux lignes "effacer cet evenement; $game_map.events.delete_if" par "appel de script > purge_event"
|
Après test, j'ai une erreur :
Script 'Sprite_Character' line 27: RGSSError occured. disposed sprite
J'ai eu cette erreur en retirant la commande "effacer cet évènement", comme tu me l'avais conseillé.
Quand je la remets je n'ai plus d'erreur mais le framerate chute comme avant, après 200 events supprimés.
|
xvw -
posté le 15/05/2020 à 12:02:25 (736 messages postés)
| yo | Excuse moi, j'ai effectivement fait une erreur :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class Spriteset_Map
def purge_character(id)
@character_sprites.delete(id)
end
end
class Game_Map
def purge_event(id)
@events[id].erase
$scene.spriteset.purge_character(id)
end
end
class Interpreter
def purge_event
$game_map.purge_event(@event_id)
end
end
|
(nb: Roi de la suisse se trompe, delete fonctionne par clé)
|
https://xvw.lol |
Aurora -
posté le 15/05/2020 à 12:44:57 (437 messages postés)
| | Plus d'erreur mais toujours le même souci de framerate.
Je pense que, comme tu le penses, le souci vient du script de clonage.
Je vais voir pour me tourner vers Ace avec RME et tester sa fonction de clonage (i me semble qu'il y en a une).
Je ne vais pas vous embêter plus longtemps, merci pour votre aide
|
Gari -
posté le 15/05/2020 à 12:48:44 (5901 messages postés)
- | | De mémoire, l'un des puzzles de Polaris 03 utilise aussi un système de clonage d'event sur XP, et ça ramait aussi quand on atteignait un certain seuil, mais la map en question était beaucoup plus grande. Après je ne sais pas si le côté ergonomie avait été testé.
Bon courage pour résoudre ton problème.
|
Aurora -
posté le 15/05/2020 à 12:58:46 (437 messages postés)
| | Le framerate chute très fort après 200 events effacés, et dans le type de jeu que je veux faire, 200 "pièces" ce n'est rien du tout.
Puis, je m'obstine à faire des jeux sur RM (qui n'est pas adapté pour), donc à un moment nous rencontrons les limites du logiciel.
|
gif -
posté le 15/05/2020 à 13:15:21 (4782 messages postés)
- | Egotrip Gigamaxé | C'est pas possible de réutiliser les pièces à effacer pour créer les nouvelles (les recycler en quelque sorte) ?
Si on ne trouve pas de solution pour le design actuel, on peut peut-être t'aider à le modifier.
|
Itch.io | Twitter | Une IA qui génère des sprites de Pokémon | Cochouchou à la coupe du monde ! | le concours hebdomadaire du meilleur screen ! |
Aurora -
posté le 15/05/2020 à 13:26:46 (437 messages postés)
| | gif a dit:
C'est pas possible de réutiliser les pieces à effacer pour créer les nouvelles (les recycler en quelque sorte) ?
Si on ne trouve pas de solution pour le design actuel, on peut peut-être t'aider à le modifier.
|
Hum, chemin intéressant auquel je n'avais pas pensé...
Ça implique de limiter l'envoi d'un type de pièce (20 de chaque par exemple) et de ne pouvoir en re-balancer une du même type que si ce type est < 20.
Une pièce effacée (désactivée par switch local) serait en attente de pouvoir être ré-injectée.
Je vais plancher sur cette voie.
Merci pour l'idée.
|
Index du forum > Entraide > [RESOLU] [RMXP] Un moyen de libérer la mémoire ?
|
|
|