欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Golang編寫貪吃蛇游戲

 更新時間:2023年07月28日 16:59:49   作者:LeoForBest  
這篇文章主要為大家學習介紹了Golang如何基于終端庫termbox-go做個功能較簡單的貪吃蛇游戲,文中的示例代碼講解詳細,具有一定的學習價值

基于終端庫termbox-go做了個貪吃蛇游戲, 功能較簡單,代碼約160行左右

一:原理介紹

1. 繪制原理

存儲好蛇身和食物坐標都存儲在Snake結構中

定時300毫秒執(zhí)行移動蛇身/生成食物,然后清空終端再重新根據坐標繪制點●

達到模擬動畫效果

type Location struct {
	X int
	Y int
}
type Snake struct {
	Body      []Location
	Food      Location
	......
}
func Draw(s *Snake) {
	termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
	for _, location := range s.Body {
		termbox.SetCell(location.X, location.Y, '●', termbox.ColorGreen, termbox.ColorDefault)
	}
	termbox.SetCell(s.Food.X, s.Food.Y, '●', termbox.ColorRed, termbox.ColorDefault)
	termbox.Flush()
}

2.貪吃蛇移動過程

原理很簡單,根據當前行走方向,追加一個點到[]Localtion如果蛇頭位置不是食物位置,刪除[]Localtion第一個點, 添加一個點(最后一個點位置+1)相當于行走了

如果恰好是食物位置,添加一個點(最后一個點位置+1),再隨機生成食物

// 移動一步, 如果碰壁返回false, 否則返回true
func (s *Snake) Move() bool {
	head := s.GetHead()
	switch s.Direction {
	case DIRECTION_UP:
		s.Body = append(s.Body, Location{head.X, head.Y - 1})
	case DIRECTION_DOWN:
		s.Body = append(s.Body, Location{head.X, head.Y + 1})
	case DIRECTION_LEFT:
		s.Body = append(s.Body, Location{head.X - 1, head.Y})
	case DIRECTION_RIGHT:
		s.Body = append(s.Body, Location{head.X + 1, head.Y})
	}
	head = s.GetHead()
	// 蛇頭到達食物位置時標記食物已吃,并且追加到蛇尾(s.Body[0]不用剔除, 否則剔除)
	if head == s.Food {
		s.FoodEated = true
		s.RandomFood()
		s.Score += 10
	} else {
		s.Body = s.Body[1:]
	}
	return 0 <= head.X && head.X <= s.MaxX && 0 <= head.Y && head.Y <= s.MaxY
}

3.生成食物過程

僅需要注意是否生成在蛇身本身,是的話再生成

// 判斷生成的食物坐標是否在蛇身上
func (s *Snake) isFoodInSnake(location Location) bool {
	for _, l := range s.Body {
		if l == location {
			return true
		}
	}
	return false
}
// 生成食物
func (s *Snake) RandomFood() {
	w, h := termbox.Size()
	// 上下兩邊留點空隙
	location := Location{rand.Intn(w-10) + 5, rand.Intn(h-10) + 5}
	for s.isFoodInSnake(location) {
		location = Location{rand.Intn(w), rand.Intn(h)}
	}
	s.Food = location
}

4.效果

二:完整代碼

package main
import (
	"fmt"
	"math/rand"
	"time"
	"github.com/nsf/termbox-go"
)
const (
	DIRECTION_LEFT int = iota
	DIRECTION_RIGHT
	DIRECTION_UP
	DIRECTION_DOWN
)
type Location struct {
	X int
	Y int
}
type Snake struct {
	Body      []Location
	Food      Location
	FoodEated bool
	Direction int
	MaxX      int
	MaxY      int
	Score     int
}
// 獲取蛇頭位置
func (s *Snake) GetHead() Location {
	return s.Body[len(s.Body)-1]
}
// 移動一步, 如果碰壁返回false, 否則返回true
func (s *Snake) Move() bool {
	head := s.GetHead()
	switch s.Direction {
	case DIRECTION_UP:
		s.Body = append(s.Body, Location{head.X, head.Y - 1})
	case DIRECTION_DOWN:
		s.Body = append(s.Body, Location{head.X, head.Y + 1})
	case DIRECTION_LEFT:
		s.Body = append(s.Body, Location{head.X - 1, head.Y})
	case DIRECTION_RIGHT:
		s.Body = append(s.Body, Location{head.X + 1, head.Y})
	}
	head = s.GetHead()
	// 蛇頭到達食物位置時標記食物已吃,并且追加到蛇尾(s.Body[0]不用剔除, 否則剔除)
	if head == s.Food {
		s.FoodEated = true
		s.RandomFood()
		s.Score += 10
	} else {
		s.Body = s.Body[1:]
	}
	return 0 <= head.X && head.X <= s.MaxX && 0 <= head.Y && head.Y <= s.MaxY
}
// 判斷生成的食物坐標是否在蛇身上
func (s *Snake) isFoodInSnake(location Location) bool {
	for _, l := range s.Body {
		if l == location {
			return true
		}
	}
	return false
}
// 生成食物
func (s *Snake) RandomFood() {
	w, h := termbox.Size()
	// 上下兩邊留點空隙
	location := Location{rand.Intn(w-10) + 5, rand.Intn(h-10) + 5}
	for s.isFoodInSnake(location) {
		location = Location{rand.Intn(w), rand.Intn(h)}
	}
	s.Food = location
}
func Draw(s *Snake) {
	termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
	for _, location := range s.Body {
		termbox.SetCell(location.X, location.Y, '●', termbox.ColorGreen, termbox.ColorDefault)
	}
	termbox.SetCell(s.Food.X, s.Food.Y, '●', termbox.ColorRed, termbox.ColorDefault)
	termbox.Flush()
}
func main() {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()
	w, h := termbox.Size()
	// 初始給它三個長度吧, 太小不好看
	snake := Snake{
		Body:      []Location{{0, 0}, {1, 0}, {2, 0}},
		Direction: DIRECTION_RIGHT,
		MaxX:      w,
		MaxY:      h,
		FoodEated: false,
	}
	snake.RandomFood()
	Draw(&snake)
	event_queue := make(chan termbox.Event)
	go func() {
		for {
			event_queue <- termbox.PollEvent()
		}
	}()
	gameFinished := false
	msgPrinted := false
	msg := `\n
*****************************************
		Game Over !
		Score: %d
		Press Esc to exit!
*****************************************
`
loop:
	for {
		select {
		case ev := <-event_queue:
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEsc {
				break loop
			} else if ev.Type == termbox.EventKey {
				switch ev.Key {
				case termbox.KeyArrowUp:
					snake.Direction = DIRECTION_UP
				case termbox.KeyArrowDown:
					snake.Direction = DIRECTION_DOWN
				case termbox.KeyArrowLeft:
					snake.Direction = DIRECTION_LEFT
				case termbox.KeyArrowRight:
					snake.Direction = DIRECTION_RIGHT
				}
			}
		default:
			time.Sleep(300 * time.Millisecond)
			if gameFinished && !msgPrinted {
				termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
				termbox.Flush()
				fmt.Printf(msg, snake.Score)
				msgPrinted = true
			} else {
				if success := snake.Move(); !success {
					gameFinished = true
				}
				Draw(&snake)
			}
		}
	}
}

到此這篇關于基于Golang編寫貪吃蛇游戲的文章就介紹到這了,更多相關Golang貪吃蛇內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Golang爬蟲框架 colly的使用

    Golang爬蟲框架 colly的使用

    本文主要介紹了Golang爬蟲框架 colly的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • GO的range如何使用詳解

    GO的range如何使用詳解

    本文主要介紹了GO的range如何使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • golang?beego框架環(huán)境搭建過程

    golang?beego框架環(huán)境搭建過程

    這篇文章主要為大家介紹了golang?beego框架環(huán)境搭建的過程腳本,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • Go項目開發(fā)中如何讀取應用配置詳解

    Go項目開發(fā)中如何讀取應用配置詳解

    本文主要介紹了Go項目開發(fā)中如何讀取應用配置詳解,Go生態(tài)中有很多包可以加載并解析配置,最受歡迎的是Viper包,下面就來詳細的介紹一下
    2024-05-05
  • Golang空接口與類型斷言的實現(xiàn)

    Golang空接口與類型斷言的實現(xiàn)

    本文主要介紹了Golang空接口與類型斷言的實現(xiàn),文中根據實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Go語言算法之尋找數組第二大元素的方法

    Go語言算法之尋找數組第二大元素的方法

    這篇文章主要介紹了Go語言算法之尋找數組第二大元素的方法,以實例形式分析了不排序、只循環(huán)一次來實現(xiàn)尋找數組第二大元素的技巧,是比較典型的算法,需要的朋友可以參考下
    2015-02-02
  • 使用Golang獲取音視頻時長信息的示例代碼

    使用Golang獲取音視頻時長信息的示例代碼

    這篇文章主要介紹了如何使用Golang獲取音視頻時長信息,文中通過代碼示例講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03
  • golang連接redis庫及基本操作示例過程

    golang連接redis庫及基本操作示例過程

    這篇文章主要介紹了golang連接redis庫及基本操作示例過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • Go語言中日志統(tǒng)一處理詳解

    Go語言中日志統(tǒng)一處理詳解

    在現(xiàn)代軟件開發(fā)中,日志記錄是一項至關重要的任務,它不僅幫助開發(fā)人員診斷問題,還有助于監(jiān)控和維護應用程序,本文主要來和大家聊聊日志的統(tǒng)一處理,感興趣的小伙伴可以了解下
    2024-01-01
  • Golang內存對齊的規(guī)則及實現(xiàn)

    Golang內存對齊的規(guī)則及實現(xiàn)

    本文介紹了Golang內存對齊的規(guī)則及實現(xiàn),通過合理的內存對齊,可以提高程序的執(zhí)行效率和性能,通過對本文的閱讀,讀者可以更好地理解Golang內存對齊的原理和技巧,并應用于實際編程中
    2023-08-08

最新評論