最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Golang編寫貪吃蛇游戲

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

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

一:原理介紹

1. 繪制原理

存儲(chǔ)好蛇身和食物坐標(biāo)都存儲(chǔ)在Snake結(jié)構(gòu)中

定時(shí)300毫秒執(zhí)行移動(dòng)蛇身/生成食物,然后清空終端再重新根據(jù)坐標(biāo)繪制點(diǎn)●

達(dá)到模擬動(dòng)畫效果

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.貪吃蛇移動(dòng)過程

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

如果恰好是食物位置,添加一個(gè)點(diǎn)(最后一個(gè)點(diǎn)位置+1),再隨機(jī)生成食物

// 移動(dòng)一步, 如果碰壁返回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()
	// 蛇頭到達(dá)食物位置時(shí)標(biāo)記食物已吃,并且追加到蛇尾(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.生成食物過程

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

// 判斷生成的食物坐標(biāo)是否在蛇身上
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()
	// 上下兩邊留點(diǎn)空隙
	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]
}
// 移動(dòng)一步, 如果碰壁返回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()
	// 蛇頭到達(dá)食物位置時(shí)標(biāo)記食物已吃,并且追加到蛇尾(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
}
// 判斷生成的食物坐標(biāo)是否在蛇身上
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()
	// 上下兩邊留點(diǎn)空隙
	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()
	// 初始給它三個(gè)長(zhǎng)度吧, 太小不好看
	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)
			}
		}
	}
}

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

相關(guān)文章

  • Go語言中http.ResponseWriter接口

    Go語言中http.ResponseWriter接口

    http.ResponseWriter是Go語言中用來設(shè)置HTTP響應(yīng)的接口,本文主要介紹了Go語言中http.ResponseWriter接口,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-08-08
  • 使用go的interface案例實(shí)現(xiàn)多態(tài)范式操作

    使用go的interface案例實(shí)現(xiàn)多態(tài)范式操作

    這篇文章主要介紹了使用go的interface案例實(shí)現(xiàn)多態(tài)范式操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang timer可能造成的內(nèi)存泄漏問題分析

    Golang timer可能造成的內(nèi)存泄漏問題分析

    本文探討了Golang中timer可能造成的內(nèi)存泄漏問題,通過分析一段代碼,解釋了為什么協(xié)程在調(diào)用timer.Stop()后無法正常退出,文章指出,timer.Stop()并不關(guān)閉Channel,導(dǎo)致協(xié)程無法繼續(xù)執(zhí)行,最后,提出了一種修復(fù)方法,并呼吁大家關(guān)注和分享
    2024-12-12
  • Go每日一庫之quicktemplate的使用

    Go每日一庫之quicktemplate的使用

    quicktemplate快速、功能強(qiáng)大、易于使用的Go模板引擎。比html/模板快20倍,本文我們就詳細(xì)的介紹一下quicktemplate的具體使用,感興趣的可以了解一下
    2021-07-07
  • Go語言單線程運(yùn)行也會(huì)有的并發(fā)問題解析

    Go語言單線程運(yùn)行也會(huì)有的并發(fā)問題解析

    這篇文章主要為大家介紹了Go語言單線程運(yùn)行的并發(fā)問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Linux系統(tǒng)下Go語言開發(fā)環(huán)境搭建

    Linux系統(tǒng)下Go語言開發(fā)環(huán)境搭建

    這篇文章主要介紹了Linux系統(tǒng)下Go開發(fā)環(huán)境搭建,需要的朋友可以參考下
    2022-04-04
  • 用Go獲取短信驗(yàn)證碼的示例代碼

    用Go獲取短信驗(yàn)證碼的示例代碼

    要用Go獲取短信驗(yàn)證碼,通常需要連接到一個(gè)短信服務(wù)提供商的API,并通過該API發(fā)送請(qǐng)求來獲取驗(yàn)證碼,由于不同的短信服務(wù)提供商可能具有不同的API和授權(quán)方式,我將以一個(gè)簡(jiǎn)單的示例介紹如何使用Go語言來獲取短信驗(yàn)證碼,需要的朋友可以參考下
    2023-07-07
  • beego獲取ajax數(shù)據(jù)的實(shí)例

    beego獲取ajax數(shù)據(jù)的實(shí)例

    下面小編就為大家分享一篇beego獲取ajax數(shù)據(jù)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例

    Golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例

    這篇文章主要給大家介紹了golang反射獲取結(jié)構(gòu)體的值和修改值的代碼示例及演示效果,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,感興趣的同學(xué)可以參考閱讀本文
    2023-08-08
  • Go語言通道之緩沖通道

    Go語言通道之緩沖通道

    這篇文章介紹了Go語言通道之緩沖通道,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07

最新評(píng)論

东乌| 册亨县| 临海市| 平遥县| 长顺县| 永丰县| 巴林左旗| 阿鲁科尔沁旗| 南安市| 侯马市| 镇康县| 雷州市| 远安县| 绥阳县| 寻甸| 黑山县| 安阳县| 岳池县| 古浪县| 海宁市| 太白县| 浦东新区| 马山县| 大英县| 大关县| 普安县| 清远市| 龙州县| 宁乡县| 枞阳县| 阿城市| 闻喜县| 游戏| 彭水| 富宁县| 叙永县| 灵宝市| 光泽县| 运城市| 铜川市| 威海市|