通过游戏开发学习F#第3章错误
我正在阅读《通过游戏开发学习》一书,在第3章中,我得到了一个TypeInitializationException,代码如下:通过游戏开发学习F#第3章错误,f#,F#,我正在阅读《通过游戏开发学习》一书,在第3章中,我得到了一个TypeInitializationException,代码如下: // edit: missing definitions, thanks John let earth_mass = 5.97e24<kg> // defined in other file that is ref'd in ok let moon_mass = 7.35e22<kg> let lerp (x:float<'T>)
// edit: missing definitions, thanks John
let earth_mass = 5.97e24<kg> // defined in other file that is ref'd in ok
let moon_mass = 7.35e22<kg>
let lerp (x:float<'T>) (y:float<'T>) (a:float) = (x * a) + (y * (1.0 - a))
// inside list comprehension for loop -
let m = (lerp earth_mass moon_mass (rand.NextDouble())) * 1.0e-4 // error!!
//编辑:缺少定义,谢谢John
让earth_mass=5.97e24//在ok中引用的其他文件中定义
让月球的质量=7.35e22
设lerp(x:float)(a:float)=(x*a)+(y*(1.0-a))
//循环的内部列表理解-
设m=(lerp地球质量月球质量(rand.NextDouble())*1.0e-4//错误!!
我已经下载了作者的源代码,看看我是否遗漏了什么,但它会产生同样的错误。
异常消息对问题是什么(至少对我来说)没有什么线索
以下是本章的全部代码,以供参考:
namespace Games
module Chapter3 =
open System
open System.Threading
open Games.Math
type Asteroid =
{
Position : Vector2<m>
Velocity : Vector2<m/s>
Mass : float<kg>
Name : string
}
let dt = 60.0<s>
let G = 6.67e-11<m^3 * kg^-1 * s^-2>
let earth_radius = 6.37e6<m>
let field_size = earth_radius * 60.0
let max_velocity = 2.3e4<m/s>
let earth_mass = 5.97e24<kg>
let moon_mass = 7.35e22<kg>
let create_field num_asteroids =
let lerp (x:float<'T>) (y:float<'T>) (a:float) = x * a + y * (1.0 - a)
let rand = Random()
[
for i = 1 to num_asteroids do
let m = (lerp earth_mass moon_mass (rand.NextDouble())) * 1.0e-4
let x = lerp 0.0<m> field_size (rand.NextDouble())
let y = lerp 0.0<m> field_size (rand.NextDouble())
let vx = max_velocity * (rand.NextDouble() * 2.0 - 1.0) * 0.1
let vy = max_velocity * (rand.NextDouble() * 2.0 - 1.0) * 0.1
yield
{
Position = { X = x; Y = y}
Velocity = { X = vx; Y = vy}
Mass = m
Name = "a"
}
]
let f0 = create_field 20
let clamp (p:Vector2<_>, v:Vector2<_>) =
let p,v =
if p.X < 0.0<_> then
{p with X = 0.0<_>}, {v with X = -v.X}
else
p,v
let p,v =
if p.X > field_size then
{p with X = field_size}, {v with X = -v.X}
else
p,v
let p,v =
if p.Y < 0.0<_> then
{p with Y = 0.0<_>}, {v with Y = -v.Y}
else
p,v
let p,v =
if p.Y > field_size then
{p with Y = field_size}, {v with Y = -v.Y}
else
p,v
p,v
let force (a:Asteroid, a':Asteroid) =
let dir = a'.Position - a.Position
let dist = dir.Length + 1.0<m>
G * a.Mass * a'.Mass * dir/(dist * dist * dist)
let simulation_step (asteroids:Asteroid list) =
[
for a in asteroids do
let forces =
[
for a' in asteroids do
if a' <> a then
yield force(a, a')
]
let F = List.sum forces
let p', v' = clamp(a.Position, a.Velocity)
yield
{
a with
Position = p' + dt * v'
Velocity = v' + dt * F/a.Mass
}
]
let print_scene (asteroids:Asteroid list) =
do Console.Clear()
for i = 0 to 79 do
Console.SetCursorPosition(i, 0)
Console.Write("*")
Console.SetCursorPosition(i, 23)
Console.Write("*")
for j = 0 to 23 do
Console.SetCursorPosition(0, j)
Console.Write("*")
Console.SetCursorPosition(79, j)
Console.Write("*")
let set_cursor_on_body b =
Console.SetCursorPosition(
((b.Position.X/4.0e8<m>) * 78.0 + 1.0) |> int,
((b.Position.Y/4.0e8<m>) * 23.0 + 1.0) |> int)
for a in asteroids do
do set_cursor_on_body a
do Console.Write(a.Name)
do Thread.Sleep(100)
let simulation() =
let rec simulation m =
do print_scene m
let m' = simulation_step m
do simulation m'
do simulation f0
命名空间游戏
模块第3章=
开放系统
开放系统。线程
开放游戏,数学
类型小行星=
{
位置:Vector2
速度:矢量2
质量:浮子
名称:string
}
设dt=60.0
设G=6.67e-11
让地球半径=6.37e6
让场大小=地球半径*60.0
设最大速度=2.3e4
假设地球质量=5.97e24
让月球的质量=7.35e22
让我们创建\u字段num\u小行星=
设lerp(x:float)(a:float)=x*a+y*(1.0-a)
设rand=Random()
[
对于i=1到num_小行星
设m=(lerp地球质量月球质量(rand.NextDouble())*1.0e-4
设x=lerp 0.0字段大小(rand.NextDouble())
设y=lerp 0.0字段大小(rand.NextDouble())
设vx=最大速度*(rand.NextDouble()*2.0-1.0)*0.1
设vy=最大速度*(rand.NextDouble()*2.0-1.0)*0.1
产量
{
位置={X=X;Y=Y}
速度={X=vx;Y=vy}
质量=m
Name=“a”
}
]
设f0=创建_字段20
let钳位(p:Vector2,v:Vector2)=
让p,v=
如果p.X<0.0,则
{p与X=0.0},{v与X=-v.X}
其他的
p、 五
让p,v=
如果p.X>字段大小,则
{p与X=field_size},{v与X=-v.X}
其他的
p、 五
让p,v=
如果p.Y<0.0,则
{p与Y=0.0},{v与Y=-v.Y}
其他的
p、 五
让p,v=
如果p.Y>字段大小,则
{p with Y=field_size},{v with Y=-v.Y}
其他的
p、 五
p、 五
让力(a:小行星,a:小行星)=
设dir=a'.位置-a.位置
设距离=方向长度+1.0
G*a.质量*a.质量*dir/(距离*dist*dist*dist)
让模拟_步骤(小行星:小行星列表)=
[
对于一个在小行星吗
让力量=
[
对于一个'在小行星吗
如果是a,那么
屈服力(a,a’)
]
设F=List.sum力
设p',v'=夹具(a位置,a速度)
产量
{
与
位置=p'+dt*v'
速度=v'+dt*F/a.质量
}
]
让我们打印场景(小行星:小行星列表)=
执行控制台清除()
对于i=0到79 do
Console.SetCursorPosition(i,0)
控制台。写入(“*”)
控制台.设置光标位置(i,23)
控制台。写入(“*”)
对于j=0到23 do
控制台。设置光标位置(0,j)
控制台。写入(“*”)
控制台.设置光标位置(79,j)
控制台。写入(“*”)
让我们在主体b上设置光标=
Console.SetCursorPosition(
((b.Position.X/4.0e8)*78.0+1.0)|>int,
((b.Position.Y/4.0e8)*23.0+1.0)|>int)
对于一个在小行星吗
是否在主体a上设置光标
do Console.Write(a.Name)
做线程。睡眠(100)
let simulation()=
让rec模拟m=
不要打印场景
设m'=模拟步骤m
做我的
进行模拟f0
数学模块代码:
namespace Games
module Math =
[<Measure>]
type m //metres
[<Measure>]
type kg //kilogram
[<Measure>]
type s // seconds
[<Measure>]
type N = kg*m/s^2 //Newtons
type Vector2<[<Measure>]'T> =
{
X : float<'T>
Y : float<'T>
}
static member Zero : Vector2<'T> =
{ X = 0.0<_>; Y = 0.0<_> }
static member (+) (v1:Vector2<'T>, v2:Vector2<'T>) : Vector2<'T> =
{ X = v1.X + v2.X; Y = v1.Y + v2.Y }
static member (+) (v:Vector2<'T>, k:float<'T>) : Vector2<'T> =
{ X = v.X + k; Y = v.Y + k }
static member (+) (k:float<'T>, v:Vector2<'T>) : Vector2<'T> = v + k
static member (~-) (v:Vector2<'T>) : Vector2<'T> =
{ X = -v.X; Y = -v.Y }
static member (-) (v1:Vector2<'T>, v2:Vector2<'T>) : Vector2<'T> =
v1 + (-v2)
static member (-) (v:Vector2<'T>, k:float<'T>) : Vector2<'T> =
v + (-k)
static member (-) (k:float<'T>, v:Vector2<'T>) : Vector2<'T> =
k + (-v)
static member (*) (v1:Vector2<'a>, v2:Vector2<'b>) : Vector2<'a * 'b> =
{ X = v1.X * v2.X; Y = v1.Y * v2.Y }
static member (*) (v:Vector2<'a>, f:float<'b>) : Vector2<'a * 'b> =
{ X = v.X * f; Y = v.Y * f }
static member (*) (f:float<'b>, v:Vector2<'a>) : Vector2<'b * 'a> =
{ X = f * v.X; Y = f * v.Y }
static member (/) (v:Vector2<'a>, f:float<'b>) : Vector2<'a / 'b> =
v * (1.0/f)
member this.Length : float<'a> =
sqrt((this.X * this.X + this.Y * this.Y))
static member Distance(v1:Vector2<'T>, v2:Vector2<'T>) =
(v1 - v2).Length
static member Normalize(v:Vector2<'T>) : Vector2<1> =
v / v.Length
命名空间游戏
模块数学=
[]
m型//米
[]
类型kg//kg
[]
键入s//seconds
[]
类型N=kg*m/s^2//牛顿
类型向量2
Y:浮子=
{X=0.0;Y=0.0}
静态成员(+)(v1:Vector2):Vector2,k:浮点=
{X=v.X+k;Y=v.Y+k}
静态成员(+)(k:float):Vector2:Vector2,v2:Vector2=
v1+(-v2)
静态成员(-)(v:Vector2):Vector2,v:Vector2=
k+(-v)
静态成员(*)(v1:Vector2):Vector2=
{X=v1.X*v2.X;Y=v1.Y*v2.Y}
静态成员(*)(v:Vector2):Vector2=
{X=v.X*f;Y=v.Y*f}
静态成员(*)(f:float):向量2=
{X=f*v.X;Y=f*v.Y}
静态成员(/)(v:Vector2):Vector2=
v*(1.0/f)
此成员。长度:float,v2:Vector2):Vector2=
v/v.长度
要运行的代码示例:
[<EntryPoint>]
let main argv =
Games.Chapter3.simulation()
0 // return an integer exit code
[]
让主argv=
游戏。第三章。模拟()
0//返回整数退出代码
有人能用VS2013和F#3.1/.Net4.5解释一下发生了什么吗
多谢各位
Mick它认为您遇到了F#编译器错误。它出现在F#3.1.2及更早版本中,但此后已被修复,因此在4.0及更高版本中可以使用 根据问题讨论,在F#3.0及更早版本中,存在该缺陷,但并不总是导致运行时崩溃。看看这本书的示例代码项目,我猜作者使用F#3.0或更早版本编写了这些示例,但没有意识到它们触发了bug 解决办法:
- 在发布模式下编译(启用优化),codegen应该是正确的(假设这确实是同一个问题)
- 尝试使用F#4.0预发行版(通过或仅从中获取F#位)