parent
692cac6920
commit
4d0d0bb8a6
|
@ -107,7 +107,7 @@ linters-settings:
|
|||
# https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#add-constant
|
||||
- name: add-constant
|
||||
severity: warning
|
||||
disabled: false
|
||||
disabled: true
|
||||
arguments:
|
||||
- maxLitCount: "3"
|
||||
allowStrs: "\"\""
|
||||
|
|
65
internal/ball.go
Normal file
65
internal/ball.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/vector"
|
||||
)
|
||||
|
||||
type ball struct {
|
||||
x float32
|
||||
speedX float32
|
||||
y float32
|
||||
speedY float32
|
||||
r float32
|
||||
}
|
||||
|
||||
const (
|
||||
ballBaselRadius = 5
|
||||
ballBaseSpeedX = 1
|
||||
ballBaseSpeedY = 1
|
||||
)
|
||||
|
||||
func newBall(screenWidth, screenHeight int) *ball {
|
||||
fScreenWidth := float32(screenWidth)
|
||||
fScreenHeight := float32(screenHeight)
|
||||
r := ballBaselRadius * fScreenHeight / BaseHeight
|
||||
return &ball{
|
||||
x: fScreenWidth/2.0 - r,
|
||||
speedX: ballBaseSpeedX * fScreenWidth / BaseWidth,
|
||||
y: fScreenHeight/2.0 - r,
|
||||
speedY: ballBaseSpeedY * fScreenHeight / BaseHeight,
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
var ballColor = color.White
|
||||
|
||||
func (b *ball) draw(img *ebiten.Image) {
|
||||
vector.DrawFilledCircle(img, b.x, b.y, b.r, ballColor, false)
|
||||
}
|
||||
|
||||
func (b *ball) update(bounds image.Rectangle) error {
|
||||
if b.x+b.r >= float32(bounds.Max.X) || b.x-b.r <= float32(bounds.Min.X) {
|
||||
b.speedX *= -1
|
||||
}
|
||||
|
||||
if b.y+b.r >= float32(bounds.Max.Y) || b.y-b.r <= float32(bounds.Min.Y) {
|
||||
b.speedY *= -1
|
||||
}
|
||||
|
||||
b.x += b.speedX
|
||||
b.y += b.speedY
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *ball) resize(x, y float32) {
|
||||
b.x *= x
|
||||
b.speedX *= x
|
||||
b.y *= y
|
||||
b.speedY *= y
|
||||
b.r *= y
|
||||
}
|
89
internal/game.go
Normal file
89
internal/game.go
Normal file
|
@ -0,0 +1,89 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
)
|
||||
|
||||
const (
|
||||
BaseWidth = 640
|
||||
BaseHeight = 360
|
||||
)
|
||||
|
||||
type Game struct {
|
||||
width int
|
||||
height int
|
||||
ball *ball
|
||||
debug bool
|
||||
img *ebiten.Image
|
||||
}
|
||||
|
||||
var _ ebiten.Game = (*Game)(nil)
|
||||
|
||||
func NewGame(width, height int, debug bool) *Game {
|
||||
return &Game{
|
||||
width: width,
|
||||
height: height,
|
||||
ball: newBall(width, height),
|
||||
debug: debug,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Game) Update() error {
|
||||
return g.ball.update(image.Rect(0, 0, g.width, g.height))
|
||||
}
|
||||
|
||||
var backgroundColor = color.Black
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
if g.img == nil {
|
||||
g.img = ebiten.NewImage(g.width, g.height)
|
||||
}
|
||||
|
||||
g.img.Fill(backgroundColor)
|
||||
|
||||
g.ball.draw(g.img)
|
||||
|
||||
if g.debug {
|
||||
g.drawDebug()
|
||||
}
|
||||
|
||||
screen.DrawImage(g.img, nil)
|
||||
}
|
||||
|
||||
func (g *Game) drawDebug() {
|
||||
ebitenutil.DebugPrint(
|
||||
g.img,
|
||||
fmt.Sprintf(
|
||||
"FPS: %0.2f"+
|
||||
"\nBall: x=%v, y=%v, speedX=%v, speedY=%v, radius=%v",
|
||||
ebiten.ActualFPS(),
|
||||
g.ball.x,
|
||||
g.ball.y,
|
||||
g.ball.speedX,
|
||||
g.ball.speedY,
|
||||
g.ball.r,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
//nolint:nonamedreturns
|
||||
func (g *Game) Layout(outsideWidth, outsideHeight int) (_screenWidth, _screenHeight int) {
|
||||
if g.width != outsideWidth || g.height != outsideHeight {
|
||||
g.ball.resize(float32(outsideWidth)/float32(g.width), float32(outsideHeight)/float32(g.height))
|
||||
|
||||
if g.img != nil {
|
||||
g.img.Dispose()
|
||||
g.img = nil
|
||||
}
|
||||
|
||||
g.width = outsideWidth
|
||||
g.height = outsideHeight
|
||||
}
|
||||
|
||||
return outsideWidth, outsideHeight
|
||||
}
|
49
main.go
49
main.go
|
@ -1,43 +1,30 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"gitea.dwysokinski.me/classic-games/tennis-game/internal"
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
|
||||
)
|
||||
|
||||
type Game struct{}
|
||||
|
||||
var _ ebiten.Game = (*Game)(nil)
|
||||
|
||||
func (g *Game) Update() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *Game) Draw(screen *ebiten.Image) {
|
||||
ebitenutil.DebugPrint(screen, "Hello, World!")
|
||||
}
|
||||
|
||||
const (
|
||||
screenWidth = 320
|
||||
screenHeight = 240
|
||||
)
|
||||
|
||||
//nolint:nonamedreturns
|
||||
func (g *Game) Layout(_, _ int) (_screenWidth, _screenHeight int) {
|
||||
return screenWidth, screenHeight
|
||||
}
|
||||
|
||||
const (
|
||||
windowWidth = 640
|
||||
windowHeight = 480
|
||||
)
|
||||
|
||||
func main() {
|
||||
ebiten.SetWindowSize(windowWidth, windowHeight)
|
||||
ebiten.SetWindowTitle("Hello, World!")
|
||||
if err := ebiten.RunGame(&Game{}); err != nil {
|
||||
fullscreen := flag.Bool("fullscreen", true, "")
|
||||
debug := flag.Bool("debug", false, "")
|
||||
flag.Parse()
|
||||
|
||||
ebiten.SetWindowTitle("Tennis game")
|
||||
ebiten.SetWindowResizingMode(ebiten.WindowResizingModeEnabled)
|
||||
ebiten.SetWindowSizeLimits(internal.BaseWidth, internal.BaseHeight, -1, -1)
|
||||
w, h := ebiten.ScreenSizeInFullscreen()
|
||||
|
||||
if *fullscreen {
|
||||
ebiten.SetFullscreen(true)
|
||||
} else {
|
||||
ebiten.SetWindowSize(w, h)
|
||||
}
|
||||
|
||||
if err := ebiten.RunGame(internal.NewGame(w, h, *debug)); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user