设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1568|回复: 12
打印 上一主题 下一主题

[已经解决] 求改良打砖块的反弹方法

[复制链接]

Lv5.捕梦者

梦石
0
星屑
24479
在线时间
5077 小时
注册时间
2016-3-8
帖子
1623
跳转到指定楼层
1
发表于 2022-5-15 23:13:54 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
1000星屑
本帖最后由 alexncf125 于 2022-5-16 12:08 编辑

有大神可以帮忙看看171行跟243行的算法该怎样地改良才能正常么

三张图片放置于Graphics/Breakout_Clone之內
RUBY 代码复制
  1. $imported ||= {}
  2. $imported["AI-BreakoutClone"] = true
  3.  
  4. module BREAKOUT_CLONE
  5.   STAGE = {}
  6.   STAGE[0] = [
  7.   [7, 15, 0], [7, 91, 0], [7, 167, 0], [7, 242, 0], [7, 317, 0], [7, 393, 0], [7, 469, 0],
  8.   [6, 15, 40], [6, 91, 40], [6, 167, 40], [6, 242, 40], [6, 317, 40], [6, 393, 40], [6, 469, 40],
  9.   [3, 15, 80], [1, 91, 80], [1, 167, 80], [1, 242, 80], [1, 317, 80], [1, 393, 80], [1, 469, 80],
  10.   [4, 15, 120], [2, 91, 120], [1, 167, 120], [1, 242, 120], [1, 317, 120], [2, 393, 120], [4, 469, 120],
  11.   [5, 15, 160], [3, 91, 160], [1, 167, 160], [1, 242, 160], [1, 317, 160], [3, 393, 160], [5, 469, 160],
  12.   [6, 15, 200], [4, 91, 200], [2, 167, 200], [1, 242, 200], [2, 317, 200], [4, 393, 200], [6, 469, 200],
  13.   [7, 15, 240], [6, 91, 240], [4, 167, 240], [1, 242, 240], [4, 317, 240], [6, 393, 240], [7, 469, 240]
  14.   ]
  15. end
  16.  
  17. module Cache
  18.   def self.breakout_clone(filename)
  19.     load_bitmap("Graphics/Breakout_Clone/", filename)
  20.   end
  21. end
  22.  
  23. module SceneManager
  24.   class << self; alias :breakout_clone_first_scene_class :first_scene_class; end
  25.   def self.first_scene_class
  26.     if $imported["AI-BreakoutClone"] && !$BTEST
  27.       Graphics.resize_screen(544, 480)
  28.       return Scene_Breakout_Clone
  29.     end
  30.     breakout_clone_first_scene_class
  31.   end
  32. end
  33.  
  34. class Game_Temp
  35.  
  36.   attr_accessor :breakout_clone_start
  37.   attr_accessor :breakout_clone_gameover
  38.  
  39.   alias breakout_clone_initialize initialize
  40.   def initialize
  41.     breakout_clone_initialize
  42.     @breakout_clone_start = false
  43.     @breakout_clone_gameover = false
  44.   end
  45.  
  46.   def set_breakout_clone_start(flag); @breakout_clone_start = flag; end
  47.   def reset_breakout_clone_start; @breakout_clone_start = false; end
  48.   def breakout_clone_start?; @breakout_clone_start == true; end
  49.  
  50.   def set_breakout_clone_gameover(flag); @breakout_clone_gameover = flag; end
  51.   def reset_breakout_clone_gameover; @breakout_clone_gameover = false; end
  52.   def breakout_clone_gameover?; @breakout_clone_gameover == true; end
  53.  
  54. end
  55.  
  56. class Sprite_Breakout_Clone_Paddle < Sprite
  57.  
  58.   def initialize
  59.     super
  60.     init_members
  61.     create_bitmap
  62.   end
  63.  
  64.   def init_members
  65.     @slide_speed = 8
  66.   end
  67.  
  68.   def create_bitmap
  69.     self.bitmap = Cache.breakout_clone("paddle")
  70.     self.x = (Graphics.width - paddle_width) / 2
  71.     self.y = Graphics.height - paddle_height
  72.   end
  73.  
  74.   def slide_speed; @slide_speed; end
  75.   def paddle_width; self.bitmap.width; end
  76.   def paddle_height; self.bitmap.height; end
  77.   def paddle_x; self.x + paddle_width; end
  78.   def paddle_y; self.y + paddle_height; end
  79.  
  80.   def dispose
  81.     self.bitmap.dispose
  82.     super
  83.   end
  84.  
  85.   def update
  86.     super
  87.     update_position
  88.   end
  89.  
  90.   def update_position
  91.     slide_left if Input.press?(:LEFT)
  92.     slide_right if Input.press?(:RIGHT)
  93.   end
  94.  
  95.   def slide_left
  96.     result = self.x - slide_speed
  97.     return self.x = 0 if result <= 0
  98.     self.x -= slide_speed
  99.   end
  100.  
  101.   def slide_right
  102.     result = self.x + slide_speed
  103.     block = Graphics.width - paddle_width
  104.     return self.x = block if result >= block
  105.     self.x += slide_speed
  106.   end
  107.  
  108. end
  109.  
  110. class Sprite_Breakout_Clone_Ball < Sprite
  111.  
  112.   attr_accessor :route_x
  113.   attr_accessor :route_y
  114.   attr_accessor :ball_last_touch
  115.  
  116.   def initialize(viewport, paddle = nil)
  117.     super(viewport)
  118.     @paddle = paddle
  119.     init_members
  120.     create_bitmap
  121.   end
  122.  
  123.   def init_members
  124.     @move_speed = 4
  125.     @route_x = [-(rand(@move_speed) + 1), rand(@move_speed) + 1][rand(2)]
  126.     @route_y = -(@move_speed + 1)
  127.     @ball_last_touch = :paddle
  128.   end
  129.  
  130.   def create_bitmap
  131.     self.bitmap = Cache.breakout_clone("ball")
  132.     self.x = (Graphics.width - ball_width) / 2
  133.     self.y = Graphics.height - @paddle.bitmap.height - ball_height
  134.   end
  135.  
  136.   def move_speed; @move_speed; end
  137.   def route_x; @route_x; end
  138.   def route_y; @route_y; end
  139.   def ball_width; self.bitmap.width; end
  140.   def ball_height; self.bitmap.height; end
  141.   def ball_x; self.x + ball_width; end
  142.   def ball_y; self.y + ball_height; end
  143.  
  144.   def dispose
  145.     self.bitmap.dispose
  146.     super
  147.   end
  148.  
  149.   def update
  150.     super
  151.     update_position
  152.     update_ball_touch
  153.   end
  154.  
  155.   def update_position
  156.     if $game_temp.breakout_clone_start?
  157.       self.x = (@paddle.x + @paddle.bitmap.width) / 2  - ball_width / 2
  158.       self.y = Graphics.height - @paddle.bitmap.height - ball_height
  159.     else
  160.       self.x += route_x
  161.       self.y += route_y
  162.     end
  163.   end
  164.  
  165.   def update_ball_touch
  166.     return if $game_temp.breakout_clone_gameover?
  167.     update_touch_paddle
  168.     update_touch_wall
  169.   end
  170.  
  171.   def update_touch_paddle
  172.     return if @ball_last_touch == :paddle
  173.     if ball_x.between?(@paddle.x, @paddle.x + @paddle.bitmap.width + ball_width) && ball_y.between?(@paddle.y, @paddle.y + @paddle.bitmap.height)
  174.       if (ball_x.between?(@paddle.x, @paddle.x + (ball_width / 2)) && route_x > 0) || (self.x.between?(@paddle.x + @paddle.bitmap.width - (ball_width / 2), @paddle.x + @paddle.bitmap.width) && route_x < 0)
  175.         if Input.press?(:RIGHT) && route_x < 0
  176.           @route_x =  rand(move_speed) + 1
  177.         elsif Input.press?(:LEFT) && route_x > 0
  178.           @route_x = -(rand(move_speed) + 1)
  179.         else
  180.           @route_x = -(route_x)
  181.         end
  182.       else
  183.         @route_x =  rand(move_speed) + 1 if Input.press?(:RIGHT)
  184.         @route_x = -(rand(move_speed) + 1) if Input.press?(:LEFT)
  185.       end
  186.       @route_y = -(move_speed) unless self.y > @paddle.y
  187.       @ball_last_touch = :paddle
  188.     end
  189.   end
  190.  
  191.         def update_touch_wall
  192.     if self.x <= 0 || ball_x >= Graphics.width
  193.       @route_x = -(route_x)
  194.       @ball_last_touch = :wall
  195.     end
  196.     if self.y <= 0
  197.       @route_y = -(route_y)
  198.       @ball_last_touch = :wall
  199.     end
  200.   end
  201.  
  202. end
  203.  
  204. class Sprite_Breakout_Clone_Brick < Sprite
  205.  
  206.   def initialize(viewport, balls = nil, brick = nil)
  207.     super(viewport)
  208.     @ball = balls
  209.     @brick = brick
  210.     init_members
  211.     create_bitmap
  212.   end
  213.  
  214.   def init_members
  215.     @brick_life = @brick[0]
  216.   end
  217.  
  218.   def create_bitmap
  219.     self.bitmap = Cache.breakout_clone("brick")
  220.     self.x = @brick[1]
  221.     self.y = @brick[2]
  222.   end
  223.  
  224.   def dispose
  225.     self.bitmap.dispose
  226.     super
  227.   end
  228.  
  229.   def update
  230.     super
  231.     update_src_rect
  232.     update_brick_touch
  233.     update_brick_visible
  234.   end
  235.  
  236.   def update_src_rect
  237.     return if @brick_life.zero?
  238.     index = @brick_life
  239.     sy = (index - 1) * 24
  240.     self.src_rect.set(0, sy, 68, 24)
  241.   end
  242.  
  243.   def update_brick_touch
  244.     return if self.visible == false
  245.     @ball.each do |b|
  246.       return if b.ball_last_touch == self
  247.       if b.ball_x.between?(self.x, self.x + self.bitmap.width + b.ball_width) && b.ball_y.between?(self.y, self.y + self.bitmap.height / 7 + b.ball_height)
  248.         if (b.x).between?(self.x - b.bitmap.width + 1, self.x + self.bitmap.width - 1)
  249.           b.route_y = -(b.route_y)
  250.         end
  251.         if (b.y).between?(self.y - b.bitmap.height + 1, self.y + self.bitmap.height / 7 - 1)
  252.           b.route_x = -(b.route_x)
  253.         end
  254.         @brick_life -= 1 if @brick_life > 0
  255.         b.ball_last_touch = self
  256.       end
  257.     end
  258.   end
  259.  
  260.   def update_brick_visible
  261.     self.visible = !@brick_life.zero?
  262.   end
  263.  
  264. end
  265.  
  266. class Scene_Breakout_Clone < Scene_Base
  267.  
  268.   include BREAKOUT_CLONE
  269.  
  270.   def start
  271.     super
  272.     create_breakout_clone_paddle
  273.     create_breakout_clone_ball
  274.     create_breakout_clone_brick
  275.   end
  276.  
  277.   def create_breakout_clone_paddle
  278.     @breakout_clone_paddle_sprite = Sprite_Breakout_Clone_Paddle.new
  279.   end
  280.  
  281.   def create_breakout_clone_ball
  282.     @breakout_clone_ball_sprite ||= []
  283.     @breakout_clone_ball_sprite.push(Sprite_Breakout_Clone_Ball.new(@viewport1, @breakout_clone_paddle_sprite))
  284.   end
  285.  
  286.   def create_breakout_clone_brick
  287.     @breakout_clone_brick_sprite ||= []
  288.     STAGE[0].each do |brick|
  289.       @breakout_clone_brick_sprite.push(Sprite_Breakout_Clone_Brick.new(@viewport1, @breakout_clone_ball_sprite, brick))
  290.     end
  291.   end
  292.  
  293.   def terminate
  294.     super
  295.     dispose_breakout_clone_paddle
  296.     dispose_breakout_clone_ball
  297.     dispose_breakout_clone_brick
  298.   end
  299.  
  300.   def dispose_breakout_clone_paddle
  301.     @breakout_clone_paddle_sprite.bitmap.dispose
  302.     @breakout_clone_paddle_sprite.dispose
  303.   end
  304.  
  305.   def dispose_breakout_clone_ball
  306.     @breakout_clone_ball_sprite.each do |sprite|
  307.       sprite.bitmap.dispose
  308.       sprite.dispose
  309.     end
  310.   end
  311.  
  312.   def dispose_breakout_clone_brick
  313.     @breakout_clone_brick_sprite.each do |sprite|
  314.       sprite.bitmap.dispose
  315.       sprite.dispose
  316.     end
  317.   end
  318.  
  319.   def update
  320.     super
  321.     @breakout_clone_paddle_sprite.update
  322.     @breakout_clone_ball_sprite.each {|sprite| sprite.update}
  323.     @breakout_clone_brick_sprite.each {|sprite| sprite.update}
  324.   end
  325.  
  326. end


Lv5.捕梦者

梦石
0
星屑
24479
在线时间
5077 小时
注册时间
2016-3-8
帖子
1623
2
 楼主| 发表于 2022-5-17 11:49:11 | 显示全部楼层
仇九 发表于 2022-5-16 21:52
呜~

写了一个RectangleAndRectangle模块来集成矩形的碰撞检测和球的反弹,然后将球与玩家控制的板子,球与 ...

谢谢大神~
球与砖块的碰撞都变得美好了~

不过现在到球与底板的碰撞变得不正常了...
比如, 球向右下走时, 按方向左键, 球不会削回去左上
另外球好像会穿透底板...
要是能改用回之前的就好像完美了~

点评

啊……错了错了,应该是需要在373行后再加一句ball_y_change(ball,false) if ifIsPaddle,这样就能在球碰到板的左右侧壁时在y方向上也反弹。  发表于 2022-5-17 23:32
唔,要改的话在RectangleAndRectangle模块下的ball_x_change方法中添加东西就行。  发表于 2022-5-17 23:27
回复

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-15 20:01

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表