add slow trap

This commit is contained in:
VisualGMQ 2022-08-06 02:31:13 +08:00
parent 21740b8349
commit 530f347b7b
7 changed files with 119 additions and 19 deletions

View File

@ -36,3 +36,7 @@ cmake --build build --target install
# 体积过大 # 体积过大
游戏最后的可执行文件和库是经过压缩的(先`strip`再`upx`最后结果超出1M很正常。 游戏最后的可执行文件和库是经过压缩的(先`strip`再`upx`最后结果超出1M很正常。
# 游戏截图
![snapshot](./snapshot/snapshot.png)

25
game/HowToPlay.txt Normal file
View File

@ -0,0 +1,25 @@
# InfinitShoot
## 游戏介绍
玩家扮演一个枪手,要尽可能地在怪物的围攻中活下来
## 游戏玩法
左键射击wasd移动
## 游戏内容
游戏中的敌人会向你移动,想办法击杀或者躲开它们。
游戏中存在三种类型的子弹:
* 普通子弹:玩家初始的子弹,射速最快,伤害中等,但是没有特殊效果
* 火焰子弹:射速最慢,但是伤害最高,附加怪物火焰效果
* 冰冻子弹:射速中等,伤害中等,可以冻住怪物,冰冻期间触碰怪物不会受到伤害
特殊效果子弹通过击杀20个敌人后从空投中获得。
空投中除了子弹,还有回血的道具,吃完后立刻回血。
游戏中的敌人尸体在一定时间后会腐烂,踩在腐烂的尸体上将会极大地减少玩家的速度

View File

@ -13,14 +13,17 @@ _M.SoundName = {
_M.TileSize = 32 _M.TileSize = 32
_M.PlayerInfo = { _M.PlayerInfo = {
velocity = 250, velocity = 200,
hp = 100, hp = 50,
} }
_M.PlayerSlowSpeed = 50
_M.MonsterInfo = { _M.MonsterInfo = {
velocity = 100, velocity = 100,
hp = 50, hp = 50,
damage = 10, damage = 10,
} }
_M.MonsterDissolveTime = 5
_M.RoleColliBox = { _M.RoleColliBox = {
w = 14, w = 14,
h = 32, h = 32,
@ -51,9 +54,6 @@ _M.MonsetHpBarInfo= {
width = _M.TileSize, width = _M.TileSize,
height = 5, height = 5,
} }
_M.GunInfo = {
cooldown = 0.1
}
_M.BulletType = { _M.BulletType = {
Normal = 1, Normal = 1,
@ -71,20 +71,20 @@ _M.BulletInfo = {
[_M.BulletType.Ice] = { [_M.BulletType.Ice] = {
damage = 5, damage = 5,
velocity = 400, velocity = 400,
cooldown = 0.1, cooldown = 0.2,
initNum = 100, initNum = 100,
}, },
[_M.BulletType.Fire] = { [_M.BulletType.Fire] = {
damage = 7, damage = 7,
velocity = 600, velocity = 600,
cooldown = 0.1, cooldown = 0.4,
fireDamage = 1, fireDamage = 1,
initNum = 100, initNum = 100,
}, },
} }
_M.BulletEffectTime = { _M.BulletEffectTime = {
IceTime = 2, IceTime = 5,
FireTime = 2, FireTime = 2,
} }
_M.RoleState = { _M.RoleState = {

View File

@ -117,7 +117,8 @@ local ComponentType = {
Animator = 11, Animator = 11,
State = 12, State = 12,
Supply = 13, Supply = 13,
Image = 14, SlowTrap = 14,
Image = 15,
} }
_M.ComponentType = ComponentType _M.ComponentType = ComponentType
@ -430,6 +431,9 @@ function _M.CreateGunComponent(type, bulletNum)
o.SetType = function(self, type) o.SetType = function(self, type)
self.type = type or constants.BulletType.Normal self.type = type or constants.BulletType.Normal
self.bulletNum = constants.BulletInfo[self.type].initNum self.bulletNum = constants.BulletInfo[self.type].initNum
o.cdTimer = timer.CreateTimer(constants.BulletInfo[type].cooldown, -1, function()
o.canShoot = true
end)
end end
o.GetBulletNum = function(self) o.GetBulletNum = function(self)
@ -521,6 +525,36 @@ function _M.CreateSupplyComponent(type)
end end
---@class SlowTrapComponent:Component
---@field IsEnable function
---@field StartDissolve function
---@return SupplyComponent
function _M.CreateSlowTrapComponent()
local o = { isActive = true, name = ComponentType.SlowTrap, isEnable = false, parent = nil }
---@type Timer
o.timer = nil
o.StartDissolve = function(self)
self.timer = timer.CreateTimer(constants.MonsterDissolveTime, 1, function()
self.isEnable = true
---@type ImageComponent
local image = self:GetParent():GetComponent(ComponentType.Image)
if image then
image.row = 12
image.col = 0
end
end)
end
o.IsEnable = function(self) return self.isEnable end
o.Update = function(self)
if self.timer then
self.timer:Update()
end
end
return _M.CreateComponent(o)
end
---@class StateComponent:Component ---@class StateComponent:Component
---@field rect Rect ---@field rect Rect
@ -575,6 +609,9 @@ function _M.CreateStateComponent(state)
local oldHp = roleProp.hp local oldHp = roleProp.hp
roleProp.hp = roleProp.hp - constants.BulletInfo[constants.BulletType.Fire].fireDamage roleProp.hp = roleProp.hp - constants.BulletInfo[constants.BulletType.Fire].fireDamage
if oldHp > 0 and roleProp.hp <= 0 then if oldHp > 0 and roleProp.hp <= 0 then
local slowTrap = _M.CreateSlowTrapComponent()
self:GetParent():SetComponent(slowTrap)
slowTrap:StartDissolve()
content.Score = content.Score + 1 content.Score = content.Score + 1
helpfuncs.IncKillNum() helpfuncs.IncKillNum()
end end
@ -634,7 +671,6 @@ function _M.CreateAnimatorComponent(ani)
return _M.CreateComponent(o) return _M.CreateComponent(o)
end end
---@return Entity ---@return Entity
---@param pos Point ---@param pos Point
---@param damage number ---@param damage number
@ -665,7 +701,7 @@ function _M.CreatePlayer(pos)
entity:SetComponent(_M.CreateImageComponent(content.Tilesheet, 0, 0)) entity:SetComponent(_M.CreateImageComponent(content.Tilesheet, 0, 0))
entity:SetComponent(_M.CreateRolePropComponent(constants.PlayerInfo.hp, constants.PlayerInfo.velocity)) entity:SetComponent(_M.CreateRolePropComponent(constants.PlayerInfo.hp, constants.PlayerInfo.velocity))
entity:SetComponent(_M.CreateDirectionComponent(0)) entity:SetComponent(_M.CreateDirectionComponent(0))
entity:SetComponent(_M.CreateGunComponent(constants.BulletType.Fire)) entity:SetComponent(_M.CreateGunComponent(constants.BulletType.Normal))
entity:SetComponent(_M.CreateColliBoxComponent(constants.RoleColliBox)) entity:SetComponent(_M.CreateColliBoxComponent(constants.RoleColliBox))
entity:SetComponent(_M.CreateInvincibleComponent(constants.Invincible)) entity:SetComponent(_M.CreateInvincibleComponent(constants.Invincible))
entity:SetComponent(_M.CreateStateComponent()) entity:SetComponent(_M.CreateStateComponent())

View File

@ -66,9 +66,14 @@ end
local function updateMonster() local function updateMonster()
---@param v Entity ---@param v Entity
for _, v in pairs(content.MonsterList) do for i, v in pairs(content.MonsterList) do
if v:GetComponent(ECS.ComponentType.RoleProp):IsDie() then
table.insert(content.MonsterCorpseList, v)
content.MonsterList[i] = nil
else
v:Update() v:Update()
end end
end
end end
local function updateMonsterCropse() local function updateMonsterCropse()
@ -92,7 +97,7 @@ local function collisionDeal()
local playerPos = content.PlayerEntity:GetComponent(ECS.ComponentType.Transform).position local playerPos = content.PlayerEntity:GetComponent(ECS.ComponentType.Transform).position
---@type Rect ---@type Rect
local playerColliBox = hazel.CreateRect(playerPos.x + playerBox.x, playerPos.y + playerBox.y, playerBox.w, playerBox.h) local playerColliBox = hazel.CreateRect(playerPos.x + playerBox.x, playerPos.y + playerBox.y, playerBox.w, playerBox.h)
---@type m Entity ---@type Entity
for km, _ in pairs(content.MonsterList) do for km, _ in pairs(content.MonsterList) do
---@type Entity ---@type Entity
local monster = content.MonsterList[km] local monster = content.MonsterList[km]
@ -162,11 +167,13 @@ local function collisionDeal()
hazel.Sound.Play(constants.SoundName.MonsterHurt) hazel.Sound.Play(constants.SoundName.MonsterHurt)
if monsterRoleProp:IsDie() then if monsterRoleProp:IsDie() then
if oldHp > 0 then if oldHp > 0 then
---@type SlowTrapComponent
local slowTrap = ECS.CreateSlowTrapComponent()
monster:SetComponent(slowTrap)
slowTrap:StartDissolve()
content.Score = content.Score + 1 content.Score = content.Score + 1
helpfunc.IncKillNum() helpfunc.IncKillNum()
end end
table.insert(content.MonsterCorpseList, monster)
content.MonsterList[km] = nil
end end
end end
end end
@ -188,7 +195,7 @@ local function collisionDeal()
if type == constants.SupplyType.HpRecover then if type == constants.SupplyType.HpRecover then
local index = #content.HpRecoverListAnim + 1 local index = #content.HpRecoverListAnim + 1
local hpRecoverAnim = animation.CreateAnimation(content.Tilesheet, { local hpRecoverAnim = animation.CreateAnimation(content.Tilesheet, {
{row = 12, col = 0, time = 0.5}, {row = 12, col = 1, time = 0.5},
}, function() }, function()
content.HpRecoverListAnim[index] = nil content.HpRecoverListAnim[index] = nil
end) end)
@ -213,6 +220,33 @@ local function collisionDeal()
end end
end end
end end
---@type boolean
local isSlowed = False
---@type RolePropComponent
local playerProp = content.PlayerEntity:GetComponent(ECS.ComponentType.RoleProp)
playerProp.speed = constants.PlayerSlowSpeed
---@param mk number
---@param corpse Entity
for mk, corpse in pairs(content.MonsterCorpseList) do
---@type Point
local corpsePos = corpse:GetComponent(ECS.ComponentType.Transform).position
---@type Rect
local corpseBox = corpse:GetComponent(ECS.ComponentType.ColliBox).rect
---@type Rect
local corpseColliBox = hazel.CreateRect(corpsePos.x + corpseBox.x, corpsePos.y + corpseBox.y,
corpseBox.w, corpseBox.h)
---@type SlowTrapComponent
local slowTrap = corpse:GetComponent(ECS.ComponentType.SlowTrap)
if slowTrap:IsEnable() and vmath.IsRectIntersect(corpseColliBox, playerColliBox) then
isSlowed = true
playerProp.speed = constants.PlayerSlowSpeed
end
end
if not isSlowed then
playerProp.speed = constants.PlayerInfo.velocity
end
end end
local function showRestartHint() local function showRestartHint()
@ -243,6 +277,7 @@ local function initGame()
content.HpRecoverListAnim = {} content.HpRecoverListAnim = {}
content.BulletList = {} content.BulletList = {}
content.MonsterList = {} content.MonsterList = {}
content.MonsterCorpseList = {}
content.SupplyList = {} content.SupplyList = {}
content.PlayerEntity = ECS.CreatePlayer(hazel.CreatePos(constants.TileSize * 16, constants.TileSize * 13)) content.PlayerEntity = ECS.CreatePlayer(hazel.CreatePos(constants.TileSize * 16, constants.TileSize * 13))
content.MonsterBirthNum = constants.MonsterBirthInitNum content.MonsterBirthNum = constants.MonsterBirthInitNum
@ -346,7 +381,7 @@ local function updateRoles()
monster:RemoveComponent(ECS.ComponentType.Direction) monster:RemoveComponent(ECS.ComponentType.Direction)
monster:RemoveComponent(ECS.ComponentType.AI) monster:RemoveComponent(ECS.ComponentType.AI)
monster:RemoveComponent(ECS.ComponentType.HpShow) monster:RemoveComponent(ECS.ComponentType.HpShow)
monster:RemoveComponent(ECS.ComponentType.ColliBox) -- monster:RemoveComponent(ECS.ComponentType.ColliBox)
monster:RemoveComponent(ECS.ComponentType.State) monster:RemoveComponent(ECS.ComponentType.State)
---@type ImageComponent ---@type ImageComponent
local image = monster:GetComponent(ECS.ComponentType.Image) local image = monster:GetComponent(ECS.ComponentType.Image)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
snapshot/snapshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB