- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些现有的 C# 代码,用于一个非常非常简单的 RogueLike 引擎。故意天真,因为我试图尽可能简单地做最少的事情。它所做的只是使用箭头键和 System.Console 在硬编码 map 周围移动 @ 符号:
//define the map
var map = new List<string>{
" ",
" ",
" ",
" ",
" ############################### ",
" # # ",
" # ###### # ",
" # # # # ",
" #### #### # # # ",
" # # # # # # ",
" # # # # # # ",
" #### #### ###### # ",
" # = # ",
" # = # ",
" ############################### ",
" ",
" ",
" ",
" ",
" "
};
//set initial player position on the map
var playerX = 8;
var playerY = 6;
//clear the console
Console.Clear();
//send each row of the map to the Console
map.ForEach( Console.WriteLine );
//create an empty ConsoleKeyInfo for storing the last key pressed
var keyInfo = new ConsoleKeyInfo( );
//keep processing key presses until the player wants to quit
while ( keyInfo.Key != ConsoleKey.Q ) {
//store the player's current location
var oldX = playerX;
var oldY = playerY;
//change the player's location if they pressed an arrow key
switch ( keyInfo.Key ) {
case ConsoleKey.UpArrow:
playerY--;
break;
case ConsoleKey.DownArrow:
playerY++;
break;
case ConsoleKey.LeftArrow:
playerX--;
break;
case ConsoleKey.RightArrow:
playerX++;
break;
}
//check if the square that the player is trying to move to is empty
if( map[ playerY ][ playerX ] == ' ' ) {
//ok it was empty, clear the square they were standing on before
Console.SetCursorPosition( oldX, oldY );
Console.Write( ' ' );
//now draw them at the new square
Console.SetCursorPosition( playerX, playerY );
Console.Write( '@' );
} else {
//they can't move there, change their location back to the old location
playerX = oldX;
playerY = oldY;
}
//wait for them to press a key and store it in keyInfo
keyInfo = Console.ReadKey( true );
}
open System
//define the map
let map = [ " ";
" ";
" ";
" ";
" ############################### ";
" # # ";
" # ###### # ";
" # # # # ";
" #### #### # # # ";
" # # # # # # ";
" # # # # # # ";
" #### #### ###### # ";
" # = # ";
" # = # ";
" ############################### ";
" ";
" ";
" ";
" ";
" " ]
//set initial player position on the map
let mutable playerX = 8
let mutable playerY = 6
//clear the console
Console.Clear()
//send each row of the map to the Console
map |> Seq.iter (printfn "%s")
//create an empty ConsoleKeyInfo for storing the last key pressed
let mutable keyInfo = ConsoleKeyInfo()
//keep processing key presses until the player wants to quit
while not ( keyInfo.Key = ConsoleKey.Q ) do
//store the player's current location
let mutable oldX = playerX
let mutable oldY = playerY
//change the player's location if they pressed an arrow key
if keyInfo.Key = ConsoleKey.UpArrow then
playerY <- playerY - 1
else if keyInfo.Key = ConsoleKey.DownArrow then
playerY <- playerY + 1
else if keyInfo.Key = ConsoleKey.LeftArrow then
playerX <- playerX - 1
else if keyInfo.Key = ConsoleKey.RightArrow then
playerX <- playerX + 1
//check if the square that the player is trying to move to is empty
if map.Item( playerY ).Chars( playerX ) = ' ' then
//ok it was empty, clear the square they were standing on
Console.SetCursorPosition( oldX, oldY )
Console.Write( ' ' )
//now draw them at the new square
Console.SetCursorPosition( playerX, playerY )
Console.Write( '@' )
else
//they can't move there, change their location back to the old location
playerX <- oldX
playerY <- oldY
//wait for them to press a key and store it in keyInfo
keyInfo <- Console.ReadKey( true )
最佳答案
一般而言,游戏编程将测试您管理复杂性的能力。我发现函数式编程鼓励您将解决的问题分解成更小的部分。
您要做的第一件事是通过分离所有不同的关注点,将您的脚本变成一堆函数。我知道这听起来很愚蠢,但这样做的行为将使代码更具功能性(双关语)。您主要关注的是状态管理。我用一个记录来管理位置状态,用一个元组来管理运行状态。随着您的代码变得更高级,您将需要对象来干净地管理状态。
尝试在此游戏中添加更多内容,并随着功能的增长不断分解这些功能。最终,您将需要对象来管理所有功能。
在游戏编程笔记上,不要将状态更改为其他内容,如果未通过某些测试,则将其更改回来。你想要最小的状态变化。因此,例如下面我计算了 newPosition
然后只更改 playerPosition
如果这个 future 的职位过去了。
open System
// use a third party vector class for 2D and 3D positions
// or write your own for pratice
type Pos = {x: int; y: int}
with
static member (+) (a, b) =
{x = a.x + b.x; y = a.y + b.y}
let drawBoard map =
//clear the console
Console.Clear()
//send each row of the map to the Console
map |> List.iter (printfn "%s")
let movePlayer (keyInfo : ConsoleKeyInfo) =
match keyInfo.Key with
| ConsoleKey.UpArrow -> {x = 0; y = -1}
| ConsoleKey.DownArrow -> {x = 0; y = 1}
| ConsoleKey.LeftArrow -> {x = -1; y = 0}
| ConsoleKey.RightArrow -> {x = 1; y = 0}
| _ -> {x = 0; y = 0}
let validPosition (map:string list) position =
map.Item(position.y).Chars(position.x) = ' '
//clear the square player was standing on
let clearPlayer position =
Console.SetCursorPosition(position.x, position.y)
Console.Write( ' ' )
//draw the square player is standing on
let drawPlayer position =
Console.SetCursorPosition(position.x, position.y)
Console.Write( '@' )
let takeTurn map playerPosition =
let keyInfo = Console.ReadKey true
// check to see if player wants to keep playing
let keepPlaying = keyInfo.Key <> ConsoleKey.Q
// get player movement from user input
let movement = movePlayer keyInfo
// calculate the players new position
let newPosition = playerPosition + movement
// check for valid move
let validMove = newPosition |> validPosition map
// update drawing if move was valid
if validMove then
clearPlayer playerPosition
drawPlayer newPosition
// return state
if validMove then
keepPlaying, newPosition
else
keepPlaying, playerPosition
// main game loop
let rec gameRun map playerPosition =
let keepPlaying, newPosition = playerPosition |> takeTurn map
if keepPlaying then
gameRun map newPosition
// setup game
let startGame map playerPosition =
drawBoard map
drawPlayer playerPosition
gameRun map playerPosition
//define the map
let map = [ " ";
" ";
" ";
" ";
" ############################### ";
" # # ";
" # ###### # ";
" # # # # ";
" #### #### # # # ";
" # # # # # # ";
" # # # # # # ";
" #### #### ###### # ";
" # = # ";
" # = # ";
" ############################### ";
" ";
" ";
" ";
" ";
" " ]
//initial player position on the map
let playerPosition = {x = 8; y = 6}
startGame map playerPosition
关于f# - 在 F# 中非常简单的 RogueLike,使它更 "functional",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4495993/
我正在努力实现以下目标, 假设我有字符串: ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ) ) ) ) ) 我想编写一个正则
给定: 1 2 3 4 5 6
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
大家好,我卡颂。 Svelte问世很久了,一直想写一篇好懂的原理分析文章,拖了这么久终于写了。 本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一
身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或者大写字母”X“。 与之匹配的正则表达式: ?
我们先来最简单的,网页的登录窗口; 不过开始之前,大家先下载jquery的插件 本人习惯用了vs2008来做网页了,先添加一个空白页 这是最简单的的做法。。。先在body里面插入 <
1、MySQL自带的压力测试工具 Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等
Go语言语法类似于C语言,因此熟悉C语言及其派生语言( C++、 C#、Objective-C 等)的人都会迅速熟悉这门语言。 C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的
我正在使用快速将 mkv 转换为 mp4 ffmpeg 命令 ffmpeg -i test.mkv -vcodec copy -acodec copy new.mp4 但不适用于任何 mkv 文件,当
我想计算我的工作簿中的工作表数量,然后从总数中减去特定的工作表。我错过了什么?这给了我一个对象错误: wsCount = ThisWorkbook.Sheets.Count - ThisWorkboo
我有一个 perl 文件,用于查看文件夹中是否存在 ini。如果是,它会从中读取,如果不是,它会根据我为它制作的模板创建一个。 我在 ini 部分使用 Config::Simple。 我的问题是,如果
尝试让一个 ViewController 通过标准 Cocoa 通知与另一个 ViewController 进行通信。 编写了一个简单的测试用例。在我最初的 VC 中,我将以下内容添加到 viewDi
我正在绘制高程剖面图,显示沿路径的高程增益/损失,类似于下面的: Sample Elevation Profile with hand-placed labels http://img38.image
嗨,所以我需要做的是最终让 regStart 和 regPage 根据点击事件交替可见性,我不太担心编写 JavaScript 函数,但我根本无法让我的 regPage 首先隐藏。这是我的代码。请简单
我有一个非常简单的程序来测量一个函数花费了多少时间。 #include #include #include struct Foo { void addSample(uint64_t s)
我需要为 JavaScript 制作简单的 C# BitConverter。我做了一个简单的BitConverter class BitConverter{ constructor(){} GetBy
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我是 Simple.Data 的新手。但我很难找到如何进行“分组依据”。 我想要的是非常基本的。 表格看起来像: +________+ | cards | +________+ | id |
我现在正在开发一个 JS UDF,它看起来遵循编码。 通常情况下,由于循环计数为 2,Alert Msg 会出现两次。我想要的是即使循环计数为 3,Alert Msg 也只会出现一次。任何想法都
我是一名优秀的程序员,十分优秀!