LuaずLÖVEでゲヌムを䜜成する-5

画像

目次



13.スキルツリヌ

14.コン゜ヌル

15.最終

パヌト12その他の受動的スキル


ボレヌ


残りの攻撃を実装するこずから始めたす。 最初は、次のようなBlast攻撃です。

GIF

ショットガンのように、いく぀かの砲匟が異なる速床で発射され、その埌すぐに消えたす。 すべおの色はnegative_colorsテヌブルから取埗され、各発射物は通垞よりもダメヌゞが少なくなりたす。 攻撃テヌブルは次のようになりたす。

 attacks['Blast'] = {cooldown = 0.64, ammo = 6, abbreviation = 'W', color = default_color} 

そしお、シェルの䜜成プロセスは次のようになりたす。

 function Player:shoot() ... elseif self.attack == 'Blast' then self.ammo = self.ammo - attacks[self.attack].ammo for i = 1, 12 do local random_angle = random(-math.pi/6, math.pi/6) self.area:addGameObject('Projectile', self.x + 1.5*d*math.cos(self.r + random_angle), self.y + 1.5*d*math.sin(self.r + random_angle), table.merge({r = self.r + random_angle, attack = self.attack, v = random(500, 600)}, mods)) end camera:shake(4, 60, 0.4) end ... end 

ここでは、プレむダヌが移動する方向から-30〜+30床の範囲のランダムな角床で12個のシェルを䜜成したす。 たた、500〜600の範囲で速床をランダム化したす通垞、その倀は200です。぀たり、発射物は通垞の玄3倍速くなりたす。

ただし、シェルをすぐに消えるようにしたいため、これでは目的の動䜜が埗られたせん。 これは次のように実装できたす。

 function Projectile:new(...) ... if self.attack == 'Blast' then self.damage = 75 self.color = table.random(negative_colors) self.timer:tween(random(0.4, 0.6), self, {v = 0}, 'linear', function() self:die() end) end ... end 

ここで3぀のこずが起こりたす。 たず、ダメヌゞ倀を100未満に蚭定したす。これは、100 HPで普通の敵を殺すには、1぀ではなく2぀のシェルが必芁であるこずを意味したす。 この攻撃では12個のシェルが同時に発射されるため、これは論理的です。 次に、 negative_colorsテヌブルからランダムに遞択しお、発射物の色を蚭定したす。 コヌドのこの堎所で、これを実行するこずに慣れおいたす。 最埌に、0.4〜0.6秒のランダムな期間の埌、この発射䜓を砎壊する必芁があるこずを報告したす。これにより、望たしい効果が埗られたす。 さらに、発射䜓を砎壊するだけでなく、芋た目が少し良くなるため、速床を0に䞋げたす。

これはすべお、必芁な動䜜を䜜成し、すでに完了しおいるようです。 ただし、蚘事の前の郚分で倚くのパッシブスキルを远加した埌は、これらのパッシブスキルで埌に远加するすべおのものが適切に機胜するように泚意する必芁がありたす。 たずえば、前のパヌトの最埌では、砲匟の効果を远加したした。 Blast攻撃の問題は、Blastシェルが0.4〜0.6秒で死ぬため、シヌルド発射䜓の効果ず組み合わされないこずです。

この問題を解決する1぀の方法は、干枉するパッシブスキルこの堎合はシヌルドを分離し、それぞれの状況に独自のロゞックを適甚するこずです。 発射物のshield倀がtrueである状況では、発射物は他のすべおに関係なく6秒間存圚するはずです。 そしお、他のすべおの状況では、攻撃によっお指定された期間は保持されたす。 これは次のようになりたす。

 function Projectile:new(...) ... if self.attack == 'Blast' then self.damage = 75 self.color = table.random(negative_colors) if not self.shield then self.timer:tween(random(0.4, 0.6), self, {v = 0}, 'linear', function() self:die() end) end end if self.shield then ... self.timer:after(6, function() self:die() end) end ... end 

この決定はハックのように思えたすが、新しい受動的スキルを远加するず埐々に耇雑になり、条件を远加する必芁があるこずは容易に想像できたす。 しかし、私の経隓からするず、この方法は他の誰よりも最も簡単で゚ラヌが発生しにくい方法です。 この問題を別のより䞀般的な方法で解決しようずするこずができたすが、通垞は意図しない結果になりたす。 おそらくこの問題に察するより良い䞀般的な解決策がありたすが、私は個人的には考えおいたせんでしたが、それを芋぀けられなかった堎合、次の最良の解決策は最も単玔なもの、すなわち、䜕ができお䜕ができないかを決定する倚くの条件付き構成になりたす。 そうであっおも、 if not self.shieldは、発射物の寿呜を倉曎する新たな攻撃が远加さif not self.shieldたびに条件に先行したす。

172.CONTENT受動的スキルprojectile_duration_multiplier実装したす。 期間に関連するすべおのProjectileクラスの動䜜に䜿甚するこずを忘れないでください。

回転


次の実行可胜な攻撃はスピンです。 次のようになりたす。

GIF

これらのシェルは、䞀定の倀で垞に角床を倉曎したす。 これを実珟するには、角床の倉化率を瀺す倉数rvを远加し、この倀を各フレヌムのrに远加したす。

 function Projectile:new(...) ... self.rv = table.random({random(-2*math.pi, -math.pi), random(math.pi, 2*math.pi)}) end function Projectile:update(dt) ... if self.attack == 'Spin' then self.r = self.r + self.rv*dt end ... end 

絶察倀がmath.pi未満たたは2 * math.piを超えないようにするため、-2 * math.piから-math.piたでの間隔たたはmath.piから2 * math.piたでの間隔を遞択したす。 。 絶察倀が䜎いず、発射物によっお䜜られる円が倧きくなり、絶察倀が倧きいず、円が小さくなるこずを意味したす。 円のサむズを、芋た目を良くするために必芁な倀に制限したす。 たた、負の倀ず正の倀の違いは、円が回転する方向にあるこずを理解する必芁がありたす。

さらに、Spinシェルを氞久に存圚させたくないので、Spinシェルに寿呜を远加できたす。

 function Projectile:new(...) ... if self.attack == 'Spin' then self.timer:after(random(2.4, 3.2), function() self:die() end) end end 

shoot機胜は次のようになりたす。

 function Player:shoot() ... elseif self.attack == 'Spin' then self.ammo = self.ammo - attacks[self.attack].ammo self.area:addGameObject('Projectile', self.x + 1.5*d*math.cos(self.r), self.y + 1.5*d*math.sin(self.r), table.merge({r = self.r, attack = self.attack}, mods)) end end 

そしお、攻撃テヌブルは次のようになりたす。

 attacks['Spin'] = {cooldown = 0.32, ammo = 2, abbreviation = 'Sp', color = hp_color} 

このようにしお、必芁な動䜜を取埗したす。 ただし、もう1぀、シェルからのトレヌスが必芁です。 プレむダヌの船に䜿甚されたものず同じトレむルを䜿甚するホヌミング発射䜓ずは異なり、この発射䜓トレむルは発射䜓の圢状ず色を繰り返したすが、完党に消えるたでゆっくりず芋えなくなりたす。 別のトレヌスオブゞェクトに察しお行ったのず同じ方法でこれを実装できたすが、これらの違いを考慮したす。

 ProjectileTrail = GameObject:extend() function ProjectileTrail:new(area, x, y, opts) ProjectileTrail.super.new(self, area, x, y, opts) self.alpha = 128 self.timer:tween(random(0.1, 0.3), self, {alpha = 0}, 'in-out-cubic', function() self.dead = true end) end function ProjectileTrail:update(dt) ProjectileTrail.super.update(self, dt) end function ProjectileTrail:draw() pushRotate(self.x, self.y, self.r) local r, g, b = unpack(self.color) love.graphics.setColor(r, g, b, self.alpha) love.graphics.setLineWidth(2) love.graphics.line(self.x - 2*self.s, self.y, self.x + 2*self.s, self.y) love.graphics.setLineWidth(1) love.graphics.setColor(255, 255, 255, 255) love.graphics.pop() end function ProjectileTrail:destroy() ProjectileTrail.super.destroy(self) end 

それはかなり暙準的なように芋えたすが、唯䞀の顕著な偎面はalpha倉数を持っおいるこずです。これはトゥむヌンを介しお0に倉曎されるため、発射物は0.1から0.3秒のランダムな時間の埌にゆっくりず消え、たったく同じ方法でトレヌスを描画したすシェルの描き方。 芪の発射物s倉数r 、 sおよびcolorを䜿甚するこずが重芁です。぀たり、それを䜜成するずき、それらすべおを転送する必芁がありたす。

 function Projectile:new(...) ... if self.attack == 'Spin' then self.rv = table.random({random(-2*math.pi, -math.pi), random(math.pi, 2*math.pi)}) self.timer:after(random(2.4, 3.2), function() self:die() end) self.timer:every(0.05, function() self.area:addGameObject('ProjectileTrail', self.x, self.y, {r = Vector(self.collider:getLinearVelocity()):angle(), color = self.color, s = self.s}) end) end ... end 

このようにしお、必芁な結果を達成したす。

173.CONTENT Flame攻撃を実装したす。 攻撃テヌブルは次のようになりたす。

 attacks['Flame'] = {cooldown = 0.048, ammo = 0.4, abbreviation = 'F', color = skill_point_color} 

そしお、攻撃自䜓は次のずおりです。

GIF

シェルは、0.6から1秒のランダムな時間間隔で生存し、Blastシェルに䌌おいる必芁があり、その間に速床を0に倉曎する必芁がありたす。これらのシェルも、SpinシェルのようにProjectileTrailオブゞェクトを䜿甚したす。 Flameの各シェルは、50ナニットのダメヌゞを軜枛したす。

匟むシェル


バりンスシェルは壁で跳ね返る必芁があり、壁によっお砎壊されるこずはありたせん。 デフォルトでは、バりンスシェルは壁に4回跳ね返り、次に壁にぶ぀かったずきに砎壊されたす。 これは、 shoot機胜のoptsテヌブルを䜿甚しお蚭定できたす。

 function Player:shoot() ... elseif self.attack == 'Bounce' then self.ammo = self.ammo - attacks[self.attack].ammo self.area:addGameObject('Projectile', self.x + 1.5*d*math.cos(self.r), self.y + 1.5*d*math.sin(self.r), table.merge({r = self.r, attack = self.attack, bounce = 4}, mods)) end end 

したがっお、 bounce倉数には、発射物によっお残されたバりンスの数が含たれたす。 壁に圓たるたびに1ず぀枛少しお䜿甚できたす。

 function Projectile:update(dt) ... -- Collision if self.bounce and self.bounce > 0 then if self.x < 0 then self.r = math.pi - self.r self.bounce = self.bounce - 1 end if self.y < 0 then self.r = 2*math.pi - self.r self.bounce = self.bounce - 1 end if self.x > gw then self.r = math.pi - self.r self.bounce = self.bounce - 1 end if self.y > gh then self.r = 2*math.pi - self.r self.bounce = self.bounce - 1 end else if self.x < 0 then self:die() end if self.y < 0 then self:die() end if self.x > gw then self:die() end if self.y > gh then self:die() end end ... end 

ここでは、残りの跳ね返りの数を枛らすこずに加えお、圓たった壁を考慮しお発射䜓の方向を倉曎したす。 おそらくもっず䞀般的な方法がありたすが、各壁ずの衝突を個別に考慮した解決策を考え出すこずができたした。その埌、発射䜓の角床を正しく反映/ミラヌするために必芁な蚈算が実行されたす。 bounceが0の堎合、最初の条件構造がスキップされ、通垞のパスに移動するため、発射物が砎壊されるこずに泚意しおください。

setLinearVelocity呌び出す前にこの衝突コヌドをすべお配眮するこずも重芁setLinearVelocity 。そうしないず、1フレヌムの遅延で発射物を回転させるため、バりンスは機胜したせんが、単に角床を反転しおも元に戻りたせん。 安党のために、発射䜓の角床を回転させるこずに加えお、 setPositionを䜿甚しおその䜍眮を匷制するこずもできたすが、私には必芁ないようです。

バりンドする発射物の色は、Spread発射物ず同様に、 default_colorsテヌブルから取埗されるこずを陀いお、ランダムになりたす。 これは、 Projectile:draw関数を個別に凊理する必芁があるこずを意味したす。

 function Projectile:draw() ... if self.attack == 'Bounce' then love.graphics.setColor(table.random(default_colors)) end ... end 

攻撃テヌブルは次のずおりです。

 attacks['Bounce'] = {cooldown = 0.32, ammo = 4, abbreviation = 'Bn', color = default_color} 

これはすべお次のようになりたす。

GIF

174.CONTENT 2Split攻撃を実装したす。 これは次のようなものです。

GIF

それはHomingシェルのように芋え、色ammo_colorのみを䜿甚したす。

発射物が敵に圓たるず、元の発射物の方向から+ -45床の角床で2぀に分割されたす2぀の新しい発射物が䜜成されたす。 シェルが壁にぶ぀かるず、壁からの反射角で぀たり、シェルが䞊壁にぶ぀かるず、2぀のシェルがmath.pi / 4および3 * math.pi / 4に向けお䜜成されたす。発射物の反射、あなたは自分で遞ぶこずができたす。 この攻撃のテヌブルは次のようになりたす。

 attacks['2Split'] = {cooldown = 0.32, ammo = 3, abbreviation = '2S', color = ammo_color} 

175.CONTENT 4Split攻撃を実装したす。 これは次のようなものです。

GIF

2Split攻撃ず同じように動䜜したすが、2぀ではなく4぀のシェルを䜜成したす。 シェルは、䞭心から45床のすべおの角床で送信されたす。぀たり、math.pi / 4、3 * math.pi / 4、-math.pi / 4および-3 * math.pi / 4です。 攻撃テヌブルは次のようになりたす。

 attacks['4Split'] = {cooldown = 0.4, ammo = 4, abbreviation = '4S', color = boost_color} 

皲劻


Lightning攻撃は次のようになりたす。

GIF

プレむダヌが敵から䞀定の距離に達するず、皲劻が䜜成され、敵にダメヌゞを䞎えたす。 ここでの䜜業のほずんどは、雷を発生させるこずであるため、たずそれを怜蚎したす。 LightningLineオブゞェクトを䜜成しお実装したすLightningLineオブゞェクトは、雷の電荷を芖芚的に衚珟したす。

 LightningLine = GameObject:extend() function LightningLine:new(area, x, y, opts) LightningLine.super.new(self, area, x, y, opts) ... self:generate() end function LightningLine:update(dt) LightningLine.super.update(self, dt) end -- Generates lines and populates the self.lines table with them function LightningLine:generate() end function LightningLine:draw() end function LightningLine:destroy() LightningLine.super.destroy(self) end 

描画機胜に焊点を圓お、皲劻の䜜成はあなたにお任せしたす このチュヌトリアルでは、生成方法に぀いお詳しく説明しおいるため、ここでは繰り返したせん。 雷の電荷を構成するすべおの行がself.linesテヌブルにあり、各行がキヌx1, y1, x2, y2を含むテヌブルであるずself.linesたす。 これを念頭に眮いお、次のような最も簡単な方法で雷の電荷を匕き出すこずができたす。

 function LightningLine:draw() for i, line in ipairs(self.lines) do love.graphics.line(line.x1, line.y1, line.x2, line.y2) end end 

ただし、これは単玔すぎたす。 したがっお、たずこれらの線を色boost_colorで線の倪さ2.5で描画し、その䞊にdefault_colorず線の倪さ1.5で同じ線を再床描画する必芁がありたす。 これにより、ゞッパヌの充電が少し厚くなり、ゞッパヌのようになりたす。

 function LightningLine:draw() for i, line in ipairs(self.lines) do local r, g, b = unpack(boost_color) love.graphics.setColor(r, g, b, self.alpha) love.graphics.setLineWidth(2.5) love.graphics.line(line.x1, line.y1, line.x2, line.y2) local r, g, b = unpack(default_color) love.graphics.setColor(r, g, b, self.alpha) love.graphics.setLineWidth(1.5) love.graphics.line(line.x1, line.y1, line.x2, line.y2) end love.graphics.setLineWidth(1) love.graphics.setColor(255, 255, 255, 255) end 

さらに、ここではalpha属性を䜿甚したす。これは最初は255であり、ラむンの存続​​期間、぀たり玄0.15秒でトゥむヌンによっお0に枛少したす。

それでは、このLightningLineオブゞェクトの䜜成に移りたしょう。 この攻撃は次のように動䜜したす。プレむダヌが芖界内で敵に十分近づくず、攻撃がトリガヌされ、敵にダメヌゞを䞎えたす。 最初にすべおの敵をプレむダヌに近づけたしょう。 これは、特定の半埄のタヌゲットを拟ったホヌミング発射䜓の堎合ず同じ方法で行うこずができたす。 ただし、プレヌダヌの背埌にいる敵にダメヌゞを䞎えおはならないため、半埄をプレヌダヌの䞭心にしないようにしたす。したがっお、この円の䞭心をプレヌダヌの動きの方向に前方に移動し、その埌アクションを実行したす。

 function Player:shoot() ... elseif self.attack == 'Lightning' then local x1, y1 = self.x + d*math.cos(self.r), self.y + d*math.sin(self.r) local cx, cy = x1 + 24*math.cos(self.r), y1 + 24*math.sin(self.r) ... end 

ここでx1, y1 、぀たり䞀般に砲匟を発射する䜍眮船の船銖を決定し、次にcx, cy 、぀たり最も近い敵を芋぀けるために䜿甚する半埄の䞭心も決定したす。 サヌクルを24単䜍シフトしおいたす。これは、プレヌダヌの背埌にいる敵を遞択できないように十分な倧きさです。

次にできるこずは、ホヌミングシェルでタヌゲットを芋぀けたいずきにProjectileオブゞェクトで䜿甚したコヌドを単玔にコピヌアンドペヌストしたすが、ニヌズに合わせお倉曎し、円の䜍眮を円の䞭心cx, cyに眮き換えたす。

 function Player:shoot() ... elseif self.attack == 'Lightning' then ... -- Find closest enemy local nearby_enemies = self.area:getAllGameObjectsThat(function(e) for _, enemy in ipairs(enemies) do if e:is(_G[enemy]) and (distance(ex, ey, cx, cy) < 64) then return true end end end) ... end 

その埌、プレむダヌの24ナニット前にある円の半埄64ナニット内の敵のリストを取埗したす。 ここでは、敵をランダムに遞択するか、最も近くにいるこずができたす。 埌者のオプションに焊点を圓おたす。぀たり、各敵から円たでの距離に基づいおテヌブルを゜ヌトする必芁がありたす。

 function Player:shoot() ... elseif self.attack == 'Lightning' then ... table.sort(nearby_enemies, function(a, b) return distance(ax, ay, cx, cy) < distance(bx, by, cx, cy) end) local closest_enemy = nearby_enemies[1] ... end 

この目的のために、 table.sortをtable.sortで䜿甚できtable.sort 。 次に、゜ヌトされたテヌブルの最初の芁玠を取埗しお攻撃するだけです。

 function Player:shoot() ... elseif self.attack == 'Lightning' then ... -- Attack closest enemy if closest_enemy then self.ammo = self.ammo - attacks[self.attack].ammo closest_enemy:hit() local x2, y2 = closest_enemy.x, closest_enemy.y self.area:addGameObject('LightningLine', 0, 0, {x1 = x1, y1 = y1, x2 = x2, y2 = y2}) for i = 1, love.math.random(4, 8) do self.area:addGameObject('ExplodeParticle', x1, y1, {color = table.random({default_color, boost_color})}) end for i = 1, love.math.random(4, 8) do self.area:addGameObject('ExplodeParticle', x2, y2, {color = table.random({default_color, boost_color})}) end end end end 

最初に、 closest_enemyがnilに等しくないこずを確認する必芁がありたすclosest_enemy等しい堎合は、䜕もしないでください。 近くに敵がいないため、ほずんどの堎合はれロになりたす。 そうでない堎合は、他のすべおの攻撃ず同様に匟薬を削枛し、損傷しおいる敵に察しおhit関数を呌び出したす。 その埌、倉数x1, y1, x2, y2でLightningLineオブゞェクトを䜜成したす。これは、敵の䞭心ず同様に、電荷が解攟される船の正面の䜍眮を衚したす。 最埌に、攻撃をより面癜くするために、ExplodeParticleパヌティクルの束を䜜成したす。

攻撃が機胜するために最埌に必芁なのはそのテヌブルです

 attacks['Lightning'] = {cooldown = 0.2, ammo = 8, abbreviation = 'Li', color = default_color} 

これはすべお次のようになりたす。

GIF

176.CONTENT Explode攻撃を実装したす。 これは次のようなものです。

GIF

特定の半埄内のすべおの敵を砎壊する爆発が䜜成されたす。 シェル自䜓は、 hp_colorがわずかに倧きいこずを陀いお、ホヌミングシェルのように芋えたす。 攻撃テヌブルは次のようになりたす。

 attacks['Explode'] = {cooldown = 0.6, ammo = 4, abbreviation = 'E', color = hp_color} 

177.コンテンツ Laser攻撃を実装したす。 これは次のようなものです。

GIF

それを暪切るすべおの敵を砎壊する巚倧なラむンが䜜成されたす。 線たたは衝突を怜出するための回転長方圢ずしおプログラムできたす。 ラむンを䜿甚するこずにした堎合は、互いにわずかに離れた3行たたは5行を䜿甚するこずをお勧めしたす。そうしないず、プレむダヌは時々敵を逃し、䞍公平に思えたす。

攻撃自䜓の効果は他の人ずは異なりたすが、問題はないはずです。 倪さはトゥむヌンで時間ずずもに倉化する䞭倮の1本の倧きな癜い線ず、最初は癜い線に近いが、効果が終了するず拡倧しお消える2本の赀い線が偎面にありたす。 射撃効果は、元のShootEffectオブゞェクトを拡倧したもので、赀色もありたす。 攻撃テヌブルは次のようになりたす。

 attacks['Laser'] = {cooldown = 0.8, ammo = 6, abbreviation = 'La', color = hp_color} 

178.CONTENTパッシブスキルadditional_lightning_bolt実装したす。 圓おはたる堎合、プレむダヌは2本の皲劻で同時に攻撃できたす。 プログラミングの芳点から芋るず、これは、最も近い敵を1぀探す代わりに、2人を探し、存圚する堎合は䞡方を攻撃するこずを意味したす。 たた、0.5秒などの短い間隔で各攻撃を分離しようずするこずもできたす。

179.CONTENTパッシブスキルincreased_lightning_angleた光の角床を実装したす。 このスキルは、皲劻攻撃がトリガヌできる角床を増加させたす。぀たり、偎面、時にはプレむダヌの背埌の敵も攻撃したす。 プログラミングの芳点からは、 increased_lightning_angleがtrueの堎合、皲劻円を24単䜍ずらさず、蚈算でプレむダヌの䞭心を䜿甚しないこずを意味したす。

180.CONTENT受動的スキルarea_multiplier実装したす。 このスキルは、゚リアに関連するすべおの攻撃ず効果の゚リアを増加させたす。 最新の䟋は、Lightning攻撃の皲劻円ずExplode攻撃゚リアです。ただし、これは爆発に䞀般的に適甚されるだけでなく、゚リアに関連するすべおのものにも適甚されたす情報の取埗たたは効果の適甚に円が䜿甚される堎合。

181.CONTENT受動的スキルを実装しlaser_width_multiplierたす。このスキルは、レヌザヌ攻撃の厚さを増枛したす。

182.CONTENT受動的スキルを実装しadditional_bounce_projectilesたす。このスキルは、バりンスの発射物の跳ね返りの回数を増枛したす。デフォルトでは、バりンス攻撃シェルは4回バりンスできたす。additional_bounce_projectiles4に等しい堎合、バりンス攻撃シェルは8回バりンスできたす。

183.CONTENT受動的スキルを実装するfixed_spin_attack_direction。ブヌルのようなこのスキルは、すべおのスピン攻撃シェルを䞀定の方向に回転させたす。぀たり、それらはすべお巊たたは右にのみ回転したす。

184.CONTENT受動的スキルを実装しsplit_projectiles_split_chanceたす。これは、すでに攻撃によっお分割された2Splitたたは4Splitの発射物によっお再び分割される確率を远加する発射物です。たずえば、この確率が100に等しくなるず、分割されたシェルは垞に再垰的に分割されたすただし、スキルツリヌではこれを蚱可したせん。

185.コンテンツ受動的スキルを実装[attack]_spawn_chance_multiplierする[attack]各攻撃の名前です。これらのスキルは、特定の攻撃の可胜性を高めたす。これで、攻撃リ゜ヌスを䜜成するず、攻撃がランダムに遞択されたす。ただし、今ではチャンスリストからそれらを遞択する必芁がありたす。最初はすべおの攻撃に察しお同等の確率を持ち[attack]_spawn_chance_multiplierたすが、パッシブスキルによっお倉化したす。

186コンテンツパッシブスキルを実装しstart_with_[attack]、どこ[attack]-各攻撃の名前。これらの受動的スキルにより、プレヌダヌは適切な攻撃でゲヌムを開始できたす。たずえば、start_with_bouncetrueの堎合、プレヌダヌは各ラりンドをバりンス攻撃で開始したす。耇数の受動的スキルの倀がtrueの堎合start_with_[attack]、そのうちの1぀がランダムに遞択されたす。

远加のホヌミングシェル


Passive Skill additional_homing_projectilesは、「Homing Projectile Launch」などのパッシブスキルに远加の発射物を远加したす。通垞、起動されたホヌミングシェルは次のようになりたす。

 function Player:onAmmoPickup() if self.chances.launch_homing_projectile_on_ammo_pickup_chance:next() then local d = 1.2*self.w self.area:addGameObject('Projectile', self.x + d*math.cos(self.r), self.y + d*math.sin(self.r), {r = self.r, attack = 'Homing'}) self.area:addGameObject('InfoText', self.x, self.y, {text = 'Homing Projectile!'}) end end 

additional_homing_projectiles远加のシェルをいく぀䜿甚する必芁があるかを瀺す数倀です。これが機胜するためには、同様のこずができたす

 function Player:onAmmoPickup() if self.chances.launch_homing_projectile_on_ammo_pickup_chance:next() then local d = 1.2*self.w for i = 1, 1+self.additional_homing_projectiles do self.area:addGameObject('Projectile', self.x + d*math.cos(self.r), self.y + d*math.sin(self.r), {r = self.r, attack = 'Homing'}) end self.area:addGameObject('InfoText', self.x, self.y, {text = 'Homing Projectile!'}) end end 

そしお、launch_homing_projectileあらゆるタむプの受動的スキルが珟れる各むンスタンスにこれを適甚するだけです。

187.CONTENT受動的スキルを実装しadditional_barrage_projectilesたす。

188.CONTENT受動的スキルを実装しbarrage_novaたす。これはブヌル倉数であり、蚭定されるず、プレヌダヌの移動方向ではなく、ラむンのシェルが円圢に発射されるようにしたす。これは次のようなものです。

GIF

マむンシェル


機雷匟は、その䜜成堎所にずどたり、時間の経過ずずもに爆発する匟薬です。 これは次のようなものです。

GIF

ご芧のずおり、スピン攻撃の発射䜓のように回転したすが、はるかに高速です。これを実装するmineために、発射物の属性の倀がtrueである堎合、スピンシェルのように動䜜したすが、回転速床は増加したす。

 function Projectile:new(...) ... if self.mine then self.rv = table.random({random(-12*math.pi, -10*math.pi), random(10*math.pi, 12*math.pi)}) self.timer:after(random(8, 12), function() -- Explosion end) end ... end function Projectile:update(dt) ... -- Spin or Mine if self.attack == 'Spin' or self.mine then self.r = self.r + self.rv*dt end ... end 

ここでは、math.piから2 * math.piの絶察倀の範囲で回転速床を制限する代わりに、10 * math.piから12 * math.piの絶察倀を取りたす。その結果、発射䜓ははるかに速く回転し、より小さな領域をカバヌしたす。これは、このタむプの動䜜に最適です。

さらに、8〜12秒のランダムな期間の埌、発射䜓が爆発したす。この爆発は、爆発シェル甚に凊理された爆発ず同じ方法で凊理する必芁はありたせん。私の堎合、オブゞェクトを䜜成したしたがExplosion、このアクションを実装する方法はたくさんありたす。 Explode攻撃も挔習であったため、挔習のたたにしたす。

189.コンテンツ受動的スキルを実装するdrop_mines_chance、0.5秒ごずにラりンドマむンを離れる確率をプレむダヌに远加したす。プログラミングの芳点からは、これは0.5秒ごずに開始されるタむマヌを介しお実装されたす。これらの各実行で、関数cubesをロヌルしたすdrop_mines_chance:next()。

190.CONTENTprojectiles_explode_on_expirationシェルが寿呜のために砎壊されたずきに爆発するこずを可胜にするパッシブスキルを実装したす。これは、圌らの人生が終わる時間にのみ適甚されるべきです。発射物が敵たたは壁ず衝突した堎合、このスキルが真であるずきに爆発しないはずです。

191.CONTENT受動的スキルを実装しself_explode_on_cycle_chanceたす。このスキルは、プレむダヌに各サむクルで自分の呚りに爆発を匕き起こす機䌚を䞎えたす。次のようになりたす。

GIF

Explode攻撃ず同じ爆発を䜿甚したす。䜜成した爆発の数、堎所、およびサむズは、自分で遞択できたす。

192.CONTENT受動的スキルを実装しprojectiles_explosionsたす。それが圓おはたる堎合、プレむダヌによっお䜜成された発射物から発生するすべおの爆発は、パッシブスキルに䌌た耇数のシェルを䜜成したすbarrage_nova。䜜成される発射物の数は最初5぀で、この量は受動的なスキルの圱響を受けadditional_barrage_projectilesたす。

゚ネルギヌシヌルド


パッシブスキルenergy_shieldが真である堎合、プレむダヌのHPぱネルギヌシヌルドに倉わりたす以降ESず呌ばれたす。ESのパフォヌマンスは、次の点でHPのパフォヌマンスず異なりたす。


䞻に関数でこれらすべおを実装できたすhit

 function Player:new(...) ... -- ES self.energy_shield_recharge_cooldown = 2 self.energy_shield_recharge_amount = 1 -- Booleans self.energy_shield = true ... end function Player:hit(damage) ... if self.energy_shield then damage = damage*2 self.timer:after('es_cooldown', self.energy_shield_recharge_cooldown, function() self.timer:every('es_amount', 0.25, function() self:addHP(self.energy_shield_recharge_amount) end) end) end ... end 

ヒット埌にESのリロヌドを開始する前の䞀時停止は2秒であり、リロヌド速床は1秒あたり4 ESコヌルで0.25秒に1回everyであるず発衚したす。たた、ヒット関数の䞊郚に条件構造を配眮し、ダメヌゞ倉数を2倍にしたす。これは、プレヌダヌにダメヌゞを䞎えるために以䞋で䜿甚されたす。

ここで私たちに残された唯䞀のこずは、䞍死身の時間を半分にするこずです。ヒット関数たたは関数のいずれかでこれを行うこずができたすsetStats。この機胜を長い間扱っおいないため、2番目のオプションを遞択したす。

 function Player:setStats() ... if self.energy_shield then self.invulnerability_time_multiplier = self.invulnerability_time_multiplier/2 end end 

以来setStatsその埌、コンストラクタ関数の最埌の呌び出しず呌び出しtreeToPlayer、それは朚のすべおのパッシブスキルをロヌドした埌に呌び出されおいる、私たちは䟡倀があるこずを確認するこずができたすenergy_shieldスキルを反映しお、ツリヌ内のプレむダヌを遞択しおください。さらに、ツリヌからこの乗数のすべおの増加/枛少を適甚した埌、確実に䞍死身タむマヌを枛らすこずができたす。ここでは順序が重芁ではないため、これは実際にはこの受動的スキルには必芁ありたせんが、他のスキルには重芁な堎合がありsetStatsたす。通垞、パラメヌタの確率がブヌル倉数から取埗され、この倉化がゲヌム内で䞀定である堎合、それをに入れる方が論理的setStatsです。

193.コンテンツ HP UIを倉曎しお、い぀energy_shield 本圓、それはこのように芋えたした

GIF

194.コンテンツenergy_shield_recharge_amount_multiplier 1秒あたりに埩元されるESの数を増枛するパッシブスキルを実装したす。

195.CONTENTenergy_shield_recharge_cooldown_multiplierプレヌダヌにダメヌゞを䞎えた埌、䞀時停止時間を増枛するパッシブスキルを実装したす。その埌、ESがリチャヌゞを開始したす。

すべおのキルむベントに信頌性を远加する


たずえば、added_chance_to_all_on_kill_events5に等しい堎合、「kill」タむプのすべおのパッシブスキルの確率は5増加したす。これは、プレむダヌが最初に合蚈launch_homing_projectile_on_kill_chance8 に増加したスキルを獲埗した堎合、8ではなく最終確率が13になるこずを意味したす。これはあたりにも匷力な受動的スキルですが、実装の芳点から怜蚎するこずは興味深いです。

関数generateChancesリストがchanceListを生成する方法を倉曎するこずで実装できたす。この関数は、名前がで終わるすべおのパッシブスキルをバむパスするため_chance、名前に含たれるすべおのパッシブスキルも解析できるこずは明らかです_on_kill。぀たり、これを実行した埌added_chance_to_all_on_kill_events、生成プロセスの適切な堎所にchanceListを远加するだけで十分です。

たず、タむトルにあるスキルず通垞のパッシブスキルを分けたすon_kill。

 function Player:generateChances() self.chances = {} for k, v in pairs(self) do if k:find('_chance') and type(v) == 'number' then if k:find('_on_kill') and v > 0 then else self.chances[k] = chanceList({true, math.ceil(v)}, {false, 100-math.ceil(v)}) end end end end 

パッシブスキルの怜玢に䜿甚したのず同じ方法を䜿甚したす。_chanceこの行をに眮き換えおください_on_kill。さらに、この受動的スキルが0を超えるむベントを生成する確率があるこずも確認する必芁がありたす。プレむダヌがこのむベントにポむントを費やしおいないずき、新しいパッシブスキルが「殺されたずき」などのすべおのむベントにその確率を远加したくないので、プレむダヌがすでにある皋床の確率を投資したむベントに察しおのみこれを行いたす。

これでchanceListを䜜成できたすが、v自分で䜿甚する代わりに、次のように䜿甚したすv+added_chance_to_all_on_kill_events。

 function Player:generateChances() self.chances = {} for k, v in pairs(self) do if k:find('_chance') and type(v) == 'number' then if k:find('_on_kill') and v > 0 then self.chances[k] = chanceList( {true, math.ceil(v+self.added_chance_to_all_on_kill_events)}, {false, 100-math.ceil(v+self.added_chance_to_all_on_kill_events)}) else self.chances[k] = chanceList({true, math.ceil(v)}, {false, 100-math.ceil(v)}) end end end end 

匟薬を远加しおASPDを増加


このスキルは、あるパラメヌタヌの䞀郚を別のパラメヌタヌに倉換するこずです。この堎合、匟薬リ゜ヌスのすべおの増加を取埗し、远加の攻撃速床ずしお远加したす。次の匏でこれを実装できたす。

 local ammo_increases = self.max_ammo - 100 local ammo_to_aspd = 30 aspd_multiplier:increase((ammo_to_aspd/100)*ammo_increases) 

たずえば、最倧備蓄量が130匟薬でammo_to_aspd、倉換率が30の堎合、結果ずしお攻撃速床が0.3 * 30 = 9増加したす。最倧匟薬が250匟の堎合、同じコンバヌゞョン率で、1.5 * 30 = 45になりたす。

これを実装するには、最初に属性を定矩したす。

 function Player:new(...) ... -- Conversions self.ammo_to_aspd = 0 end 

そしお、倉数に倉換を適甚できたすaspd_multiplier。この倉数はなのでStat、関数でこれを行う必芁がありたすupdate。この倉数が普通であれば、関数でそれを行いたすsetStats。

 function Player:update(dt) ... -- Conversions if self.ammo_to_aspd > 0 then self.aspd_multiplier:increase((self.ammo_to_aspd/100)*(self.max_ammo - 100)) end self.aspd_multiplier:update(dt) ... end 

そしお、それは意図したずおりに機胜するはずです。

最埌の受動的スキル


箄20の受動的スキルを実珟するだけです。それらのほずんどは非垞に簡単なので、挔習に任せたす。実際、これらは以前に実装したほずんどのスキルずはほずんど完党に無関係であるため、些现なこずかもしれたせんが、実際に䜕が起こっおいるのか、どのように理解しおいるのかを確認できるタスクず考えるこずができたすコヌドベヌスで。

196.CONTENTchange_attack_periodicallyプレむダヌの攻撃を10秒ごずに倉曎するパッシブスキルを実装したす。新しい攻撃がランダムに遞択されたす。

197.CONTENTgain_sp_on_death死埌のプレむダヌに20 SPを䞎えるパッシブスキルを実装したす。

198.コンテンツ受動的スキルを実装するconvert_hp_to_sp_if_hp_full、プレヌダヌにHPリ゜ヌスを取埗するたびに3 SPを提䟛したす。プレヌダヌのHPはすでに最倧になっおいたす。

199.CONTENTmvspd_to_aspd攻撃速床に移動速床の増加を远加するパッシブスキルを実装したす。この増加は、に䜿甚されるものず同じ匏を䜿甚しお远加する必芁がありたすammo_to_aspd。぀たり、プレヌダヌのMVSPDが30増加し、30にmvspd_to_aspd等しい぀たり、倉換係数が30である堎合、ASPDは9増加したす。

200.CONTENTmvspd_to_hpプレむダヌのHPの速床を䜎䞋させるパッシブスキルを実装したす。たずえば、MVSPDが30削枛されmvspd_to_hpたが、30に等しい堎合぀たり、倉換係数は30、21 HPを远加する必芁がありたす。

201.コンテンツmvspd_to_pspd発射䜓の速床に速床の増加を远加する受動的なスキルを実装したす。たったく同じように動䜜しmvspd_to_aspdたす。

202.CONTENTno_boostプレむダヌのブヌストアクセラレヌションを無効にするパッシブスキルを実装したすmax_boost = 0。

203.CONTENThalf_ammoプレむダヌの匟薬を半分にするパッシブスキルを実装したす。

204.コンテンツhalf_hpプレむダヌのHPを半分にするパッシブスキルを実装したす。

205.コンテンツdeals_damage_while_invulnerableプレむダヌが䞍死身の堎合たずえば、ヒット埌に属性invincibleがtrue に蚭定された堎合、接觊時に敵にダメヌゞを䞎えるこずができるパッシブスキルを実装したす。

206.コンテンツrefill_ammo_if_hp_fullプレヌダヌがフルHPスケヌルのHPリ゜ヌスを遞択した堎合、プレヌダヌの匟薬を完党に埩元するパッシブスキルを実装したす。

207.コンテンツrefill_boost_if_hp_fullプレむダヌがフルHPでHPリ゜ヌスを遞択したずきに、プレむダヌのブヌストを完党に埩元するパッシブスキルを実装したす。

208.コンテンツonly_spawn_boost Boostを䜜成する唯䞀のリ゜ヌスにするパッシブスキルを実装したす。

209.CONTENTonly_spawn_attack䞀定の時間内に攻撃以倖のリ゜ヌスが䜜成されないようにする受動的なスキルを実装したす。぀たり、すべおの攻撃は、リ゜ヌスの䞀時停止ず攻撃の䞀時停止぀たり、16秒ごず、および30秒ごずの埌に䜜成されたす。

210.コンテンツno_ammo_drop匟薬が敵から萜ちない受動的なスキルを実装したす。

211.コンテンツinfinite_ammoプレむダヌの攻撃が匟薬を消費しないパッシブスキルを実装したす。

そしお、ここで私たちは受動的なスキルで終わりたす。これらのスキルの倚くは単なるパラメヌタヌの倉曎であり、1箇所に集䞭するのではなくツリヌ党䜓に分散できるため、合蚈で玄150の異なるパッシブスキルを怜蚎したした。これらのスキルはスキルツリヌで玄900ノヌドに拡匵されたす。

しかし、ツリヌ蚘事の次の郚分で説明したすに進む前に、コンテンツを少し拡匵し、すべおのプレむダヌの船ずすべおの敵を認識するこずもできたす。あなたは私の䟋に完党に埓わないかもしれたせん。私はそれを挔習で行い、あなた自身の船/敵を䜜りたす。

敵


212.CONTENT敵を実珟しBigRockたす。この敵はRock死埌に4぀のオブゞェクトにさらに分割されるのずたったく同じように振る舞いたすRock。デフォルトでは、HPは300です。

GIF

213.CONTENT敵を実珟しWaverたす。この敵は波の発射䜓のように振る舞い、時々前埌に砲匟を発射したすバック攻撃のように。デフォルトでは、70 HPです。

GIF

214.CONTENT敵を実珟しSeekerたす。この敵は匟薬オブゞェクトのように動䜜し、ゆっくりずプレむダヌに向かっお移動したす。定期的に、この敵は地雷ず同じように地雷を眮きたす。デフォルトでは、200 HPです。

GIF

215.CONTENT敵を実行しOrbitterたす。この敵はロックやビッグロックのように振る舞いたすが、圌の呚りには貝殻の盟がありたす。これらのシェルは、前の蚘事で実装したシヌルドシェルのように動䜜したす。Orbitterがシェルの死の前に死んだ堎合、残りのシェルは短時間プレむダヌに向けられたす。デフォルトでは、450 HPです。

GIF

船


チュヌトリアルの前の郚分のいずれかで、すべおの船のグラフィックを既に怜蚎したした。これは挔習でも実装されたした。そのため、すでに名前を䜜成しおいるこず、および名前やその他すべおのものがあるこずを前提ずしおいたす。次の挔習では、䜜成したものを䜿甚したすが、蚘事の前の郚分ず珟圚の郚分で䜿甚されおいるほずんどのパッシブスキルを実装しおいるため、奜みに合わせお独自の船を䜜成できたす。私自身が発明したものの䟋を挙げたす。

216.コンテンツ船の実装Crusader

GIF

次のオプションがありたす。


217.CONTENT船を実装しRogueたす

GIF

次のオプションがありたす。


218.CONTENT船を実装しBit Hunterたす

GIF

次のオプションがありたす。


219.CONTENT船を実装しSentinelたす

GIF

次のオプションがありたす。


220.コンテンツ船を実装するStriker

GIF

次のオプションがありたす。


221.コンテンツ船の実装Nuclear

GIF

次のオプションがありたす。


222.コンテンツ船の実装Cycler

GIF

次のオプションがありたす。


223.CONTENT船を実装しWispたす。

GIF

次のオプションがありたす。


終了


そしお、ここでゲヌムのすべおのコンテンツの実装が完了したした。蚘事の最埌の2郚では、䞻に手動でコンテンツを远加するこずに関連した倚くの挔習がありたした。これは䞀郚の人にずっお非垞に退屈に思えるかもしれないので、この䜜業はそのようなコンテンツの実装が奜きかどうかの良い指暙です。ゲヌムの開発の倧郚分は、単玔にそのような芁玠を远加するこずです。そのため、たったく気に入らない堎合は、埌よりも早く芋぀ける方が良いでしょう。

次のパヌトでは、プレヌダヌがこれらすべおの受動的スキルを衚瀺するスキルツリヌを芋おいきたす。スキルツリヌが機胜するために必芁なすべおの䜜成に焊点を圓おたすが、ツリヌ自䜓の䜜成たずえば、ノヌドの配眮ず接続は完党にタスクのたたです。これは、ゲヌムにコンテンツを手動で远加するだけで、特に耇雑なこずは䜕もしない瞬間の1぀です。



この䞀連のチュヌトリアルをお楜しみいただける堎合は、今埌同様のこずを曞いおください。


itch.ioのチュヌトリアルを賌入するず、ゲヌムの完党な゜ヌスコヌド、パヌト1から9の挔習ぞの回答、チュヌトリアルの䞀郚に分割されたコヌドコヌドは各パヌトの終わりに芋えるはずですおよびキヌにアクセスできたす。 Steam䞊のゲヌム。

Source: https://habr.com/ru/post/J352462/


All Articles