Jump to content
Rpg²S Forum

Keroro

Utenti
  • Posts

    646
  • Joined

  • Last visited

Posts posted by Keroro

  1. Keyboard Input V. 3.0



    News

    • Versione 3.0

    Porting al 100% compatibile con qualsiasi altro script, non sono necessari fix perché

    non si interferisce con il normale funzionamento del modulo Input!

    • Versione 2.0

    Framework per cambiare facilmente i tasti di gioco

    Integrato e compatibile con le classi di default dell'RGSS3

    • Versione 1.0

    Implementato Scene_Name con input da tastiera!

    • Versione 0.5

    Estensione del modulo Input



    Descrizione





    Porting per VX-ACE dello script YEM Keyboard Script per VX.

    Rimpiazza lo Scene_Name facendo inserire direttamente da tastiera.

    TODO: Gestire la punteggiatura


    Autore





    Keroro, based on OriginalWij and Yanfly work


    Immagine





    http://img190.imageshack.us/img190/2647/vultus5.png

     

    Istruzioni per l'uso

    Creare una nuova tab sotto Materials e incollare lo script.
    Oltre a modificare lo Scene_Name modifica la classe Input consentendo,
    al programmatore volenteroso di utilizzare tutti le lettere e i numeri tramite sintassi:

     

    if Input.press(:VK_A)
    #se premo la lettera a
    end
    if Input.press(:NUM5) or Input.press(:PAD5)
    #se premo il numero 5 sulla tastiera o sul numpad
    end




    Script da incollare

    #===============================================================================
    # Keyboard Input - Porting to VX-ACE
    # By Keroro - cris87@gmail.com
    # Version 3.0
    # Last Date Updated. 2012.03.17
    #===============================================================================
    #
    # OriginalWij and Yanfly Collaboration - Keyboard Input
    # Last Date Updated: 2010.06.12
    # Level: Normal
    #
    # This is a utility script that provides the functionality to return inputs
    # from the keyboard as well as free up more keys to be used in the Input module.
    # This script will also replace Scene_Name and allow for direct keyboard input
    # to type in an actor's name as well as fix the maximum characters shown from
    # the default base script.
    #
    #===============================================================================
    
    $imported = {} if $imported == nil
    $imported["KeyboardInput"] = true
    
    
    
    class << Input
    	#--------------------------------------------------------------------------
    	# Aliases (Mods - Linked to Module) - Created by OriginalWij
    	#--------------------------------------------------------------------------
    	alias ow_dt_i_press press? unless $@
    	alias ow_dt_i_trigger trigger? unless $@
    	alias ow_dt_i_repeat repeat? unless $@
    	alias ow_dt_i_update update unless $@
    end
    
    module Input
    	#--------------------------------------------------------------------------
    	# constants - Created by OriginalWij and Yanfly and Keroro
    	#--------------------------------------------------------------------------
    	VALUES = {}
    	VALUES[:VK_A] = 65; VALUES[:VK_B] = 66; VALUES[:VK_C] = 67;
    	VALUES[:VK_D] = 68; VALUES[:VK_E] = 69; VALUES[:VK_F] = 70;
    	VALUES[:VK_G] = 71; VALUES[:VK_H] = 72; VALUES[:VK_I] = 73;
    	VALUES[:VK_J] = 74; VALUES[:VK_K] = 75; VALUES[:VK_L] = 76
    	VALUES[:VK_M] = 77; VALUES[:VK_N] = 78; VALUES[:VK_O] = 79;
    	VALUES[:VK_P] = 80; VALUES[:VK_Q] = 81; VALUES[:VK_R] = 82;
    	VALUES[:VK_S] = 83; VALUES[:VK_T] = 84; VALUES[:VK_U] = 85;
    	VALUES[:VK_V] = 86; VALUES[:VK_W] = 87; VALUES[:VK_X] = 88
    	VALUES[:VK_Y] = 89; VALUES[:VK_Z] = 90;
    	LETTERS = [:VK_A,:VK_B,:VK_C,:VK_D,:VK_E,:VK_F,:VK_G,:VK_H,:VK_I,:VK_J, \
    	:VK_K,:VK_L,:VK_M,:VK_N,:VK_O,:VK_P,:VK_Q,:VK_R,:VK_S,:VK_T, \
    	:VK_U,:VK_V,:VK_W,:VK_X,:VK_Y,:VK_Z]
    	VALUES[:NUM0] = 48; VALUES[:NUM1] = 49; VALUES[:NUM2] = 50;
    	VALUES[:NUM3] = 51; VALUES[:NUM4] = 52; VALUES[:NUM5] = 53;
    	VALUES[:NUM6] = 54; VALUES[:NUM7] = 55; VALUES[:NUM8] = 56;
    	VALUES[:NUM9] = 57; VALUES[:PAD0] = 96; VALUES[:PAD1] = 97;
    	VALUES[:PAD2] = 98; VALUES[:PAD3] = 99; VALUES[:PAD4] = 100;
    	VALUES[:PAD5] = 101; VALUES[:PAD6] = 102; VALUES[:PAD7] = 103;
    	VALUES[:PAD8] = 104; VALUES[:PAD9] = 105;
    	NUMBERS = [:NUM0,:NUM1,:NUM2,:NUM3,:NUM4,:NUM5,:NUM6,:NUM7,:NUM8,:NUM9]
    	NUMPAD = [:PAD0,:PAD1,:PAD2,:PAD3,:PAD4,:PAD5,:PAD6,:PAD7,:PAD8,:PAD9]
    	VALUES[:ENTER] = 13;
    	VALUES[:SPACE] = 32;
    	VALUES[:ESC] = 27;
    	VALUES[:BACK] = 8;
    	VALUES[:PGUP] = 33;
    	VALUES[:PGDN] = 34;
    	VALUES[:CAPS] = 20;
    	#TODO: aggiungere tags per punteggiatura
    	
    	#--------------------------------------------------------------------------
    	# initial module settings - Created by OriginalWij and Yanfly
    	#--------------------------------------------------------------------------
    	GetKeyState = Win32API.new("user32", "GetAsyncKeyState", "i", "i")
    	GetCapState = Win32API.new("user32", "GetKeyState", "i", "i")
    	KeyRepeatCounter = {}
    	module_function
    	#--------------------------------------------------------------------------
    	# alias method: update - Created by OriginalWij and Keroro
    	#--------------------------------------------------------------------------
    	def update
    		ow_dt_i_update
    		for key in KeyRepeatCounter.keys
    			if (GetKeyState.call(VALUES[key]).abs & 0x8000 == 0x8000)
    				KeyRepeatCounter[key] += 1
    			else
    				KeyRepeatCounter.delete(key)
    			end
    		end
    	end
    	
    	#--------------------------------------------------------------------------
    	# alias method: press? - Created by OriginalWij and Keroro
    	#--------------------------------------------------------------------------
    	def press?(key)
    		return ow_dt_i_press(key) if !VALUES.has_key?(key)
    		return true unless KeyRepeatCounter[key].nil?
    		return key_pressed?(key)
    	end
    	#--------------------------------------------------------------------------
    	# alias method: trigger? - Created by OriginalWij and Keroro
    	#--------------------------------------------------------------------------
    	def trigger?(key)
    		return ow_dt_i_trigger(key) if !VALUES.has_key?(key)
    		count = KeyRepeatCounter[key]
    		return ((count == 0) or (count.nil? ? key_pressed?(key) : false))
    	end
    	#--------------------------------------------------------------------------
    	# alias method: repeat? - Created by OriginalWij and Keroro
    	#--------------------------------------------------------------------------
    	def repeat?(key)
    		return ow_dt_i_trigger(key) if !VALUES.has_key?(key)
    		count = KeyRepeatCounter[key]
    		return true if count == 0
    		if count.nil?
    			return key_pressed?(key)
    		else
    			return (count >= 23 and (count - 23) % 6 == 0)
    		end
    	end
    	
    	
    	#--------------------------------------------------------------------------
    	# new method: key_pressed? - Created by OriginalWij and Keroro
    	#--------------------------------------------------------------------------
    	def key_pressed?(key)
    		if (GetKeyState.call(VALUES[key]).abs & 0x8000 == 0x8000)
    			KeyRepeatCounter[key] = 0
    			return true
    		end
    		return false
    	end
    	
    	#--------------------------------------------------------------------------
    	# new method: typing? - Created by Yanfly and Keroro
    	#--------------------------------------------------------------------------
    	def typing?
    		return true if repeat?(:SPACE)
    		for key in LETTERS
    			return true if repeat?(key)
    		end
    		for key in NUMBERS
    			return true if repeat?(key)
    		end
    		return false
    	end
    	
    	#--------------------------------------------------------------------------
    	# new method: key_type - Created by Yanfly and Keroro
    	#--------------------------------------------------------------------------
    	
    	def key_type
    		return " " if repeat?(:SPACE)
    		for key in LETTERS
    			next unless repeat?(key)
    			return upcase? ? key.to_s[3].upcase : key.to_s[3].downcase
    		end
    		for key in NUMBERS
    			return key.to_s[3] if repeat?(key)
    		end
    		for key in NUMPADS
    			return key.to_s[3] if repeat?(key)
    		end
    		
    		return ""
    	end
    	#--------------------------------------------------------------------------
    	# new method: upcase? - Created by Yanfly
    	#--------------------------------------------------------------------------
    	def upcase?
    		return !press?(:SHIFT) if GetCapState.call(VALUES[:CAPS]) == 1
    		return true if press?(:SHIFT)
    		return false
    	end
    end #Input
    
    
    #===============================================================================
    # Window_NameEdit
    #===============================================================================
    
    class Window_NameEdit < Window_Base
    	
    	#--------------------------------------------------------------------------
    	# overwrite method: initialize
    	#--------------------------------------------------------------------------
    	def initialize(actor, max_char)
    		dw = Graphics.width - 176
    		dy = (Graphics.height - 128) / 2
    		if $game_message.visible
    			difference = Graphics.height - 128
    			case $game_message.position
    			when 0; dy += 64
    			when 1; dy += 0
    			when 2; dy -= 64
    			end
    		end
    		super(88, dy, dw, 128)
    		@actor = actor
    		@name = actor.name
    		@max_char = max_char
    		name_array = @name.split(//)[0...@max_char]
    		@name = ""
    		for i in 0...name_array.size
    			@name += name_array[i]
    		end
    		@default_name = @name
    		@index = name_array.size
    		self.active = false
    		refresh
    	end
    	
    	#--------------------------------------------------------------------------
    	# overwrite method: item_rect
    	#--------------------------------------------------------------------------
    	def item_rect(index)
    		if index == @max_char
    			rect = Rect.new(0, 0, 0, 0)
    		else
    			rect = Rect.new(0, 0, 0, 0)
    			rect.x = 112 + index * 12
    			rect.y = 36
    			rect.width = 24
    			rect.height = line_height
    		end
    		return rect
    	end
    	
    end # Window_NameEdit
    
    #===============================================================================
    # Scene_Base
    #===============================================================================
    
    class Scene_Base
    	
    	#--------------------------------------------------------------------------
    	# new method: name_entry
    	#--------------------------------------------------------------------------
    	def name_entry(actor_id, max_char)
    		@name_actor_id = actor_id
    		@name_entry_max = max_char
    		start_name_entry
    	end_name_entry
    end
    
    #--------------------------------------------------------------------------
    # new method: start_name_entry
    #--------------------------------------------------------------------------
    def start_name_entry
    	Graphics.freeze
    	actor = $game_actors[@name_actor_id]
    	@edit_window = Window_NameEdit.new(actor, @name_entry_max)
    	Graphics.transition(10)
    	loop do
    		update_name_entry
    		if Input.repeat?(:BACK) and @edit_window.index > 0
    			Sound.play_cancel
    			@edit_window.back
    		elsif Input.typing? and @edit_window.index != @edit_window.max_char
    			Sound.play_cursor
    			@edit_window.add(Input.key_type)
    		elsif Input.trigger?(:ENTER)
    			Sound.play_ok
    			actor.name = @edit_window.name
    			break
    		elsif Input.trigger?(:ESC)
    			Sound.play_cancel
    			break
    		end
    	end
    end
    
    #--------------------------------------------------------------------------
    # new method: update_name_entry
    #--------------------------------------------------------------------------
    def update_name_entry
    	Graphics.update
    	Input.update
    	if SceneManager.scene.is_a?(Scene_Map)
    		$game_map.update
    		@spriteset.update
    	elsif SceneManager.scene.is_a?(Scene_Battle)
    		Graphics.update
    		Input.update
    		$game_system.update
    		$game_troop.update
    		@spriteset.update
    		@message_window.update
    	end
    	@edit_window.update
    end
    
    #--------------------------------------------------------------------------
    # end_name_entry
    #--------------------------------------------------------------------------
    def end_name_entry
    	@edit_window.dispose
    	@edit_window = nil
    	@name_actor_id = nil
    	@name_entry_max = nil
    end
    end # Scene_Base
    
    #===============================================================================
    # Game_Interpreter
    #===============================================================================
    
    class Game_Interpreter
    
    #--------------------------------------------------------------------------
    # overwrite method: command_303 (Name Input Processing)
    #--------------------------------------------------------------------------
    def command_303
    	if $data_actors[@params[0]] != nil
    		SceneManager.scene.name_entry(@params[0], @params[1])
    	end
    	@index += 1
    	return false
    end
    
    end # Game_Interpreter
    
    




    Bugs e Conflitti Noti
    In modalità finestra il mouse compare e scompare, a schermo intero invece resta nascosto, devo trovare il codice per nasconderlo anche in finestra ^^

  2. Da giocatore di scacchi (e coach di scacchi) il tuo progetto mi interessa molto e lo giocherei volentieri :).

     

    Da programmatore posso dirti che realizzare una IA scacchistica è semplice se ci si accontenta di una misera forza di gioco, il problema è adattarla ad un gioco come il tuo nel senso che il giocatore si confronterà con i grandi del passato: è difficile adattare un motore per rispecchiare il loro stile, specialmente se ha una forza da 1600 elo.

     

    Secondo me ti converrebbe puntare sulla risoluzione di enigmi e posizioni, se vuoi una mano su questo fronte sono molto creativo ^_^

     

    Nel frattempo installo il vx-ace, magari riesco a fare una scacchiera con l'rgss XD

  3. Condivido ciò che pensa Testament

    Ho sempre seguito una sola community e per spostarmi ci vuole un motivo (in genere morivano XD), da vgmaker a gamemaker.it a gamesoul a makerando a rpg2s.

    Pur essendo rinata non vedo elementi sufficienti per iscrivermi né frequentarla u.u

  4. +1, per esclusione.

    Avrei votato il secondo se avesse sistemato le scritte con un font più armonioso e meno stile "KAPOW!" (batman).

    Nel terzo l'artista dovrebbe imparare a usare photoshop per amalgamare le immagini.

    Il quarto è troppo grezzo, l'idea è carina ma il font è poco leggibile.

  5. Apprezzo che Testament ti abbia dato il permesso di cannibalizzare le sue risorse.

    Pocket Quest è un gioco che deve molto alla sua grafica, il gameplay è molto semplice da programmare lontano dai tool, e spero che ne migliorerai la longevità: pur essendomi piaciuto molto a suo tempo non sono riuscito a giocarlo più di un paio d'ore.

     

    Nel video ci sono molti errori, spero dovuti alla fretta:

     

    Nell'intro c'è scritto 'Poket Quest' invece di 'Pocket Quest'

    La telecamera della prima scena è un po' monotona, è come se il castello stesse nel vuoto visto che inquadri solo quello e lo sky box.

    Le tende della stanza pur essendo trasparenti non sono mosse dal vento, lasciate così sembrano cartongesso trasparente, se trovi difficile applicare l'effetto flag ti consiglio di farle come finestre o mettere delle tende pesanti e coprenti, magari sul porpora.

    Quello che si nota è anche che la stanza è molto scarna eppure dovrebbe essere la residenza di un principe.

    Nello spigolo destro della stanza si vede la volta stellata piuttosto che il muro, può essere un problema di clipping

    La casa non ha un tetto e i billboard sono fatti male, il fiore finisce dentro la finestra, nana è dilatata e l'ombra alla sua base non è sempre ben posizionata.

    Penso che hai programmato immaginando una telecamera laterale alla stessa altezza e poi tu abbia cercato di adattarla ad una presentazione con telecamera dall'alto, secondo me dovresti modificare l'angolazione e le dimensioni dei billboard oltre che aggiungere un tetto solo per il filmato.

     

    Aspetto di vedere il prossimo video

  6. Vabbè se è pertinente alla discussione chiedi qua XD

     

    Come funziona l'A-Star?

     

    Esistono due liste, una aperta ed una chiusa e ci sono delle funzioni accessorie, il costo del nodo, la distanza stimata h, la distanza cumulativa f.

    Nella lista aperta vanno i nodi da valutare e ci si mette il punto di partenza all'inizio.

    Nella lista chiusa vanno i nodi già valutati.

     

    All'algoritmo si passano due parametri, il punto di partenza ed il punto di arrivo.

     

    Nella lista aperta si individua il nodo con costo cumulativo f minore, si controlla se è il nodo finale (e se lo è, si ricostruisce il percorso migliore).

    Se non è il nodo finale si aggiunge il suddetto nodo alla lista chiusa perché ormai valutato e si mettono i suoi vicini nella lista aperta, calcolando i costi cumulati.

     

    Poi si riparte selezionando il nodo con costo cumulato minore e si va avanti finché non si trova il nodo finale oppure finché non si coprono tutti i nodi. Naturalmente più ostacoli ci sono (nel calcolo dei nodi vicini si escludono i nodi non passabili), meno nodi si dovranno analizzare nel caso peggiore e quindi paradossalmente più è complicato il percorso più veloce sarà l'analisi.

  7. Il brutto del lavorare Indie è che se fai qualcosa e te ne vuoi vantare nel curriculum devi documentarla per bene, si aspettano una bella vetrina dei tuoi lavori scaricabili e magari di dare una sbirciata al source.

    Invece se hai realizzato qualcosa lavorando in azienda quello che produci rimane a loro e non devi né puoi essere troppo specifico (nei contratti a progetto che ho firmato c'era sempre una clausola di segretezza D:) e quindi puoi dire al massimo titolo, genere, strumenti e linguaggi che utilizzavi e magari allegare un'immagine o confidare in san google.

    Concordo che il titolo di studio non fa il professionista, la selezione vera avviene nel colloquio in cui sondano le tue capacità, ed anche sul piano remunerativo un diplomato può prendere quanto un laureato triennale.

    Il problema per chi inizia può essere quello di arrivarci al colloquio... E per questo servono conoscenze o sapersi vendere bene

  8. Creare un RTS è un'obiettivo molto interessante e non banale.

    Il ruby in RGSS è COMPLETAMENTE in GRADO di realizzare un RTS con i fiocchi, la parte difficile è l'integrazione con il sistema sovrastante ed evitare di spendere troppi cicli in cose inutili.

    Sviluppare anche un RTS che tenga incollato il giocatore è difficile, bisogna lavorare molto per automatizzare le attività ed incentivare il giocatore a potenziare la città.

    Personalmente dopo anni spesi a giocare a Age of Empires 2 ho trovato solo in Age of Mithology uno stimolo.

     

    Automatizzare le attività:

    Sicuramente qualsiasi attività includa il movimento si deve basare su un algoritmo di pathfinding, il più famoso e usato in campo videoludico è l'A-Star, una variante dell'Algoritmo di Dijkstra, al giorno d'oggi implementato con una Priority Queue per avere una performance di O(n log n) dove n è il numero delle caselle della mappa.

     

    L'algoritmo di pathfinding serve per trovare un percorso (formato da una lista di caselle da percorrere) efficiente per arrivare da un punto A ad un punto B.

    Non si cerca una soluzione perfetta perché sarebbe computazionalmente lenta ma ci si accontenta di una soluzione sub-ottima.

    Per capire se un percorso è migliore di un altro ci si affida ad una funziona che approssima la distanza (usare le radici quadrate è poco performante)

      #--------------------------------------------------------------------------
     # * Heuristic Distance
     #	u : node 1
     #	v : node 2
     #--------------------------------------------------------------------------
     def heuristic_dist(u,v)
    dx = xNode(v)-xNode(u)
    dy = yNode(v)-yNode(u)
    # Manhattan distance heuristic
    return (dx.abs+dy.abs)
     end

     

     

    Per estrarre il percorso migliore si usa una Priority Queue.

    La Priority Queue è una struttura di dati visualizzabile come un albero binario, implementabile sia come lista linkata ma più spesso da un array.

    Selezionato un elemento a[k] questo ha due figli situati in a[2*k+1] e a[2*k+2]. L'implementazione garantisce che un padre contiene sempre un valore minore dei propri figli ( a[k] < a[2k+1] e a[k]< a[2k+2]),

    Per induzione il k per cui si ha il valore minore è lo 0, la radice dell'albero.

     

    Per non incollare litri di codice ho scelto di pubblicare un'implementazione per RpgMaker Xp qui: http://www.rpg2s.net...showtopic=14772

     

    Quello che manca a questo script è del codice per utilizzarlo per altre azioni, ad esempio un Evento - omino che deve andare a tagliare la legna si potrebbe fare così:

     

    def taglia_albero(albero_x,albero_y)
    sx = @x - albero_x
    sy = @y - albero_y
    # Se è nelle caselle confinanti
    if sx == 0 and sy == 0
      #controlli che ci sia davvero un albero
      #chiami la funzione che tagli e animi il taglio
      return
    end
    dir = $mgraph.AStar(@x,@y,albero.x,albero.y)
    case dir
    when 1
      move_down
    when 2
      move_left
    when 3
      move_right
    when 4
      move_up
    else  # If no path is found
      # Get absolute value of difference
      abs_sx = sx.abs
      abs_sy = sy.abs
      # If horizontal and vertical distances are equal
      if abs_sx == abs_sy
    		# Increase one of them randomly by 1
    		rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
      end
      # If horizontal distance is longer
      if abs_sx > abs_sy
    		# Move towards player, prioritize left and right directions
    		sx > 0 ? move_left : move_right
    		if not moving? and sy != 0
    		  sy > 0 ? move_up : move_down
    		end
      # If vertical distance is longer
      else
    		# Move towards player, prioritize up and down directions
    		sy > 0 ? move_up : move_down
    		if not moving? and sx != 0
    		  sx > 0 ? move_left : move_right
    		end
      end
    end
    end

    L'unico difetto di questa funzione è che finisce che l'evento si muove sopra l'albero mentre vorresti una casella adiacente, inoltre l'algoritmo non funziona se (albero_x, albero_y) non è passabile, quindi devi prima cercare la casella libera adiacente e poi chiamare la funzione su quelle coordinate.

    C'è anche da implementare che una volta finito torni al campo base con le risorse, ma è molto facile una volta che hai definito tutte le variabili.

     

    Macchina a stati finiti

    Un aspetto che trovo affascinante è come gestire gruppi di persone, innanzi tutto come fai a trovare una persona che non fa nulla?

    Crei un Enum con tutte le azioni possibili

     

    class Lavoro
    DISOCCUPATO = 0
    FALEGNAME = 1
    MINATORE = 2
    end

     

    Ad ogni evento assegni un attributo che cambi quando gli assegni un compito e resetti quando lo finisce.

    @lavoro = Lavoro::DISOCCUPATO

     

    In questo modo per trovare una persona che non fa nulla scorri tutti gli eventi della tua fazione in cerca del primo disoccupato.

  9. Listra Pathfinding Module

    Descrizione

    Lo script implementa l'algoritmo di pathfinding A* in RGSS e modifica il Player affinché i comandi Move Towards Player e Autonomous Movement - Approach facciano uso di questo algoritmo, così l'evento può trovare la strada più veloce per avvicinarsi al giocatore.

    Utile per implementare battle system su mappa e per caterpillar system e con le opportune modifiche anche per creare un RTS.

     

    Autore

    Bunga Tepi Jalan (aka Listra)

     

    Istruzioni per l'uso

    Lo script è composto da due parti, la prima parte è il CORE formato da due classi, una Priority Queue ed un Map Graph.

    La Priority Queue serve ad immagazzinare i percorsi e a restituire quello a distanza minore, il Map Graph converte la mappa in un formato idoneo a eseguire l'algoritmo A - star. Per ulteriori dettagli ho scritto qualcosa in questo topic o potete chiedere :)

     

    #==============================================================================
    # Listra Pathfinder Module by Bunga Tepi Jalan
    # for RPG Maker XP
    # Version 1.0
    #==============================================================================
    #
    #									PART 1
    #
    #==============================================================================
    # Copyrighted by Bunga Tepi Jalan.
    #  * Don't forget to credit me if you want to use this work
    #  * You are free to Share - to copy, distribute and transmit the work
    #  * You are free to Remix - to adapt the work
    #  * You may not use this work for commercial purposes
    #
    # Credits
    #  Wikipedia
    #  Amit's A* Pages
    #
    #==============================================================================
    # Information:
    #  This script improves events' Autonomous Movement of type Approach
    #  such that they will perform smart pathfinding to move towards the player,
    #  by overriding predefined move_type_toward_player and
    #  move_toward_player methods in class Game_Character with pathfinding
    #  algorithm (either Dijkstra's or A*).
    #
    #  To learn about A* and Dijkstra's algorithm, visit the following articles:
    #	- http://en.wikipedia.org/wiki/Dijkstra's_algorithm
    #	- http://en.wikipedia.org/wiki/A*_search_algorithm
    #	- http://www-cs-students.stanford.edu/~amitp/gameprog.html
    #
    # If you find any bugs or you have any suggestions, please report them via
    # e-mail (listra92@gmail.com), or either my blog or these forums:
    #  - http://bungatepijalan.wordpress.com
    #  - http://www.rpgmakerid.com
    #  - http://prodig.forumotion.net
    #  - http://vixep.forumsrpg.net
    #==============================================================================
    
    #==============================================================================
    # ** PQueue
    #------------------------------------------------------------------------------
    #  This class, as derivation of Array, provides additional operations, such
    #  as insert and remove element such that the array behaves like a priority
    #  queue, and also search value in the array. This will be used on
    #  pathfinding algorithms in MGraph class.
    #==============================================================================
    
    class PQueue < Array
     #--------------------------------------------------------------------------
     # * Add Element, the result array will be always ordered ascendingly
     #	ii : element to be added into the array
     #--------------------------------------------------------------------------
     def addEl(ii)
    iii = 0
    while iii < self.length && self[iii] < ii
      iii += 1
    end
    self.insert(iii,ii)
     end
     #--------------------------------------------------------------------------
     # * Remove Element
     #	ii : element to be removed from the array, the result remains if
     #		  ii isn't found in the array
     #--------------------------------------------------------------------------
     def remEl(ii)
    iii = 0
    while iii < self.length && self[iii] < ii
      iii += 1
    end
    self.delete_at(iii)
     end
     #--------------------------------------------------------------------------
     # * Is Element Found?
     #	ii : element to be searched in the array (using binary search)
     #  Returns true if ii found in the array
     #--------------------------------------------------------------------------
     def found?(ii)
    i = 0
    j = self.length-1
    ff = false
    while (not ff) && i <= j
      mid = (i+j)/2
      if self[mid] == ii
    	ff = true
      else
    	if self[mid] < ii
    	  i = mid+1
    	else
    	  j = mid-1
    	end
      end
    end
    return ff
     end
    end
    
    #==============================================================================
    # ** MGraph
    #------------------------------------------------------------------------------
    #  This class generates a passage graph of given 2-dimensional map and uses it
    #  for pathfinding analysis with Dijkstra's algorithm and A*. Refer to
    #  "$mgraph" for the instance of this class.
    #==============================================================================
    
    class MGraph
     #--------------------------------------------------------------------------
     # * Public Instance Variables
     #--------------------------------------------------------------------------
     attr_accessor :w, :h
     attr_accessor :neighbors
     attr_accessor :passage_table
     #--------------------------------------------------------------------------
     # * Map Graph Initialization
     #--------------------------------------------------------------------------
     def initialize(nh)
    @w = $game_map.width
    @h = $game_map.height
    @neighbors = nh
    # Passage table for each map nodes
    @passage_table = Table.new(@w,@h,nh)
    for i in 0..@w
      for j in 0..@h
    	for k in 1..nh
    	  @passage_table[i,j,k-1] = $game_map.passable2?(i,j,k*2) ? 1 : 0
    	  if not neighborExist?(nodeOf(i,j),k)
    		@passage_table[i,j,k-1] = 0
    	  end
    	end
      end
    end
     end
     #--------------------------------------------------------------------------
     # * Node/Vertex Of
     #	x : x-position
     #	y : y-position
     #--------------------------------------------------------------------------
     def nodeOf(x,y)
    return y*@w+x+1
     end
     #--------------------------------------------------------------------------
     # * xNode, yNode
     #	idxNode : index of node
     #--------------------------------------------------------------------------
     def xNode(idxNode)
    return (idxNode-1)%@w
     end
     def yNode(idxNode)
    return (idxNode-1)/@w
     end
     #--------------------------------------------------------------------------
     # * Neighbor Of
     #	idxNode : index of node
     #	dir : down(1), left(2), right(3), or up(4)
     #  Returns index of adjacent node idxNode
     #--------------------------------------------------------------------------
     def neighborOf(idxNode,dir)
    case dir
      when 1
    	return (idxNode+@w)
      when 2
    	return (idxNode-1)
      when 3
    	return (idxNode+1)
      when 4
    	return (idxNode-@w)
    end
     end
     #--------------------------------------------------------------------------
     # * Is Neighbor Exist?
     #	idxNode : index of node
     #	dir : down(1), left(2), right(3), or up(4)
     #  Returns if adjacent node of idxNode exists
     #--------------------------------------------------------------------------
     def neighborExist?(idxNode,dir)
    case dir
      when 1
    	return (yNode(idxNode)<@h-1)
      when 2
    	return (xNode(idxNode)>0)
      when 3
    	return (xNode(idxNode)<@w-1)
      when 4
    	return (yNode(idxNode)>0)
    end
     end
     #--------------------------------------------------------------------------
     # * Reconstruct Path
     #	s : source node
     #	t : target node
     #	vertices_prev : map of navigated nodes
     #  Returns movement direction 1(down), 2(left), 3(right), or 4(up)
     #--------------------------------------------------------------------------
     def reconstruct_path(s,t,vertices_prev)
    u=t
    while vertices_prev[u] != s && vertices_prev[u] != 0
      u = vertices_prev[u]
    end
    case u
      when s+@w
    	return 1
      when s-1
    	return 2
      when s+1
    	return 3
      when s-@w
    	return 4
    end
    return 0
     end
     #--------------------------------------------------------------------------
     # * Heuristic Distance
     #	u : node 1
     #	v : node 2
     #--------------------------------------------------------------------------
     def heuristic_dist(u,v)
    dx = xNode(v)-xNode(u)
    dy = yNode(v)-yNode(u)
    # Manhattan distance heuristic
    return (dx.abs+dy.abs)
     end
     #--------------------------------------------------------------------------
     # * Dijkstra's Algorithm
     #	x1, y1 : source coordinate
     #	x2, y2 : target coordinate
     #  Returns movement towards target 1(down), 2(left), 3(right), or 4(up)
     #--------------------------------------------------------------------------
     def Dijkstra(x1, y1, x2, y2)
    # Initializations
    s = nodeOf(x1,y1)
    t = nodeOf(x2,y2)
    # Create open list q (as priority queue)
    q = PQueue.new(1,0)
    # Add s into open list q
    q.addEl(s)
    # Unknown distance function from source to v
    vertices_dist = Array.new(@w*@h+1,9999)
    # Previous node in optimal path from source
    vertices_prev = Array.new(@w*@h+1,0)
    # Distance from source to source
    vertices_dist[s] = 0
    # The main loop
    while q.length > 1
      # Finds vertex u with least value of path distance
      d = vertices_dist[q[1]]
    	 u = q[1]
    	 if q.length>2
    	for ii in 2..q.length-1
    		   if vertices_dist[q[ii]]<d
    			  d = vertices_dist[q[ii]]
    			  u = q[ii]
    		   end
    	end
    	 end
      # Search completed
      if u == t
    	return reconstruct_path(s,t,vertices_prev)
      end
      # Remove u from open list q
      q.remEl(u)
      for i in 1..@neighbors
    	if @passage_table[xNode(u),yNode(u),i-1] == 1
    	  v = neighborOf(u,i)
    	  alt = vertices_dist[u]+1
    	  if alt < vertices_dist[v]
    		# Relax (u,v)
    		q.addEl(v)
    		vertices_dist[v]=alt
    		vertices_prev[v]=u
    	  end
    	end
      end
    end
    return 0
     end
     #--------------------------------------------------------------------------
     # * A* Algorithm
     #	x1, y1 : source coordinate
     #	x2, y2 : target coordinate
     #  Returns movement towards target 1(down), 2(left), 3(right), or 4(up)
     #--------------------------------------------------------------------------
     def AStar(x1, y1, x2, y2)
    # Initializations
    s = nodeOf(x1,y1)
    t = nodeOf(x2,y2)
    # Create open list q (as priority queue)
    q = PQueue.new(1,0)
    # Add s into open list q
    q.addEl(s)
    # Create closed list q1, The list of nodes already evaluated.
    q1 = Array.new(@w*@h+1,false)
    # The map of navigated nodes.
    vertices_prev = Array.new(@w*@h+1,0)
    # Unknown distance function from source to v
    vertices_dist = Array.new(@w*@h+1,9999)
    h_score = Array.new(@w*@h+1,0)
    f_score = Array.new(@w*@h+1,9999)
    # Distance from source to source
    vertices_dist[s] = 0
    h_score[s] = heuristic_dist(s,t)
    f_score[s] = h_score[s]
    # The main loop
    while q.length > 1
      # Finds vertex u with least value of f_score
      d = f_score[q[1]]
    	 u = q[1]
    	 if q.length>2
    	for ii in 2..q.length-1
    		   if f_score[q[ii]]<d
    			  d = f_score[q[ii]]
    			  u = q[ii]
    		   end
    	end
    	 end
      # Search completed
      if u == t
    	return reconstruct_path(s,t,vertices_prev)
      end
      # Move current node from open list to the closed list
      q.remEl(u)
      q1[u] = true
      for i in 1..@neighbors
    	if @passage_table[xNode(u),yNode(u),i-1] == 1
    	  v = neighborOf(u,i)
    	  if !q1[v]
    		tentative_g_score = vertices_dist[u]+1
    		if !q.found?(v)
    		  q.addEl(v)
    		  tentative_is_better = true
    		elsif tentative_g_score < vertices_dist[v]
    		  tentative_is_better = true
    		else
    		  tentative_is_better = false
    		end
    		if tentative_is_better
    		  if vertices_prev[v] != 0
    			if f_score[u] < f_score[vertices_prev[v]]
    			  vertices_prev[v] = u
    			end
    		  else
    			vertices_prev[v] = u
    		  end
    		  vertices_dist[v] = tentative_g_score
    		  h_score[v] = heuristic_dist(v,t)
    		  f_score[v] = vertices_dist[v]+h_score[v]
    		end
    	  end
    	end
      end
    end
    return 0
     end
    end

     

     

    La Seconda parte è composta dalle modifiche al Player per automatizzare il movimento degli eventi, qui dovete stare attenti a non rompere la compatibilità con gli altri script!

     

    #==============================================================================
    # Listra Pathfinder Module by Bunga Tepi Jalan
    # for RPG Maker XP
    # Version 1.0
    #==============================================================================
    #
    #									PART 2
    #
    #==============================================================================
    # Copyrighted by Bunga Tepi Jalan.
    #  * Don't forget to credit me if you want to use this work
    #  * You are free to Share - to copy, distribute and transmit the work
    #  * You are free to Remix - to adapt the work
    #  * You may not use this work for commercial purposes
    #
    # Credits
    #  Wikipedia
    #  Amit's A* Pages
    #
    #==============================================================================
    # Information:
    #  This script improves events' Autonomous Movement of type Approach
    #  such that they will perform smart pathfinding to move towards the player,
    #  by overriding predefined move_type_toward_player and
    #  move_toward_player methods in class Game_Character with pathfinding
    #  algorithm (either Dijkstra's or A*).
    #
    #  To learn about A* and Dijkstra's algorithm, visit the following articles:
    #	- http://en.wikipedia.org/wiki/Dijkstra's_algorithm
    #	- http://en.wikipedia.org/wiki/A*_search_algorithm
    #	- http://www-cs-students.stanford.edu/~amitp/gameprog.html
    #
    # If you find any bugs or you have any suggestions, please report them via
    # e-mail (listra92@gmail.com), or either my blog or these forums:
    #  - http://bungatepijalan.wordpress.com
    #  - http://www.rpgmakerid.com
    #  - http://prodig.forumotion.net
    #  - http://vixep.forumsrpg.net
    #==============================================================================
    
    #==============================================================================
    # ** Game_Map (part 2 - overriden)
    #------------------------------------------------------------------------------
    #  This class handles the map. It includes scrolling and passable determining
    #  functions. Refer to "$game_map" for the instance of this class.
    #  This part overrides setup to use MGraph initialization and adds passable2?
    #  method to detect obstacles (excluding events).
    #==============================================================================
    
    class Game_Map
     #--------------------------------------------------------------------------
     # * Setup
     #	map_id : map ID
     #--------------------------------------------------------------------------
     def setup(map_id)
    # Put map ID in @map_id memory
    @map_id = map_id
    # Load map from file and set @map
    @map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
    # set tile set information in opening instance variables
    tileset = $data_tilesets[@map.tileset_id]
    @tileset_name = tileset.tileset_name
    @autotile_names = tileset.autotile_names
    @panorama_name = tileset.panorama_name
    @panorama_hue = tileset.panorama_hue
    @fog_name = tileset.fog_name
    @fog_hue = tileset.fog_hue
    @fog_opacity = tileset.fog_opacity
    @fog_blend_type = tileset.fog_blend_type
    @fog_zoom = tileset.fog_zoom
    @fog_sx = tileset.fog_sx
    @fog_sy = tileset.fog_sy
    @battleback_name = tileset.battleback_name
    @passages = tileset.passages
    @priorities = tileset.priorities
    @terrain_tags = tileset.terrain_tags
    # Initialize displayed coordinates
    @display_x = 0
    @display_y = 0
    # Clear refresh request flag
    @need_refresh = false
    # Set map event data
    @events = {}
    for i in @map.events.keys
      @events[i] = Game_Event.new(@map_id, @map.events[i])
    end
    # Set common event data
    @common_events = {}
    for i in 1...$data_common_events.size
      @common_events[i] = Game_CommonEvent.new(i)
    end
    # Initialize all fog information
    @fog_ox = 0
    @fog_oy = 0
    @fog_tone = Tone.new(0, 0, 0, 0)
    @fog_tone_target = Tone.new(0, 0, 0, 0)
    @fog_tone_duration = 0
    @fog_opacity_duration = 0
    @fog_opacity_target = 0
    # Initialize scroll information
    @scroll_direction = 2
    @scroll_rest = 0
    @scroll_speed = 4
    # Make MGraph
    $mgraph = MGraph.new(4)
     end
     #--------------------------------------------------------------------------
     # * Determine if Passable (ignoring events)
     #	x		  : x-coordinate
     #	y		  : y-coordinate
     #	d		  : direction (0,2,4,6,8,10)
     #				  *  0,10 = determine if all directions are impassable
     #--------------------------------------------------------------------------
     def passable2?(x, y, d)
    # If coordinates given are outside of the map
    unless valid?(x, y)
      # impassable
      return false
    end
    # Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
    bit = (1 << (d / 2 - 1)) & 0x0f
    # Loop searches in order from top of layer
    for i in [2, 1, 0]
      # Get tile ID
      tile_id = data[x, y, i]
      # Tile ID acquistion failure
      if tile_id == nil
    	# impassable
    	return false
      # If obstacle bit is set
      elsif @passages[tile_id] & bit != 0
    	# impassable
    	return false
      # If obstacle bit is set in all directions
      elsif @passages[tile_id] & 0x0f == 0x0f
    	# impassable
    	return false
      # If priorities other than that are 0
      elsif @priorities[tile_id] == 0
    	# passable
    	return true
      end
    end
    # passable
    return true
     end
    end
    
    #==============================================================================
    # ** Game_Character (part 4 - overriden)
    #------------------------------------------------------------------------------
    #  This class deals with characters. It's used as a superclass for the
    #  Game_Player and Game_Event classes.
    #  This part overrides move_type_toward_player and move_toward_player method to
    #  perform pathfinding with either Dijkstra's algorithm or A*.
    #==============================================================================
    
    class Game_Character
     #--------------------------------------------------------------------------
     # * Move Type : Approach (modified)
     #--------------------------------------------------------------------------
     def move_type_toward_player
    # Approach player
    move_toward_player
     end
     #--------------------------------------------------------------------------
     # * Move toward Player (modified)
     #--------------------------------------------------------------------------
     def move_toward_player
    # Get difference in player coordinates
    sx = @x - $game_player.x
    sy = @y - $game_player.y
    # If coordinates are equal
    if sx == 0 and sy == 0
      return
    end
    # Determines the movement towards player with pathfinding algorithm
    # Uncomment one of these statements to use either A* or Dijkstra's
    # algorithm.
    # Note that:
    #  - Dijkstra's algorithm is always accurate but lacks its performance.
    #	You should only use this algorithm for small maps.
    #  - A* algorithm is accurate but not as well as Dijkstra's algorithm.
    #	However, A* works much faster than Dijkstra's do. Recommended to
    #	use this, even for large maps.
    dir = $mgraph.AStar(@x,@y,$game_player.x,$game_player.y)
    #dir = $mgraph.Dijkstra(@x,@y,$game_player.x,$game_player.y)
    case dir
    when 1
      move_down
    when 2
      move_left
    when 3
      move_right
    when 4
      move_up
    else  # If no path is found
      # Get absolute value of difference
      abs_sx = sx.abs
      abs_sy = sy.abs
      # If horizontal and vertical distances are equal
      if abs_sx == abs_sy
    	# Increase one of them randomly by 1
    	rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
      end
      # If horizontal distance is longer
      if abs_sx > abs_sy
    	# Move towards player, prioritize left and right directions
    	sx > 0 ? move_left : move_right
    	if not moving? and sy != 0
    	  sy > 0 ? move_up : move_down
    	end
      # If vertical distance is longer
      else
    	# Move towards player, prioritize up and down directions
    	sy > 0 ? move_up : move_down
    	if not moving? and sx != 0
    	  sx > 0 ? move_left : move_right
    	end
      end
    end
     end
    end

  10. Non riesco ad aprire gli spoiler :|

    Non ci si deve rovinare la sorpresa XD

     

    Ho trovato problemi nella modifica di profilo, mancano le stringhe dei mesi della data di nascita.

    La funzione rispondi fatta su vecchi post è lentissima.

     

    Qualcuno diceva che il merito delle funzioni è da dare ad Html5 ma Html5 non c'entra nulla, è tutto grazie a javascript.

     

    Tra l'altro pur avendo dichiarato un doctype da html 5 i tag sono sbagliati, ad esempio andrebbe messo un:

    <meta charset="iso-8859-1" />

    invece di un xhtmlliano:

    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />

  11. L'Heroengine era una scelta troppo ambiziosa e ulteriormente spersonalizzante dopo il passaggio al 3d.

    Sono contento che fai un passo indietro e ti consiglio di far pace con il vecchio team.

    Il prezzo su steam è alto contando che stiamo parlando di un gioco amatoriale e ancora a carissimo amico.

    A me piaceva molto il concept in 2d

×
×
  • Create New...