当前位置: 首页 > article >正文

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) // 如果游戏运行错误,输出错误信息
	}
}


http://www.kler.cn/a/468514.html

相关文章:

  • 用户界面软件01
  • Docker:安装 XXL-JOB 分布式调度任务的技术指南
  • 前后端环境配置java/vue/maven/node.js/mysql
  • 【视觉SLAM:六、视觉里程计Ⅰ:特征点法】
  • AWS Auto Scaling基础知识
  • ChatGPT在数据分析与处理中的使用详解
  • 使用Dinky快速提交Flink operator任务
  • 【zig】0.zig的下载安装
  • 【Python基础语法】
  • Leecode刷题C语言之设计一个ATM机器
  • Gitee上传项目代码教程(详细)
  • MySQL中表之间关联不同方式操作详解
  • Spring Boot 的自动配置,以rabbitmq为例,请详细说明
  • 凸包(convex hull)简述
  • 全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(while循环语句)
  • 20241231在Ubuntu20.04.5系统中下载安装Android Studio 2024.2.1.12
  • Kafka 消费者专题
  • 如何通过本地部署的DIFY辅助学习算法(PS可以辅助帮你学习任何想学习的资料)
  • 探索WebAssembly:前端与后端的新未来
  • unity学习6:unity的3D项目的基本界面和菜单
  • MCP(Model Context Protocol)模型上下文协议 进阶篇3 - 传输
  • 互动为王:开源AI智能名片链动2+1模式商城小程序在社群运营中的深度应用与价值探索
  • 解锁AI Agent潜能:智能时代的信息处理利器2(18/30)
  • ES-深度分页问题
  • LeetCode题练习与总结:随机翻转矩阵--519
  • 使用FDBatchMove的几个问题总结