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

【首先】

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. Jetpack Compose学习(15)——Pager组件的使用(对标ViewPager)

    原文地址: Jetpack Compose学习(15)--Pager组件的使用(对标ViewPager)-Stars-One的杂货小窝 从名字可以看出,Pager这个就是ViewPager的替代产物 ...

  2. 12C++循环结构-for循环(2)——教学

    一.循环变量为字符型 (第32课 26个兄弟姐妹)参考视频1 试编一程序,按字典顺序输出26个字母. 流程图: 思考:先顺序输出26个小写英文字母,再逆序输出26个大写英文字母. 循环可以是递增型循环 ...

  3. 云数据备份 | MySQL、SQL Server 数据备份到 COS

    随着互联网高速发展,数据安全的重要性日趋明显.数据备份是企业应对系统故障的重要手段.数据备份可以提高系统的高可用性和灾难可恢复性,使用备份还原数据是系统崩溃时提供数据恢复最小代价的最优方案. 一.云数 ...

  4. 小程序canvas白屏解决(

    造成canvas白屏的原因(两个原因) 1. 使用网络图片经绘制,没有配置downloadfile域名 ctx.drawImage('https://img1.imgtn.bdimg.com/it/u ...

  5. KTL 用C++14写公式的K线工具 - 0.9.3版

    K,K线,Candle蜡烛图. T,技术分析,工具平台 L,公式Language语言使用c++14,Lite小巧简易. 项目仓库:https://github.com/bbqz007/KTL 国内仓库 ...

  6. Android信任证书,把用户级别放入系统级别

    三.操作步骤 1.在Windows安装openssl,用来把证书转成 .pem 格式 1)下载和安装 下载其他人做的便捷版安装包:http://slproweb.com/products/Win32O ...

  7. MyBatisPlus中updateById与updateAllColumnById方法区别

    实现 updateById方法在插入时,会根据实体类的每个属性进行非空判断,只有非空的属性所对应的字段才会出现在SQL语句中. updateAllColumnById方法在插入时,不管属性是否为空,属 ...

  8. 推荐一个C#轻量级矢量图形库

    推荐一个轻量级矢量图形库,可用于生成 PDF.SVG.PNG等. 01 项目简介 VectSharp 是一个功能强大的 C# 库,专门用于创建矢量图形,包括文本,不依赖任何第三方,支持跨平台运行,包括 ...

  9. 一次 Spring 扫描 @Component 注解修饰的类坑

    问题现象 之前遇到过一个问题,在一个微服务的目录下有相同功能 jar 包的两个不同的版本,其中一个版本里面的类有 @Component 注解,另外一个版本的类里面没有 @Component 注解,且按 ...

  10. 网络编程懒人入门(十六):手把手教你使用网络编程抓包神器Wireshark

    本文由转转QA刘宝成分享,原题"抓包工具wireshark的使用",下文进行了排版和内容优化. 1.引言 跟网络通信有关的应用场景下(比如Web系统.IM聊天应用.消息推送系统等) ...