refactor: bouncing ball
This commit is contained in:
@ -0,0 +1,52 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const (
|
||||||
|
width = 50
|
||||||
|
height = 10
|
||||||
|
|
||||||
|
cellEmpty = ' '
|
||||||
|
cellBall = '⚾'
|
||||||
|
)
|
||||||
|
|
||||||
|
var cell rune // current cell (for caching)
|
||||||
|
|
||||||
|
// create the board
|
||||||
|
board := make([][]bool, width)
|
||||||
|
for row := range board {
|
||||||
|
board[row] = make([]bool, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw a smiley
|
||||||
|
board[12][2] = true
|
||||||
|
board[16][2] = true
|
||||||
|
board[14][4] = true
|
||||||
|
board[10][6] = true
|
||||||
|
board[18][6] = true
|
||||||
|
board[12][7] = true
|
||||||
|
board[14][7] = true
|
||||||
|
board[16][7] = true
|
||||||
|
|
||||||
|
// print the board directly to the console
|
||||||
|
for y := range board[0] {
|
||||||
|
for x := range board {
|
||||||
|
cell = cellEmpty
|
||||||
|
if board[x][y] {
|
||||||
|
cell = cellBall
|
||||||
|
}
|
||||||
|
fmt.Print(string(cell), " ")
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
}
|
@ -1,47 +0,0 @@
|
|||||||
// For more tutorials: https://blog.learngoprogramming.com
|
|
||||||
//
|
|
||||||
// Copyright © 2018 Inanc Gumus
|
|
||||||
// Learn Go Programming Course
|
|
||||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
||||||
//
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
width = 25
|
|
||||||
height = 8
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// -------------------------------------------------
|
|
||||||
// CREATE THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
board := make([][]bool, width)
|
|
||||||
for row := range board {
|
|
||||||
board[row] = make([]bool, height)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// DRAW THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
var (
|
|
||||||
buf = make([]rune, 0, width*height)
|
|
||||||
ball rune
|
|
||||||
)
|
|
||||||
|
|
||||||
for y := range board[0] {
|
|
||||||
for x := range board {
|
|
||||||
ball = '🎱'
|
|
||||||
if board[x][y] {
|
|
||||||
ball = '🎾'
|
|
||||||
}
|
|
||||||
buf = append(buf, ball, ' ')
|
|
||||||
}
|
|
||||||
buf = append(buf, '\n')
|
|
||||||
}
|
|
||||||
fmt.Print(string(buf))
|
|
||||||
}
|
|
@ -0,0 +1,66 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const (
|
||||||
|
width = 50
|
||||||
|
height = 10
|
||||||
|
|
||||||
|
cellEmpty = ' '
|
||||||
|
cellBall = '⚾'
|
||||||
|
)
|
||||||
|
|
||||||
|
var cell rune // current cell (for caching)
|
||||||
|
|
||||||
|
// create the board
|
||||||
|
board := make([][]bool, width)
|
||||||
|
for row := range board {
|
||||||
|
board[row] = make([]bool, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a drawing buffer
|
||||||
|
buf := make([]rune, 0, width*height)
|
||||||
|
|
||||||
|
// draw a smiley
|
||||||
|
board[12][2] = true
|
||||||
|
board[16][2] = true
|
||||||
|
board[14][4] = true
|
||||||
|
board[10][6] = true
|
||||||
|
board[18][6] = true
|
||||||
|
board[12][7] = true
|
||||||
|
board[14][7] = true
|
||||||
|
board[16][7] = true
|
||||||
|
|
||||||
|
// use the loop for measuring the performance difference
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
// rewind the buffer so that the program reuses it
|
||||||
|
buf = buf[:0]
|
||||||
|
|
||||||
|
// draw the board into the buffer
|
||||||
|
for y := range board[0] {
|
||||||
|
for x := range board {
|
||||||
|
cell = cellEmpty
|
||||||
|
if board[x][y] {
|
||||||
|
cell = cellBall
|
||||||
|
}
|
||||||
|
// fmt.Print(string(cell), " ")
|
||||||
|
buf = append(buf, cell, ' ')
|
||||||
|
}
|
||||||
|
// fmt.Println()
|
||||||
|
buf = append(buf, '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the buffer
|
||||||
|
fmt.Print(string(buf))
|
||||||
|
}
|
||||||
|
}
|
@ -1,68 +0,0 @@
|
|||||||
// For more tutorials: https://blog.learngoprogramming.com
|
|
||||||
//
|
|
||||||
// Copyright © 2018 Inanc Gumus
|
|
||||||
// Learn Go Programming Course
|
|
||||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
||||||
//
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/inancgumus/screen"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
width = 25
|
|
||||||
height = 8
|
|
||||||
|
|
||||||
maxFrames = 1200
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// -------------------------------------------------
|
|
||||||
// CREATE THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
board := make([][]bool, width)
|
|
||||||
for row := range board {
|
|
||||||
board[row] = make([]bool, height)
|
|
||||||
}
|
|
||||||
|
|
||||||
var X, Y int // ball positions
|
|
||||||
|
|
||||||
screen.Clear()
|
|
||||||
|
|
||||||
for i := 0; i < maxFrames; i++ {
|
|
||||||
// -------------------------------------------------
|
|
||||||
// PUT THE BALL
|
|
||||||
// -------------------------------------------------
|
|
||||||
board[X][Y] = true
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// DRAW THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
var (
|
|
||||||
buf = make([]rune, 0, width*height)
|
|
||||||
ball rune
|
|
||||||
)
|
|
||||||
|
|
||||||
for y := range board[0] {
|
|
||||||
for x := range board {
|
|
||||||
ball = '🎱'
|
|
||||||
if board[x][y] {
|
|
||||||
ball = '🎾'
|
|
||||||
}
|
|
||||||
buf = append(buf, ball, ' ')
|
|
||||||
}
|
|
||||||
buf = append(buf, '\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
screen.MoveTopLeft()
|
|
||||||
fmt.Print(string(buf))
|
|
||||||
|
|
||||||
// draw after a while: slows down the animation
|
|
||||||
time.Sleep(time.Second / 20)
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,93 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/inancgumus/screen"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const (
|
||||||
|
width = 50
|
||||||
|
height = 10
|
||||||
|
|
||||||
|
cellEmpty = ' '
|
||||||
|
cellBall = '⚾'
|
||||||
|
|
||||||
|
maxFrames = 1200
|
||||||
|
speed = time.Second / 20
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
px, py int // ball position
|
||||||
|
vx, vy = 1, 1 // velocities
|
||||||
|
|
||||||
|
cell rune // current cell (for caching)
|
||||||
|
)
|
||||||
|
|
||||||
|
// create the board
|
||||||
|
board := make([][]bool, width)
|
||||||
|
for row := range board {
|
||||||
|
board[row] = make([]bool, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a drawing buffer
|
||||||
|
buf := make([]rune, 0, width*height)
|
||||||
|
|
||||||
|
// clear the screen once
|
||||||
|
screen.Clear()
|
||||||
|
|
||||||
|
for i := 0; i < maxFrames; i++ {
|
||||||
|
// calculate the next ball position
|
||||||
|
px += vx
|
||||||
|
py += vy
|
||||||
|
|
||||||
|
// when the ball hits a border reverse its direction
|
||||||
|
if px <= 0 || px >= width-1 {
|
||||||
|
vx *= -1
|
||||||
|
}
|
||||||
|
if py <= 0 || py >= height-1 {
|
||||||
|
vy *= -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the previous ball
|
||||||
|
for y := range board[0] {
|
||||||
|
for x := range board {
|
||||||
|
board[x][y] = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// put the new ball
|
||||||
|
board[px][py] = true
|
||||||
|
|
||||||
|
// rewind the buffer (allow appending from the beginning)
|
||||||
|
buf = buf[:0]
|
||||||
|
|
||||||
|
// draw the board into the buffer
|
||||||
|
for y := range board[0] {
|
||||||
|
for x := range board {
|
||||||
|
cell = cellEmpty
|
||||||
|
if board[x][y] {
|
||||||
|
cell = cellBall
|
||||||
|
}
|
||||||
|
buf = append(buf, cell, ' ')
|
||||||
|
}
|
||||||
|
buf = append(buf, '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the buffer
|
||||||
|
screen.MoveTopLeft()
|
||||||
|
fmt.Print(string(buf))
|
||||||
|
|
||||||
|
// slow down the animation
|
||||||
|
time.Sleep(speed)
|
||||||
|
}
|
||||||
|
}
|
@ -1,94 +0,0 @@
|
|||||||
// For more tutorials: https://blog.learngoprogramming.com
|
|
||||||
//
|
|
||||||
// Copyright © 2018 Inanc Gumus
|
|
||||||
// Learn Go Programming Course
|
|
||||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
||||||
//
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/inancgumus/screen"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
width = 25
|
|
||||||
height = 8
|
|
||||||
|
|
||||||
maxFrames = 1200
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// -------------------------------------------------
|
|
||||||
// CREATE THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
board := make([][]bool, width)
|
|
||||||
for row := range board {
|
|
||||||
board[row] = make([]bool, height)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
X, Y int // ball positions
|
|
||||||
xVel, yVel = 1, 1 // velocities
|
|
||||||
)
|
|
||||||
|
|
||||||
screen.Clear()
|
|
||||||
|
|
||||||
for i := 0; i < maxFrames; i++ {
|
|
||||||
// -------------------------------------------------
|
|
||||||
// CALCULATE THE NEXT BALL POSITION
|
|
||||||
// -------------------------------------------------
|
|
||||||
X += xVel
|
|
||||||
Y += yVel
|
|
||||||
|
|
||||||
// when the ball hits the borders change its direction
|
|
||||||
// by changing its velocity
|
|
||||||
if X <= 0 || X >= width-1 {
|
|
||||||
xVel *= -1
|
|
||||||
}
|
|
||||||
if Y <= 0 || Y >= height-1 {
|
|
||||||
yVel *= -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// CLEAR THE BOARD AND PUT THE BALL
|
|
||||||
// -------------------------------------------------
|
|
||||||
for y := range board[0] {
|
|
||||||
for x := range board {
|
|
||||||
board[x][y] = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
board[X][Y] = true
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// DRAW THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
var (
|
|
||||||
buf = make([]rune, 0, width*height)
|
|
||||||
ball rune
|
|
||||||
)
|
|
||||||
|
|
||||||
for y := range board[0] {
|
|
||||||
for x := range board {
|
|
||||||
ball = '🎱'
|
|
||||||
if board[x][y] {
|
|
||||||
ball = '🏈'
|
|
||||||
}
|
|
||||||
buf = append(buf, ball, ' ')
|
|
||||||
}
|
|
||||||
buf = append(buf, '\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear the screen and draw the board
|
|
||||||
screen.MoveTopLeft()
|
|
||||||
fmt.Print(string(buf))
|
|
||||||
|
|
||||||
// TODO: in the notes this is at the beginning of the loop
|
|
||||||
|
|
||||||
// draw after a while: slows down the animation
|
|
||||||
time.Sleep(time.Second / 20)
|
|
||||||
}
|
|
||||||
}
|
|
100
x-tba/slices/21-bouncing-ball-project/04-finalize/main.go
Normal file
100
x-tba/slices/21-bouncing-ball-project/04-finalize/main.go
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// For more tutorials: https://blog.learngoprogramming.com
|
||||||
|
//
|
||||||
|
// Copyright © 2018 Inanc Gumus
|
||||||
|
// Learn Go Programming Course
|
||||||
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/inancgumus/screen"
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const (
|
||||||
|
cellEmpty = ' '
|
||||||
|
cellBall = '⚾'
|
||||||
|
|
||||||
|
maxFrames = 1200
|
||||||
|
speed = time.Second / 20
|
||||||
|
)
|
||||||
|
|
||||||
|
// get the width and height of the terminal dynamically ***
|
||||||
|
width, height, err := terminal.GetSize(int(os.Stdout.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("cannot get width and height", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
width /= 2 // our emoji is 2 chars wide
|
||||||
|
|
||||||
|
var (
|
||||||
|
px, py int // ball position
|
||||||
|
ppx, ppy int // previous ball position ***
|
||||||
|
vx, vy = 1, 1 // velocities
|
||||||
|
|
||||||
|
cell rune // current cell (for caching)
|
||||||
|
)
|
||||||
|
|
||||||
|
// create the board
|
||||||
|
board := make([][]bool, width)
|
||||||
|
for row := range board {
|
||||||
|
board[row] = make([]bool, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a drawing buffer
|
||||||
|
buf := make([]rune, 0, width*height)
|
||||||
|
|
||||||
|
// clear the screen once
|
||||||
|
screen.Clear()
|
||||||
|
|
||||||
|
for i := 0; i < maxFrames; i++ {
|
||||||
|
// calculate the next ball position
|
||||||
|
px += vx
|
||||||
|
py += vy
|
||||||
|
|
||||||
|
// when the ball hits a border reverse its direction
|
||||||
|
if px <= 0 || px >= width-1 {
|
||||||
|
vx *= -1
|
||||||
|
}
|
||||||
|
if py <= 0 || py >= height-1 {
|
||||||
|
vy *= -1
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether the ball goes beyond the borders
|
||||||
|
if !(px >= width || py >= height) {
|
||||||
|
// remove the previous ball and put the new ball
|
||||||
|
board[px][py], board[ppx][ppy] = true, false
|
||||||
|
|
||||||
|
// save the previous positions
|
||||||
|
ppx, ppy = px, py
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewind the buffer (allow appending from the beginning)
|
||||||
|
buf = buf[:0]
|
||||||
|
|
||||||
|
// draw the board into the buffer
|
||||||
|
for y := range board[0] {
|
||||||
|
for x := range board {
|
||||||
|
cell = cellEmpty
|
||||||
|
if board[x][y] {
|
||||||
|
cell = cellBall
|
||||||
|
}
|
||||||
|
buf = append(buf, cell, ' ')
|
||||||
|
}
|
||||||
|
buf = append(buf, '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the buffer
|
||||||
|
screen.MoveTopLeft()
|
||||||
|
fmt.Print(string(buf))
|
||||||
|
|
||||||
|
// slow down the animation
|
||||||
|
time.Sleep(speed)
|
||||||
|
}
|
||||||
|
}
|
@ -1,92 +0,0 @@
|
|||||||
// For more tutorials: https://blog.learngoprogramming.com
|
|
||||||
//
|
|
||||||
// Copyright © 2018 Inanc Gumus
|
|
||||||
// Learn Go Programming Course
|
|
||||||
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
||||||
//
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/inancgumus/screen"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
width = 25
|
|
||||||
height = 8
|
|
||||||
|
|
||||||
maxFrames = 1200
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// -------------------------------------------------
|
|
||||||
// CREATE THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
board := make([][]bool, width)
|
|
||||||
for row := range board {
|
|
||||||
board[row] = make([]bool, height)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
X, Y int // ball positions
|
|
||||||
pX, pY int // previous ball positions (for clearing)
|
|
||||||
xVel, yVel = 1, 1 // velocities
|
|
||||||
|
|
||||||
buf [width * height]rune // drawing buffer
|
|
||||||
)
|
|
||||||
|
|
||||||
screen.Clear()
|
|
||||||
|
|
||||||
for i := 0; i < maxFrames; i++ {
|
|
||||||
// -------------------------------------------------
|
|
||||||
// CALCULATE THE NEXT BALL POSITION
|
|
||||||
// -------------------------------------------------
|
|
||||||
X += xVel
|
|
||||||
Y += yVel
|
|
||||||
|
|
||||||
// when the ball hits the borders change its direction
|
|
||||||
// by changing its velocity
|
|
||||||
if X <= 0 || X >= width-1 {
|
|
||||||
xVel *= -1
|
|
||||||
}
|
|
||||||
if Y <= 0 || Y >= height-1 {
|
|
||||||
yVel *= -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// PUT THE BALL AND CLEAR THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
board[X][Y] = true
|
|
||||||
board[pX][pY] = false
|
|
||||||
pX, pY = X, Y
|
|
||||||
|
|
||||||
// -------------------------------------------------
|
|
||||||
// DRAW THE BOARD
|
|
||||||
// -------------------------------------------------
|
|
||||||
var ball rune
|
|
||||||
|
|
||||||
// rewind the buffer
|
|
||||||
bufs := buf[:]
|
|
||||||
|
|
||||||
for y := range board[0] {
|
|
||||||
for x := range board {
|
|
||||||
ball = ' '
|
|
||||||
if board[x][y] {
|
|
||||||
ball = '🎾'
|
|
||||||
}
|
|
||||||
bufs = append(bufs, ball, ' ')
|
|
||||||
}
|
|
||||||
bufs = append(bufs, '\n')
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear the screen and draw the board
|
|
||||||
screen.MoveTopLeft()
|
|
||||||
fmt.Print(string(bufs))
|
|
||||||
|
|
||||||
// draw after a while: slows down the animation
|
|
||||||
time.Sleep(time.Second / 20)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +1,14 @@
|
|||||||
# Bouncing Ball Challenge
|
# Bouncing Ball Challenge Tips
|
||||||
|
|
||||||
This document contains what you need to do to create the bouncing ball animation.You're going to learn a great deal of knowledge about slices and you'll gain a good experience while doing this.
|
Use the following tips only when you get stuck. This document isn't in a particular order, please do not follow it like so.
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||||
|
|
||||||
## Declare the constants
|
## Ball position and velocity
|
||||||
* The width and the height of the board.
|
|
||||||
|
|
||||||
* It can be anything, just experiment.
|
You can use velocity to change the ball's speed and position. In my example, the speed is constant, so I always use unit value: 1.
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
On each loop step: Add velocities to ball's position. This will make the ball move.
|
||||||
|
|
||||||
## Declare the ball positions and velocity:
|
|
||||||
The ball should be in a known position on your board, and it should have a velocity.
|
|
||||||
|
|
||||||
* **Velocity means: Speed and Direction**
|
* **Velocity means: Speed and Direction**
|
||||||
|
|
||||||
@ -21,146 +17,58 @@ The ball should be in a known position on your board, and it should have a veloc
|
|||||||
* Y velocity = 1 -> _ball moves down_
|
* Y velocity = 1 -> _ball moves down_
|
||||||
* Y velocity = -1 -> _ball moves up_
|
* Y velocity = -1 -> _ball moves up_
|
||||||
|
|
||||||
* Declare variables for the ball's positions: `X` and `Y`
|
* **For more information on graphics and velocity:**
|
||||||
|
* Youtube: Crash Course: 2D Graphics
|
||||||
|
-> https://www.youtube.com/watch?v=7Jr0SFMQ4Rs&t=529
|
||||||
|
|
||||||
* Declare variables for the ball's velocity: `xVelocity` and `yVelocity`
|
* Youtube: Crash Course: Velocity
|
||||||
|
-> https://www.youtube.com/watch?v=ZM8ECpBuQYE
|
||||||
* On each step: Add velocities to ball's position. This will make the ball move.
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||||
|
|
||||||
## 🎾 CREATE THE BOARD
|
## CREATE THE BOARD
|
||||||
|
|
||||||
You can use a multi-dimensional bool slice to create the board. Each element in the slice corresponds to whether the ball is in that element (or position) or not.
|
I use `[][]bool` for the board but you can use anything you like. For example, you can directly use `[][]rune` or `[]rune`. Experiment with them and decide which one is the best for you.
|
||||||
|
|
||||||
* Use the `make` function to initialize your board.
|
|
||||||
|
|
||||||
* Remember: Zero value for a slice is `nil`.
|
|
||||||
* So, you need to initialize each sub-slice of the board slice.
|
|
||||||
|
|
||||||
* You can use `[][]bool` for your board.
|
|
||||||
|
|
||||||
* It's because, when you set one of the elements to true, then you'd know that the ball is in that position.
|
|
||||||
|
|
||||||
* *EXAMPLE:*
|
|
||||||
```
|
|
||||||
false false false false
|
|
||||||
false true -+ false false
|
|
||||||
false false | false false
|
|
||||||
v
|
|
||||||
the ball is here
|
|
||||||
board[1][1] is true
|
|
||||||
```
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||||
|
|
||||||
## 🎾 CLEAR THE SCREEN
|
## CLEAR THE SCREEN
|
||||||
|
|
||||||
* Before the loop, clear the screen once by using the screen package.
|
* Before the loop, clear the screen once by using my screen package.
|
||||||
|
|
||||||
|
* After each loop step, move the cursor to the top-left position by using the screen package. So that you can draw the animation frame all over again in the same position.
|
||||||
|
|
||||||
* It's [here](https://github.com/inancgumus/screen).
|
* It's [here](https://github.com/inancgumus/screen).
|
||||||
* Its documentation is [here](https://godoc.org/github.com/inancgumus/screen).
|
* Its documentation is [here](https://godoc.org/github.com/inancgumus/screen).
|
||||||
|
* You can find more information about it in the Retro Clock project section.
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
|
||||||
|
|
||||||
## 🎾 DRAWING LOOP
|
|
||||||
This is the main loop that will draw the board and the ball to the screen continuously.
|
|
||||||
|
|
||||||
* Create the loop
|
|
||||||
|
|
||||||
* On each step of the loop, you're going to:
|
|
||||||
* Clear the board
|
|
||||||
* Calculate the next ball position
|
|
||||||
* Draw the board and the balls
|
|
||||||
|
|
||||||
Explanations for these steps follow...
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||||
|
|
||||||
## 🎾 CLEAR THE BOARD
|
## DRAW THE BOARD
|
||||||
At the beginning your board should not contain the ball.
|
Instead of drawing the board and the ball to the screen everytime, you will fill a buffer, and when you complete, you can draw the board and the ball once by printing the buffer.
|
||||||
|
|
||||||
* So, set all the inner slices of the board slice to `false`.
|
I use a `[]rune` buffer because `rune` can store an emoji character, and I use a slice of runes because I want to draw empty cells and a ball in the end.
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
|
||||||
|
|
||||||
## 🎾 CALCULATE THE NEXT BALL POSITION
|
|
||||||
You need to calculate the ball's next position on the board.
|
|
||||||
|
|
||||||
* Add the velocities to the ball's current position:
|
|
||||||
|
|
||||||
* `X += xVelocity`
|
|
||||||
* `Y += yVelocity`
|
|
||||||
|
|
||||||
* When the ball hits the borders of the board change its direction.
|
|
||||||
|
|
||||||
* **HINT:** You can multiply any velocity by `-1` to change its direction.
|
|
||||||
|
|
||||||
* Set the ball's position on the board.
|
|
||||||
|
|
||||||
* You will use this information when drawing the board.
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
|
||||||
|
|
||||||
## 🎾 DRAW THE BOARD
|
|
||||||
Instead of drawing the board and the ball to the screen everytime, you will fill a buffer, and when you complete, you will draw the whole board and the ball once by printing the buffer that you filled.
|
|
||||||
|
|
||||||
* Make a large enough rune slice named `buf` using the `make` function.
|
* Make a large enough rune slice named `buf` using the `make` function.
|
||||||
|
|
||||||
* **HINT:** `width * height` will give you a large enough buffer.
|
* **HINT:** `width * height` will give you a large enough buffer.
|
||||||
|
|
||||||
* **TIP:** You could also use `string` concatenation but it would be inefficient.
|
* **TIP:** You could also use `string` concatenation to draw into a `string` buffer but it would be inefficient.
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
* You will find more information about bytes and runes in the strings section.
|
||||||
|
|
||||||
## FILL YOUR BUFFER:
|
```go
|
||||||
|
// TIP for converting the buffer
|
||||||
|
var buffer []rune
|
||||||
|
|
||||||
* Filling your buffer:
|
// For printing, you can convert a rune slice to a string like so:
|
||||||
|
str := string(buffer)
|
||||||
* Loop for the height of the board (_described below_).
|
```
|
||||||
|
|
||||||
* Then in a nested loop (_described below_), loop for the width of the board.
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
|
||||||
|
|
||||||
## NESTEP LOOP: WIDTH LOOP
|
|
||||||
* On each step of the nested loop, do this:
|
|
||||||
|
|
||||||
* Check whether the ball is in the x, y positions.
|
|
||||||
* You need to check for it using your board slice.
|
|
||||||
|
|
||||||
* If so, `append` this tennis ball '🎾' to the buffer.
|
|
||||||
* If not, `append` this pool ball '🎱' to the buffer.
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
|
||||||
|
|
||||||
## NESTEP LOOP: HEIGHT LOOP
|
|
||||||
|
|
||||||
* After the nested loop (but in the height loop):
|
|
||||||
|
|
||||||
* `append` the newline character to the buffer: `'\n'`
|
|
||||||
* This will allow you to print the next row to the next line.
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
|
||||||
|
|
||||||
## 🎾 MOVE THE CURSOR
|
|
||||||
|
|
||||||
* After the loop, move the cursor to the top-left position by using the screen package.
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
|
||||||
|
|
||||||
## PRINT THE BOARD (USING THE BUFFER):
|
|
||||||
|
|
||||||
* Do not forget converting it to `string`. Because your buffer is `[]rune`, like so:
|
|
||||||
|
|
||||||
`fmt.Print(string(buf))`
|
|
||||||
|
|
||||||
* You'll learn the details about rune and strings later.
|
|
||||||
|
|
||||||
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖➖
|
||||||
|
|
||||||
## SLOW DOWN THE SPEED
|
## SLOW DOWN THE SPEED
|
||||||
|
|
||||||
And lastly, call the `time.Sleep` function to slow down the speed of the loop, so you can see the ball :) Like so:
|
Call the `time.Sleep` function to slow down the speed of the loop a little bit, so you can see the ball :)
|
||||||
|
|
||||||
`time.Sleep(time.Millisecond * 60)`
|
`time.Sleep(time.Second / 20)`
|
||||||
|
Reference in New Issue
Block a user