查看: 3438|回复: 9

[胡扯] 教你如何用RM写一个贪吃蛇

[复制链接]

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2015-4-3 15:33:05 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×

注意该主题的标签,注意该主题的标签,因为很重要所以说两遍!

[fold=第一步:在屏幕上显示一个点]
[pre lang="ruby"]
s = Sprite.new
s.bitmap = b = Bitmap.new(32, 32)

b.fill_rect(0, 0, 32, 32, Color.new(255, 255, 255))

loop { Graphics.update }
[/pre]
[/fold]

[fold=第二步:根据键盘的输入移动这一个点]
[pre lang="ruby"]

s = Sprite.new
s.bitmap = b = Bitmap.new(32, 32)

b.fill_rect(0, 0, 32, 32, Color.new(255, 255, 255))

loop do
  Input.update

  case Input.dir4
  when 2 then s.y += 32
  when 4 then s.x -= 32
  when 6 then s.x += 32
  when 8 then s.y -= 32
  end

  s.x %= Graphics.width
  s.y %= Graphics.height

  Graphics.update
end
[/pre]
[/fold]

[fold=第三步:完成其他各种细节]
[pre lang="ruby"]
# encoding: utf-8

POINT_SIZE = 32                       # 点的大小
WIDTH = Graphics.width / POINT_SIZE   # 地图宽度
HEIGHT = Graphics.height / POINT_SIZE # 地图高度
MOVE_FRAME = 10                       # 多少帧移动一次

# 表示地图的模块。
module Map

  class << self

    def init
      @points = Array.new(WIDTH) { Array.new(HEIGHT) }
    end

    # 往地图上添加一个点。
    # 如果点的位置上已经有另一个点,会调用点的 collide_with 方法。
    def add(point)
      original_point = @points[point.x][point.y]

      return if original_point == point

      point.collide_with(original_point) if original_point
      @points[point.x][point.y] = point
    end

    # 从地图上删去一个点。
    def delete(point)
      if @points[point.x][point.y] == point
        @points[point.x][point.y] = nil
      end
    end

    # 迭代地图上每一个点。
    def each_with_index
      # return to_enum(__method__) unless block_given?
      WIDTH.times do |x|
        HEIGHT.times do |y|
          point = @points[x][y]
          yield point, x, y if point
        end
      end

      self
    end
  end
end

# 表示一个正方形的,显示在地图上的点。
# 一旦生成了点,就不应该修改这个点的属性。
class Point

  # 在地图上生成一个位置随机的点。
  # 可以指定该点的颜色。
  # 返回 self 的一个实例。
  def self.random(color = Color.new(rand(256), rand(256), rand(256)))
    new(rand(WIDTH), rand(HEIGHT), color)
  end

  attr_reader :x, :y, :color

  # 在坐标 x, y 处的一个颜色为 color 的点。
  # x, y 是整数,color 为 Color 类的实例。
  def initialize(x, y, color)
    @x = x % WIDTH
    @y = y % HEIGHT
    @color = color
    # freeze        # 调用 freeze 可以防止手贱修改
  end

  # 当该点撞上其他点时调用该方法。
  # 接受的参数是撞上的那一个点(Point)。
  def collide_with(_)
  end

  # 使点出现在地图上。
  # 返回 self。
  def appear
    Map.add(self)
    self
  end

  # 让点从地图上消失、
  # 返回 self。
  def disappear
    Map.delete(self)
    self
  end
end

# 表示食物的模块
module Food

  # 表示食物的点
  class FoodPoint < Point

    # 用于判断点的类型。
    def food?
      true
    end
  end

  class << self

    def init
      @point = FoodPoint.random.appear
    end
  end
end

# 表示蛇的模块
module Snake

  # 表示蛇的身体的点。在 Snake 内部使用。
  class SnakePoint < Point

    def collide_with(point)
      if point.food?
        Snake.eat_food
        Food.init
      else                # 撞上除了食物之外的点
        raise 'game over'
      end
    end

    def food?
      false
    end
  end

  class << self

    # @points:SnakePoint 构成的数组
    # @direction:当前前进的方向
    # @last_direction:上次移动时的方向

    def init
      @points = [SnakePoint.random.appear]
      @direction = @last_direction = 2
    end

    def update
      update_direction
      update_movement
    end

    # 吃到食物时调用该方法。在下一次移动时长度增加一格。
    def eat_food
      @food_eaten = true
    end

    private

    # 往前增长一格
    def lengthen
      @points.unshift(next_point.appear)
    end

    # 蛇的最前方的点(Point)
    def head
      @points.first
    end

    # 头部前方一个点(Point)
    def next_point
      dx, dy = dir2xy(@direction)
      SnakePoint.new(head.x + dx, head.y + dy, head.color)
    end

    # 将方向(2,4,6,8)转为坐标的偏移量。
    # 以 [x, y] 的形式返回。
    def dir2xy(direction)
      case direction
      when 2 then [0, 1]
      when 4 then [-1, 0]
      when 6 then [1, 0]
      when 8 then [0, -1]
      else [0, 0]
      end
    end

    # 根据键盘输入更新蛇的方向(不能回头)
    def update_direction
      dir = Input.dir4
      @direction = dir if dir != 0 && dir + @last_direction != 10
    end

    def update_movement
      move if Graphics.frame_count % MOVE_FRAME == 0
    end

    # 往前行走一格。
    def move
      lengthen

      if @food_eaten
        @food_eaten = false
      else
        @points.pop.disappear
      end

      @last_direction = @direction
    end
  end
end

# 向屏幕上绘制地图的模块。
module Screen

  class << self
    def init
      @sprite = Sprite.new
      @bitmap = Bitmap.new(Graphics.width, Graphics.height)
      @sprite.bitmap = @bitmap
    end

    def update
      @bitmap.clear
      Map.each_with_index do |point, x, y|
        @bitmap.fill_rect(x * POINT_SIZE, y * POINT_SIZE,
          POINT_SIZE, POINT_SIZE, point.color)
      end
    end
  end
end

rgss_main do

  Map.init
  Food.init
  Snake.init
  Screen.init

  loop do
    Input.update
    Snake.update
    Screen.update
    Graphics.update
  end
end
[/pre]
[/fold]

评分

参与人数 2星屑 +115 收起 理由
湛蓝de海 + 30 好!
晴兰 + 85 画马

查看全部评分

梦石
0
星屑
1446
在线时间
6552 小时
注册时间
2010-12-30
回帖
8655
发表于 2015-4-3 16:41:59 | 显示全部楼层
QQ图片20150331131906.jpg 那怎样制作俄罗斯方块呢?
回复

使用道具 举报

老黄鸡

梦石
4
星屑
45700
在线时间
7948 小时
注册时间
2009-7-6
回帖
13338

MZ评测员RM创作大赛01组委会开拓者贵宾

发表于 2015-4-3 22:45:36 | 显示全部楼层
怎样制作h游戏呢?
RGDirect - DirectX驱动的RGSS,点我了解.
(排满,暂停)RM全系列成套系统定制请联系QQ1213237796
不接受对其他插件维护的委托
回复 1 0

使用道具 举报

梦石
4
星屑
4454
在线时间
6784 小时
注册时间
2014-1-6
回帖
4956

开拓者

发表于 2015-4-3 23:01:21 | 显示全部楼层
怎样制作galgame呢?
回复

使用道具 举报

炎

梦石
0
星屑
98
在线时间
1617 小时
注册时间
2013-8-15
回帖
4322
发表于 2015-4-3 23:04:43 | 显示全部楼层
怎么制作H漫呢?

评分

参与人数 1星屑 -15 收起 理由
三途亚梦 -15 刻意队形

查看全部评分

神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦神烦
回复

使用道具 举报

梦石
0
星屑
1816
在线时间
2527 小时
注册时间
2010-10-12
回帖
1336

开拓者

发表于 2015-4-3 23:30:27 | 显示全部楼层
[ 本帖最后由 刺夜之枪 于 2015-4-3 11:22 编辑 ]\n\n[ 本帖最后由 刺夜之枪 于 2015-4-3 11:21 编辑 ]
<s>改下队伍跟随脚本人物上限
大功告成{:2_274:}</s>

怎么制作坦克大战呢?

评分

参与人数 1星屑 +1 收起 理由
永燃的狂炎 + 1 破坏队形!

查看全部评分


回复

使用道具 举报

梦石
0
星屑
431
在线时间
403 小时
注册时间
2014-9-6
回帖
1212
发表于 2015-4-4 11:28:58 | 显示全部楼层
都什么乱七八糟的,要问就要问这个!

我擦“胡扯”是什么鬼啊啊啊!
大家好,我今年24岁,是学生
回复

使用道具 举报

梦石
0
星屑
9292
在线时间
2504 小时
注册时间
2011-5-20
回帖
14521

开拓者

发表于 2015-4-4 12:18:38 | 显示全部楼层
本帖最后由 chd114 于 2015-4-3 22:58 编辑
  1. s = Sprite.new
  2. s.bitmap = b = Bitmap.new(32, 32)

  3. b.fill_rect(0, 0, 32, 32, Color.new(255, 255, 255))

  4. loop do
  5.   Input.update

  6.   case Input.dir8
  7.   when 1
  8.   s.x += 32
  9.   s.y += 32
  10.   when 3
  11.   s.x -= 32
  12.   s.y += 32
  13.   when 5
  14.   s.x += 32
  15.   s.y -= 32
  16.   when 7
  17.   s.x -= 32
  18.   s.y -= 32
  19.   when 2 then s.y += 32
  20.   when 4 then s.x -= 32
  21.   when 6 then s.x += 32
  22.   when 8 then s.y -= 32
  23.   end

  24.   s.x %= Graphics.width
  25.   s.y %= Graphics.height

  26.   Graphics.update
  27. end
复制代码
八方向就这么干?@三途亚梦 @寒冷魔王  

评分

参与人数 1星屑 +1 收起 理由
寒冷魔王 + 1 -100 理由:不言而喻

查看全部评分

[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复

使用道具 举报

寒

梦石
0
星屑
1049
在线时间
1391 小时
注册时间
2010-8-9
回帖
3301
发表于 2015-4-4 15:13:54 | 显示全部楼层
本帖最后由 寒冷魔王 于 2015-4-4 15:23 编辑

学习了(各种意义上的)


其实我一直和01234打交道,在Bitmap方面真的很无力= =

不过也无所谓,SRPG的Map不需要用Bitmap,貌似

如果这段代码让我写,我会先写成01版的,然后再时时刷新为Bitmap版

实际上比较迅捷的操作是使用二进制操作符,比如RM的Map判断可否通行就是用的这个

点评

增了一句  发表于 2015-4-4 15:20
学校里闲着蛋疼瞎写的= = 总之这贴是「胡扯」啦~  发表于 2015-4-4 15:18
回复

使用道具 举报

梦石
0
星屑
1547
在线时间
688 小时
注册时间
2009-11-11
回帖
2692
发表于 2015-4-4 23:58:22 | 显示全部楼层
好评如潮

嘿。嘿。嘿
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部