可以看到,虽然非常抽象简单,但是基础游戏框架已经搭建,游戏机制完善,就缺美工了,哈哈~~~~

【首先】

Powershell不是用来开发游戏的,但是没人规定不能开发。因为它可以调取windows下的程序集,比如 .net framework。因此我们可以猜想,只要能开启一个实时刷新的窗口,就可以在窗口内绘制图形和文字。至于实时刷新的窗口如何实现,则需要调取程序集,如下:

Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms

Drawing 负责绘制任务

WindowsForm负责管理窗口

然后关键的操作是,设计一个定时器,让其不断地触发,不断地让其绘制新的图形。

# 定时器用于控制游戏更新,每秒触发 60 次(约 16.67 毫秒)
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 16.67

然后设计定时器触发事件

$timer.Add_Tick({
// ...
})

在定时器触发事件中写上这句:

$form.Invalidate()

即让每次触发时,让窗体重新paint一次,因此,需要定义窗体的 Paint 事件处理程序

$form.Add_Paint({
// ...
})

剩下的就是交互动画设计基础了,三部曲 【初始化 - 更新 - 绘画】

【程序】

# 加载必要的程序集
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms # 创建窗体
$form = New-Object System.Windows.Forms.Form
$form.Text = "打蜜蜂小游戏"
$form.Size = New-Object System.Drawing.Size(800, 600)
$form.BackColor = [System.Drawing.Color]::Black
$form.StartPosition = "CenterScreen"
$form.KeyPreview = $true # 启用双缓冲以减少闪烁
$doubleBufferProperty = $form.GetType().GetProperty("DoubleBuffered", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance)
$doubleBufferProperty.SetValue($form, $true, $null) # 定义飞机
$planeWidth = 50
$planeHeight = 30
$planeX = ($form.ClientSize.Width - $planeWidth) / 2
$planeY = $form.ClientSize.Height - $planeHeight - 10 # 定义蜜蜂
$beeSize = 40
$bees = New-Object System.Collections.Generic.List[object]
$beeFallSpeed = 0.5 # 定义子弹
$bulletSize = 5
$bullets = New-Object System.Collections.Generic.List[object]
$bulletSpeed = 10 # 定义计分板,初始分数设为 100
$score = 100
$font = New-Object System.Drawing.Font("Arial", 20)
$brush = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::White) # 定时器用于控制游戏更新,每秒触发 60 次(约 16.67 毫秒,设为 17 毫秒)
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 17
$beeSpawnCounter = 0 # 重置游戏的函数
function ResetGame {
$script:planeX = ($form.ClientSize.Width - $planeWidth) / 2
$script:bees.Clear()
$script:bullets.Clear()
$script:score = 100
$script:beeSpawnCounter = 0
} # 定时器的 Tick 事件处理程序
$timer.Add_Tick({
param($sender, $e)
try {
$script:beeSpawnCounter++
Write-Host "定时器触发,当前计数: $beeSpawnCounter" # 调试信息,显示定时器触发及计数情况 # 控制蜜蜂每秒生成 1 只
if ($beeSpawnCounter % 60 -eq 0) { # 每秒触发 60 次,每 60 次生成 1 只蜜蜂
$beeX = Get-Random -Minimum 0 -Maximum ($form.ClientSize.Width - $beeSize)
$bees.Add(@{
X = $beeX
Y = 0
})
Write-Host "生成蜜蜂,X: $beeX, Y: 0" # 调试信息,显示蜜蜂生成信息
} # 更新蜜蜂位置
for ($i = $bees.Count - 1; $i -ge 0; $i--) {
$bee = $bees[$i]
$bee.Y += $beeFallSpeed
if ($bee.Y -ge $form.ClientSize.Height) {
$bees.RemoveAt($i)
# 蜜蜂到达画面底部,扣 10 分
$script:score = [Math]::Max(0, $score - 10)
}
} # 更新子弹位置
for ($i = $bullets.Count - 1; $i -ge 0; $i--) {
$bullet = $bullets[$i]
$bullet.Y -= $bulletSpeed
if ($bullet.Y -lt 0) {
$bullets.RemoveAt($i)
}
} # 检查子弹是否击中蜜蜂
for ($i = $bullets.Count - 1; $i -ge 0; $i--) {
$bullet = $bullets[$i]
for ($j = $bees.Count - 1; $j -ge 0; $j--) {
$bee = $bees[$j]
if ($bullet.X -lt $bee.X + $beeSize -and $bullet.X + $bulletSize -gt $bee.X -and
$bullet.Y -lt $bee.Y + $beeSize -and $bullet.Y + $bulletSize -gt $bee.Y) {
$bees.RemoveAt($j)
$bullets.RemoveAt($i)
break
}
}
} # 检查蜜蜂是否碰撞到飞机(不做得分和消失处理)
foreach ($bee in $bees) {
if ($bee.Y + $beeSize -ge $planeY -and $bee.X + $beeSize -ge $planeX -and $bee.X -le $planeX + $planeWidth) {
# 不做任何处理,蜜蜂继续下落
}
} # 检查分数是否为 0,为 0 则重置游戏
if ($score -eq 0) {
ResetGame
} $form.Invalidate()
}
catch {
Write-Host "定时器 Tick 事件处理出错: $_"
Write-Host $_.ScriptStackTrace
}
}) # 窗体的 MouseMove 事件处理程序,用于通过鼠标控制飞机位置
$form.Add_MouseMove({
param($sender, $e)
$newX = $e.X - $planeWidth / 2
if ($newX -ge 0 -and $newX + $planeWidth -le $form.ClientSize.Width) {
$script:planeX = $newX
}
}) # 窗体的 MouseClick 事件处理程序,用于通过鼠标点击发射子弹
$form.Add_MouseClick({
param($sender, $e)
$bullets.Add(@{
X = $planeX + $planeWidth / 2 - $bulletSize / 2
Y = $planeY
})
}) # 窗体的 Paint 事件处理程序,用于绘制游戏元素
$form.Add_Paint({
param($sender, $e)
$graphics = $e.Graphics # 绘制飞机
$graphics.FillRectangle([System.Drawing.Brushes]::Blue, $planeX, $planeY, $planeWidth, $planeHeight) # 绘制蜜蜂
foreach ($bee in $bees) {
$graphics.FillEllipse([System.Drawing.Brushes]::Yellow, $bee.X, $bee.Y, $beeSize, $beeSize)
} # 绘制子弹
foreach ($bullet in $bullets) {
$graphics.FillRectangle([System.Drawing.Brushes]::Red, $bullet.X, $bullet.Y, $bulletSize, $bulletSize)
} # 绘制计分板
$graphics.DrawString("Score: $score", $font, $brush, 10, 10)
}) # 窗体关闭事件处理程序,用于清空数据缓存
$form.Add_FormClosing({
param($sender, $e)
ResetGame
Write-Host "数据缓存已清空"
}) # 启动定时器
$timer.Start() # 显示窗体
$form.ShowDialog()

PS:

注意程序健壮性,添加异常捕获,注意数据的冗余,即时清空消除。

【最后】

可以看到,Powershell可以开发游戏,这只是象征性尝试,我们还是关注它擅长的领域。不过,这次尝试让笔者很开心,因为即使不借助任何软件或程序开发框架也能开发应用,想想就很酷 !~!··· ···

PowerShell开发游戏 · 打蜜蜂的更多相关文章

  1. GJM : 各大开发游戏引擎

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  2. 独立开发游戏越来越容易:Unity 发布旗下的最新游戏引擎 Unity 5,依然有免费版(转)

    独立开发者开发游戏正变得越来越容易,因为在游戏设计中很多吃力不讨好的工作可以直接采用像 Epic Games 或 Unity Technologies 这样的游戏引擎来解决.而这几天,游戏引擎商们先后 ...

  3. 【转】针对iOS VS. Android开发游戏的优劣——2013-08-25 17

    http://game.dapps.net/gamedev/experience/8670.html 问题:如果你正在一个新工作室开发一款新的平板/手机游戏,你会选择iOS还是Android? 回答: ...

  4. 【C语言探索之旅】 第三部分第二课:SDL开发游戏之创建窗口和画布

    内容简介 1.第三部分第二课: SDL开发游戏之创建窗口和画布 2.第三部分第三课预告: SDL开发游戏之显示图像 第三部分第二课:SDL开发游戏之创建窗口和画布 在上一课中,我们对SDL这个开源库做 ...

  5. 【C语言探索之旅】 第三部分第一课:SDL开发游戏之安装SDL

    内容简介 1.课程大纲 2.第三部分第一课: SDL开发游戏之安装SDL 3.第三部分第二课预告: SDL开发游戏之创建窗口和画布 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会 ...

  6. 使用 Unity 3D 开发游戏的架构设计难点

    Unity 3D 引擎对于开发者来说,入手非常快,因为它采用的是 C# 作为开发语言,这也大大降低了开发者的门槛.但凡只要懂一门编程语言的人都能使用 Unity 3D 引擎开发,另外 Unity 3D ...

  7. Unity 开发游戏编写代码的技巧

    在平时开发游戏过程中,遇到一些编写代码很繁琐的问题. 我发现我团队中每个人都会遇到,就算打写出来分享下经验. 条件断点 利用IDE提供的工具, 右键断点的时候 输入条件, 当条件达成的时候,断点才能命 ...

  8. dotNet开发游戏微端

    需求分析 功能要求 当玩家使用不支持 unity webplayer 的浏览器进入游戏时,让玩家通过微端玩游戏. 确保微端的功能和页游戏功能一致. 大体功能就是为unity web game开发微端, ...

  9. Unity 开发游戏Game分辨率设置

    最近自己开发小游戏,突然又被Game视图中设置分辨率被诱惑了, 我到底该怎么设置分辨率设置的图片才能让电脑和手机尺寸显示的大小一模一样呢? 然后又被手机尺寸和分辨率迷惑了! =.= 越搞越混   分辨 ...

  10. Unity3D游戏开发之开发游戏带来的问题

    昨日曾就某投资人把移动团队失败原因之中的一个归于选择Unity引擎进行了一番评论,工具本身无罪,但怎样理解工具.正确使用Unity引擎确实须要讨论,在选择Unity之前你也许须要了解下这个引擎实际开发 ...

随机推荐

  1. Redis应用—7.大Value处理方案

    大纲 1.⽅案设计 2.安装与配置环境 1.⽅案设计 步骤一:首先需要配置一个crontab定时调度shell脚本,然后该脚本每天凌晨会通过rdbtools⼯具解析Redis的RDB⽂件,接着对解析出 ...

  2. [.NET Blog] .NET Aspire 测试入门

    https://devblogs.microsoft.com/dotnet/getting-started-with-testing-and-dotnet-aspire/ 自动化测试是软件开发的重要一 ...

  3. 入门 .NET Aspire: 使用 .NET 简化云原生应用开发

    入门 .NET Aspire: 使用 .NET 简化云原生应用开发 https://devblogs.microsoft.com/dotnet/introducing-dotnet-aspire-si ...

  4. 动态 import()

    动态 import() https://v8.dev/features/dynamic-import Dynamic import() 引入了一个新的类似函数的功能,相比静态的 import 提供了新 ...

  5. arch 输入法

    输入法配置 输入法采用fcitx + Sogou的组合,安装需要的包: yay -S fcitx fcitx-im fcitx-configtool fcitx-sogoupinyin 然后写一个fc ...

  6. Ubuntu中文件夹建立软链接方法

    1:预备知识 -s 是代号(symbolic)的意思. 这里有两点要注意:第一,ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化:第二,ln的链接又软链 ...

  7. 用 Cursor 写出第一个程序

    大家好,我是汤师爷 最近几个月,Cursor迅速走红,成为一款强大的编程助手.Cursor不仅使用简单,而且通过集成各种大模型技术,编程能力一流. Cursor是什么? Cursor是一个类似VSCo ...

  8. modbus调试助手/mqtt调试工具/超轻巧物联网组件/多线程实时采集/各种协议支持

    一.前言说明 搞物联网开发很多年,用的最多的当属modbus协议,一个稳定好用的物联网组件是物联网平台持续运行多年的基石,所以这个物联网组件从一开始就定位于自研,为了满足各种场景的需求,当然最重要的一 ...

  9. Qt/C++推流程序(视频文件/视频流/摄像头/桌面转成流媒体rtmp+hls+webrtc)可在网页和播放器远程观看

    一.前言说明 推流直播就是把采集阶段封包好的内容传输到服务器的过程.其实就是将现场的视频信号从手机端,电脑端,摄影机端打包传到服务器的过程."推流"对网络要求比较高,如果网络不稳定 ...

  10. Dynamic CRM插件中获取Entity属性值问题

    插件中获取Entity不同类型字段时稍有区别,一般用如下两种方式: Entity targetEntity = (Entity)context.InputParameters["Target ...