SoloCodigo

Programación General => Visual Basic 6.0 e inferiores => Mensaje iniciado por: viktor479 en Lunes 25 de Octubre de 2010, 05:06

Título: Mover picturebox y que se detenga en un shape para laberinto
Publicado por: viktor479 en Lunes 25 de Octubre de 2010, 05:06
Hola recien estoy aprendiendo a realizar proyectos en visual basic 6.0 para el estudio y debo hacer un laberinto de momento esto es lo que tengo pensado hacer:
Un picturebox que se mueva con las teclas de direccion y que cada vez que se encuentre con shape este se detenga asi hasta encontrar la salida.
ya encontre la forma de mover el picturebox con las teclas pero ahora el problema es que se detenga al encontrase con un shape para tomar una nueva direcion ya que de momento se encuentra con un shape y pasa por encima como coorijo esto. me gustaria que me dieran una orientacion sobre cual es la mejor forma para hacerlo.
Muchas Gracias.
Este es el codigo:


Private Sub Form_Load()

End Sub

Private Sub Picture1_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode

'Movimiento

Case vbKeyUp

Picture1.Top = Picture1.Top - 10

Case vbKeyDown

Picture1.Top = Picture1.Top + 10

Case vbKeyLeft
Picture1.Left = Picture1.Left - 10

Case vbKeyRight

Picture1.Left = Picture1.Left + 10

End Select
End Sub

Aqui la imagen=>h-ttp://i53.tinypic.com/95pj0z.jpg
Título: Re: Se debe crear un matriz Mapa() de 2 dimensiones
Publicado por: Nebire en Lunes 25 de Octubre de 2010, 17:11
Primero tienes que dividir el laberinto en 'casillas lógicas', así si te mueves de 10 en 10, es de suponer que un bloque de 10x10 es una casilla y que por tanto con cada movimiento se avanza a la casilla adhyacente (si está libre)...

Estando entonces tu laberinto fijado en casillas de xCasillas de ancho x yCasillas de alto, entonces todo lo que tienes que hacer es fijar el obstáculo deseado/s deseado/s (utilizas una matriz de 2 dimensiones luego te explico). Así una variable Obstaculo de tipo punto, señala la casilla que ocupa el obstáculo. Ahora tu antes de cada movimiento de casilla, debes verificar si se está en una casilla de obstáculo, y si está decidir que ocurre en tal situación...

La matriz obstáculo es la propia matriz del contenido del laberinto, o puedes tener 2... un simple código que te ilustre como se crea y se usa...

Código: Visual Basic
  1.  
  2. public enum TiposDeCasilla
  3.      CASILLA_LIBRE = 0  ' son las casillas por donde se puede mover libremente.
  4.      CASILLA_PARED = 1 ' son casillas que impien que se pueda mover en esa dirección y que marcan claramente el laberinto.
  5.      CASILLA_OBSTACULO = 2 '  son casilas que se comportan como una pared y que requieren cierta acción conocida para acceder a su interior (por ejemplo recoger un objeto dentro del laberinto
  6.      CASILLA_PASADIZO_OCULTO = 3 ' es una pared, pero que en determinada situación se comporta como una casilla libre o como una pared
  7.      CASILLA_PUERTA = 4 ' una o varias casilas pueden ser elpunto de salida  del laberinto y la entrada a otro laberinto
  8.      CASILLA_TESORO = 5 ' una o más casillas pueden representar un tesoro que esdeseable recoger y da puntos.
  9.      CASILA_META = 6 ' una o más casillas puede ser el objeto final perseguido en el laberinto.
  10. end enum
  11.  
  12. private  Mapa(0 to 24, 0 to 24) as TiposDecasilla  ' define un mapa de 25x25 casillas
  13. private Mx as byte ' casilla actual del Mapa en la cordenada X
  14. private My as byte ' casila actual del Mapa en la cordenada Y
  15. private cX as byte  ' casilla propuesta para moverse a ella en el eje X
  16. private cY as byte  ' casilla propuesta para moverse a ella en el eje Y
  17.  
  18. private sub CrearMapaParcial(byval Casillas() as byte)
  19.      dim x as byte, y as byte, n as integer
  20.  
  21.      for y =0 to 24
  22.           for x =0 to 24
  23.                  Mapa(x,y)=casillas(n)
  24.                  n=n +1
  25.           next
  26.     next
  27. end Sub    
  28.  
  29. private sub CrearMapa
  30.    dim c(0 to 624) as byte
  31.    dim tc as TiposDeCasilla
  32.  
  33.   ' fija las paredes del laberinto, para ello recorre la matriz casillas, el método para decidir las paredes según tu creas o uses...
  34.   tc=   CASILLA_PARED
  35.   c(20)=tc: c(120)=tc
  36.    for k= 50 to 80
  37.        c(k)=tc
  38.    next
  39.    call CrearMapaParcial(c)
  40.  
  41.    ' procedemos de modo similar para marcar las casillas restantes del tipo que se desee, por ejemplo marquemos ahora las puertas
  42.    erase c   ' borramos el contenido previo de la matriz estática 'c()'
  43.    tc = CASILLA_PUERTA
  44.     c(22)=tc : c(424)= tc : c(375)= tc: c(615) = tc    ' marcamos 4 puertas sobre el mapa
  45.    call CrearMapaParcial(c)  ' añadimos las puertas al mapa
  46. End Sub
  47.  
  48. Private Sub Picture1_KeyDown(KeyCode As Integer, Shift As Integer)
  49.     'Movimiento .. mejor: ¿ puedo moverme ahí ?
  50.     Select Case KeyCode
  51.          Case vbKeyUp
  52.             cX = MX  : cY = My - 1
  53.             If CasillaLibre(cx,cy)=true then
  54.                   Picture1.Top = Picture1.Top - 10
  55.                   mX= cx: My=cY  ' la casilla  propuesta a ser ocupada es ahora la actual, la ocupada
  56.             else
  57.                beep
  58.             end if
  59.         Case vbKeyDown
  60.             cX = MX  : cY = My + 1
  61.             If CasillaLibre(cx,cy)=true then
  62.                 Picture1.Top = Picture1.Top + 10
  63.                 mX= cx: My=cY  ' la casilla  propuesta a ser ocupada es ahora la actual, la ocupada
  64.            else
  65.                beep
  66.            end if
  67.         Case vbKeyLeft
  68.             cX = MX - 1  : cY = My
  69.             If CasillaLibre(cx,cy)=true then
  70.                 Picture1.Left = Picture1.Left - 10
  71.                 mX= cx: My=cY  ' la casilla  propuesta a ser ocupada es ahora la actual, la ocupada
  72.             else
  73.                beep
  74.             end if
  75.         Case vbKeyRight
  76.             cX = MX + 1 : cY = My
  77.             If CasillaLibre(cx,cy)=true then
  78.                 Picture1.Left = Picture1.Left + 10
  79.                 mX= cx: My=cY  ' la casilla  propuesta a ser ocupada es ahora la actual, la ocupada
  80.             else
  81.                beep
  82.             end if
  83.     End Select
  84. End Sub
  85.  
  86. '  determina que se debe hacer al pretender ocupar dicha casilla y aparte devuelve si la casilla es ocupable o no.
  87. private Function CasillaLibre(byval X as byte, byval Y as byte) as boolean  
  88.        select case Mapa(x,y)
  89.               case CASILLA_LIBRE  ' se puede mover a dicha casilla, y no hace nada más
  90.                   CasillaLibre = True
  91.               case CASILLA_PARED = 1 ' no se puede mover y no hace nada más
  92.                   exit function
  93.               case CASILLA_OBSTACULO = 2 '  si se tiene un objeto recogido del mapa es libre puede ser cruzada aunque se vea como pared. si no, no
  94.                  CasillaLibre = Obstaculos(25) ' si previamente visitamos la casilla 25, (y=0, x=24) allí había un objeto (llave) que permite atravesar el obstáculo.
  95.               case CASILLA_PASADIZO_OCULTO = 3 ' a diferencia de obstáculo, es oculto porque no se dibuja de manera especial (como ocurre con abstáculo), sino como pared
  96.                   ' si la condición exigida se cumple casillalibre=true, si no false... normalmente si la condición se cumple, en dicho instante que se cumpla podría
  97.                   '   abrirse un hueco en la pared, dejando entonces vía libre de acceso... es decir en ese momento un tramo marcado como pared es marcado como libre y dibujado como libre...
  98.                  ' en un pasadizo oculto puede haber tesoros extras, no visibles hasta entonces.
  99.               case CASILLA_PUERTA = 4 ' una o varias casilas pueden ser elpunto de salida  del laberinto y la entrada a otro laberinto
  100.                      call CambiarDeMapa(x,y) ' accedemos a otra 'sala' otro mapa, debemos guardar el mapa actual antes de cargar el nuevo mapa, el punto de entrada son las cordenadas de salida de éste...
  101.                      CasillaLibre = True
  102.               case CASILLA_TESORO = 5 ' esta casilla contiene un objeto (para el caso, simplificamos a tener una ''lave de activación'' de un obstáculo...
  103.                   Obstaculos((y* 25) + x)=true  ' se ha recogido un tesoro en la casilla, en este caso simplemente habilita un obstaculo....
  104.                   ' call RetirarTesoroDelMapa(x,y)  
  105.                   CasillaLibre = True
  106.                case CASILA_META = 6    
  107.                    Call ContarPuntuacion
  108.                    call FinPartida
  109.                    End
  110.         end select
  111. end functon
  112.  
  113.  

El código sólo está a medias, es trabajo tuyo la elaboración completa, yo sólo te doy las sugerencias necesarias para hacer algo interesante...
Podrás ver que he modificado tu rutina de movimiento, de entrada no muevo, 1º consulto que hay en dicha casilla, es decir que tipo de casilla es, si es 'pasillo libre, simplemente significa que puedo avanzar y no ocurre nada, si es una pared, no puedo moverme a ella (podrías hacer sonar un beep), pero una casilla puede además ser otras cosas, tantas como queramos, yo  te he propuesto sólo algunas de las más frecuentes... puerta hacia otros mapas, casilla de un tesoro, casilla que representa un obstáculo (como una puerta dentro del mapa) que requere aventurarse a recoger las llaves que permiten abrirla y traspasarla) y también una parte oculta, (un pared que forma un cuadrado cerrado puede ser algo inaccesible o puede ser una cámara oculta de la que no se conoce la puerta y tal vez tampoco la forma o condición para entrar (podría por ejemplo activarse sólo si hasta el momento se ha recogido x tesoros, puntos, o bien si se cruzó cierto pasillo o se pasó por una casilla específica, podrías hacer casillas de daño y determinar que si el daño llega a cierto valor termina la partida , pero si hay daños tienes que ofrecer también su complementario, casillas de cura para recuperar salud.... en fin es cuestión de imaginación.

Fíjate que lo 1º que debe hacerse al iniciar una partida es crear el mapa, ahí tu debes decidir  que casilla son de pared, cuales libres, etc... en el ejemplo se ha utilizado una rutina parcial que va rellenando el mapa, esto no es óptimo, pero se hace así, para que te quede claro que debe procederse con orden, primero marca las paredes,  el resto de entrada queda libre, porque el resto de tipos de casillas pueden requerir saber de antemano si una casilla es libre o es pared, para determinar si puede ponerse allí un tesoro, por ejemplo, un tesoro lógicamente sólo puede estar en una casilla libre, sobre la pared, además de no visible es inaccesible, pero por ejemplo una puerta, puede situarse indistintamente sobre una casilla libre o sobre una casilla de pared, pero una puerta oculta sólo puede situarse sobre una sailla de pared. ....cámaras ocultas y obstáculos deben recaer sobre paredes, así mismo, las puertas de salida a otras salas, pueden rescribir una pared como una puerta, pero obviamente debe haber camino libre de acceso a la puerta... Puedes tener una rutina de creación automática de laberintos (es lo deseable) o puedes inicialmente crearlos manualmente y guardarlos a disco, sería simplemente escribir a fichero 625 bytes, que indican que son cada casilla y leerlos tras cargar el programa y dar a elegir 1 de entre varios mapas, una vez que te familiarices en la forma de crear mapas, debería serte asequible crearlos de modo automático...

Lógicamente aparte de tener un mapa requiere dibujarlo, luego necesitamos un icono (imagen) por cada tipo de casilla, un objeto oculto, podría tener inicialmente la imagen de una pared u otro objeto y tras ser recogido-descubierto cambiar su imagen a la propia que define el objeto.

Lo importante para tu cuestión, fíjate que el laberinto, más que gráfico se apoya completamente en una matriz que tiene tantas casillas como queramos de ancho y alto, es decir la info del mapa consta totalmente en esta matriz, y adicionalmente se pueden requerir alguna matriz más para por ejemplo llevar la cuenta de tesoros recogidos, de trampas abiertas, cámaras ocultas, abiertas o aún ocultas... estas matrices en vez de tener una mapa del mismo tamaño que el mapa basta que sea una matriz con tantos elementos como objetos deesta naturaleza tenga... un buen modo de representarlos es utilizar una matriz de integer, por ejmplo si tenemos 10 tesoros podríamos tener una variable Tesoros(0 to 9) as integer... cada elemento tiene el nº de casilla que contiene el tesoro, por ejemplo Tesoro(3)= 231, indica que el tesoro 3 está en la casilla 231... esto se monta y desmonta traduciendo una matriz bidimensional a unidimensional y viceversa; desmontar:  y= 23125=  9; x= (231 mod 25) ; ahoramontar unidimensional: Kasilla= (y*25) + x = (9*25) + 6 = 231. De tal forma que cuando el tesoro aún no ha sido cogido el valor puede ser positivo y si fue cogido, descubierto se cambia a negativo. También puede omitirse si una vez descubierto-cogido,etc... ya no tiene representación en el mapa (1 sólo uso), en cuyo caso tras coger el tesor, abrir una puerta (que ya no se cierra más), lo mejor es cambiar el mapa, es decir rescribir la casilla del mapa que antes tenía un tesoro ahora se marca libre, si había una puerta 8pared), ahora se marca libre ...

Es cosa de tu ingenio y un poco de trabajo... tienes la base. No tengo tiempo para extenderme en exceso, pero si tienes alguna duda, concreta y exponla...
Título: Re: Mover picturebox y que se detenga en un shape para laberinto
Publicado por: viktor479 en Martes 26 de Octubre de 2010, 03:47
Excelente muchas muchas Gracias esta era la orientación que necesitaba, me pondré a trabajar en el código y el formulario.
Mas adelante te comentare mis avances o inquietudes.
Gracias.
 :good:  :good:  :good:  :good:  :good:  :good: