Go项目开发----2048小游戏(下)

时间:2022-05-05
本文章向大家介绍Go项目开发----2048小游戏(下),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
//向左旋转90度
func (t *G2048)left90() {
    tn := new(G2048)
 for i, line := range t {
 for j, num := range line {
            tn[len(line)-j-1][i] =num
        }
    }
 *t = *tn
}
func (t *G2048)right180() {
    tn := new(G2048)
 for i, line := range t {
 for j, num := range line {
            tn[len(line)-i-1][len(line)-j-1] = num
        }
    }
 *t = *tn
}
//向上移动并合并
func (t *G2048)mergeUp() bool {
    tl := len(t)
    changed := false
    notfull := false
 for i := 0; i <tl; i++ {
        np := tl
        n := 0 // 统计每一列中非零值的个数
 // 向上移动非零值,如果有零值元素,则用非零元素进行覆盖
 for x := 0; x <np; x++ {
 if t[x][i] != 0 {
                t[n][i] = t[x][i]
 if n != x {
                    changed = true //标示数组的元素是否有变化
                }
                n++
            }
        }
 if n < tl {
            notfull = true
        }
        np = n
 // 向上合并所有相同的元素
 for x := 0; x <np-1; x++ {
 if t[x][i] == t[x+1][i] {
                t[x][i] *= 2
                t[x+1][i] = 0
                Score += t[x][i] *step // 计算游戏分数
                x++
                changed = true
            }
        }
 // 合并完相同元素以后,再次向上移动非零元素
        n = 0
 for x := 0; x <np; x++ {
 if t[x][i] != 0 {
                t[n][i] = t[x][i]
                n++
            }
        }
 for x := n; x <tl; x++ {
            t[x][i] = 0
        }
    }
 return changed || !notfull
}
//向下移动合并的操作可以转换向上移动合并:
//1.向右旋转180度矩阵
//2.向上合并
//3.再次向右旋转180度矩阵
func (t *G2048)mergeDwon() bool {
 //t.mirrorV()
    t.right180()
    changed := t.mergeUp()
 //t.mirrorV()
    t.right180()
 return changed
}
//向左移动合并转换为向上移动合并
func (t *G2048)mergeLeft() bool {
    t.right90()
    changed := t.mergeUp()
    t.left90()
 return changed
}
///向右移动合并转换为向上移动合并
func (t *G2048)mergeRight() bool {
    t.left90()
    changed := t.mergeUp()
    t.right90()
 return changed
}
//检查按键,做出不同的移动动作或者退出程序
func (t *G2048)mrgeAndReturnKey() termbox.Key {
    var changed bool
Lable:
    changed = false
 //ev := termbox.PollEvent()
    event_queue := make(chan termbox.Event)
    go func() { // 在其他goroutine中开始监听
 for {
            event_queue <- termbox.PollEvent()// 开始监听键盘事件
        }
    }()
    ev := <-event_queue
    switch ev.Type {
    case termbox.EventKey:
        switch ev.Key {
        case termbox.KeyArrowUp:
            changed = t.mergeUp()
        case termbox.KeyArrowDown:
            changed = t.mergeDwon()
        case termbox.KeyArrowLeft:
            changed = t.mergeLeft()
        case termbox.KeyArrowRight:
            changed = t.mergeRight()
        case termbox.KeyEsc, termbox.KeyEnter:
            changed = true
        default:
            changed = false
        }
 //如果元素的值没有任何更改,则从新开始循环
 if !changed {
            goto Lable
        }
    case termbox.EventResize:
        x, y := termbox.Size()
        t.initialize(x/2-10, y/2-4)
        goto Lable
    case termbox.EventError:
        panic(ev.Err)
    }
    step++ // 计算游戏操作数
 return ev.Key
}
//重置
func (b *G2048)clear() {
 next :=new(G2048)
    Score = 0
    step = 0
 *b = *next
}
//开始游戏
func (b *G2048)Run() {
    err := termbox.Init()
 if err != nil {
        panic(err)
    }
    defer termbox.Close()
    rand.Seed(time.Now().UnixNano())
A:
    b.clear()
 for { // 进入无限循环
        st := b.checkWinOrAdd()
        x, y := termbox.Size()
        b.initialize(x/2-10, y/2-4) // 初始化游戏界面
        switch st {
        case Win:
 str := "Win!!"
            strl := len(str)
            coverPrintStr(x/2-strl/2, y/2, str, termbox.ColorMagenta,termbox.ColorYellow)
        case Lose:
 str := "Lose!!"
            strl := len(str)
            coverPrintStr(x/2-strl/2, y/2, str, termbox.ColorBlack,termbox.ColorRed)
        case Add:
        default:
            fmt.Print("Err")
        }
 // 检查用户按键
        key := b.mrgeAndReturnKey()
 // 如果按键是 Esc 则退出游戏
 if key == termbox.KeyEsc{
 return
        }
 // 如果按键是 Enter 则从新开始游戏
 if key == termbox.KeyEnter{
            goto A
        }
    }
}

本文来自:CSDN博客

感谢作者:hzy305365977

查看原文:Go项目开发----2048小游戏