使用 Ring 编程语言构建 Flappy Bird 3000






2.87/5 (5投票s)
开始 2D 游戏开发,并使用 Ring 编程语言构建 Flappy Bird 3000 游戏。
引言
在本文中,我们将学习如何使用 Ring 编程语言进行 2D 游戏开发,还将创建 Flappy Bird 游戏。我们的版本允许您在获得 3000 分时获胜,因此我将其命名为 Flappy Bird 3000 游戏。
Ring 语言简单,力求自然,鼓励组织,并具有透明和可视化的实现。它具有紧凑的语法和一组功能,使程序员能够花费极少的时间来创建自然界面和声明式领域特定语言。它非常小巧、快速,并且配备了一个智能垃圾回收器,可以将内存置于程序员的控制之下。它支持多种编程范式,并附带了有用实用的库。该语言旨在提高生产力,并开发可扩展的高质量解决方案。
您可以通过此链接下载 Ring
背景
查看有关 Ring 的下一篇文章
(1) Ring 编程语言
(2) Ring 语言的语法灵活性
还可以查看以下教程
(1) 入门
(2) 控制结构
(3) 函数
(4) 列表
(5) 类
(6) 函数式编程
(7) 声明式编程
关于 Ring 语言
如果您是 Ring 新手,以下注释将帮助您快速理解 Ring 代码
* 动态语言
* 不区分大小写
* 使用 'Load' 命令加载库
* 支持使用 'Main' 函数
* 使用 'New' 关键字创建新对象
* 使用大括号 {} 访问对象属性和方法
* 在 # 之后编写注释
* 配备垃圾回收器
使用 Ring 游戏引擎
要开始使用游戏引擎,请使用 "gameengine.ring" 库
然后创建一个 Game 类的对象
Load "gameengine.ring"  # Give Control to the Game Engine
func main               # Called by the Game Engine
        oGame = New Game        # Create the Game Object
        {
                        # Game Code
        }                       
在接下来的示例中,我们将学习使用 "gameengine.ring" 提供的许多功能
下表展示了 Game 类属性。
| 属性 | 描述 | 
|---|---|
| 帧率 (FPS) | Number 决定 draw() 方法每秒被调用的次数。 | 
| FixedFPS | Number 决定 animate() 方法每秒被调用的次数。 | 
| 标题 | String 决定游戏的窗口标题。 | 
| aObjects | List 包含游戏中的所有对象 | 
| 关闭 | True/False 值用于结束游戏循环。 | 
下表展示了类方法。
| 方法 | 描述 | 
|---|---|
| refresh() | 删除对象。 | 
| settitle(cTitle) | 使用字符串参数设置窗口标题。 | 
| shutdown() | 关闭应用程序。 | 
下表展示了一组由类定义的关键字。
| 关键字 | 描述 | 
|---|---|
| sprite | 创建新的 Sprite 对象并将其添加到游戏对象中。 | 
| 文本 | 创建新的 Text 对象并将其添加到游戏对象中。 | 
| animate | 创建新的 Animate 对象并将其添加到游戏对象中。 | 
| sound | 创建新的 Sound 对象并将其添加到游戏对象中。 | 
| map | 创建新的 Map 对象并将其添加到游戏对象中。 | 
创建游戏窗口
下一个示例使用 (New Game) 创建 Game 对象,对象名为 oGame。
使用大括号 {},我们访问 oGame 对象属性和方法。
我们将 'title' 属性值设置为 "My First Game"
Load "gameengine.ring"  # Give Control to the Game Engine
func main               # Called by the Game Engine
        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
        }                       # Start the Events Loop
绘制文本
要绘制文本,我们需要使用 Text 类
类名: Text
父类: Sprite Class
下表展示了类属性。
| 属性 | 描述 | 
|---|---|
| size | Number 决定字体大小 | 
| font | String 决定字体文件名 | 
| text | String 决定要显示的文本 | 
| color | Number 决定颜色 | 
下表展示了类方法。
| 方法 | 描述 | 
|---|---|
| Draw(oGame) | 绘制对象 | 
下一个示例使用 'Load' 命令加载游戏引擎
执行从 main 函数开始
在 main 函数内部,我们从 Game Class 创建新对象
创建的对象名为 oGame,我们使用大括号访问此对象以修改对象属性和方法。
在对象 (oGame) 内部,我们使用 text {} 创建了一个 Text 类的对象
'test' 关键字由 Game 类定义,用于创建新对象并返回该对象,我们可以使用大括号 {} 访问该对象
我们将 text 属性设置为 "game development using ring is very fun!"
并使用 file 属性设置字体文件名: "fonts/pirulen.ttf"
字体大小为 20
使用 color 属性,我们将文本颜色设置为黑色,使用 rgb(0,0,0)
Load "gameengine.ring"  # Give Control to the Game Engine
func main               # Called by the Game Engine
        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
                text {
                        x = 10  y=50
                        animate = false
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "game development using ring is very fun!"
                        color = rgb(0,0,0)
                }
        }               # Start the Events Loop
下一个屏幕截图展示了应用程序在运行时的情况。
移动文本
下一个示例使用 Text 类显示文本并使其在屏幕上移动
要移动文本,我们将 'animate' 属性设置为 True
我们有 'direction' 属性,将其设置为 GE_DIRECTION_INCVERTICAL,文本将从上到下移动。
'point' 属性决定了移动何时停止。我们有 y=150,它将一直增加直到 y = point 属性值(即 400)。
Load "gameengine.ring"  # Give Control to the Game Engine
func main               # Called by the Game Engine
        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
                text {
                        x = 10  y=50
                        animate = false
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "game development using ring is very fun!"
                        color = rgb(0,0,0)      # Color = black
                }
                text {
                        x = 10  y=150
                        # Animation Part =====================================
                        animate = true                  # Use Animation
                        direction = GE_DIRECTION_INCVERTICAL    # Increase y
                        point = 400                     # Continue until y=400
                        nStep = 3                       # Each time y+= 3
                        #=====================================================
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "welcome to the real world!"
                        color = rgb(0,0,255)            # Color = Blue
                }
        }                                       # Start the Events Loop
播放声音
类名: Sound
父类: GameObject Class
下表展示了类属性。
| 属性 | 描述 | 
|---|---|
| 文件 | String 决定声音文件名。 | 
| once | True/False 决定是播放一次文件还是循环播放。 | 
下表展示了类方法。
| 方法 | 描述 | 
|---|---|
| playsound() | 播放声音文件 | 
下一个示例使用 sound {} 创建一个声音对象来播放声音文件
示例将使用 'file' 属性确定声音文件名
我们将 'file' 属性值设置为 "sound/music1.wav"
Load "gameengine.ring"  # Give Control to the Game Engine
func main               # Called by the Game Engine
        oGame = New Game        # Create the Game Object
        {
                title = "My First Game"
                text {
                        x = 10  y=50
                        animate = false
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "game development using ring is very fun!"
                        color = rgb(0,0,0)      # Color = black
                }
                text {
                        x = 10  y=150
                        # Animation Part ======================================
                        animate = true                          # Use Animation
                        direction = GE_DIRECTION_INCVERTICAL    # Increase y
                        point = 400             # Continue until y=400
                        nStep = 3               # Each time y+= 3
                        #======================================================
                        size = 20
                        file = "fonts/pirulen.ttf"
                        text = "welcome to the real world!"
                        color = rgb(0,0,255)    # Color = Blue
                }
                Sound {                                 # Play Sound
                        file = "sound/music1.wav"       # Sound File Name
                }
        }                                       # Start the Events Loop
动画
类名: Animate
父类: Sprite Class
下表展示了类属性。
| 属性 | 描述 | 
|---|---|
| frames | Number 决定帧数 | 
| frame | Number 决定活动帧 | 
| framewidth | Number 决定帧的宽度。 | 
| animate | True/False 决定是否使用动画。 | 
| scaled | True/False 决定是否缩放图像。 | 
下表展示了类方法。
| 方法 | 描述 | 
|---|---|
| Draw(oGame) | 绘制对象 | 
下一个示例使用 animate {} 创建一个 animate 类的对象。
此类将播放一系列图像
我们有一张图像文件 "images/fire.png",将使用 'file' 属性指定。
使用 framewidth 属性,我们将确定每帧的宽度(framewidth = 40)
我们有 13 帧要显示。
Load "gameengine.ring"  # Give Control to the Game Engine
func main               # Called by the Game Engine
  oGame = New Game      # Create the Game Object
  {
        title = "My First Game"
        animate {
          file = "images/fire.png"
          x = 100
          y = 200
          framewidth = 40
          height = 42
          nStep = 3      # Used for delay
          transparent = true
          state = func oGame,oSelf {  # Called by engine each frame
                oSelf {
                  nStep--
                  if nStep = 0
                        nStep = 3
                        if frame < 13      # we have 13 frames in animation
                          frame++   # move to next frame
                        else
                          oGame.remove(oself.nIndex)   # remove object
                        ok
                  ok
                }
          }
         }
  }          # Start the Events Loop
动画与函数
我们可以调用函数来创建新对象
通过在 for 循环中调用此函数,我们可以创建许多对象
在下一个示例中,我们有一个 showfire() 函数,它创建 (animate) 类型的对象。
Load "gameengine.ring"  # Give Control to the Game Engine
func main               # Called by the Game Engine
  oGame = New Game      # Create the Game Object
  {
        title = "My First Game"
        for x = 70 to 700 step 50
          for y = 70 to 500 step 50
                showfire(oGame,x,y)
          next
        next
  }          # Start the Events Loop
func showfire oGame,nX,nY
  oGame {
        animate {
          file = "images/fire.png"
          x = nX
          y = nY
          framewidth = 40
          height = 42
          nStep = 3      # Used for delay
          transparent = true
          state = func oGame,oSelf {  # Called by engine each frame
                oSelf {
                  nStep--
                  if nStep = 0
                        nStep = 3
                        if frame < 13      # we have 13 frames in animation
                          frame++   # move to next frame
                        else
                          frame=1
                        ok
                  ok
                }
          }
         }
  }
下一个屏幕截图展示了应用程序在运行时的情况。
Sprite - 使用键盘自动移动
在下一个示例中,我们将使用 sprite {} 创建 Sprite 类的新对象。
通过将 'Move' 属性设置为 'True',我们可以使用键盘箭头移动精灵
Load "gameengine.ring"                          # Give control to the game engine
func main                                       # Called by the Game Engine
        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=true       # we can move it using keyboard arrows
                        Scaled=true
                }
        }                                       # Start the Events Loop
Sprite - 按键事件
下一个示例创建一个 Sprite 对象,但通过将 'Move' 属性设置为 False 来显示默认移动。
使用 Keypress 属性,我们可以定义一个匿名函数,在按下按键时调用它
匿名函数将接收诸如 Game 对象 (oGame)、Sprite 对象 (oSelf) 和按下的键代码 (nKey) 等参数
我们可以使用 Switch 语句检查按下的键值,然后根据按下的键更新 x 和 y 值。
Load "gameengine.ring"                          # Give control to the game engine
func main                                       # Called by the Game Engine
        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=false                      # Custom Movement
                        Scaled=true
                        keypress = func oGame,oSelf,nKey {
                                oSelf {
                                        Switch nKey
                                        on KEY_LEFT
                                                x -= 10
                                        on KEY_RIGHT
                                                x += 10
                                        on KEY_UP
                                                y -= 10
                                        on KEY_DOWN
                                                y += 10
                                        off
                                }
                        }
                }
        }                                       # Start the Events Loop
Sprite - 鼠标事件
下一个示例使用 sprite {} 创建一个 sprite 对象,然后使用 Mouse 属性确定一个匿名函数,当发生鼠标事件时调用该函数来处理。
匿名函数将接收 4 个参数: oGame, oSelf, nType, aMouseList
oGame = Game 对象
oSelf = Sprite 对象
nType = 事件类型
aMouseList = 鼠标信息 (x,y)
Load "gameengine.ring"                          # Give control to the game engine
func main                                       # Called by the Game Engine
        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=false                      # Custom Movement
                        Scaled=true
                        keypress = func oGame,oSelf,nKey {
                                oSelf {
                                        Switch nKey
                                        on KEY_LEFT
                                                x -= 10
                                        on KEY_RIGHT
                                                x += 10
                                        on KEY_UP
                                                y -= 10
                                        on KEY_DOWN
                                                y += 10
                                        off
                                }
                        }
                        mouse = func oGame,oSelf,nType,aMouseList {
                                if nType = GE_MOUSE_UP
                                        oSelf {
                                                x = aMouseList[GE_MOUSE_X]
                                                y = aMouseList[GE_MOUSE_Y]
                                        }
                                ok
                        }
                }
        }                                       # Start the Events Loop
Sprite - 状态事件
下一个示例展示了如何在 Sprite 类中使用 state 属性定义匿名函数,该函数将在每次帧更新时调用。
下一个示例使用 State 和匿名函数来防止对象/精灵移出屏幕。
Load "gameengine.ring"                          # Give control to the game engine
func main                                       # Called by the Game Engine
        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                sprite
                {
                        type = GE_TYPE_PLAYER           # Just for our usage
                        x=400 y=400 width=100 height=100
                        file = "images/player.png"
                        transparent = true
                        Animate=false
                        Move=false                      # Custom Movement
                        Scaled=true
                        keypress = func oGame,oSelf,nKey {
                                oSelf {
                                        Switch nKey
                                        on KEY_LEFT
                                                x -= 10
                                        on KEY_RIGHT
                                                x += 10
                                        on KEY_UP
                                                y -= 10
                                        on KEY_DOWN
                                                y += 10
                                        off
                                }
                        }
                        mouse = func oGame,oSelf,nType,aMouseList {
                                if nType = GE_MOUSE_UP
                                        oSelf {
                                                x = aMouseList[GE_MOUSE_X]
                                                y = aMouseList[GE_MOUSE_Y]
                                        }
                                ok
                        }
                        state = func oGame,oSelf {
                                oself {
                                        if x < 0 x = 0 ok
                                        if y < 0 y = 0 ok
                                        if x > ogame.width-width
                                                x= ogame.width - width ok
                                        if y > ogame.height-height
                                                y=ogame.height - height ok
                                }
                        }
                }
        }                                       # Start the Events Loop
Animate - 事件
与 sprites 一样,Animate Class 支持使用 KeyPress、Mouse 和 State 事件
下一个示例展示了这一点。
我们将创建鸟,使其动画化,并在按下空格键后向上移动它。
此外,在按下空格键后的几帧后,鸟会自动向下移动。
Load "gameengine.ring"                          # Give control to the game engine
func main                                       # Called by the Game Engine
        oGame = New Game                        # Create the Game Object
        {
                title = "My First Game"
                animate {
                        file = "images/fbbird.png"
                        x = 10
                        y = 10
                        framewidth = 20
                        scaled = true
                        height = 50
                        width = 50
                        nStep = 3
                        transparent = true
                        state = func oGame,oSelf {
                                oSelf {
                                        # Animation
                                                nStep--
                                                if nStep = 0
                                                        nStep = 3
                                                        if frame < 3
                                                                frame++
                                                        else
                                                                frame=1
                                                        ok
                                                ok
                                        # Move Down
                                                y += 3
                                                if y > 550 y=550 ok
                                }
                        }
                        keypress = func ogame,oself,nKey {
                                oself {
                                        if nkey = key_space
                                                y -= 55
                                                if y<=0 y=0 ok
                                        ok
                                }
                        }
                        mouse = func ogame,oself,nType,aMouseList {
                                if nType = GE_MOUSE_UP
                                        cFunc = oself.keypress
                                        call cFunc(oGame,oSelf,Key_Space)
                                ok
                        }
                }
        }                                       # Start the Events Loop
下一个屏幕截图展示了应用程序在运行时的情况。
映射
类名: Map
父类: Sprite Class
下表展示了类属性。
| 属性 | 描述 | 
|---|---|
| aMap | List 使用数字确定地图内容。 | 
| aImages | List 决定地图中每个数字使用的图像。 | 
| BlockWidth | Number 决定块的宽度(默认 = 32)。 | 
| BlockHeight | Number 决定块的高度(默认 = 32)。 | 
| Animate | True/False 决定动画状态。 | 
下表展示了类方法。
| 方法 | 描述 | 
|---|---|
| getvalue(x,y) | 根据可见部分返回地图中的项目值 | 
使用 Map 类,我们可以显示和移动地图
地图使用列表通过数字确定地图内容
每个数字代表一个用于绘制的图像。
下一个示例创建了一个地图并将其向左移动
Load "gameengine.ring"        # Give control to the game engine
func main          # Called by the Game Engine
oGame = New Game      # Create the Game Object
{
  title = "My First Game"
  Map {
        blockwidth = 80
        blockheight = 80
        aMap = [
                [0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,1,0,0,0],
                [0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
        ]
        aImages = ["images/fbwall.png",
                 "images/fbwallup.png",
                 "images/fbwalldown.png"]
        state = func oGame,oSelf {
          oSelf {
                x -= 3
                if x < - 2100  x = 0  ok
          }
        }
  }
}          # Start the Events Loop
下一个屏幕截图展示了应用程序在运行时的情况。
地图事件
我们可以为地图定义事件以采取行动并响应环境
下一个示例使用 mouse 属性定义一个匿名函数,当用户单击地图上的某个位置时会调用该函数。
如果用户单击了一个带有图像的位置,图像将消失
如果用户单击了一个没有图像的位置,则会将一个图像添加到地图中。
Load "gameengine.ring"        # Give control to the game engine
func main          # Called by the Game Engine
  oGame = New Game      # Create the Game Object
  {
        title = "My First Game"
        Map {
          blockwidth = 80
          blockheight = 80
          aMap = [
                   [0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,1,0,0,0],
                  [0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0],
                  [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                  [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
          ]
          aImages = ["images/fbwall.png",
                         "images/fbwallup.png",
                         "images/fbwalldown.png"]
          state = func oGame,oSelf {
                oSelf {
                  x -= 3
                  if x < - 2100  x = 0  ok
                }
          }
          mouse = func ogame,oself,nType,aMouseList {
                if nType = GE_MOUSE_UP
                  oSelf {
                        mX = aMouseList[GE_MOUSE_X]
                        mY = aMouseList[GE_MOUSE_Y]
                        nValue = GetValue(mX,mY)
                        nRow = GetRow(mX,mY)
                        nCol = GetCol(mX,mY)
                        Switch nValue
                        On 1  aMap[nRow][nCol] = 0
                        On 2  aMap[nRow][nCol] = 0
                        On 3  aMap[nRow][nCol] = 0
                        On 0  aMap[nRow][nCol] = 1
                        Off
                  }
                ok
          }
        }
  }          # Start the Events Loop
下一个屏幕截图展示了应用程序在运行时的情况。
Flappy Bird 3000 游戏
在理解了前面的示例之后,我们可以看到并理解这个游戏
Flappy Bird 3000 游戏源代码
游戏中还有 GameState 类,用于存储我们游戏的自定义信息。
以下代码用于启动游戏和显示游戏信息
还支持(再玩一次)功能
oGameState = NULL
Load "gameengine.ring"
func main
  oGame = New Game
  while true
        oGameState = New GameState
        oGame {
          title = "Flappy Bird 3000"
          sprite
          {
                file = "images/fbback.png"
                x = 0 y=0 width=800 height = 600 scaled = true animate = false
                keypress = func ogame,oself,nKey {
                  if nkey = key_esc or nKey = GE_AC_BACK
                        ogame.shutdown()
                  but nKey = key_space
                        oGameState.startplay=true
                        ogame.shutdown=true
                  ok
                }
                mouse = func ogame,oself,nType,aMouseList {
                  if nType = GE_MOUSE_UP
                        cFunc = oself.keypress
                        call cFunc(oGame,oSelf,Key_Space)
                  ok
                }
          }
          text {
                animate = false
                size = 35
                file = "fonts/pirulen.ttf"
                text = "Flappy Bird 3000"
                x = 150  y=50
          }
          text {
                animate = false
                size = 25
                file = "fonts/pirulen.ttf"
                text = "Version 1.0"
                x = 280  y=100
          }
          text {
                animate = false
                size = 16
                file = "fonts/pirulen.ttf"
                text = "(C) 2016, Mahmoud Fayed"
                x = 245  y=140
          }
          text {
                animate = false
                size = 25
                file = "fonts/pirulen.ttf"
                text = "To Win Get Score = 3000"
                x = 150  y=270
          }
          text {
                animate = false
                size = 25
                file = "fonts/pirulen.ttf"
                text = "Press Space to start"
                x = 190  y=470
          }
          text {
                animate = false
                size = 20
                file = "fonts/pirulen.ttf"
                text = "Press Esc to Exit"
                x = 260  y=510
          }
          animate {
                file = "images/fbbird.png"
                x = 200
                y = 200
                framewidth = 20
                scaled = true
                height = 50
                width = 50
                nStep = 3
                transparent = true
                animate = true
                direction = ge_direction_random
                state = func oGame,oSelf {
                  oSelf {
                        nStep--
                        if nStep = 0
                          nStep = 3
                          if frame < 3
                                frame++
                          else
                                frame=1
                          ok
                        ok
                        if x <= 0 x=0 ok
                        if y <= 0 y=0 ok
                        if x >= 750 x= 750 ok
                        if y > 550 y=550 ok
                  }
                }
          }
          Sound {
                file = "sound/music2.wav"
          }
        }
        if oGameState.startplay
          oGame.refresh()
          playstart(oGame)
          oGame.refresh()
        ok
  end
下一个函数 playstart() 包含实际玩游戏的代码
func playstart oGame
    oGame {
        FPS = 60
        FixedFPS = 120
        Title = "Flappy Bird 3000"
        Sprite {
            file = "images/fbback.png"
            x = 0 y=0 width=800 height = 600 scaled = true animate = false
            keypress = func ogame,oself,nKey {
                if nkey = key_esc or nKey = GE_AC_BACK
                    ogame.shutdown()
                ok
            }
        }
        Map {
            blockwidth = 80
            blockheight = 80
            aMap = [
                     [0,0,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,1,0,0,0,1,0,0,0],
                    [0,0,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0],
                    [0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
                ]
            newmap(aMap)
            aImages = ["images/fbwall.png","images/fbwallup.png",
                    "images/fbwalldown.png"]
            state = func oGame,oSelf {
                if oGameState.gameresult = false
                    px = oGame.aObjects[3].x
                    py = oGame.aObjects[3].y
                    oSelf {
                        x -=  3
                        if x < - 2100
                            x = 0
                            newmap(aMap)
                        ok
                        nCol =  getcol(px,0)
                        if nCol=11 or nCol=15 or nCol=19 or nCol=23 or nCol=27
                            if nCol != oGameState.lastcol
                                oGameState.lastcol = nCol
                                oGameState.Score += 100
                                oGame { Sound {
                                    once = true
                                    file = "sound/sfx_point.wav"
                                } }
                                checkwin(oGame)
                            ok
                        ok
                    }
                    if  oSelf.getvalue(px+40,py) != 0 or
                        oSelf.getvalue(px+40,py+40) != 0 or
                        oSelf.getvalue(px,py) != 0 or
                        oSelf.getvalue(px,py+40) != 0
                        oGameState.gameresult = true
                        oGame {
                            text {
                                point = 550
                                size = 30
                                nStep = 3
                                file = "fonts/pirulen.ttf"
                                text = "Game Over !!!"
                                x = 500    y=10
                                state = func ogame,oself {
                                    if oself.y >= 550
                                            ogame.shutdown = true
                                    ok
                                        if oself.y = 90
                                        ogame {
                                            Sound {
                                                once = true
                                                file = "sound/sfx_die.wav"
                                            }
                                        }
                                    ok
                                }
                            }
                            Sound {
                                once = true
                                file = "sound/sfx_hit.wav"
                            }
                        }
                    ok
                ok
            }
        }
        animate {
            file = "images/fbbird.png"
            x = 10
            y = 10
            framewidth = 20
            scaled = true
            height = 50
            width = 50
            nStep = 3
            transparent = true
            state = func oGame,oSelf {
                oSelf {
                    nStep--
                    if nStep = 0
                        nStep = 3
                        if frame < 3
                            frame++
                        else
                            frame=1
                        ok
                    ok
                }
                if not oGameState.playerwin
                    oGameState.down --
                    if oGameState.down = 0
                        oGameState.down = 3
                        oself {
                            y += 25
                            if y > 550 y=550 ok
                        }
                    ok
                ok
            }
            keypress = func ogame,oself,nKey {
                if oGameState.gameresult = false
                    oself {
                        if nkey = key_space
                            y -= 55
                            oGameState.down = 60
                            if y<=0 y=0 ok
                        ok
                    }
                ok
            }
            mouse = func ogame,oself,nType,aMouseList {
                if nType = GE_MOUSE_UP
                    cFunc = oself.keypress
                    call cFunc(oGame,oSelf,Key_Space)
                ok
            }
        }
        text {
            animate = false
            point = 400
            size = 30
            file = "fonts/pirulen.ttf"
            text = "Score : " + oGameState.score
            x = 500    y=10
            state = func oGame,oSelf {
                oSelf { text = "Score : " + oGameState.score }
            }
        }
    }
下一个函数 newmap() 用于创建新地图(随机地图)
func newmap aMap aV = [ [1,1,3,0,0,2,1,1], [1,3,0,0,0,2,1,1], [1,1,1,3,0,2,1,1], [1,1,1,3,0,0,0,0], [0,0,0,0,2,1,1,1], [0,0,2,1,1,1,1,1], [0,0,0,2,1,1,1,1], [1,1,1,3,0,2,1,1], [1,1,1,1,1,3,0,0], [3,0,0,2,1,1,1,1], [3,0,0,2,3,0,0,2] ] for x = 10 to 24 step 4 aVar = aV[ (random(10)+1) ] for y = 1 to 8 aMap[y][x] = aVar[y] next next
下一个函数 checkwin() 用于检查玩家是否获胜
我们通过检查分数来做到这一点
如果分数等于 300,玩家获胜。
func checkwin ogame
    if oGameState.score = 3000
        oGameState.gameresult = true
        oGameState.playerwin = true
        oGame {
            text {
                point = 400
                size = 30
                nStep = 3
                file = "fonts/pirulen.ttf"
                text = "You Win !!!"
                x = 500    y=10
                state = func ogame,oself {
                    if oself.y >= 400
                        ogame.shutdown = true
                        oGameState.value = 0
                    ok
                }
            }
        }
    ok
下一个类用于存储游戏状态和重要信息,如分数。
Class GameState down = 3 gameresult = false Score = 0 startplay=false lastcol = 0 playerwin = false
下一个屏幕截图展示了游戏在运行时的情况。

关注点
Ring 是一种新语言,游戏引擎也是新的,许多东西都可以添加以使 Ring 和引擎成为更好的作品,您也可以提供帮助和贡献
一旦您了解了如何使用游戏引擎,您就可以在短时间内创建许多游戏。游戏引擎用于提高生产力。Ring 游戏引擎可用于原型设计游戏。







