Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #57 da revista programar. Faz já o download aqui!

NCPereira

Colisão de Grupo de Objetos

Mensagens Recomendadas

NCPereira    0
NCPereira

Olá pessoal. Sou novo aqui, registei-me para ver se me podiam dar uma ajudinha.

Sou novo em VB .net e estou a fazer um jogo de plataformas em 2D, visto de cima, que vai funcionar tipo um labirinto. Começo numa parte e tenho uma meta, tendo de percorrer o mapa.

Eu estou a programar a parte da colisão de objetos e deparei-me com uma questão.

Fiz várias PicturesBoxes, deixando uma para cada parede, e estava a pensar fazer um If para cada PictureBox, mas depois pensei se não seria possível eu conseguir juntar todas as PictureBoxes como se fossem um grupo, e com um só If ou Função conseguir tratar todos os casos, em vez de ter de fazer 10 Ifs.

Não quero fazer Arrays nem Fors nem Whiles para não tornar o programa pesado.

Não há uma maneira de tratar todos os casos assim rapidamente e facilmente?

O que eu estava a fazer era isto:

'posx e posy têm a posição da PicBox1 antes do movimento

'Movimento Aqui

If Me.PictureBox1.Bounds.IntersectsWith(Me.PictureBox2.Bounds) Then
            Me.PictureBox1.Location = New Point(posx, posy)
        End If

- Não queria ter de fazer 10 destas.

Obrigado desde já ;)

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
edmolko    3
edmolko

Se estás a pensar fazer um jogo de plataformas em 2D e não queres utilizar arrays nem ciclos, parece-me que nao vai sair daí grande jogo  ;)

Aconselho-te a ires ao google e pesquisares por XNA. Essa framework já traz muitos métodos utilizados em jogos (deteção de colisões, etc.), não vale a pena estares a inventar a roda.  :thumbsup:

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
NCPereira    0
NCPereira

Não sei se percebes-te bem o que eu queria dizer, não é 2D visto de lado, tipo Mario, é visto de cima, tipo labirinto.

E quanto aos arrays e ciclos, eu tinha pensado em fazer assim, mas disseram-me que assim o programa ia ficar pesado, e mais valia tentar arranjar uma função ou evento que conseguisse tratar todos os casos mais facilmente.

Vou deixar aqui uma imagem do layout do jogo (Está com buttons porque era só um teste, vou fazer depois com PicBoxs):

280ulok.png

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
ribeiro55    44
ribeiro55

Fazer ciclos torna o programa pesado, e alinhar 10000 testes lógicos não? ;)

10000 testes lógicos, ou um ciclo com um teste lógico que sofra 10000 iterações é a mesma coisa... quer dizer, não é a mesma coisa porque o programa com o ciclo vai ocupar muito menos espaço, mas em termos de processamento é igual.

Para o teu problema, se colocares todas as paredes numa colecção, por exemplo uma List(Of Button) (para atender à imagem exemplo que anexaste no post anterior), podes iterar todos os obstáculos e executar apenas um set de verificações por cada um.

Bastaria depois:

        For Each obstaculo As Button In Paredes
            'testar colisão com jogador
        Next

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
edmolko    3
edmolko

Não sei se percebes-te bem o que eu queria dizer, não é 2D visto de lado, tipo Mario, é visto de cima, tipo labirinto.

O que é que te fez pensar que eu percebi que era 2D visto de lado?  :hmm:

Bem, o XNA que te referi dá para qualquer tipo de perspetiva (tanto em 2D como em 3D), visto de cima, visto de lado, visto de onde queiras.

Além disso em 2D penso que não existe essa distinção, se o jogo é visto de cima ou de lado depende da forma como os elementos são desenhados e dos movimentos que eles suportam.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
NCPereira    0
NCPereira

Fazer ciclos torna o programa pesado, e alinhar 10000 testes lógicos não? ;)

10000 testes lógicos, ou um ciclo com um teste lógico que sofra 10000 iterações é a mesma coisa... quer dizer, não é a mesma coisa porque o programa com o ciclo vai ocupar muito menos espaço, mas em termos de processamento é igual.

Para o teu problema, se colocares todas as paredes numa colecção, por exemplo uma List(Of Button) (para atender à imagem exemplo que anexaste no post anterior), podes iterar todos os obstáculos e executar apenas um set de verificações por cada um.

Bastaria depois:

        For Each obstaculo As Button In Paredes
            'testar colisão com jogador
        Next

Pois, eu já comecei a fazer o programa definitivo e estou a nomear as paredes de wall1, wall2 ... etc. Acho que vou fazer um while. Achas que é a melhor opção? Não seria talvez melhor que criar esse grupo? Quanto ao tamanho do programa o ciclo é a melhor opção? Há maneira de fazer de outra forma que aumente o desempenho, diminuindo o processamento?

vê um pouco desta teoria www.vbweb.com.br/download.asp?Download=Apostilas&CodigoLink=147

(vai aparecer logo a janela para fazeres o download do documento word)

espero que ajude alguma coisa

Obrigado, realmente está interessante, mas no fim já começa a falar de coisas mais complicadas que acho que ainda não estou pronto xP

O que é que te fez pensar que eu percebi que era 2D visto de lado?  :hmm:

Bem, o XNA que te referi dá para qualquer tipo de perspetiva (tanto em 2D como em 3D), visto de cima, visto de lado, visto de onde queiras.

Além disso em 2D penso que não existe essa distinção, se o jogo é visto de cima ou de lado depende da forma como os elementos são desenhados e dos movimentos que eles suportam.

Pois, também não sei xP

Mas acho que isso não vai dar para mim, eu ainda percebo mesmo muito pouco de programação, estou a começar, e também eu este trabalho é para um projeto, que depois irei apresentar a um juri, estou no 11º ano, tenho 16 anos. Mas muito obrigado.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
NCPereira    0
NCPereira

Muito muito obrigado a todos, já resolvi o problema. Caso alguém queira saber, fiz assim:

Public Class level1

    Public posx, posy As Integer
    Public walls(13) As PictureBox



    Private Sub level1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown, player.KeyDown

        ' _________________________________________
        '|                                         |
        '| SAVES PLAYER'S LOCATION BEFORE MOVEMENT |
        '|_________________________________________|

        posx = Me.player.Location.X
        posy = Me.player.Location.Y



        ' _________________
        '|                 |
        '| PLAYER MOVEMENT |
        '|_________________|

        If e.KeyCode = Keys.W Then
            Me.player.Location = New Point(Me.player.Location.X, Me.player.Location.Y - 40)
        End If

        If e.KeyCode = Keys.A Then
            Me.player.Location = New Point(Me.player.Location.X - 40, Me.player.Location.Y)
        End If

        If e.KeyCode = Keys.S Then
            Me.player.Location = New Point(Me.player.Location.X, Me.player.Location.Y + 40)
        End If

        If e.KeyCode = Keys.D Then
            Me.player.Location = New Point(Me.player.Location.X + 40, Me.player.Location.Y)
        End If



        ' _________________________
        '|                         |
        '| WALL COLISION DETECTION |
        '|_________________________|

        'MAIN WALLS

        If Me.player.Bounds.IntersectsWith(Me.walltop.Bounds) Then
            Me.player.Location = New Point(posx, posy)
        End If

        If Me.player.Bounds.IntersectsWith(Me.wallbottom.Bounds) Then
            Me.player.Location = New Point(posx, posy)
        End If

        If Me.player.Bounds.IntersectsWith(Me.wallleft.Bounds) Then
            Me.player.Location = New Point(posx, posy)
        End If

        If Me.player.Bounds.IntersectsWith(Me.wallright.Bounds) Then
            Me.player.Location = New Point(posx, posy)
        End If


        'MIDDLE WALLS

        Dim i As Integer

        For i = 1 To 13

            If Me.player.Bounds.IntersectsWith(Me.walls(i).Bounds) Then
                Me.player.Location = New Point(posx, posy)
            End If

        Next



        ' ________________________
        '|                        |
        '| MOB COLISION DETECTION |
        '|________________________|

        If Me.player.Bounds.IntersectsWith(Me.mob1.Bounds) Then
            Me.player.Location = New Point(40, 40)
        End If

        If Me.player.Bounds.IntersectsWith(Me.mob2.Bounds) Then
            Me.player.Location = New Point(40, 40)
        End If

        If Me.player.Bounds.IntersectsWith(Me.mob3.Bounds) Then
            Me.player.Location = New Point(40, 40)
        End If



        ' ___________________________
        '|                           |
        '| PORTAL COLISION DETECTION |
        '|___________________________|

        If Me.player.Bounds.IntersectsWith(Me.portal.Bounds) Then
            Me.player.Location = New Point(360, 440)
        End If



        ' _________________________
        '|                         |
        '| GOAL COLISION DETECTION |
        '|_________________________|

        If Me.player.Bounds.IntersectsWith(Me.goal.Bounds) Then
            MsgBox("CONGRATULATIONS!")
            Me.player.Location = New Point(40, 40)
        End If



    End Sub



    Sub fill_wall_array()

        ' ________________________________
        '|                                |
        '| FILLS THE ARRAY WITH THE WALLS |
        '|________________________________|

        Dim i As Integer


        For i = 1 To 13

            Dim x As PictureBox
            x = New PictureBox


            x = Me.Controls.Find("wall" & i, True)(0) 'FINDS OBJECTS WITH THAT NAME - (0) FOR FIRST POSITION
            walls(i) = x

        Next


    End Sub



    Private Sub level1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Me.player.Focus()

        fill_wall_array()

    End Sub


End Class

LAYOUT:

1fvmds.png

Muito obrigado outra vez :)

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora


×

Aviso Sobre Cookies

Ao usar este site você aceita a nossa Política de Privacidade