| 赞 | 72 |
| VIP | |
| 好人卡 | |
| 积分 | 23 |
| 经验 | |
| 最后登录 | 2022-3-9 |
| 在线时间 | 4033 小时 |
…あたしは天
- 梦石
- 0
- 星屑
- 2308
- 在线时间
- 4033 小时
- 注册时间
- 2010-10-4
- 回帖
- 10548
 
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
注意该主题的标签,注意该主题的标签,因为很重要所以说两遍!
[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] |
评分
-
查看全部评分
|