Go Ebiten小球弹性碰撞代码示例

Go Ebiten小球弹性碰撞代码示例

我们来编写一个简单的示例程序,在其中实现一个小球在窗口中弹性碰撞的效果。具体来说,当小球碰到窗口的边缘时,它会反弹回来,改变运动方向。我们将使用Ebiten的图形和物理模拟功能来实现这个效果。

woademo

代码解析

  1. 结构体定义

    • Position 用于表示小球的坐标(X和Y)。
    • Velocity 表示小球的速度,包含水平速度Vx和垂直速度Vy
    • Ball 结构体包含了小球的坐标、速度和半径。
  2. 游戏逻辑 (Update 方法)
    Update方法中,我们检查小球是否碰到窗口的边界。如果小球碰到边界(即小球的X或Y坐标超出了边界),我们就反转相应的速度(使得小球反弹回来)。这就是实现弹性碰撞的基本逻辑。

    if g.B.Pos.X <= g.B.R || g.B.Pos.X >= WindowWidth-g.B.R {
        g.B.V.Vx = -g.B.V.Vx // 水平方向速度取反,实现弹性碰撞
    }
    if g.B.Pos.Y <= g.B.R || g.B.Pos.Y >= WindowHeight-g.B.R {
        g.B.V.Vy = -g.B.V.Vy // 垂直方向速度取反,实现弹性碰撞
    }
    
  3. 绘制小球 (Draw 方法)
    Draw方法中,我们使用vector.DrawFilledCircle方法来绘制小球。小球的颜色是白色的,位置根据小球的坐标来确定。

  4. 随机初始化
    小球的初始位置和速度是通过rand.Float32()随机生成的,这样每次运行游戏时,都会有不同的效果。

完整代码

package main

import (
	"image/color"
	"math/rand/v2"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/vector"
)

const (
	WindowWidth  = 640 // 窗口宽度
	WindowHeight = 480 // 窗口高度
	ballRadius   = 20  // 小球的半径
)

// 定义小球的位置结构体
type Position struct {
	X, Y float32 // X 和 Y 坐标
}

// 定义小球的速度结构体
type Velocity struct {
	Vx, Vy float32 // X 和 Y 方向的速度
}

// 定义小球结构体
type Ball struct {
	Pos Position // 小球的位置
	V   Velocity // 小球的速度
	R   float32  // 小球的半径
}

// 游戏主结构体
type Game struct {
	B *Ball // 包含一个小球对象
}

// 游戏的逻辑更新函数
func (g *Game) Update() error {
	// 检测小球是否碰到左右墙壁
	if g.B.Pos.X <= g.B.R || g.B.Pos.X >= WindowWidth-g.B.R {
		g.B.V.Vx = -g.B.V.Vx // 水平方向速度取反,实现弹性碰撞
	}

	// 检测小球是否碰到上下墙壁
	if g.B.Pos.Y <= g.B.R || g.B.Pos.Y >= WindowHeight-g.B.R {
		g.B.V.Vy = -g.B.V.Vy // 垂直方向速度取反,实现弹性碰撞
	}

	// 更新小球的位置
	g.B.Pos.X += g.B.V.Vx
	g.B.Pos.Y += g.B.V.Vy

	return nil
}

// 游戏的绘制函数
func (g *Game) Draw(screen *ebiten.Image) {
	// 绘制小球,使用白色填充
	vector.DrawFilledCircle(screen, g.B.Pos.X, g.B.Pos.Y, g.B.R, color.White, true)
}

// 游戏窗口的布局设置函数
func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	return outsideWidth, outsideHeight // 返回窗口大小
}

// 主函数
func main() {
	// 设置窗口大小
	ebiten.SetWindowSize(WindowWidth, WindowHeight)

	// 设置窗口标题
	ebiten.SetWindowTitle("Ball dome")

	// 初始化一个小球
	ball := &Ball{
		// 随机初始化小球的位置
		Position{
			X: WindowWidth * rand.Float32(),  // 随机X坐标
			Y: WindowHeight * rand.Float32(), // 随机Y坐标
		},
		// 随机初始化小球的速度
		Velocity{
			Vx: 2 * rand.Float32(), // 随机水平速度
			Vy: 2 * rand.Float32(), // 随机垂直速度
		},
		ballRadius, // 小球半径
	}

	// 启动游戏
	if err := ebiten.RunGame(&Game{ball}); err != nil {
		panic(err) // 如果游戏运行错误,输出错误信息
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值