Un piccolo serpente ci conduce attraverso le principali caratteristiche del Windows Phone 7
Introduzione Core UI & Design Conclusione Premi Discussioni
Marcosroom.it Didatticando

Serpenti nemici

In verità, c'è un ultimo aspetto del gioco del quale non ho ancora parlato: i serpenti nemici. Se ci fai caso, alcuni si muovono casualmente, e altri puntano direttamente al cibo. Per risolvere questo problema, ho creato un'interfaccia che contiene le azioni che il serpente nemico deve fare:

IEnemySnake interface

Come puoi vedere, ci sono solo 3 metodi e una proprietà: la proprietà è l'oggetto Level che contiene il serpente nemico, e deve essere impostata con priorità assoluta. Reset ha il compito di reimpostare i campi privati per riportare il serpente allo stato iniziale; Cut, invece, taglia il serpente nella cella data.

La parte più interessante è il metodo Move: come dice il nome, questo metodo fa muovere il serpente, e qui si differenziano i due tipi di serpente (quello che si muove casualmente, e quello alla ricerca del cibo). Il RandomlyMovingSnake è il più semplice, perchè si muove senza alcuno scopo logico, e, per questo, non ne parleremo. Al contrario, spiegheremo il FoodCatcherSnake, poichè è più complesso del primo, e a noi non ci piacciono le cose semplici, giusto? :P

Questo serpente deve puntare direttamente alle celle cibo. Ma... ma... come trovare la strada? Cercando su Google qualche algoritmo di path finding, ho trovato moltissime implementazioni dell'algoritmo A* (davvero impressionante, ne dovresti vedere uno in azione!), ma erano troppo per ciò di cui avevo bisogno! Fortunatamente, dopo qualche altra ricerca ho trovato questo. L'unica cosa che ho modificato è il valore di ritorno della funzione FindPath da int[,] a IEnumerable<Point>, nient'altro. (Ti consiglio di leggere l'articolo sul MazeSolver, altrimenti, potresti non comprendere a pieno le successive spiegazioni)

Nel cotruttore inizializziamo il MazeSolver impostando i muri, cioè le celle con la proprietà CellType impostata a Wall o DeathFood. Nel metodo Move, invece, utilizziamo il MazeSolver per trovare il percorso da seguire:

//Controlla se il percorso deve essere ricalcolato
if (_pathToFollow.Count() == 0 ||
    _cells[(int)_pathToFollow.PeekLast().X, (int)_pathToFollow.PeekLast().Y].CellType != CellType.Food) {
                
    //Aggiorna la lista i tutte le celle cibo
    List<point> lst = new List<point>();
    for (int x = 0; x < _gridSize.Width; x++)
        for (int y = 0; y < _gridSize.Height; y++)
            if (_cells[x, y].CellType == CellType.Food)
                lst.Add(new Point(x, y));
    _foodCells = lst;

    //Controlla che ci sia del cibo da mangiare
    if (_foodCells.Count() == 0) throw new Exception();
                
    //Trova il cibo più lontano
    Point furthestFood = _foodCells.OrderBy<point,>(x => Math.Abs((int)x.X) + Math.Abs((int)x.Y)).First();

    //Rende tutti i segmenti della coda del serpente muri
    _snakeQueue.ForEach(x => _mazeSolver[Grid.GetColumn(x), Grid.GetRow(x)] = 1);
    _mazeSolver[Grid.GetColumn(head), Grid.GetRow(head)] = 0;

    //Trova il percorso da seguire
    _pathToFollow = new Queue<point>(
        _mazeSolver.FindPath(
            Grid.GetColumn(head),
            Grid.GetRow(head),
            (int)furthestFood.X,
            (int)furthestFood.Y
        ).Skip(1)
    );
                
    //Rimuove i muri dalla coda del serpente
    _snakeQueue.ForEach(x => _mazeSolver[Grid.GetColumn(x), Grid.GetRow(x)] = 0);

    //Controlla che sia stato trovato un percorso
    if (_pathToFollow.Count == 0) return;

}

Se è necessario trovare un nuovo percorso, prima crechiamo, tutte le celle che contengono cibo, poi, troviamo il più lontano, e memorizziamo il percorso in una Queue<Point>. Ad ogni chiamata del metodo Move, prendiamo un elemento da questa coda e spostiamo il serpente a quelle coordinate.

 

Condividi
Indietro Tutti i webmaster che volessero segnalare, non copiare,
il contenuto di questa pagina sul proprio sito, possono farlo liberamente.
E' gradito un preavviso tramite mail all'autore e l'iserimento,
nella pagina di citazione, di un link verso la pagina corrente.
© Copyright    Marco's Room
Avanti
Download SnakeMobile

Scaricato 115 volte

Celle IoC (Inversione di controllo) Un contenitore per Windows Phone 7 Controller di movimento Obiettivi Livelli Serpenti nemici Salvataggio e caricamento dei livelli