package main import ( "fmt" "image/color" "math/rand" "time" "golang.org/x/image/font" "golang.org/x/image/font/basicfont" "image" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/inpututil" "github.com/hajimehoshi/ebiten/v2/text") const ( screenWidth = 800 screenHeight = 600 stageHeight = 50 stlitWidth = 10 stlitHeight = 150 charWidth = 50 charHeight = 50 ballWidth = 20 ballHeight = 20) var ( backgroundColor = color.RGBA{255, 255, 255, 255} // 흰색 stageColor = color.RGBA{0, 0, 0, 255} // 검정색 stlitColor = color.RGBA{0, 0, 255, 255} // 파란색 char1Color = color.RGBA{255, 0, 0, 255} // 빨간색 char2Color = color.RGBA{0, 255, 0, 255} // 녹색 ball1Color = color.RGBA{255, 255, 0, 255} // 노란색 ball2Color = color.RGBA{0, 255, 255, 255} // 하늘색 char1X, char1Y float64 char2X, char2Y float64 char1VX, char1VY float64 char2VX, char2VY float64 ball1X, ball1Y float64 ball2X, ball2Y float64 ball1VX, ball1VY float64 ball2VX, ball2VY float64 score1, score2 int gameOver bool gameResult string gravity float64 = 0.5 face font.Face) type Game struct{} func (g *Game) Update() error { if gameOver { if inpututil.IsKeyJustPressed(ebiten.KeyR) { initializeGame() } return nil } handleInput() char1X += char1VX char1Y += char1VY char2X += char2VX char2Y += char2VY ball1X += ball1VX ball1Y += ball1VY ball2X += ball2VX ball2Y += ball2VY ball1VY += gravity ball2VY += gravity checkBounds() if char1Y < 0 { char1Y = 0 } if char1Y > screenHeight-stageHeight-charHeight { char1Y = screenHeight - stageHeight - charHeight } if char2Y < 0 { char2Y = 0 } if char2Y > screenHeight-stageHeight-charHeight { char2Y = screenHeight - stageHeight - charHeight } if ball1Y > screenHeight-ballHeight-stageHeight { if ball1X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball2Y > screenHeight-ballHeight-stageHeight { if ball2X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball1Y < 0 { ball1Y = 0 ball1VY = 3 } if ball2Y < 0 { ball2Y = 0 ball2VY = 3 } checkCollisions() // 중앙선을 넘어가지 않도록 설정 if ball1X > screenWidth/2-ballWidth { ball1X = screenWidth/2 - ballWidth ball1VX = -ball1VX } if ball2X < screenWidth/2 { ball2X = screenWidth / 2 ball2VX = -ball2VX } if score1 == 5 { gameResult = "Player1 WIN" gameOver = true } else if score2 == 5 { gameResult = "Player2 WIN" gameOver = true } return nil} func (g *Game) Draw(screen ebiten.Image) { screen.Fill(backgroundColor) ebitenutil.DrawRect(screen, 0, screenHeight-stageHeight, screenWidth, stageHeight, stageColor) ebitenutil.DrawRect(screen, screenWidth/2-stlitWidth/2, screenHeight-stlitHeight-stageHeight, stlitWidth, stlitHeight, stlitColor) ebitenutil.DrawRect(screen, char1X, char1Y, charWidth, charHeight, char1Color) ebitenutil.DrawRect(screen, char2X, char2Y, charWidth, charHeight, char2Color) ebitenutil.DrawRect(screen, ball1X, ball1Y, ballWidth, ballHeight, ball1Color) ebitenutil.DrawRect(screen, ball2X, ball2Y, ballWidth, ballHeight, ball2Color) // 점수를 각 구역의 중앙쯤에 큰 글씨로 표시 score1Str := fmt.Sprintf("%d", score1) score2Str := fmt.Sprintf("%d", score2) text.Draw(screen, score1Str, face, screenWidth/4-len(score1Str)20, 80, color.Black) text.Draw(screen, score2Str, face, screenWidth3/4-len(score2Str)20, 80, color.Black) if gameOver { text.Draw(screen, gameResult, face, screenWidth/2-len(gameResult)10, screenHeight/2, color.RGBA{255, 0, 0, 255}) }} func (g Game) Layout(outsideWidth, outsideHeight int) (int, int) { return screenWidth, screenHeight} func main() { rand.Seed(time.Now().UnixNano()) initializeGame() ebiten.SetWindowSize(screenWidth, screenHeight) ebiten.SetWindowTitle("공 튀기기") face = basicfont.Face7x13 if err := ebiten.RunGame(&Game{}); err != nil { panic(err) }} func initializeGame() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - bandwidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0 score1, score2 = 0, 0 gameResult = "" gameOver = false} func resetPositions() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - ballWidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0} func handleInput() { if ebiten.IsKeyPressed(ebiten.KeyA) { char1VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyD) { char1VX = 7 } else { char1VX = 0 } if ebiten.IsKeyPressed(ebiten.KeyLeft) { char2VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyRight) { char2VX = 7 } else { char2VX = 0 } if inpututil.IsKeyJustPressed(ebiten.KeySpace) { char1VY = -10 } if inpututil.IsKeyJustPressed(ebiten.KeyEnter) { char2VY = -10 } char1VY += gravity char2VY += gravity} func checkBounds() { if char1X < 0 { char1X = 0 } if char1X > screenWidth/2-stlitWidth/2-charWidth { char1X = screenWidth/2 - stlitWidth/2 - charWidth } if char2X < screenWidth/2+stlitWidth/2 { char2X = screenWidth/2 + stlitWidth/2 } if char2X > screenWidth-charWidth { char2X = screenWidth - charWidth } if ball1X < 0 || ball1X > screenWidth/2-ballWidth { ball1VX = -ball1VX } if ball2X < screenWidth/2 || ball2X > screenWidth-ballWidth { ball2VX = -ball2VX }} func checkCollisions() { char1Rect := image.Rect(int(char1X), int(char1Y), int(char1X+charWidth), int(char1Y+charHeight)) char2Rect := image.Rect(int(char2X), int(char2Y), int(char2X+charWidth), int(char2Y+charHeight)) ball1Rect := image.Rect(int(ball1X), int(ball1Y), int(ball1X+ballWidth), int(ball1Y+ballHeight)) ball2Rect := image.Rect(int(ball2X), int(ball2Y), int(ball2X+ballWidth), int(ball2Y+ballHeight)) if char1Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char1Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) }}

package main import ( "fmt" "image/color" "math/rand" "time" "golang.org/x/image/font" "golang.org/x/image/font/basicfont" "image" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/inpututil" "github.com/hajimehoshi/ebiten/v2/text") const ( screenWidth = 800 screenHeight = 600 stageHeight = 50 stlitWidth = 10 stlitHeight = 150 charWidth = 50 charHeight = 50 ballWidth = 20 ballHeight = 20) var ( backgroundColor = color.RGBA{255, 255, 255, 255} // 흰색 stageColor = color.RGBA{0, 0, 0, 255} // 검정색 stlitColor = color.RGBA{0, 0, 255, 255} // 파란색 char1Color = color.RGBA{255, 0, 0, 255} // 빨간색 char2Color = color.RGBA{0, 255, 0, 255} // 녹색 ball1Color = color.RGBA{255, 255, 0, 255} // 노란색 ball2Color = color.RGBA{0, 255, 255, 255} // 하늘색 char1X, char1Y float64 char2X, char2Y float64 char1VX, char1VY float64 char2VX, char2VY float64 ball1X, ball1Y float64 ball2X, ball2Y float64 ball1VX, ball1VY float64 ball2VX, ball2VY float64 score1, score2 int gameOver bool gameResult string gravity float64 = 0.5 face font.Face) type Game struct{} func (g *Game) Update() error { if gameOver { if inpututil.IsKeyJustPressed(ebiten.KeyR) { initializeGame() } return nil } handleInput() char1X += char1VX char1Y += char1VY char2X += char2VX char2Y += char2VY ball1X += ball1VX ball1Y += ball1VY ball2X += ball2VX ball2Y += ball2VY ball1VY += gravity ball2VY += gravity checkBounds() if char1Y < 0 { char1Y = 0 } if char1Y > screenHeight-stageHeight-charHeight { char1Y = screenHeight - stageHeight - charHeight } if char2Y < 0 { char2Y = 0 } if char2Y > screenHeight-stageHeight-charHeight { char2Y = screenHeight - stageHeight - charHeight } if ball1Y > screenHeight-ballHeight-stageHeight { if ball1X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball2Y > screenHeight-ballHeight-stageHeight { if ball2X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball1Y < 0 { ball1Y = 0 ball1VY = 3 } if ball2Y < 0 { ball2Y = 0 ball2VY = 3 } checkCollisions() // 중앙선을 넘어가지 않도록 설정 if ball1X > screenWidth/2-ballWidth { ball1X = screenWidth/2 - ballWidth ball1VX = -ball1VX } if ball2X < screenWidth/2 { ball2X = screenWidth / 2 ball2VX = -ball2VX } if score1 == 5 { gameResult = "Player1 WIN" gameOver = true } else if score2 == 5 { gameResult = "Player2 WIN" gameOver = true } return nil} func (g *Game) Draw(screen ebiten.Image) { screen.Fill(backgroundColor) ebitenutil.DrawRect(screen, 0, screenHeight-stageHeight, screenWidth, stageHeight, stageColor) ebitenutil.DrawRect(screen, screenWidth/2-stlitWidth/2, screenHeight-stlitHeight-stageHeight, stlitWidth, stlitHeight, stlitColor) ebitenutil.DrawRect(screen, char1X, char1Y, charWidth, charHeight, char1Color) ebitenutil.DrawRect(screen, char2X, char2Y, charWidth, charHeight, char2Color) ebitenutil.DrawRect(screen, ball1X, ball1Y, ballWidth, ballHeight, ball1Color) ebitenutil.DrawRect(screen, ball2X, ball2Y, ballWidth, ballHeight, ball2Color) // 점수를 각 구역의 중앙쯤에 큰 글씨로 표시 score1Str := fmt.Sprintf("%d", score1) score2Str := fmt.Sprintf("%d", score2) text.Draw(screen, score1Str, face, screenWidth/4-len(score1Str)20, 80, color.Black) text.Draw(screen, score2Str, face, screenWidth3/4-len(score2Str)20, 80, color.Black) if gameOver { text.Draw(screen, gameResult, face, screenWidth/2-len(gameResult)10, screenHeight/2, color.RGBA{255, 0, 0, 255}) }} func (g Game) Layout(outsideWidth, outsideHeight int) (int, int) { return screenWidth, screenHeight} func main() { rand.Seed(time.Now().UnixNano()) initializeGame() ebiten.SetWindowSize(screenWidth, screenHeight) ebiten.SetWindowTitle("공 튀기기") face = basicfont.Face7x13 if err := ebiten.RunGame(&Game{}); err != nil { panic(err) }} func initializeGame() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - ballWidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0 score1, score2 = 0, 0 gameResult = "" gameOver = false} func resetPositions() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - ballWidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0} func handleInput() { if ebiten.IsKeyPressed(ebiten.KeyA) { char1VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyD) { char1VX = 7 } else { char1VX = 0 } if ebiten.IsKeyPressed(ebiten.KeyLeft) { char2VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyRight) { char2VX = 7 } else { char2VX = 0 } if inpututil.IsKeyJustPressed(ebiten.KeySpace) { char1VY = -10 } if inpututil.IsKeyJustPressed(ebiten.KeyEnter) { char2VY = -10 } char1VY += gravity char2VY += gravity} func checkBounds() { if char1X < 0 { char1X = 0 } if char1X > screenWidth/2-stlitWidth/2-charWidth { char1X = screenWidth/2 - stlitWidth/2 - charWidth } if char2X < screenWidth/2+stlitWidth/2 { char2X = screenWidth/2 + stlitWidth/2 } if char2X > screenWidth-charWidth { char2X = screenWidth - charWidth } if ball1X < 0 || ball1X > screenWidth/2-ballWidth { ball1VX = -ball1VX } if ball2X < screenWidth/2 || ball2X > screenWidth-ballWidth { ball2VX = -ball2VX }} func checkCollisions() { char1Rect := image.Rect(int(char1X), int(char1Y), int(char1X+charWidth), int(char1Y+charHeight)) char2Rect := image.Rect(int(char2X), int(char2Y), int(char2X+charWidth), int(char2Y+charHeight)) ball1Rect := image.Rect(int(ball1X), int(ball1Y), int(ball1X+ballWidth), int(ball1Y+ballHeight)) ball2Rect := image.Rect(int(ball2X), int(ball2Y), int(ball2X+ballWidth), int(ball2Y+ballHeight)) if char1Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char1Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) }}

package main import ( "fmt" "image/color" "math/rand" "time" "golang.org/x/image/font" "golang.org/x/image/font/basicfont" "image" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/inpututil" "github.com/hajimehoshi/ebiten/v2/text") const ( screenWidth = 800 screenHeight = 600 stageHeight = 50 stlitWidth = 10 stlitHeight = 150 charWidth = 50 charHeight = 50 ballWidth = 20 ballHeight = 20) var ( backgroundColor = color.RGBA{255, 255, 255, 255} // 흰색 stageColor = color.RGBA{0, 0, 0, 255} // 검정색 stlitColor = color.RGBA{0, 0, 255, 255} // 파란색 char1Color = color.RGBA{255, 0, 0, 255} // 빨간색 char2Color = color.RGBA{0, 255, 0, 255} // 녹색 ball1Color = color.RGBA{255, 255, 0, 255} // 노란색 ball2Color = color.RGBA{0, 255, 255, 255} // 하늘색 char1X, char1Y float64 char2X, char2Y float64 char1VX, char1VY float64 char2VX, char2VY float64 ball1X, ball1Y float64 ball2X, ball2Y float64 ball1VX, ball1VY float64 ball2VX, ball2VY float64 score1, score2 int gameOver bool gameResult string gravity float64 = 0.5 face font.Face) type Game struct{} func (g *Game) Update() error { if gameOver { if inpututil.IsKeyJustPressed(ebiten.KeyR) { initializeGame() } return nil } handleInput() char1X += char1VX char1Y += char1VY char2X += char2VX char2Y += char2VY ball1X += ball1VX ball1Y += ball1VY ball2X += ball2VX ball2Y += ball2VY ball1VY += gravity ball2VY += gravity checkBounds() if char1Y < 0 { char1Y = 0 } if char1Y > screenHeight-stageHeight-charHeight { char1Y = screenHeight - stageHeight - charHeight } if char2Y < 0 { char2Y = 0 } if char2Y > screenHeight-stageHeight-charHeight { char2Y = screenHeight - stageHeight - charHeight } if ball1Y > screenHeight-ballHeight-stageHeight { if ball1X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball2Y > screenHeight-ballHeight-stageHeight { if ball2X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball1Y < 0 { ball1Y = 0 ball1VY = 3 } if ball2Y < 0 { ball2Y = 0 ball2VY = 3 } checkCollisions() // 중앙선을 넘어가지 않도록 설정 if ball1X > screenWidth/2-ballWidth { ball1X = screenWidth/2 - ballWidth ball1VX = -ball1VX } if ball2X < screenWidth/2 { ball2X = screenWidth / 2 ball2VX = -ball2VX } if score1 == 5 { gameResult = "Player1 WIN" gameOver = true } else if score2 == 5 { gameResult = "Player2 WIN" gameOver = true } return nil} func (g *Game) Draw(screen ebiten.Image) { screen.Fill(backgroundColor) ebitenutil.DrawRect(screen, 0, screenHeight-stageHeight, screenWidth, stageHeight, stageColor) ebitenutil.DrawRect(screen, screenWidth/2-stlitWidth/2, screenHeight-stlitHeight-stageHeight, stlitWidth, stlitHeight, stlitColor) ebitenutil.DrawRect(screen, char1X, char1Y, charWidth, charHeight, char1Color) ebitenutil.DrawRect(screen, char2X, char2Y, charWidth, charHeight, char2Color) ebitenutil.DrawRect(screen, ball1X, ball1Y, ballWidth, ballHeight, ball1Color) ebitenutil.DrawRect(screen, ball2X, ball2Y, ballWidth, ballHeight, ball2Color) // 점수를 각 구역의 중앙쯤에 큰 글씨로 표시 score1Str := fmt.Sprintf("%d", score1) score2Str := fmt.Sprintf("%d", score2) text.Draw(screen, score1Str, face, screenWidth/4-len(score1Str)20, 80, color.Black) text.Draw(screen, score2Str, face, screenWidth3/4-len(score2Str)20, 80, color.Black) if gameOver { text.Draw(screen, gameResult, face, screenWidth/2-len(gameResult)10, screenHeight/2, color.RGBA{255, 0, 0, 255}) }} func (g Game) Layout(outsideWidth, outsideHeight int) (int, int) { return screenWidth, screenHeight} func main() { rand.Seed(time.Now().UnixNano()) initializeGame() ebiten.SetWindowSize(screenWidth, screenHeight) ebiten.SetWindowTitle("공 튀기기") face = basicfont.Face7x13 if err := ebiten.RunGame(&Game{}); err != nil { panic(err) }} func initializeGame() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - bandwidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0 score1, score2 = 0, 0 gameResult = "" gameOver = false} func resetPositions() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - ballWidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0} func handleInput() { if ebiten.IsKeyPressed(ebiten.KeyA) { char1VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyD) { char1VX = 7 } else { char1VX = 0 } if ebiten.IsKeyPressed(ebiten.KeyLeft) { char2VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyRight) { char2VX = 7 } else { char2VX = 0 } if inpututil.IsKeyJustPressed(ebiten.KeySpace) { char1VY = -10 } if inpututil.IsKeyJustPressed(ebiten.KeyEnter) { char2VY = -10 } char1VY += gravity char2VY += gravity} func checkBounds() { if char1X < 0 { char1X = 0 } if char1X > screenWidth/2-stlitWidth/2-charWidth { char1X = screenWidth/2 - stlitWidth/2 - charWidth } if char2X < screenWidth/2+stlitWidth/2 { char2X = screenWidth/2 + stlitWidth/2 } if char2X > screenWidth-charWidth { char2X = screenWidth - charWidth } if ball1X < 0 || ball1X > screenWidth/2-ballWidth { ball1VX = -ball1VX } if ball2X < screenWidth/2 || ball2X > screenWidth-ballWidth { ball2VX = -ball2VX }} func checkCollisions() { char1Rect := image.Rect(int(char1X), int(char1Y), int(char1X+charWidth), int(char1Y+charHeight)) char2Rect := image.Rect(int(char2X), int(char2Y), int(char2X+charWidth), int(char2Y+charHeight)) ball1Rect := image.Rect(int(ball1X), int(ball1Y), int(ball1X+ballWidth), int(ball1Y+ballHeight)) ball2Rect := image.Rect(int(ball2X), int(ball2Y), int(ball2X+ballWidth), int(ball2Y+ballHeight)) if char1Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char1Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) }}

package main import ( "fmt" "image/color" "math/rand" "time" "golang.org/x/image/font" "golang.org/x/image/font/basicfont" "image" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/inpututil" "github.com/hajimehoshi/ebiten/v2/text") const ( screenWidth = 800 screenHeight = 600 stageHeight = 50 stlitWidth = 10 stlitHeight = 150 charWidth = 50 charHeight = 50 ballWidth = 20 ballHeight = 20) var ( backgroundColor = color.RGBA{255, 255, 255, 255} // 흰색 stageColor = color.RGBA{0, 0, 0, 255} // 검정색 stlitColor = color.RGBA{0, 0, 255, 255} // 파란색 char1Color = color.RGBA{255, 0, 0, 255} // 빨간색 char2Color = color.RGBA{0, 255, 0, 255} // 녹색 ball1Color = color.RGBA{255, 255, 0, 255} // 노란색 ball2Color = color.RGBA{0, 255, 255, 255} // 하늘색 char1X, char1Y float64 char2X, char2Y float64 char1VX, char1VY float64 char2VX, char2VY float64 ball1X, ball1Y float64 ball2X, ball2Y float64 ball1VX, ball1VY float64 ball2VX, ball2VY float64 score1, score2 int gameOver bool gameResult string gravity float64 = 0.5 face font.Face) type Game struct{} func (g *Game) Update() error { if gameOver { if inpututil.IsKeyJustPressed(ebiten.KeyR) { initializeGame() } return nil } handleInput() char1X += char1VX char1Y += char1VY char2X += char2VX char2Y += char2VY ball1X += ball1VX ball1Y += ball1VY ball2X += ball2VX ball2Y += ball2VY ball1VY += gravity ball2VY += gravity checkBounds() if char1Y < 0 { char1Y = 0 } if char1Y > screenHeight-stageHeight-charHeight { char1Y = screenHeight - stageHeight - charHeight } if char2Y < 0 { char2Y = 0 } if char2Y > screenHeight-stageHeight-charHeight { char2Y = screenHeight - stageHeight - charHeight } if ball1Y > screenHeight-ballHeight-stageHeight { if ball1X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball2Y > screenHeight-ballHeight-stageHeight { if ball2X < screenWidth/2-stlitWidth/2 { score2++ } else { score1++ } resetPositions() } if ball1Y < 0 { ball1Y = 0 ball1VY = 3 } if ball2Y < 0 { ball2Y = 0 ball2VY = 3 } checkCollisions() // 중앙선을 넘어가지 않도록 설정 if ball1X > screenWidth/2-ballWidth { ball1X = screenWidth/2 - ballWidth ball1VX = -ball1VX } if ball2X < screenWidth/2 { ball2X = screenWidth / 2 ball2VX = -ball2VX } if score1 == 5 { gameResult = "Player1 WIN" gameOver = true } else if score2 == 5 { gameResult = "Player2 WIN" gameOver = true } return nil} func (g *Game) Draw(screen ebiten.Image) { screen.Fill(backgroundColor) ebitenutil.DrawRect(screen, 0, screenHeight-stageHeight, screenWidth, stageHeight, stageColor) ebitenutil.DrawRect(screen, screenWidth/2-stlitWidth/2, screenHeight-stlitHeight-stageHeight, stlitWidth, stlitHeight, stlitColor) ebitenutil.DrawRect(screen, char1X, char1Y, charWidth, charHeight, char1Color) ebitenutil.DrawRect(screen, char2X, char2Y, charWidth, charHeight, char2Color) ebitenutil.DrawRect(screen, ball1X, ball1Y, ballWidth, ballHeight, ball1Color) ebitenutil.DrawRect(screen, ball2X, ball2Y, ballWidth, ballHeight, ball2Color) // 점수를 각 구역의 중앙쯤에 큰 글씨로 표시 score1Str := fmt.Sprintf("%d", score1) score2Str := fmt.Sprintf("%d", score2) text.Draw(screen, score1Str, face, screenWidth/4-len(score1Str)20, 80, color.Black) text.Draw(screen, score2Str, face, screenWidth3/4-len(score2Str)20, 80, color.Black) if gameOver { text.Draw(screen, gameResult, face, screenWidth/2-len(gameResult)10, screenHeight/2, color.RGBA{255, 0, 0, 255}) }} func (g Game) Layout(outsideWidth, outsideHeight int) (int, int) { return screenWidth, screenHeight} func main() { rand.Seed(time.Now().UnixNano()) initializeGame() ebiten.SetWindowSize(screenWidth, screenHeight) ebiten.SetWindowTitle("공 튀기기") face = basicfont.Face7x13 if err := ebiten.RunGame(&Game{}); err != nil { panic(err) }} func initializeGame() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - ballWidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0 score1, score2 = 0, 0 gameResult = "" gameOver = false} func resetPositions() { char1X = screenWidth/4 - charWidth/2 char1Y = screenHeight - charHeight - stageHeight char1VX, char1VY = 0, 0 char2X = screenWidth3/4 - charWidth/2 char2Y = screenHeight - charHeight - stageHeight char2VX, char2VY = 0, 0 ball1X = screenWidth/4 - ballWidth/2 ball1Y = 0 ball1VX = float64(rand.Intn(6) - 3) ball1VY = 0 ball2X = screenWidth3/4 - ballWidth/2 ball2Y = 0 ball2VX = float64(rand.Intn(6) - 3) ball2VY = 0} func handleInput() { if ebiten.IsKeyPressed(ebiten.KeyA) { char1VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyD) { char1VX = 7 } else { char1VX = 0 } if ebiten.IsKeyPressed(ebiten.KeyLeft) { char2VX = -7 } else if ebiten.IsKeyPressed(ebiten.KeyRight) { char2VX = 7 } else { char2VX = 0 } if inpututil.IsKeyJustPressed(ebiten.KeySpace) { char1VY = -10 } if inpututil.IsKeyJustPressed(ebiten.KeyEnter) { char2VY = -10 } char1VY += gravity char2VY += gravity} func checkBounds() { if char1X < 0 { char1X = 0 } if char1X > screenWidth/2-stlitWidth/2-charWidth { char1X = screenWidth/2 - stlitWidth/2 - charWidth } if char2X < screenWidth/2+stlitWidth/2 { char2X = screenWidth/2 + stlitWidth/2 } if char2X > screenWidth-charWidth { char2X = screenWidth - charWidth } if ball1X < 0 || ball1X > screenWidth/2-ballWidth { ball1VX = -ball1VX } if ball2X < screenWidth/2 || ball2X > screenWidth-ballWidth { ball2VX = -ball2VX }} func checkCollisions() { char1Rect := image.Rect(int(char1X), int(char1Y), int(char1X+charWidth), int(char1Y+charHeight)) char2Rect := image.Rect(int(char2X), int(char2Y), int(char2X+charWidth), int(char2Y+charHeight)) ball1Rect := image.Rect(int(ball1X), int(ball1Y), int(ball1X+ballWidth), int(ball1Y+ballHeight)) ball2Rect := image.Rect(int(ball2X), int(ball2Y), int(ball2X+ballWidth), int(ball2Y+ballHeight)) if char1Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball1Rect) { ball1VY = -15 ball1VX = float64(rand.Intn(6) - 3) } if char1Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) } if char2Rect.Overlaps(ball2Rect) { ball2VY = -15 ball2VX = float64(rand.Intn(6) - 3) }}