Menu

Connexion



Retenir ?

Mot de passe oublié ?
Eclipso logo
Merry Christmas !
06/06/2020 12:12:28

[Résolu]comande combat par pression de touche...

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


dim. 26 janv. 2014 - 09h00

bonjour
je souhaiterais faire des combat plus dynamique et j'ai trouver une solution qui me le permettrais,
utiliser les touche directement comme commande de combat coupler
comme suit :
La touche :C => attaquer
La touche :B => se défendre
La touche :A => Objet
La touche :X => Compétence (avec une petite variante pour celle si)

la touche X devra ouvrir une petite fenêtre au cas ou il y ai plusieurs type de compétence exemple magie/technique...

pour la gestion de touche j'utilise ce script si cela peut aider :Input Ultimate 2.3 by Zeus81
[spoiler][code]=begin
Input Ultimate 2.3 by Zeus81
Free for non-commercial use

Pour simplement régler les touches sans vouloir en savoir plus, aller ligne 1471.

REFERENCES
Input :
Constantes :
REPEAT : Permet de régler la façon dont la méthode repeat? fonctionne, ligne 1417.
PLAYERS_MAX : Le nombre de joueurs gérés par le script, à configurer ligne 1424.
KEYS_MAX : Définit une limite pour optimiser la mémoire, ligne 1425.
Players : La liste des contrôles joueurs.
Gamepads : La liste des manettes détectées.
Méthodes :
Input.update : A appeler une fois par frame pour tout mettre à jour.
Input.refresh : Détecte les manettes connectées au PC.
Input[i] : Retourne le contrôle du joueur i (commence à 0).
Le premier Player est fusionné avec le module Input
Faire Input.trigger?(k) équivaut à faire Input[0].trigger?(k)

Device :
Base commune à Player, Gamepad, Keyboard et Mouse
Propriétés :
enabled : Permet d'activer ou désactiver un contrôle.
Par exemple si on fait un jeu multijoueur mais qu'on joue en solo
on peut désactiver les autres joueurs pour optimiser les perfs.
Par défaut tous les contrôles sont activés sauf la souris et les
manettes non utilisées.
ntrigger_max : Option de la fonction ntrigger? décrite plus en dessous.
C'est ce qui est utilisé pour les doubles clics de la souris.
Par défaut cette option est désactivée (égale à 0) sauf
pour la souris où elle est égale à 3 (pour les triples clic).
Cette limite sert à faire boucler les clics, par exemple là
si je fais 5 clics ça sera considéré comme un triple clic
suivi d'un double clic.
ntrigger_time : Temps en nombre de frames pouvant s'écouler entre deux
clics pour être considérés comme une série de clics.
Si on met 0 ce temps sera le même que dans Windows. (Défaut)
Méthodes :
press?(*a) : Retourne true si la touche est pressée sinon false.
La fonction peut être utilisée de plusieurs façons :
Input.press?(Input::C)
Input.press?(:C)
Input.press?('C')
Input.press?(13)
Input::C.press?
Tout ceci revient au même, cela dit en terme de performance
Input::C.press? est deux fois plus rapide que les autres.
On peut aussi mettre plusieurs touches à la fois :
Input.press?(:A, :B, :C) = :A or :B or :C
En regroupant des touches dans un tableaux on inverse or/and :
Input.press?([:A, :B, :C]) = :A and :B and :C
On peut mélanger les deux :
Input.press?(:A, [:B, :C]) = :A or (:B and :C)
Et mettre plusieurs niveaux de tableaux :
Input.press?([:A, [:B, :C]]) = :A and (:B or :C)
En plus des tableaux on peut aussi utiliser des Range :
Input.press?(:A..:C) = Input.press?([:A, :B, :C])
Input.press?(*:A..:C) = Input.press?(:A, :B, :C)
Oui je sais, tout ça ne servira absolument à rien.
trigger?(*a) : Retourne true si la touche vient d'être pressée.
Pour les arguments fonctionne comme press?
release?(*a) : Retourne true si la touche vient d'être relâchée.
Pour les arguments fonctionne comme press?
repeat?(*a) : Retourne true ou false selon le schéma de REPEAT
Pour les arguments fonctionne comme press?
ntrigger?(n,*a) : Retourne true si la touche vient d'être pressée comme
trigger? mais en comptant le nombre de fois.
Mouse.ntrigger?(2, :Left) retournera true uniquement si
on fait un double clic, si ensuite on fait un troisième
clic seul Mouse.ntrigger?(3, :Left) retournera true.
n doit être inférieur ou égal à ntrigger_max
Pour les arguments fonctionne comme press?
count(k) : Retourne le temps en nombre de frames depuis quand la touche k
est pressée, 0 si elle n'est pas pressée.
Comme pour le reste k peut être égal à Input::C, :C, 'C', 13.
Et on peut aussi écrire Input::C.count
key(i) : Retourne la touche Key ayant pour id i.
Ici aussi i peut être un symbole, string, nombre (:C, 'C', 13).
capture_key(*exclude) : Si jamais vous faites un menu pour configurer les
touches utilisez cette fonction pour attendre
que le joueur appuie comme ceci :
until key = Keyboard.capture_key || Input.gamepad.capture_key
Graphics.update
Input.update
end
key sera un Keyboard_Key ou Gamepad_Key, vous pouvez
bien entendu les séparer si vous ne voulez que l'un
ou l'autre.
Protip, avant d'appeler cette méthode utilisez un
release? plutôt qu'un trigger? pour éviter que la
touche soit capturée. De même il vaut mieux
ensuite attendre que la touche capturée soit
relâchée avant de continuer, ce qui donne :
if Input::C.release?
until key = Keyboard.capture_key || Input.gamepad.capture_key
Graphics.update
Input.update
end
while key and key.push?
Graphics.update
Input.update
end
end
Vous pouvez aussi mettre en arguments des touches
que vous désirez ignorer.

Player < Device :
Pour les jeux multijoueur on y accède en utilisant Input[i]
Pour simplifier les jeux solo le premier Player est fusionné avec Input :
Input.trigger?(*a) = Input[0].trigger?(*a)
Constantes :
A, B, C, etc... : Les touches du jeu virtuelles (à ne pas confondre avec
les touches du clavier), à configurer ligne 1433.
Ce ne sont pas des nombres mais des objets de type Player_Key
ce qui permet de faire des chose comme : Input::C.press?
Pour les jeux multijoueurs on peut aussi faire :
Input::C[i].press? où i est l'id du joueur.
Propriétés :
id : Id du joueur. (lecture seule)
gamepad_id : Id du gamepad, par défaut égal à l'id du joueur.
Pour que le joueur n'ai pas de gamepad, mettre la valeur -1.
gamepad : Contrôleur Gamepad associé au joueur. (lecture seule)
Méthodes :
setup(h) : Configure la relation entre les touches virtuelles du jeu et
les touches réelles des clavier/manettes.
Nécessite un format particulier, voir ligne 1471.
dir4() : Retourne la direction pressée, format 4 directions.
dir8() : Retourne la direction pressée, format 8 directions.
dir360() : Retourne la direction pressée sous forme d'un angle et une
pression (pourcentage entre 0 et 1).
angle, power = Input.dir360
A la base créé pour les joysticks analogiques comme la fonction
analog? celle-ci retourne des valeurs aux extrémités si utilisé
sans manette analogique.
dirXY() : Retourne la direction pressée sous forme de deux axes entre -1 et 1.
x, y = Input.dirXY
Si le stick est orienté vers la gauche x = -1, vers la droite x = 1.
Si le stick est orienté vers le bas y = -1, vers le haut y = 1.
Par contre attention, la portée d'un joystick n'est pas carrée
(ni ronde d'ailleurs, c'est plus un carré aux bords arrondis)
de ce fait si on oriente le stick vers bas gauche par exemple
on aura pas x, y = -1, -1 mais plus x, y = -0.8, -0.8

Gamepad < Device :
Il y a trois types de gamepad, Multimedia_Gamepad pour les manettes
standard, XBox360_Gamepad spécialement pour les manettes Xbox et
No_Gamepad quand on a aucune manette, toutes ont les mêmes fonctions.
La classe No_Gamepad est là juste pour qu'on ait pas à se soucier de savoir
si un pad est branché ou pas avant d'utiliser ses fonctions.
Par exemple si on veut utiliser la fonction vibrate! on l'utilise, si une
manette xbox est branchée ça vibrera sinon ça fera rien, pas d'erreur.
Constantes :
AXIS_PUSH : Les joysticks analogiques ont une valeur de pression entre
0 et 32768 par direction.
Cette variable contient la valeur au delà de laquelle ces
touches seront considérés comme pressés si on utilise la
fonction press? par exemple.
Par défaut 16384 (soit 50%), à configurer ligne 679.
AXIS_DEADZONE : La position de repos d'un joystick analogique (au milieu)
n'est pas très stable, par conséquent si on utilise la
fonction analog? on obtient jamais 0, une zone morte est
établie au centre du joystick pour pallier à ça.
Par défaut 6666 (soit 10%), à configurer ligne 679.
TRIGGER_PUSH : Les gâchettes LT et RT des manettes XBox360 ont une valeur
de pression entre 0 et 255.
Cette variable contient la valeur au delà de laquelle ces
touches seront considérés comme pressés si on utilise la
fonction press? par exemple.
Par défaut 0, à configurer ligne 679.
Button1, Button2, etc.. : Les touches standard des manettes, liste ligne 681.
On les utilise uniquement lors du setup des Player.
Gamepad::Button1
LB, RB, etc... : Les touches des manettes xbox, liste ligne 689.
On les utilise uniquement lors du setup des Player.
XBox360_Gamepad::A
Ça revient au même que d'utiliser les touches standard
c'est juste l'écriture qui change, utilisez celle que
vous préférez.

Propriétés :
unplugged : Retourne true si la manette est débranchée. (lecture seule)
Ça peut être utilisé pour détecter une perte de manette soudaine.
Si on a pas de manette depuis le départ ce n'est pas considéré
comme une manette débranchée mais comme une manette de type
No_Gamepad avec unplugged = false
vibration : Permet d'activer ou pas les vibrations.
Méthodes :
analog?(*a) : Retourne un pourcentage entre 0 et 1 si la touche pressée est
analogique (sticks des manettes et gâchettes LT RT pour les
pads xbox) sinon retourne 0 ou 1.
Cette fonction est là pour les manettes cela dit on écrira
jamais : Input.gamepad.analog?(XBox360_Gamepad::AxisLY_0)
Mais plutôt : Input.analog?(Input::DOWN)
Les touches de la manette étant liées au setup du Player.
Pour les arguments fonctionne comme press?.
vibrate!(id, speed, fade_in, duration, fade_out) :
Fait vibrer la manette, ne fait rien si les vibrations
sont désactivées ou que ce n'est pas une manette XBox360.
id = 0 ou 1, pour les moteurs gauche ou droite.
Ou sinon 2 pour les deux en même temps.
speed = pourcentage entre 0 et 1
fade_in = durée de la transition entre le niveau de vibration
en cours et celui désiré.
duration = durée de la vibration.
fade_out = durée de la transition vers 0 à la fin du temps.
Exemple :
Input.gamepad.vibrate!(2, 0.5, 50, 200, 50)
Les deux moteurs vibreront à 50% sur en tout 300 frames.

Keyboard < Device :
Attention normalement vous ne devriez jamais utiliser le clavier directement.
Pour créer des jeux il est préférable d'utiliser des touches virtuelles
qui peuvent correspondre à plusieurs touches du clavier + des manettes en
même temps et éventuellement être configurable par le joueur,
donc utilisation directe du clavier à éviter.
Pour ce qui est de la saisie de texte la classe Text_Entry_Box est là.
Constantes :
Escape, Enter, etc... : Les touches du clavier, voir la liste ligne 862.
Ce ne sont pas des nombres mais des objets de type
Keyboard_Key ce qui permet de faire des chose comme :
Keyboard::Enter.push?
Méthodes :
setup(*a) : Si toutefois vous étiez amené pour une raison ou une autre à
devoir malgré tout utiliser directement le clavier, il faudra
d'abord lui dire quelles touches mettre à jour.
Par défaut aucune n'est mise à jour parce que ça prendrait du
temps pour rien.
Comme pour le reste plusieurs écritures sont supportées :
Keyboard.setup(Keyboard::Enter, :Escape, 'A'..'Z', 1)
Pour désactiver la mise à jour des touches :
Keyboard.setup()
A chaque setup toutes les touches envoyées remplacent les
anciennes, elles ne s'ajoutent pas.
Cependant vous n'avez besoin de faire ça que si vous désirez
utiliser les fonctions press?, trigger?, release?, repeat?,
ntrigger? et count, les fonctions push?, toggle?, push!, release!
et toggle! si dessous peuvent être utilisées sur n'importe
quelle touche en permanence.
push?(*a) : Fonctionne exactement comme la fonction press? mais en regardant
directement l'état du matériel donc un peu plus lentement.
A n'utiliser que dans le cas cité précédemment, si vous voulez
l'état press d'une touche du clavier sans vouloir passer par
le setup, sinon il est préférable d'utiliser press?
Vous pouvez aussi l'utiliser sur les constantes Key du clavier :
Keyboard::Escape.push?
toggle?(*a) : Retourne true si la touche est verrouillée sinon false.
Le vérouillage est ce qui est utilisé pour les touches
Verr. Num, Verr. Maj et Verr. Défil pour savoir si elles
sont sur On ou Off, mais vous pouvez l'utiliser sur n'importe
quelle touche en fait.
Comme push? cette fonction regarde directement l'état du
matériel et peut être utilisée sans setup.
Vous pouvez aussi l'utiliser sur les constantes Key du clavier :
Keyboard::CapsLock.toggle?
Pour les arguments fonctionne comme press?
push!(*a) : Appuie sur les touches du clavier à la place du joueur.
Les signaux sont envoyés directement à Windows donc attention.
Vous pouvez par exemple forcer le passage en plein écran :
Keyboard.push!(:Alt, :Enter)
Vous pouvez aussi l'utiliser sur les constantes Key du clavier :
Keyboard::Space.push!
Pour les arguments fonctionne comme press?
release!(*a) : Relâche les touches du clavier.
Après avoir appeler push! il faut appeler release! pour que
le système comprenne qu'elle n'est pas appuyée en permanence.
Ce n'est pas automatique !
Donc pour finaliser le passage en mode plein écran il faut faire :
Keyboard.push!(:Alt, :Enter)
Keyboard.release!(:Alt, :Enter)
Vous pouvez aussi l'utiliser sur les constantes Key du clavier :
Keyboard::Space.release!
Pour les arguments fonctionne comme press?
toggle!(*a) : Change l'état de verrouillage d'une touche.
Vous pouvez aussi l'utiliser sur les constantes Key du clavier :
Keyboard::Space.release!
Pour les arguments fonctionne comme press?
key_name(k) : Retourne le nom de la touche dans la langue du système.
Comme pour press?, k peut être égal à Keyboard::W, :W, 'W', 87.
Par exemple : Keyboard.key_name(:Escape) # => "ECHAP"
Cependant les noms de toutes les touches ne sont pas forcément
bienvenus donc il est peut être préférable de s'organiser
soi-même une liste de noms manuellement.
Vous pouvez aussi l'utiliser sur les constantes Key du clavier :
Keyboard::Escape.name

Mouse < Device :
Par défaut la souris est désactivée, pour l'activer faites :
Mouse.enabled = true
Constantes :
Left, Middle, Right, X1, X2, WheelUp, WheelDown :
Les touches de la souris, j'ai tout mis inutile d'aller voir la liste ligne 990.
Ce ne sont pas des nombres mais des objets de type Mouse_Key ce qui
permet de faire des chose comme : Mouse::Left.click?
Left, Middle, Right sont les clics gauche, milieu, droit.
X1 et X2 sont les boutons sur les côtés de la souris (si y'en a).
WheelUp et WheelDown pour la roulette ne répondent malheureusement pas
parfaitement, à éviter dans un jeu du coup, d'ailleurs pour que ça marche
un tant soit peu il faut mettre le Input.update avant le Graphics.update
Propriétés :
click_max : alias de ntrigger_max
Contrairement aux autres contrôles le click_max/ntrigger_max
de la souris est par défaut égal à 3.
click_time : alias de ntrigger_time
cursor : Le curseur de la souris, c'est un Sprite classique donc vous
pouvez utiliser toutes les fonctions des sprites.
Pour modifier le curseur par défaut voir ligne 1024.
x : Raccourci de cursor.x pour la lecture.
Vous pouvez aussi modifier manuellement la position de la souris.
Mouse.x = 123
Attention Mouse.cursor.x = 123 ne fonctionne pas.
y : Raccourci de cursor.y pour la lecture.
Vous pouvez aussi modifier manuellement la position de la souris.
Mouse.y = 456
Attention Mouse.cursor.y = 456 ne fonctionne pas.
drag : Le rectangle de sélection utilise aussi un Sprite mais a un
fonctionnement particulier.
Il apparait automatiquement quand on maintient un clic gauche et
déplace la souris, cependant par défaut il est désactivé.
Si vous désirez changer l'apparence du rectangle de sélection sachez
que c'est un Bitmap de 1x1 pixels, par défaut il est bleu transparent
voir ligne 1032, mais on peut le changer à tout moment :
Mouse.drag.bitmap.set_pixel(0, 0, Color.new(255, 0, 0, 128))
drag_enabled = Permet d'activer/désactiver la sélection, par défaut désactivée.
Pour l'activer : Mouse.drag_enabled = true
drag_x : Raccourci de drag.x (Lecture seule)
drag_y : Raccourci de drag.y (Lecture seule)
drag_width : Largeur de la sélection, équivalent de drag.zoom_x.to_i (Lecture seule)
drag_height : Hauteur de la sélection, équivalent de drag.zoom_y.to_i (Lecture seule)
drag_rect : Retourne Rect.new(drag_x, drag_y, drag_width, drag_height) (Lecture seule)
drag_auto_clear : Si activé la sélection s'effacera automatiquement
dès lors qu'on relâche le clic gauche.
drag_start_size : Nombre de pixels dont on doit déplacer la souris pour
faire apparaître le rectangle de sélection, par défaut 10.
Méthodes :
icon(s=nil, ox=0, oy=0) : Permet de changer l'apparence du curseur,
l'image doit se trouver dans le dossier picture,
l'extension est facultative.
Mouse.icon("croix")
On peut éventuellement préciser un décalage vers
le centre du curseur si nécessaire, en comptant
à partir du coin haut gauche de l'image.
Mouse.icon("croix", 4, 4)
Si on veut remettre le curseur par défaut :
Mouse.icon()
clip(*a) : Définit la zone dans laquelle la souris est libre de se mouvoir.
Il y a quatre façons d'utiliser cette fonction :
Mouse.clip(i) : Si i = 0, aucune limitation, la souris peut
voguer librement sur tout l'écran. (Défaut)
Si i = 1, la souris est bloquée dans la fenêtre
du jeu, càd surface de jeu + barre de titre.
Si i = 2, la souris est bloquée dans la surface
de jeu, on ne peut plus aller sur la barre de titre.
Déconseillé vu qu'on ne peut plus réduire/fermer
le jeu ce qui peut vite devenir pénible.
Mouse.clip() : Idem que Mouse.clip(0).
Mouse.clip(x, y, w, h) : Définit une zone manuellement,
le point 0, 0 correspond au coin
haut gauche de la surface de jeu.
Mouse.clip(rect) : Idem mais avec un objet de type Rect.
on?(*a) : Retourne true si la souris est dans la zone demandée.
Il y a cinq façons d'utiliser cette fonction :
Mouse.on?() : vérifie si le curseur est dans la surface de jeu.
Mouse.on?(x, y) : vérifie si le curseur est sur le point x y.
Mouse.on?(x, y, r) : vérifie si le curseur est dans le cercle
de centre x y et de rayon r.
Mouse.on?(x, y, w, h) : vérifie si le curseur est dans le
rectangle aux coordonnées spécifiées.
Mouse.on?(rect) : Idem mais avec un objet de type Rect.
drag_on?(*a) : Retourne true si la sélection est en contact avec la zone donnée.
Il y a quatre façons d'utiliser cette fonction :
Mouse.drag_on?(x, y) : vérifie si le point x y est compris
dans la sélection.
Mouse.drag_on?(x, y, r) : vérifie si le cercle de centre x y
et de rayon r entre en contact
avec la sélection.
Mouse.drag_on?(x, y, w, h) : vérifie si le rectangle entre
en contact avec la sélection.
Mouse.drag_on?(rect) : Idem mais avec un objet de type Rect.
drag_clear() : Efface la sélection.
dragging?() : Retourne true si une sélection est en cours.
swap_button(b) : Si b = true, inverse les clics gauches et droits,
si b = false, les remet à la normale.
click?(k=Left) : Simple clic, équivalent de ntrigger?(1, k).
L'argument est facultatif et est le clic gauche par défaut.
La différence entre click? et trigger? est que si on fait
un double clic par exemple lors du deuxième clic trigger?
renverra true alors que click? false (et dclick? true).
Vous pouvez aussi l'utiliser sur les constantes Key de la souris :
Mouse::Left.click?
dclick?(k=Left) : Double clic, équivalent de ntrigger?(2, k).
Vous pouvez aussi l'utiliser sur les constantes Key de la souris :
Mouse::Left.dclick?
tclick?(k=Left) : Triple clic, équivalent de ntrigger?(3, k).
Vous pouvez aussi l'utiliser sur les constantes Key de la souris :
Mouse::Left.tclick?

Key :
Il y en a quatre types : Player_Key, Gamepad_Key, Keyboard_Key et Mouse_Key
Certaines possèdent des fonctions en plus.
Méthodes :
to_s() : Retourne le nom de la constante.
Input::DOWN.to_s # => "DOWN"
to_i() : Retourne l'id de la touche.
Input::DOWN.to_i # => 2
push?(), toggle?(), press?(), trigger?(), release?(), repeat?(), analog?(),
ntrigger?(n), count() : Toutes les fonctions décrites précédemment sont
utilisables directement sur les touches pour plus
d'efficacité :
Input::DOWN.press?
Cependant inutile d'appeler ces fonctions sur les
touches Gamepad_Key, ça ne marchera pas.
name(), push!(), release!(), toggle!() : Fonctions supplémentaires des Keyboard_Key
click?(), dclick?(), tclick?() : Fonctions supplémentaires des Mouse_Key
[i] : Fonction supplémentaire des Player_Key pour le jeu multijoueur :
Input::DOWN[0].trigger? # joueur 1
Input::DOWN[1].trigger? # joueur 2

Text_Entry_Box < Sprite
Cette classe permet de saisir du texte au clavier, la souris est aussi
supportée pour la sélection de texte.
Text_Entry_Box est dérivée de Sprite et son affichage est automatisé.
Vous pouvez utiliser toutes les fonctions de Sprite cependant les fonctions
zoom, angle, mirror, src_rect ne seront pas compatibles avec la souris.
Si la souris est activée et survole une boite de texte, l’icône changera
automatiquement, vous pouvez modifier son apparence ligne 1180.
Propriétés :
enabled : Permet d'activer ou désactiver une boite de texte.
Une boite désactivée ne peut plus avoir le focus.
focus : L'état de focus actuel, une seule boite peut l'avoir à la fois.
text : Permet de récupérer le texte entré.
back_color : La couleur du fond, valeur par défaut ligne 1195.
Elle peut être modifiée à tout moment mais il faut ensuite
appeler refresh() pour mettre à jour le bitmap.
text_entry_box.back_color = Color.new(255, 0, 0)
select_color : Couleur de la sélection, idem que back_color.
allow_c : Liste des caractères autorisés sous forme de string.
text_entry_box.allow_c = "abcABC123"
Si la liste est vide tous les caractères sont autorisés. (Défaut)
select : Permet d'activer ou désactiver les sélections que ce soit avec la
souris ou en maintenant la touche Maj.
Activé par défaut, pour le désactiver : text_entry_box.select = false
mouse : Permet d'activer ou désactiver les fonctionnalités de la souris.
Activé par défaut, pour le désactiver : text_entry_box.mouse = false
Il faut aussi que la souris elle même soit activée sinon ça sert à rien.
case : Casse de caractère :
text_entry_box.case = 0 # normal, sensible à la casse (Défaut)
text_entry_box.case = 1 # downcase, les majuscules deviennent minuscules.
text_entry_box.case = 2 # upcase, les minuscules deviennent majuscules.
size : Le nombre de caractères actuel. (lecture seule)
size_max : Le nombre de caractères maximum autorisé.
Si 0, pas de limite.
width : Raccourci pour text_entry_box.bitmap.width (lecture seule)
width_max : La taille maximum autorisée en pixels.
Si 0, pas de limite.
height : Raccourci pour text_entry_box.bitmap.height (lecture seule)
font : Raccourci pour text_entry_box.bitmap.font
Méthodes :
Text_Entry_Box.new(width, height, viewport=nil) :
Crée une nouvelle instance de Text_Entry_Box
On est obligé de préciser width et height qui sont utilisés pour créer
le bitmap, viewport est facultatif.
text_entry_box = Text_Entry_Box.new(100, 20)

dispose : Supprime le sprite et le bitmap.
update : A appeler une fois par frame pour mettre à jour la saisie de texte.
refresh : A appeler après avoir modifié les propriétés ou le font du bitmap
pour forcer la mise à jour.
hover? : Retourne true si la souris survole la boite texte.
focus! : Donne le focus à la boite texte, une seule boite peut avoir le
focus à la fois, il est automatiquement retiré des autres.
Cette fonction est automatiquement appelée quand on clique sur la
boite texte, si la souris est activée bien sûr.
=end

class Object
remove_const(:Input)
def singleton_attach_methods(o) class << self; self end.attach_methods(o) end
def self.attach_methods(o)
@attached_methods ||= []
for m in o.public_methods-(instance_methods-@attached_methods)
define_method(m, &o.method(m))
@attached_methods << m unless @attached_methods.include?(m)
end
end
end

class String; alias getbyte [] end if RUBY_VERSION == '1.8.1'

module Input
class Key
include Comparable
attr_reader :o, :i, :s, :hash, :to_sym
alias to_i i
alias to_s s
def initialize(i,o)
@o, self.i, self.s = o, i, "#{self.class.name.split('::')[-1]}_#{i}"
end
def o=(o) @o, @hash = o, @i.hash^o.hash end
def i=(i) @i, @hash = i, i.hash^@o.hash end
def s=(s) @s, @to_sym = s, s.to_sym end
def <=>(o) @i <=> o.to_i end
def succ() self.class.new(@i+1,@o) end
def count() @o.get_count(@i) end
def push?() @o.get_push(@i) end
def toggle?() @o.get_toggle(@i) end
def press?() @o.get_press(@i) end
def trigger?() @o.get_trigger(@i) end
def release?() @o.get_release(@i) end
def repeat?() @o.get_repeat(@i) end
def ntrigger?(n) @o.get_ntrigger(n,@i) end
def analog?() @o.get_analog(@i) end
end
class Gamepad_Key < Key
def initialize(i,o=Gamepad) super end
end
class Keyboard_Key < Key
def initialize(i,o=Keyboard) super end
def name() @o.get_key_name(@i) end
def push!() @o.push!(@i) end
def release!() @o.release!(@i) end
def toggle!() @o.toggle!(@i) end
end
class Mouse_Key < Key
def initialize(i,o=Mouse) super end
def click?() ntrigger?(1) end
def dclick?() ntrigger?(2) end
def tclick?() ntrigger?(3) end
end
class Player_Key < Key
def [](i) @players_keys[i] end
def initialize(i,o=Players[0])
super
@players_keys = Players.map {|p| k = dup; k.o = p; k}
end
end

class Device
GetDoubleClickTime = Win32API.new('user32', 'GetDoubleClickTime', '', 'i')
attr_accessor :enabled, :ntrigger_max, :ntrigger_time
def initialize(max)
@enabled, @count, @release, @keys = true, Array.new(max,0), [], []
@ntrigger_count, @ntrigger_last, @ntrigger_max = @count.dup, @count.dup, 0
self.ntrigger_time = 0
end
def update
return unless @enabled
update_keys
update_ntrigger if @ntrigger_max != 0
end
def update_keys
@release.clear
for i in @keys
if get_push(i) ; @count[i] += 1
elsif @count[i] != 0; @count[i] = 0; @release << i
end
end
end
def update_ntrigger
f = Graphics.frame_count
for i in @keys
if @count[i] == 1
@ntrigger_count[i] %= @ntrigger_max
@ntrigger_count[i] += 1
@ntrigger_last[i] = f + @ntrigger_time
elsif @ntrigger_last[i] == f
@ntrigger_count[i] = 0
end
end
end
def capture_key(*exclude)
exclude = keyarrayize(*exclude) unless exclude.empty?
(@count.size-1).downto(0) {|i| return key(i) if !exclude.include?(i) and get_push(i)}
nil
end
def get_count(i) @count[i] end
def get_push(i) false end
def get_toggle(i) false end
def get_press(i) @count[i] != 0 end
def get_trigger(i) @count[i] == 1 end
def get_release(i) @release.include?(i) end
def get_repeat(i) (j=@count[i])>0 and REPEAT.any? {|w,f| break(f>0 && j%f==0) if j>=w} end
def get_ntrigger(n,i) get_trigger(i) and @ntrigger_count[i] == n end
def get_analog(i) get_push(i) ? 1.0 : 0.0 end
def count(k) get_count(k2i(k)) end
def push?(*a) a.any?{|i| enum?(i) ? i.all?{|j| push?(*j)} : get_push(k2i(i))} end
def toggle?(*a) a.any?{|i| enum?(i) ? i.all?{|j| toggle?(*j)} : get_toggle(k2i(i))} end
def press?(*a) a.any?{|i| enum?(i) ? i.all?{|j| press?(*j)} : get_press(k2i(i))} end
def trigger?(*a) a.any?{|i| enum?(i) ? i.all?{|j| trigger?(*j)} : get_trigger(k2i(i))} end
def release?(*a) a.any?{|i| enum?(i) ? i.all?{|j| release?(*j)} : get_release(k2i(i))} end
def repeat?(*a) a.any?{|i| enum?(i) ? i.all?{|j| repeat?(*j)} : get_repeat(k2i(i))} end
def ntrigger?(n,*a) a.any?{|i| enum?(i) ? i.all?{|j| ntrigger?(n,*j)} : get_ntrigger(n,k2i(i))} end
def analog?(*a)
a.each do |i|
d = if enum?(i)
sum = size = 0
i.each {|j| sum, size = sum+analog?(*j), size+1}
sum == 0 ? 0 : sum / size
else get_analog(k2i(i))
end
return d if d != 0
end
0.0
end
def ntrigger_time=(i) @ntrigger_time = (i==0 ? GetDoubleClickTime.call *
Graphics.frame_rate / 1000 : i) end
def key(o) self.class.key(o) end
def k2i(o) self.class.k2i(o) end
private
def enum?(o) o.is_a?(Array) or o.is_a?(Range) end
def keyarrayize(*a)
a.flatten!
a.map! {|o| o.is_a?(Range) ? o.to_a : o}.flatten!
a.compact!
a.map! {|k| k2i(k)}.uniq!
a
end
def self.key(o) o.is_a?(Key) || o.is_a?(Integer) ? const_get(:Keys)[o.to_i] : const_get(o) end
def self.k2i(o) o.is_a?(Key) ? o.i : o.is_a?(Integer) ? o : const_get(o).i end
end

class Player < Device
attr_reader :id, :gamepad, :gamepad_id
def initialize(id)
super(KEYS_MAX)
@id, @gamepad_id, @gamepad, @map = id, id, No_Gamepad.new, @count.map{[]}
end
def setup(h)
@keys.clear
@count.fill(0)
@map.fill([])
for i,a in h
a=@map[i=k2i(i)] = a[0].map {|j| Gamepad.key(j).dup} + a[1].map {|j| Keyboard.key(j)}
@keys << i unless a.empty?
end
self.gamepad_id += 0
end
def gamepad_id=(i)
vibration, @gamepad.enabled = @gamepad.vibration, false
@gamepad = (@gamepad_id = i) >= 0 && Gamepads[i] || No_Gamepad.new
@gamepad.vibration = vibration
Players.each {|p| p.gamepad.enabled = true}
@map.each {|a| a.each {|k| k.o = @gamepad if k.is_a?(Gamepad_Key)}}
end
def get_push(i) @map[i].any? {|k| k.push?} end
def get_toggle(i) @map[i].any? {|k| k.toggle?} end
def get_analog(i) @map[i].each {|k| d=k.analog?; return d if d != 0}; 0.0 end
def dirXY
return 0.0, 0.0 unless @enabled
return RIGHT.analog?-LEFT.analog?, UP.analog?-DOWN.analog?
end
def dir360
x, y = *dirXY
return 0.0, 0.0 if x == 0 and y == 0
return Math.atan2(y,x)*180/Math::PI, (w=Math.hypot(x,y))>1 ? 1.0 : w
end
def dir8
d = 5
d -= 3 if DOWN.press?
d -= 1 if LEFT.press?
d += 1 if RIGHT.press?
d += 3 if UP.press?
d == 5 ? 0 : d
end
def dir4
case d = dir8
when 1; DOWN.trigger? == (@last_dir==2) ? 2 : 4
when 3; DOWN.trigger? == (@last_dir==2) ? 2 : 6
when 7; UP.trigger? == (@last_dir==8) ? 8 : 4
when 9; UP.trigger? == (@last_dir==8) ? 8 : 6
else @last_dir = d
end
end
end

class Gamepad < Device
::Gamepad = self
AXIS_PUSH, AXIS_DEADZONE, TRIGGER_PUSH = 16384, 6666, 0
Keys = Array.new(48) {|i| Gamepad_Key.new(i)}
Button1 , Button2 , Button3 , Button4 , Button5 , Button6 , Button7 ,
Button8 , Button9 , Button10, Button11, Button12, Button13, Button14,
Button15, Button16, Button17, Button18, Button19, Button20, Button21,
Button22, Button23, Button24, Button25, Button26, Button27, Button28,
Button29, Button30, Button31, Button32, Axis1_0 , Axis1_1 , Axis2_0 ,
Axis2_1 , Axis3_0 , Axis3_1 , Axis4_0 , Axis4_1 , Axis5_0 , Axis5_1 ,
Axis6_0 , Axis6_1 , PovUp , PovRight, PovDown , PovLeft = *Keys
XKeys = Array.new(48) {|i| Gamepad_Key.new(i)}
A, B, X, Y, LB, RB, LT, RT, BACK, START, LS, RS,
n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n,
AxisLX_0, AxisLX_1, AxisLY_1, AxisLY_0, AxisRX_0, AxisRX_1, AxisRY_1, AxisRY_0,
n, n, n, n, DPadUp, DPadRight, DPadDown, DPadLeft = *XKeys
constants.each {|s| k = const_get(s); k.s = s.to_s if k.is_a?(Key)}

attr_accessor :vibration
attr_reader :unplugged
def initialize(id=nil)
super(48)
@id, @unplugged, @map, @vibration = id, false, @count.map{[]}, true
end
def get_push(i)
return false unless @enabled and !@unplugged
j, k = *@map[i]
case j
when :button ; button(k)
when :pov ; k.include?(pov)
when :axis_0 ; axis_raw(k) < -AXIS_PUSH
when :axis_1 ; axis_raw(k) > AXIS_PUSH-1
when :trigger; trig_raw(k) > TRIGGER_PUSH
else false
end
end
def get_analog(i)
return 0.0 unless @enabled and !@unplugged
j, k = *@map[i]
case j
when :button, :pov; super
when :axis_0 ; (k=axis_pct(k)) < 0 ? -k : 0.0
when :axis_1 ; (k=axis_pct(k)) > 0 ? k : 0.0
when :trigger; trig_pct(k)
else 0.0
end
end
def vibrate!(id, speed, fade_in, duration, fade_out) end
private
def axis_pct(i)
(i=axis_raw(i)).abs <= AXIS_DEADZONE ? 0.0 :
(i<0 ? i+AXIS_DEADZONE : i-AXIS_DEADZONE+1) / (32768.0-AXIS_DEADZONE)
end
def trig_pct(i) trig_raw(i) / 255.0 end
def axis_raw(i) 0 end
def trig_raw(i) 0 end
def pov() 0 end
def button(i) false end

singleton_attach_methods(@o = new)

class No_Gamepad < Gamepad
::No_Gamepad = Input::No_Gamepad = self
def get_push(i) false end
def get_analog(i) 0.0 end
end

class Multimedia_Gamepad < Gamepad
::Multimedia_Gamepad = Input::Multimedia_Gamepad = self
JoyGetDevCaps = Win32API.new('winmm', 'joyGetDevCaps', 'ipi', 'i')
JoyGetPosEx = Win32API.new('winmm', 'joyGetPosEx' , 'ip' , 'i')
def initialize(id)
super
JoyGetDevCaps.call(id, devcaps="\0"*404, 404)
@caps = Array.new(7) {|i| i<2 or devcaps.getbyte(96)[i-2]==1}
@buffer = [52,255,0,0,0,0,0,0,0,0,0,0,0].pack('L13')
@state = @buffer.unpack('L13')
for k,v in { Button1 =>[:button, 0], Button2 =>[:button, 1],
Button3 =>[:button, 2], Button4 =>[:button, 3], Button5 =>[:button, 4],
Button6 =>[:button, 5], Button7 =>[:button, 6], Button8 =>[:button, 7],
Button9 =>[:button, 8], Button10=>[:button, 9], Button11=>[:button,10],
Button12=>[:button,11], Button13=>[:button,12], Button14=>[:button,13],
Button15=>[:button,14], Button16=>[:button,15], Button17=>[:button,16],
Button18=>[:button,17], Button19=>[:button,18], Button20=>[:button,19],
Button21=>[:button,20], Button22=>[:button,21], Button23=>[:button,22],
Button24=>[:button,23], Button25=>[:button,24], Button26=>[:button,25],
Button27=>[:button,26], Button28=>[:button,27], Button29=>[:button,28],
Button30=>[:button,29], Button31=>[:button,30], Button32=>[:button,31],
Axis1_0 =>[:axis_0, 0], Axis1_1 =>[:axis_1, 0], Axis2_0 =>[:axis_0, 1],
Axis2_1 =>[:axis_1, 1], Axis3_0 =>[:axis_0, 2], Axis3_1 =>[:axis_1, 2],
Axis4_0 =>[:axis_0, 3], Axis4_1 =>[:axis_1, 3], Axis5_0 =>[:axis_0, 4],
Axis5_1 =>[:axis_1, 4], Axis6_0 =>[:axis_0, 5], Axis6_1 =>[:axis_1, 5],
PovUp =>[:pov,[31500, 0, 4500]], PovRight=>[:pov,[ 4500, 9000,13500]],
PovDown =>[:pov,[13500,18000,22500]], PovLeft =>[:pov,[22500,27000,31500]]}
@map[k.i] = v
end
update
end
def update
return unless @enabled and !@unplugged = JoyGetPosEx.call(@id, @buffer) != 0
@state.replace(@buffer.unpack('L13'))
super
end
private
def button(i) @state[8][i] == 1 end
def pov() @caps[6] ? @state[10] : 0 end
def axis_raw(i) @caps[i] ? @state[2+i]-32768 : 0 end
end

class XBox360_Gamepad < Gamepad
::XBox360_Gamepad = Input::XBox360_Gamepad = self
Keys = XKeys
XInputGetState = (Win32API.new(DLL='xinput1_3' , 'XInputGetState', 'ip', 'i') rescue
Win32API.new(DLL='xinput1_2' , 'XInputGetState', 'ip', 'i') rescue
Win32API.new(DLL='xinput1_1' , 'XInputGetState', 'ip', 'i') rescue
Win32API.new(DLL='xinput9_1_0', 'XInputGetState', 'ip', 'i') rescue
DLL=nil)
XInputSetState = Win32API.new(DLL , 'XInputSetState', 'ip', 'i') if DLL
def initialize(id)
super
@buffer = "\0"*16
@state = @buffer.unpack('LSC2s4')
@vibration_state = Array.new(2) {[0,0,0,0,0,false]}
for k,v in {
A =>[:button,12], B =>[:button,13], X =>[:button,14],
Y =>[:button,15], LB =>[:button, 8], RB =>[:button, 9],
LT =>[:trigger,0], RT =>[:trigger,1], BACK =>[:button, 5],
START =>[:button, 4], LS =>[:button, 6], RS =>[:button, 7],
AxisLX_0 =>[:axis_0, 0], AxisLX_1=>[:axis_1, 0], AxisLY_1=>[:axis_1, 1],
AxisLY_0 =>[:axis_0, 1], AxisRX_0=>[:axis_0, 2], AxisRX_1=>[:axis_1, 2],
AxisRY_1 =>[:axis_1, 3], AxisRY_0=>[:axis_0, 3], DPadUp =>[:button, 0],
DPadRight=>[:button, 3], DPadDown=>[:button, 1], DPadLeft=>[:button, 2]}
@map[k.i] = v
end
update
end
def update
return unless @enabled and !@unplugged = XInputGetState.call(@id, @buffer) != 0
@state.replace(@buffer.unpack('LSC2s4'))
super
update_vibration if @vibration
end
def update_vibration
vibrate = false
@vibration_state.each do |v|
next unless v[5]
last_v0 = v[0]
if v[2]>0; v[0] = (v[0]*(v[2]-=1)+v[1]) / (v[2]+1.0)
elsif v[3]>0; v[0], v[3] = v[1], v[3]-1
elsif v[4]>0; v[0] = v[0]*(v[4]-=1) / (v[4]+1.0)
else v[0], v[5] = 0, false
end
vibrate = true if last_v0 != v[0]
end
set_vibration if vibrate
end
def vibration=(b) vibrate!(2,0,0,0,0); super end
def vibrate!(id, speed, fade_in, duration, fade_out)
case id
when 0, 1; @vibration_state[id][1,5] = [speed, fade_in, duration, fade_out, true]
when 2 ; 2.times {|i| vibrate!(i, speed, fade_in, duration, fade_out)}
end
end
private
def button(i) @state[1][i] == 1 end
def axis_raw(i) @state[4+i] end
def trig_raw(i) @state[2+i] end
def set_vibration
return unless @enabled and @vibration and !@unplugged
XInputSetState.call(@id, [@vibration_state[0][0]*0xFFFF,
@vibration_state[1][0]*0xFFFF].pack('S2'))
end
end

end

class Keyboard < Device
::Keyboard = self
GetKeyboardState = Win32API.new('user32' , 'GetKeyboardState' , 'p' , 'i')
getKeyNameText = Win32API.new('user32' , 'GetKeyNameTextW' , 'ipi' , 'i')
mapVirtualKey = Win32API.new('user32' , 'MapVirtualKey' , 'ii' , 'i')
SendInput = Win32API.new('user32' , 'SendInput' , 'ipi' , 'i')
ToUnicode = Win32API.new('user32' , 'ToUnicode' , 'iippii' , 'i')
WideCharToMultiByte = Win32API.new('kernel32', 'WideCharToMultiByte', 'iipipipp', 'i')

Keys = Array.new(256) {|i| Keyboard_Key.new(i)}
None, MouseL, MouseR, Cancel, MouseM, MouseX1, MouseX2, n, Back, Tab,
LineFeed, n, Clear, Enter, n, n, Shift, Control, Alt, Pause, CapsLock,
KanaMode, n, JunjaMode, FinalMode, KanjiMode, n, Escape, IMEConvert,
IMENonConvert, IMEAccept, IMEModeChange, Space, PageUp, PageDown, End, Home,
Left, Up, Right, Down, Select, Print, Execute, PrintScreen, Insert, Delete,
Help, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, n, n, n, n, n, n, n, A, B, C,
D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, LWin,
RWin, Apps, n, Sleep, NumPad0, NumPad1, NumPad2, NumPad3, NumPad4, NumPad5,
NumPad6, NumPad7, NumPad8, NumPad9, Multiply, Add, Separator, Subtract,
Decimal, Divide, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13,
F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, n, n, n, n, n, n, n,
n, NumLock, Scroll, n, n, n, n, n, n, n, n, n, n, n, n, n, n, LShift,
RShift, LControl, RControl, LAlt, RAlt, BrowserBack, BrowserForward,
BrowserRefresh, BrowserStop, BrowserSearch, BrowserFavorites, BrowserHome,
VolumeMute, VolumeDown, VolumeUp, MediaNextTrack, MediaPreviousTrack,
MediaStop, MediaPlayPause, LaunchMail, SelectMedia, LaunchApplication1,
LaunchApplication2, n, n, OemSemicolon, OemPlus, OemComma, OemMinus,
OemPeriod, OemQuestion, OemTilde, n, n, n, n, n, n, n, n, n, n, n, n, n, n,
n, n, n, n, n, n, n, n, n, n, n, n, OemOpenBrackets, OemPipe,
OemCloseBrackets, OemQuotes, Oem8, n, n, OemBackslash, n, n, ProcessKey,
n, Packet, n, n, n, n, n, n, n, n, n, n, n, n, n, n, Attn, Crsel, Exsel,
EraseEof, Play, Zoom, NoName, Pa1, OemClear, Unknown = *Keys
constants.each {|s| k = const_get(s); k.s = s.to_s if k.is_a?(Key)}

SCAN_CODE = Array.new(256) {|i| mapVirtualKey.call(i, 0)}
(BrowserBack..LaunchApplication2).each {|k| SCAN_CODE[k.i] = 0}
for k,code in {Pause =>0x0045, PageUp =>0x0149, PageDown=>0x0151,
End =>0x014F, Home =>0x0147, Left =>0x014B, Up =>0x0148,
Right =>0x014D, Down =>0x0150, PrintScreen=>0x0137, Insert =>0x0152,
Delete=>0x0153, LWin =>0x015B, RWin =>0x015C, Apps =>0x015D,
Divide=>0x0135, NumLock=>0x0145, RControl =>0x011D, RAlt =>0x0138}
SCAN_CODE[k.i] = code
end

KEYS_NAME = Array.new(256) do |i|
if getKeyNameText.call(SCAN_CODE[i]<<16, utf16="\0"*256, 256) > 0
WideCharToMultiByte.call(65001, 0, utf16, -1, utf8="\0"*256, 256, 0, 0)
utf8.delete("\0")
else Keys[i].to_s
end
end

TEXT_KEYS = [Space.i] + (D0.i..D9.i).to_a + (A.i..Z.i).to_a +
(NumPad0.i..Divide.i).to_a + (146..150).to_a +
(OemSemicolon.i..OemTilde.i).to_a + (OemOpenBrackets.i..245).to_a

TEXT_ENTRY_KEYS = TEXT_KEYS + [Back.i,Left.i,Up.i,Right.i,Down.i,Delete.i]

DEAD_KEYS = {
'`' => {'a'=>'à', 'e'=>'è', 'i'=>'ì', 'o'=>'ò', 'u'=>'ù',
' '=>'`', 'A'=>'À', 'E'=>'È', 'I'=>'Ì', 'O'=>'Ò', 'U'=>'Ù'},

'´' => {'a'=>'á', 'e'=>'é', 'i'=>'í', 'o'=>'ó', 'u'=>'ú', 'y'=>'ý',
' '=>'´', 'A'=>'Á', 'E'=>'É', 'I'=>'Í', 'O'=>'Ó', 'U'=>'Ú', 'Y'=>'Ý'},

'^' => {'a'=>'â', 'e'=>'ê', 'i'=>'î', 'o'=>'ô', 'u'=>'û',
' '=>'^', 'A'=>'Â', 'E'=>'Ê', 'I'=>'Î', 'O'=>'Ô', 'U'=>'Û'},

'¨' => {'a'=>'ä', 'e'=>'ë', 'i'=>'ï', 'o'=>'ö', 'u'=>'ü', 'y'=>'ÿ',
' '=>'¨', 'A'=>'Ä', 'E'=>'Ë', 'I'=>'Ï', 'O'=>'Ö', 'U'=>'Ü', 'y'=>'Ÿ'},

'~' => {'a'=>'ã', 'o'=>'õ', 'n'=>'ñ',
' '=>'~', 'A'=>'Ã', 'O'=>'Õ', 'N'=>'Ñ'},
}

def initialize() super(256); @buffer = "\0"*256 end
def get_push(i) @enabled and @buffer.getbyte(i)[7] == 1 end
def get_toggle(i) @enabled and @buffer.getbyte(i)[0] == 1 end
def get_key_name(i) i.between?(0, 255) ? KEYS_NAME[i].dup : '' end
def key_name(k) get_key_name(k2i(k)) end
def push!(*a) set_state(a, true) end
def release!(*a) set_state(a, false) end
def toggle!(*a) set_state(a, true); set_state(a, false) end
def text_entry() start_text_entry unless @text_entry; @text_entry.dup end
def start_text_entry() (@text_entry = ''; setup(@keys)) unless @text_entry end
def stop_text_entry() (@text_entry = nil; setup(@user_keys)) if @text_entry end
def swap_mouse_button(b) MouseL.i, MouseR.i = b ? 2 : 1, b ? 1 : 2 end
def setup(*a)
@count.fill(0)
@keys = keyarrayize(@text_entry ? [@user_keys=a, TEXT_ENTRY_KEYS] : a)
end
def update
return unless @enabled
GetKeyboardState.call(@buffer)
super
update_text_entry if @text_entry
end
def update_text_entry
@text_entry = ''
for i in TEXT_KEYS
next if !get_repeat(i) or ToUnicode.call(i, 0, @buffer, utf16="\0"*16, 8, 0)==0
j = ToUnicode.call(i, 0, @buffer, utf16, 8, 0)
WideCharToMultiByte.call(65001, 0, utf16, 1, utf8="\0"*4, 4, 0, 0)
utf8.delete!("\0")
if @dead_key
a = DEAD_KEYS[@dead_key]
@text_entry, @dead_key = (a && a[utf8]) || (@dead_key + utf8)
else j == -1 ? @dead_key=utf8 : @text_entry=utf8
end
return
end
end
private
def set_state(keys, state)
keys, inputs = keyarrayize(keys), ''
keys.each {|i| inputs << [1,i,0,state ? 0 : 2,0,0].pack('LSSLLLx8')}
SendInput.call(keys.size, inputs, 28)
end

singleton_attach_methods(@o = new)
Keys.each {|k| k.o = @o}
def self.o() @o end
end

class Mouse < Device
::Mouse = self
ClipCursor = Win32API.new('user32', 'ClipCursor' , 'p' , 'i')
createCursor = Win32API.new('user32', 'CreateCursor' , 'iiiiipp', 'i')
findWindow = Win32API.new('user32', 'FindWindow' , 'pp' , 'i')
G

KuroFidy

Grand Maître
KuroFidy
  • Messages : 3782

[Résolu]comande combat par pression de touche...


lun. 27 janv. 2014 - 10h25

Pourrais tu préciser sur quel RM c'est ?

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


lun. 27 janv. 2014 - 11h21

a oui désoler je suis sous rpgmaker vxace ^^

Zouzaka

Elite
Zouzaka
  • Messages : 616

[Résolu]comande combat par pression de touche...


lun. 27 janv. 2014 - 11h48

Tu veut qu'on te fasse le système de combat complet ou juste comment utiliser le scripte ?

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


lun. 27 janv. 2014 - 17h09

juste m'aider a trouver l'endroit ou il faut mettre les commande
ainsi que au moins une commande histoire que je voie comme cela fonctionne après je pourrais me débrouiller .
je suppose que la commande doit être comme suit:


command_attack if Input.trigger?(:C)
command_item if Input.trigger?(:A)


par contre pour la petite fenêtre je pense qu'il faudra recréer une Windows_selectable

merci

Zouzaka

Elite
Zouzaka
  • Messages : 616

[Résolu]comande combat par pression de touche...


lun. 27 janv. 2014 - 17h44

Voila

Mais ca c'est pour si tu veut faire un systeme de A-RPG, si tu veut que ce soit dans un combat classique dit le moi et je l’adapterait

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


lun. 27 janv. 2014 - 18h31

j’orrais du préciser que c'est pour un combat classique au tour par tour désoler ^^

Zouzaka

Elite
Zouzaka
  • Messages : 616

[Résolu]comande combat par pression de touche...


lun. 27 janv. 2014 - 21h19

Ca sera Plus complexe mais je vais essayer te faire ça ^^

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


mar. 28 janv. 2014 - 12h59

merci ^^

Zouzaka

Elite
Zouzaka
  • Messages : 616

[Résolu]comande combat par pression de touche...


mar. 28 janv. 2014 - 13h06

Bon la je suis plus au moin blocké =/, si quelqu'un connait la ligne de code pour forcer une action, c'est le moment ^^'
ou bien une adaptation de ce scripte pour le rgss3

# Advanced forced action
# by Mithran
# Use an Advanced > Script event command to trigger

# format is:
# force_action(A, B, C, D, E)
# replace A with the group you want to pick the actor or enemy out of
# -1 = target actors by index
# 0 = target enemies by troop index
# 1 = target actors by party index

# replace B with the index of the actor or enemy you want to pick
# for troop and party, the index number starts at zero
# (eg., default party is 0 Ralph, 1 Ulrika, 2 Bennett, 3 Ylva)
# actor index starts at 1
# (eg., default party is 1 Ralph, 2 Ulrika, 3 Bennett, 4 Ylva)

# Replace C with the kind of action you want to force
# 0 = basic
# 1 = skill
# 2 = item *
# *ignored on enemies
# *Item is still consumed, but it is not checked before using. May change this later.

# Replace D with the id of the action you want to perform
# if C is basic (0)
# 0 - attack
# 1 - guard
# 2 - escape*
# 3 - wait
# *escape is ignored on actors
# if C is skill or item
# the id of the item or skill you are selecting to force

# Replace E with the index of the target you want to force to
# -2 = select the last target*
# -1 = choose a random target
# 0 or above = pick the selected group index
# *if the previous action had no target, this forced action will be ignored

# Example:
# force_action(-1, 1, 1, 2, -2)
# forces Ralph (if he is in the party) to use double attack on the last enemy he
# targeted


module Mithran
module ForceAction
module_function
def force_action(group, index_id, kind, basic_id, target_id, scope_change = false)
battler = nil
if group == -1
battler = $game_actors[index_id]
return if !$game_party.members.include?(battler)
elsif group == 0
battler = $game_troop[index_id]
else
battler = $game_party[index_id]
end
return if battler.nil?
return if !battler.exist?
case kind
when 1
skill = $data_skills[basic_id]
return if skill.nil?
battler.action.set_skill(basic_id)
when 2
item = $data_items[basic_id]
return if item.nil?
return if !battler.actor?
battler.action.set_item(basic_id)
else
case basic_id
when 0 # Attack
battler.action.set_attack
when 1 # Guard
battler.action.set_guard
when 2 # Escape
battler.action.kind = 0
if battler.actor?
battler.action.basic = 3
else
battler.action.basic = 2
end
else # Wait
battler.action.kind = 0
battler.action.basic = 3
end
end
case target_id
when -2
battler.action.decide_last_target
when -1
battler.action.decide_random_target
when 0..99
battler.action.target_index = target_id
end
battler.action.forcing = true
$game_troop.forcing_battler = battler
end
end
end

class Game_Interpreter
include Mithran::ForceAction
end

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


mar. 28 janv. 2014 - 18h27

bon j'y ai passer toute l’après-midi mais je tien quelque chose
par contre pas moyen de faire une fenêtre de sélection de skill du coup ça ne fonctionne pas pour les skill si tu as une idée ...

Spoiler


=begin
systeme de combat part pression de touche v1.0
=end

class Window_ActorCommand < Window_Command
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 0)
self.openness = 0
deactivate
@actor = nil
end
#--------------------------------------------------------------------------
# * Get Window Width
#--------------------------------------------------------------------------
def window_width
return 128
end
#--------------------------------------------------------------------------
# * Get Number of Lines to Show
#--------------------------------------------------------------------------
def visible_line_number
return 1
end
#--------------------------------------------------------------------------
# * Create Command List
#--------------------------------------------------------------------------
def make_command_list
return unless @actor
add_attack_command
end
#--------------------------------------------------------------------------
# * Add Attack Command to List
#--------------------------------------------------------------------------
def add_attack_command
add_command(Vocab::attack, :attack, @actor.attack_usable?)
end
def setup(actor)
@actor = actor
clear_command_list
make_command_list
refresh
select(0)
activate
open
end
end

class Window_Selectable < Window_Base
def process_handling
return unless open? && active
return process_ok if ok_enabled? && Input.trigger?(:C)
return process_cancel if cancel_enabled? && Input.trigger?(:B)
return process_pagedown if handle?(:pagedown) && Input.trigger?(:R)
return process_pageup if handle?(:pageup) && Input.trigger?(:L)
return process_input_atk if handle?(:input_atk) && Input.trigger?(:C)
return process_input_skill if handle?(:input_skill) && Input.trigger?(:X)
return process_input_def if handle?(:input_def) && Input.trigger?(:B)
return process_input_item if handle?(:input_item) && Input.trigger?(:A)
end
def process_input_atk
Sound.play_cursor
Input.update
deactivate
call_handler(:input_atk)
end
def process_input_skill
Sound.play_cursor
Input.update
deactivate
call_handler(:input_skill)
end
def process_input_def
Sound.play_cursor
Input.update
deactivate
call_handler(:input_def)
end
def process_input_item
Sound.play_cursor
Input.update
deactivate
call_handler(:input_item)
end
end

class Scene_Battle < Scene_Base


def create_actor_command_window
@actor_command_window = Window_ActorCommand.new
#@actor_command_window.viewport = @info_viewport
@actor_command_window.set_handler(:attack, method(:command_attack))
@actor_command_window.set_handler(:input_atk, method(:command_attack))
@actor_command_window.set_handler(:input_skill, method(:command_skill))
@actor_command_window.set_handler(:input_def, method(:command_guard))
@actor_command_window.set_handler(:input_item, method(:command_item))
@actor_command_window.x = Graphics.width
end
end

Zouzaka

Elite
Zouzaka
  • Messages : 616

[Résolu]comande combat par pression de touche...


mar. 28 janv. 2014 - 21h17

Aprés plusieurs tentative en event ce fut un echec donc je vais essayer de bidouiller un truc en scripte
c'est la première fois que je m'attaque a la création de scripte (ou plutot du bidouillage avancé) donc ne t'attend pas a un truc nickel, pour le moment je suis a ca :

=begin
Dynamique Battle Systeme
=end

class Scene_Battle < Scene_Base
def start
super
create_spriteset
create_all_windows
@status_window.hide
BattleManager.method_wait_for_message = method(:wait_for_message)
end
def update
super
if BattleManager.in_turn?
process_event
process_action
end
BattleManager.judge_win_loss
end
def command_fight
verifi_touche
@Battle_Started_Z = true
@Libre_Z = true
end
def verifi_touche
Graphics.wait(1)
if @Libre_Z == true
if Input.press?(:C)
command_attack
end
if Input.press?(:B)
command_guard
end
if Input.press?(:A)
command_item
end
if Input.press?(:X)
command_skill
end
end
end
def command_attack
BattleManager.actor.input.set_attack
select_enemy_selection
@Libre_Z = false
end
def command_skill
@skill_window.actor = BattleManager.actor
@skill_window.stype_id = @actor_command_window.current_ext
@skill_window.refresh
@skill_window.show.activate
@Libre_Z = false
end
def command_item
@item_window.refresh
@item_window.show.activate
@Libre_Z = false
end
end

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


mar. 28 janv. 2014 - 21h22

c'est bon merci j'ai réussi a me dépatouiller je vais poster le script sur le forum ça pourra surment aider

Zouzaka

Elite
Zouzaka
  • Messages : 616

[Résolu]comande combat par pression de touche...


mar. 28 janv. 2014 - 21h27

Ok, Désolé de ne pas t'avoir suffisamment aidé =/

johnseed

Débutôt
johnseed
  • Messages : 16

[Résolu]comande combat par pression de touche...


mar. 28 janv. 2014 - 21h30

Voila le script est ici :http://forum.eclipso.fr/viewtopic.php?f=41&t=1661