e0 = $game_troop.enemies[0]
5.times do
Sprite_Siyecao.new(e0, 12)
end
class Sprite_Siyecao < Sprite
# character :发射者
# times :发射子弹数
def initialize(character,times)
@viewport = $scene.spriteset.viewport3 #视野为战斗场面viewport3
super(@viewport)
@character = character
@ch = @character
@times = times
self.visible = true
reset
end
#--------------------------------------------------------------------------
# 设置炮弹
#--------------------------------------------------------------------------
def reset
return if $bullet.size >= 4096
for i in 0...@times
#检查指针上界
break if $bullet.size >= 4096 #子弹总数限制4096
angle = Math::PI / @times * i * 2 #角度为子弹数平分
sprite = Sprite_Small1.new(@viewport,@ch,angle) #建立小玉
s1 = Sprite_Heart1.new(@viewport, @ch, 0, sprite) #建立心弹
s2 = Sprite_Heart1.new(@viewport, @ch, 1, sprite)
s3 = Sprite_Heart1.new(@viewport, @ch, 2, sprite)
s4 = Sprite_Heart1.new(@viewport, @ch, 3, sprite)
$bullet.push(s1)
s1.z = 100 + $bullet.size
$bullet.push(s2)
s2.z = 100 + $bullet.size
$bullet.push(s3)
s3.z = 100 + $bullet.size
$bullet.push(s4)
s4.z = 100 + $bullet.size
$bullet.push(sprite)
sprite.z = 100 + $bullet.size
end
Audio.thndj_se_play("Audio/SE/bullet_2",80,100)
dispose
end
#--------------------------------------------------------------------------
# ● 释放
#--------------------------------------------------------------------------
def dispose
if self.bitmap != nil
self.bitmap.dispose
self.visible = false
end
super
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
def update
super
dispose
end
end
#--------------------------------------------------------------------------
# Small
#--------------------------------------------------------------------------
class Sprite_Small1 < Sprite
attr_accessor :available
attr_accessor :vx #x 速度
attr_accessor :vy #y 速度
attr_accessor :ax #x 加速度
attr_accessor :ay #y 加速度
attr_accessor :vx0 #x 初速度
attr_accessor :vy0 #y 初速度
attr_accessor :an #角度
attr_accessor :an0 #初速度角度
attr_accessor :omiga #角速度
attr_accessor :aomiga #角速度加速度
attr_accessor :rr #向心运动半径
attr_accessor :lifespan # 存活时间
attr_accessor :lifetime # 已存活时间
#attr_accessor :event_list # change behaviors according to time
# [eventtime,new_vx,new_vy,new_ax,new_ay,sound_effect]
# e.g. eventlist.push([300,5,5,1,1,""])
attr_accessor :actor_or_enemy #敌我识别,0为我,1为敌
attr_accessor :row_flag #旋转标志
#--------------------------------------------------------------------------
# ● 初始化对像
# viewport : 显示端口
# character: 发射者
# angle : 弧度
#--------------------------------------------------------------------------
def initialize(viewport,character,angle)
super(viewport)
@character = character
if @character.is_a?(Game_Actor)
@actor_or_enemy = 0
else
@actor_or_enemy = 1
end
self.blend_type = 0
@chox = @character.screen_x + 10
@choy = @character.screen_y - 100
@x = @chox #发射点X
@y = @choy #发射点Y
@an = angle #角度
@an0 = angle #初速度角度
@mathx = (Math.cos(@an))*18
@mathy = (Math.sin(@an))*18
reset
self.bitmap = RPG::Cache.picture("bullet/小玉-黄")
self.available = true
self.visible = true
update
end
#--------------------------------------------------------------------------
# ● 设置对像
#--------------------------------------------------------------------------
def reset
return if self.disposed?
self.ox = 8 #图片半径8
self.oy = 8
self.x = @x
self.y = @y
@vx0 = @mathx #初速x
@vy0 = @mathy #初速y
self.vx = @vx0 #速度x
self.vy = @vy0 #速度y
self.omiga = 0 #角速度 应该是 'omega'
self.aomiga = 0 #角速度加速度
@an = self.get_angle #角度
self.rr = 130 #旋转半径
self.ax = 0 #@rv**2/rr*(Math.cos(@an))
self.ay = 0 #@rv**2/rr*(Math.sin(@an))
self.lifespan = 1024 #存活时间
self.lifetime = 0
self.available = false
self.visible = false
end
# def can_be_seen?(recal = true)
# if self.x>-640 and self.x<$width+640 and self.y>-480 and self.y<$height+480
# return true
# else
# return false
# end
# end
# change 1, use && instead and
def can_be_seen?(recal = true)
return self.x > -640 && self.x < $width + 640 && self.y > -480 && self.y < $height + 480
end
# def get_angle #角度获取:以发射点为圆心,极坐标判定角度
# sign = (self.x - @chox) > 0 ? 0 : Math::PI
# return Math.atan((self.y - @choy) / ((self.x - @chox) == 0 ? 1 : (self.x - @chox))) + sign
# end
# change 2 * 重要 *
# 如果是获取角度,这个函数才是正确的,返回值在 -PI ~ +PI 之间
def get_angle
dx = self.x - @chox
dy = self.y - @choy
return Math.atan2(dy, dx)
end
#--------------------------------------------------------------------------
# ● 释放
#--------------------------------------------------------------------------
def dispose
if self.bitmap != nil
self.visible = false
end
super
end
# change 3
def move
# return false if self.visible == false
return false if !self.visible # 3.1
if self.available
if self.lifetime < self.lifespan
case self.lifetime
when 1..26 #减速运动,每t速度衰减1.13
# if @vx0.abs > 0
if @vx0 != 0 # 3.2
if @vx.abs <= 1
@vx0 = 0
self.vx = 0
else
@vx0 /= 1.13
self.vx /= 1.13
end
end
# if @vy0.abs > 0 # 3.3
if @vy0 != 0
if @vy.abs <= 1
@vy0 = 0
self.vy = 0
else
@vy0 /= 1.13
self.vy /= 1.13
end
end #速度为0时开始旋转
if @vx0 == 0 and @vy0 == 0 and @row_flag != true
self.x = @chox + @rr * Math.cos(@an0) #X定点为初方向对应的圆周
self.y = @choy + @rr * Math.sin(@an0) #Y定点为初方向对应的圆周
@row_flag = true
end
when 27 #旋转的角速度加速度为0.3
if @row_flag != true
self.x = @chox + @rr * Math.cos(@an0)
self.y = @choy + @rr * Math.sin(@an0)
@row_flag = true
end
self.aomiga = 0.3
when 28..37 #转动半径-1
@rr -= 1
when 38..48 #转动半径-3
@rr -= 3
when 49..50 #转动半径-2
@rr -= 2
when 51..60 #转动半径-1
@rr -= 1
when 70..79 #转动半径+1
@rr += 1
when 80..89 #转动半径+2
@rr += 2
when 90 #加速63t,角速度达到18.9
# self.aomiga = -1+0.01*rand(100) #角速度代入随机负值
self.aomiga = -1 + rand # 3.4
@randr = rand(11) #转动半径增加值代入随机值
when 91..102 #转动半径+4*0.1*随机值
@rr += 4 + 0.1 * @randr
when 103..113 #转动半径+随机值
@rr += @randr
when 114 #关闭转动,将当前的速度变为X速度和Y速度,置一初速度VX0,
@row_flag = false #将四叶草甩出去
# v = self.omiga * Math::PI/180 * ((self.y-@choy) * (self.y-@choy) + (self.x-@chox) * (self.x-@chox)) ** 0.5
# an = self.get_angle
# self.vx = v * Math.cos(an)
# self.vy = v * Math.sin(an)
# @vx0 = self.vx
# 3.5
_x, _y = self.x - @chox, self.y - @choy
_r = Math.sqrt(_x * _x + _y * _y)
v = self.omiga * Math::PI / 180 * _r
self.vx = v * _x / _r
self.vy = v * _y / _r
@vx0 = self.vx
# -- 3.5 不知道这样算对不对,因为 get_angle 和普通的 arctan 还是有区别
when 114..139 #减速运动,速度衰减1.11
if @vx0.abs > 1
@vx0 /= 1.11
self.vx /= 1.11
self.vy /= 1.11
if @vx0.abs <= 1
@vx0 = 0
self.vx = 0
self.vy = 0
end
end
when 140 #速度归零
self.vx = 0
self.vy = 0
when 240 #小玉代入随机加速度,匀加速离开场景
# an = rand(360) * Math::PI/180
# v = rand(5)
# self.ax = (0.1 + 0.05 * v) * Math.cos(an)
# self.ay = (0.1 + 0.05 * v) * Math.sin(an)
# 3.6
self.ax = (0.2 + rand * 0.4) * (rand(2) - 0.5)
self.ay = (0.2 + rand * 0.4) * (rand(2) - 0.5)
# -- 3.6 这里不一定必须使速度均匀分布在一个环面内
end
if @row_flag #转动模式,x和y直接由角速度和转动半径决定
@an = self.get_angle
@an += self.omiga * Math::PI / 180
self.omiga += self.aomiga
self.x = @chox + @rr * Math.cos(@an)
self.y = @choy + @rr * Math.sin(@an)
else #加速模式,x和y由正常的加速减速运动
self.x += self.vx
self.y += self.vy
self.vx += self.ax
self.vy += self.ay
end
if self.can_be_seen?(false)
self.visible = true unless self.visible
else
self.visible = false if self.visible
end
self.lifetime += 1
else
self.visible = false if self.visible
self.available = false if self.available
end
else
# if self.visible
# self.visible = false
# end
self.visible &&= false # 3.7 上面也可以这样改,未必能提升效率但是很酷
end
check
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
def update
super
#p self.visible
return if self.visible == false
if move == false
return "delete"
end
end
# change 4
def check
return unless $scene.is_a?(Scene_Battle)
dx = self.x#+self.bitmap.width*0.5*0.75
dy = self.y#+self.bitmap.height*0.5*0.75
ra = 64 #子弹判定半径7,判定点半径1,合计8
# 4.1
ra_sq = 8 * 1.42
# -- 4.1
if self.actor_or_enemy == 1 #敌军
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
sprite = $scene.spriteset.actor_sprites[$game_party.actors.size-1-i]
tx = actor.screen_x - sprite.cw*0.05 #根据位图大小取判定点位置X
ty = actor.screen_y - sprite.ch*0.445 #根据位图大小取判定点位置Y
# if (dx-tx)*(dx-tx) + (dy-ty)*(dy-ty) <= ra #圆函数判定
# 4.2
_x, _y = (dx - tx).abs, (dy - ty).abs
if _x + _y < ra_sq && (_x*_x + _y*_y) <= ra
# -- 4.2 先做一个粗略的判断
value = 1 + rand(5)
value /= 2 if actor.guarding?
actor.hp -= value
actor.damage["event"] = value
actor.damage_pop["event"] = true
actor.animation.push([807+rand(3),true]) #击中动画
# 4.3 *重要*
# $scene.status_window.refresh
$battle_status_need_refresh = true
# --4.3 阻止多次刷新窗口,请在 Scene_Battle 的 update 方法中判断 $battle_status_need_refresh 再刷新窗口
# 因为通常在 status_window.refresh 中调用了 draw_text 方法,这是耗时极高的方法
# see change 5
self.visible = false
end
if $game_party.all_dead?
# 切换到游戏结束画面
$scene = Scene_Gameover.new
return
end
end#for
else #我军弹幕
for i in 0...$game_troop.enemies.size
actor = $game_troop.enemies[i]
sprite = $scene.spriteset.enemy_sprites[$game_troop.enemies.size-1-i]
tx = actor.screen_x+sprite.cw*0.1 #根据位图大小取判定点位置X
ty = actor.screen_y-sprite.ch*0.445 #根据位图大小取判定点位置Y
# see change 4.2 and 4.3
if (dx-tx)*(dx-tx) + (dy-ty)*(dy-ty) <= ra #圆函数判定
value = 1 + rand(5)
value /= 2 if actor.guarding?
actor.hp -= value
actor.damage["event"] = value
actor.damage_pop["event"] = true
actor.animation.push([807+rand(3),true]) #击中动画
$scene.status_window.refresh
self.visible = false
end
end #for
end #if
end #def
end
# change 5
class Scene_Battle
alias _balabala_update update
def update
if $battle_status_need_refresh
@status_window.refresh
end
_balabala_update
end
end
#--------------------------------------------------------------------------
# Heart
#--------------------------------------------------------------------------
class Sprite_Heart1 < Sprite
attr_accessor :available
attr_accessor :vx #x 速度
attr_accessor :vy #y 速度
attr_accessor :ax #x 加速度
attr_accessor :ay #y 加速度
attr_accessor :an0 #最初的角度
attr_accessor :lifespan # 存活时间
attr_accessor :lifetime # 已存活时间
#attr_accessor :event_list # change behaviors according to time
# [eventtime,new_vx,new_vy,new_ax,new_ay,sound_effect]
# e.g. eventlist.push([300,5,5,1,1,""])
attr_accessor :actor_or_enemy #敌我识别,0为我,1为敌
attr_accessor :relese_flag #释放标志
#--------------------------------------------------------------------------
# ● 初始化对像
# viewport : 显示端口
# angle : 弧度 0=0 1=90 2=180 3=270
#--------------------------------------------------------------------------
def initialize(viewport,character,angle,target)
super(viewport)
@character = character
if @character.is_a?(Game_Actor)
@actor_or_enemy = 0
else
@actor_or_enemy = 1
end
self.blend_type = 0
self.lifetime = 0
@target = target
@chox = @target.x
@choy = @target.y
@an = angle * Math::PI/2
@an0 = angle * 90
@x = @chox + 16*Math.cos(@an)
@y = @choy + 16*Math.sin(@an)
reset
self.bitmap = RPG::Cache.picture("bullet/心弹-绿")
self.available = true
self.visible = true
@release_flag = false
update
end
#--------------------------------------------------------------------------
# ● 设置对像
#--------------------------------------------------------------------------
def reset
return if self.disposed?
self.ox = 16 #子弹半径16
self.oy = 16
self.x = @x
self.y = @y
self.vx = 0 #速度X
self.vy = 0 #速度Y
@an = self.get_angle #角度
self.ax = 0#@rv**2/rr*(Math.cos(@an))
self.ay = 0#@rv**2/rr*(Math.sin(@an))
self.lifespan = 1024
self.lifetime = 0
self.available = false
self.visible = false
end
def can_be_seen?(recal = true)
if self.x >-640 and self.x< $width + 640 and self.y > -480 and self.y < $height + 480
return true
else
return false
end
end # see change 1
def get_angle #角度获取:以小玉为圆心,初位置+转动相位作为角度
@chox = @target.x #小玉X
@choy = @target.y #小玉Y
an = (self.lifetime % 360 * 8 + @an0) * Math::PI / 180 #每t转动8度
#心弹自身的角度为相位负值+90度+初相位方向修正
self.angle = -self.lifetime % 360 * 8 + 90 + (@an0 % 180 == 0 ? @an0 : @an0 + 180)
return an
end # see change 2
#--------------------------------------------------------------------------
# ● 释放
#--------------------------------------------------------------------------
def dispose
if self.bitmap != nil
self.visible = false
end
super
end
# change 6
def move
return false if self.visible == false
########################
if self.available
if self.lifetime < self.lifespan
if self.lifetime == 140 #第140t时释放
get_angle #获取角度,置对应角度加速度
ang = (self.angle+(@an0%180 == 0 ? 180 : 0))*Math::PI/180
self.vx = 0
self.vy = 0
self.ax = Math.cos(ang)*0.2
self.ay = Math.sin(ang)*0.2
@release_flag = true
end
if @release_flag == true #释放后
self.x += self.vx
self.y += self.vy
self.vx += self.ax
self.vy += self.ay
# if (self.vx*self.vx+self.vy*self.vy)**0.5 >= 20 #速度大于20变为匀速
if self.vx.abs + self.vy.abs > 20 && (self.vx*self.vx+self.vy*self.vy) >= 400 # 6.1
self.ay = 0
self.ax = 0
end
else #释放前
@an = self.get_angle #获取角度
self.x = @chox + 16 * Math.cos(@an) #X定位为小玉圆周
self.y = @choy + 16 * Math.sin(@an) #Y定位为小玉圆周
end
if self.can_be_seen?(false)
self.visible = true unless self.visible
else
self.visible = false if self.visible
end
self.lifetime += 1
else
self.visible = false if self.visible
self.available = false if self.available
end
else
if self.visible
self.visible = false
end
end
check
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
def update
super
#p self.visible
return if self.visible == false
if move == false
return "delete"
end
end
# see change 4
def check
return unless $scene.is_a?(Scene_Battle)
dx = self.x#+self.bitmap.width*0.5*0.75
dy = self.y#+self.bitmap.height*0.5*0.75
ra = 256 #图形判定区15,判定点1,合计16
if self.actor_or_enemy == 1 #敌军
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
sprite = $scene.spriteset.actor_sprites[$game_party.actors.size-1-i]
tx = actor.screen_x-sprite.cw*0.05 #根据位图尺寸决定判定点
ty = actor.screen_y-sprite.ch*0.445
if (dx-tx)*(dx-tx) + (dy-ty)*(dy-ty) <= ra
value = 1 + rand(5)
value /= 2 if actor.guarding?
actor.hp -= value
actor.damage["event"] = value
actor.damage_pop["event"] = true
actor.animation.push([807+rand(3),true]) #命中动画
$scene.status_window.refresh
self.visible = false
end
if $game_party.all_dead?
# 切换到游戏结束画面
$scene = Scene_Gameover.new
return
end
end#for
else #我军弹幕
for i in 0...$game_troop.enemies.size
actor = $game_troop.enemies[i]
sprite = $scene.spriteset.enemy_sprites[$game_troop.enemies.size-1-i]
tx = actor.screen_x+sprite.cw*0.1 #根据位图尺寸决定判定点
ty = actor.screen_y-sprite.ch*0.445
if (dx-tx)*(dx-tx) + (dy-ty)*(dy-ty) <= ra
value = 1 + rand(5)
value /= 2 if actor.guarding?
actor.hp -= value
actor.damage["event"] = value
actor.damage_pop["event"] = true
actor.animation.push([807+rand(3),true]) #命中动画
$scene.status_window.refresh
self.visible = false
end
end #for
end #if
end #def
end